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, SpellTargetReferenceTypes referenceType=TARGET_REFERENCE_TYPE_CASTER)
 
void SearchChainTargets (std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
 
SpellCastResult prepare (SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
 
void cancel (bool bySelf=false)
 
void update (uint32 difftime)
 
void cast (bool skipCheck=false)
 
void _cast (bool skipCheck)
 
void finish (bool ok=true)
 
void TakePower ()
 
void TakeAmmo ()
 
void TakeRunePower (bool didHit)
 
void TakeReagents ()
 
void TakeCastItem ()
 
SpellCastResult CheckCast (bool strict, uint32 *param1=nullptr, uint32 *param2=nullptr)
 
SpellCastResult CheckPetCast (Unit *target)
 
void handle_immediate ()
 
uint64 handle_delayed (uint64 t_offset)
 
void _handle_immediate_phase ()
 
void _handle_finish_phase ()
 
void OnSpellLaunch ()
 
SpellCastResult CheckItems (uint32 *param1=nullptr, uint32 *param2=nullptr)
 
SpellCastResult CheckSpellFocus ()
 
SpellCastResult CheckRange (bool strict)
 
SpellCastResult CheckPower ()
 
SpellCastResult CheckRuneCost (uint32 RuneCostID)
 
SpellCastResult CheckCasterAuras (bool preventionOnly) const
 
int32 CalculateSpellDamage (uint8 i, Unit const *target) const
 
bool HaveTargetsForEffect (uint8 effect) const
 
void Delayed ()
 
void DelayedChannel ()
 
uint32 getState () const
 
void setState (uint32 state)
 
void DoCreateItem (uint8 effIndex, uint32 itemId)
 
void WriteSpellGoTargets (WorldPacket *data)
 Writes miss and hit targets for a SMSG_SPELL_GO packet.
 
void WriteAmmoToPacket (WorldPacket *data)
 
bool CheckEffectTarget (Unit const *target, uint32 eff) const
 
bool CanAutoCast (Unit *target)
 
void CheckSrc ()
 
void CheckDst ()
 
void SendCastResult (SpellCastResult result)
 
void SendPetCastResult (SpellCastResult result)
 
void SendSpellStart ()
 
void SendSpellGo ()
 
void SendSpellCooldown ()
 
void SendLogExecute ()
 
void ExecuteLogEffectTakeTargetPower (uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
 
void ExecuteLogEffectExtraAttacks (uint8 effIndex, Unit *victim, uint32 attCount)
 
void ExecuteLogEffectInterruptCast (uint8 effIndex, Unit *victim, uint32 spellId)
 
void ExecuteLogEffectDurabilityDamage (uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
 
void ExecuteLogEffectOpenLock (uint8 effIndex, Object *obj)
 
void ExecuteLogEffectCreateItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectDestroyItem (uint8 effIndex, uint32 entry)
 
void ExecuteLogEffectSummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectUnsummonObject (uint8 effIndex, WorldObject *obj)
 
void ExecuteLogEffectResurrect (uint8 effIndex, Unit *target)
 
void SendInterrupted (uint8 result)
 
void SendChannelUpdate (uint32 time)
 
void SendChannelStart (uint32 duration)
 
void SendResurrectRequest (Player *target)
 
void HandleEffects (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
 
void HandleThreatSpells ()
 
void AddComboPointGain (Unit *target, int8 amount)
 
int32 GetCastTime () const
 
bool IsAutoRepeat () const
 
void SetAutoRepeat (bool rep)
 
void ReSetTimer ()
 
int32 GetCastTimeRemaining ()
 
bool IsNextMeleeSwingSpell () const
 
bool IsTriggered () const
 
bool HasTriggeredCastFlag (TriggerCastFlags flag) const
 
bool IsProcDisabled () const
 
bool IsChannelActive () const
 
bool IsAutoActionResetSpell () const
 
bool IsIgnoringCooldowns () const
 
bool IsDeletable () const
 
void SetReferencedFromCurrent (bool yes)
 
bool IsInterruptable () const
 
void SetExecutedCurrently (bool yes)
 
uint64 GetDelayStart () const
 
void SetDelayStart (uint64 m_time)
 
uint64 GetDelayMoment () const
 
uint64 GetDelayTrajectory () const
 
uint64 CalculateDelayMomentForDst () const
 
void RecalculateDelayMomentForDst ()
 
bool IsNeedSendToClient (bool go) const
 
CurrentSpellTypes GetCurrentContainer () const
 
UnitGetCaster () const
 
UnitGetOriginalCaster () const
 
UnitGetOriginalTarget () const
 
SpellInfo const * GetSpellInfo () const
 
int32 GetPowerCost () const
 
bool UpdatePointers ()
 
void CleanupTargetList ()
 
void SetSpellValue (SpellValueMod mod, int32 value)
 
SpellValue const * GetSpellValue ()
 
void LoadScripts ()
 
std::list< TargetInfo > * GetUniqueTargetInfo ()
 
uint32 GetTriggeredByAuraTickNumber () const
 
SpellInfo const * GetTriggeredByAuraSpellInfo () const
 
TriggerCastFlags GetTriggeredCastFlags () const
 
SpellSchoolMask GetSpellSchoolMask () const
 

Static Public Member Functions

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

Public Attributes

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

Protected Types

typedef std::list< HitTriggerSpellHitTriggerSpellList
 

Protected Member Functions

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

Protected Attributes

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

Friends

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

Detailed Description

Member Typedef Documentation

◆ HitTriggerSpellList

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

◆ UsedSpellMods

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

Constructor & Destructor Documentation

◆ Spell()

Spell::Spell ( Unit caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
571 :
572 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
573 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster)
575{
577 m_skipCheck = skipCheck;
578 m_selfContainer = nullptr;
580 m_executedCurrently = false;
583 m_comboTarget = nullptr;
584 m_delayStart = 0;
586
588 m_auraScaleMask = 0;
589 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
590
591 // Get data for type of attack
592 switch (m_spellInfo->DmgClass)
593 {
597 else
599 break;
602 break;
603 default:
604 // Wands
607 else
609 break;
610 }
611
612 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
613
615 // wand case
618 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
619
620 if (originalCasterGUID)
621 m_originalCasterGUID = originalCasterGUID;
622 else
624
627 else
628 {
631 m_originalCaster = nullptr;
632 }
633
635 _triggeredCastFlags = triggerFlags;
636 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
638
639 m_CastItem = nullptr;
640
641 unitTarget = nullptr;
642 itemTarget = nullptr;
643 gameObjTarget = nullptr;
644 destTarget = nullptr;
645 damage = 0;
646 m_reflectionTarget = nullptr;
651 m_damage = 0;
652 m_healing = 0;
654 m_procAttacker = 0;
655 m_procVictim = 0;
656 m_procEx = 0;
657 focusObject = nullptr;
658 m_cast_count = 0;
659 m_glyphIndex = 0;
660 m_preCastSpell = 0;
661 m_spellAura = nullptr;
662 _scriptsLoaded = false;
663
664 //Auto Shot & Shoot (wand)
666
667 m_runesState = 0;
668 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
669 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
670 m_timer = 0; // will set to castime in prepare
671 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
672 m_immediateHandled = false;
673
675
677
678 // Determine if spell can be reflected back to the caster
679 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
683
685 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
686
687 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
689
690 // xinef:
691 _spellTargetsSelected = false;
692
693 m_weaponItem = nullptr;
694}
#define MAX_SPELL_EFFECTS
Definition DBCStructure.h:1637
std::uint8_t uint8
Definition Define.h:109
std::uint32_t uint32
Definition Define.h:107
@ DIMINISHING_NONE
Definition SharedDefines.h:3491
@ SPELL_EFFECT_DISPEL
Definition SharedDefines.h:804
#define CLASSMASK_WAND_USERS
Definition SharedDefines.h:151
@ SPELL_ATTR2_AUTO_REPEAT
Definition SharedDefines.h:449
@ SPELL_ATTR1_NO_REFLECTION
Definition SharedDefines.h:414
@ SPELL_ATTR3_REQUIRES_OFF_HAND_WEAPON
Definition SharedDefines.h:505
@ SPELL_DAMAGE_CLASS_RANGED
Definition SharedDefines.h:1552
@ SPELL_DAMAGE_CLASS_MAGIC
Definition SharedDefines.h:1550
@ SPELL_DAMAGE_CLASS_MELEE
Definition SharedDefines.h:1551
@ SPELL_CUSTOM_ERROR_NONE
Definition SharedDefines.h:1131
@ SPELL_ATTR0_IS_ABILITY
Definition SharedDefines.h:374
@ SPELL_ATTR0_NO_IMMUNITIES
Definition SharedDefines.h:399
@ SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING
Definition SharedDefines.h:525
@ SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER
Definition SharedDefines.h:610
SpellSchoolMask
Definition SharedDefines.h:283
TriggerCastFlags
Definition SpellDefines.h:132
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition SpellDefines.h:141
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition SpellDefines.h:139
#define sSpellMgr
Definition SpellMgr.h:847
@ SPELL_EFFECT_HANDLE_LAUNCH
Definition Spell.h:246
@ SPELL_FLAG_NORMAL
Definition Spell.h:93
@ SPELL_STATE_NULL
Definition Spell.h:236
@ OFF_ATTACK
Definition Unit.h:217
@ BASE_ATTACK
Definition Unit.h:216
@ RANGED_ATTACK
Definition Unit.h:218
@ DIMINISHING_LEVEL_1
Definition Unit.h:270
Definition ByteBuffer.h:70
Definition Item.h:220
void Clear()
Definition ObjectGuid.h:141
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:492
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:2332
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:1287
uint32 getClassMask() const
Definition Unit.h:846
Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:223
Definition Spell.h:106
Definition Spell.h:223

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

Referenced by Creature::HasSpellFocus().

◆ ~Spell()

Spell::~Spell ( )
697{
698 // FindMap() check: pending spell events are destroyed after the caster has left the map,
699 // where resolving a unit-summoned caster's owner through ObjectAccessor would assert
700 if (Player* modOwner = (m_caster && m_caster->FindMap()) ? m_caster->GetSpellModOwner() : nullptr)
701 if (modOwner->m_spellModTakingSpell == this)
702 modOwner->SetSpellModTakingSpell(this, false);
703
704 // unload scripts
705 while (!m_loadedScripts.empty())
706 {
707 std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
708 (*itr)->_Unload();
709 delete (*itr);
710 m_loadedScripts.erase(itr);
711 }
712
714 {
715 // Clean the reference to avoid later crash.
716 // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
717 LOG_ERROR("spells", "Spell::~Spell: deleting spell for spell ID {}. However, spell still referenced.", m_spellInfo->Id);
718 *m_selfContainer = nullptr;
719 }
720
721 delete m_spellValue;
722
724}
#define LOG_ERROR(filterType__,...)
Definition Log.h:145
Definition Player.h:1086
uint32 Id
Definition SpellInfo.h:344
void CheckEffectExecuteData()
Definition Spell.cpp:8586
std::list< SpellScript * > m_loadedScripts
Definition Spell.h:766
Player * GetSpellModOwner() const
Definition Unit.cpp:12962
Map * FindMap() const
Definition Object.h:632

References CheckEffectExecuteData(), WorldObject::FindMap(), Unit::GetSpellModOwner(), SpellInfo::Id, LOG_ERROR, m_caster, 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

3794{
3795 // update pointers base at GUIDs to prevent access to non-existed already object
3796 if (!UpdatePointers())
3797 {
3798 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3799 cancel();
3800 return;
3801 }
3802
3803 // cancel at lost explicit target during cast
3805 {
3806 cancel();
3807 return;
3808 }
3809
3810 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3812 {
3814 if (Pet* pet = m_caster->ToPlayer()->GetPet())
3816
3817 if (Unit* charm = m_caster->GetCharm())
3818 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, m_caster->GetGUID());
3819 }
3820
3821 if (Player* playerCaster = m_caster->ToPlayer())
3822 {
3823 // now that we've done the basic check, now run the scripts
3824 // should be done before the spell is actually executed
3825 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3826
3827 // As of 3.0.2 pets begin attacking their owner's target immediately
3828 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3829 // This prevents spells such as Hunter's Mark from triggering pet attack
3830 // xinef: take into account SPELL_ATTR3_SUPPRESS_TARGET_PROCS
3832 if (!playerCaster->m_Controlled.empty())
3833 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3834 if (Unit* pet = *itr)
3835 if (pet->IsAlive() && pet->IsCreature())
3836 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3837 }
3838
3840
3844
3846
3847 Player* modOwner = m_caster->GetSpellModOwner();
3848 // skip check if done already (for instant cast spells for example)
3849 if (!skipCheck)
3850 {
3851 SpellCastResult castResult = CheckCast(false);
3852 if (castResult != SPELL_CAST_OK)
3853 {
3854 SendCastResult(castResult);
3855 SendInterrupted(0);
3856
3857 finish(false);
3858 SetExecutedCurrently(false);
3859 return;
3860 }
3861
3862 // additional check after cast bar completes (must not be in CheckCast)
3863 // if trade not complete then remember it in trade data
3865 {
3866 if (m_caster->IsPlayer())
3867 {
3868 if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData())
3869 {
3870 if (!my_trade->IsInAcceptProcess())
3871 {
3872 // Spell will be casted at completing the trade. Silently ignore at this place
3873 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3875 SendInterrupted(0);
3876
3877 finish(false);
3878 SetExecutedCurrently(false);
3879 return;
3880 }
3881 }
3882 }
3883 }
3884 }
3885
3886 if (modOwner)
3887 modOwner->SetSpellModTakingSpell(this, true);
3888
3891
3892 if (modOwner)
3893 modOwner->SetSpellModTakingSpell(this, false);
3894
3895 // Spell may be finished after target map check
3897 {
3898 SendInterrupted(0);
3899 finish(false);
3900 SetExecutedCurrently(false);
3901 return;
3902 }
3903
3904 if (modOwner)
3905 modOwner->SetSpellModTakingSpell(this, true);
3906
3908
3910
3911 if (modOwner)
3912 modOwner->SetSpellModTakingSpell(this, false);
3913
3914 // traded items have trade slot instead of guid in m_itemTargetGUID
3915 // set to real guid to be sent later to the client
3917
3918 if (m_caster->IsPlayer())
3919 {
3921 {
3924 }
3925
3927 }
3928
3930 {
3931 // Powers have to be taken before SendSpellGo
3932 TakePower();
3933 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
3934 }
3935 else if (Item* targetItem = m_targets.GetItemTarget())
3936 {
3938 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
3939 TakeReagents();
3940 }
3941
3943
3944 // CAST SPELL
3945 if (modOwner)
3946 modOwner->SetSpellModTakingSpell(this, true);
3947
3949
3951
3952 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
3953 SendSpellGo();
3954
3956 if (resetAttackTimers)
3957 {
3959 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
3960 {
3961 if ((*i)->IsAffectedOnSpell(m_spellInfo))
3962 {
3963 resetAttackTimers = false;
3964 break;
3965 }
3966 }
3967 }
3968
3969 // CAST -> HIT -> FINISH ordering: fire CAST before handle_immediate so an aura
3970 // applied during HIT (e.g. Arcane Potency from Clearcasting) isn't consumed by
3971 // the same cast. Triggered spells skip this so periodic ticks (Blizzard etc.)
3972 // don't burn cast-charge buffs.
3973 if (m_originalCaster && !IsTriggered())
3974 {
3975 uint32 procAttacker = m_procAttacker;
3976 if (!procAttacker)
3977 {
3978 bool IsPositive = m_spellInfo->IsPositive();
3980 {
3982 }
3983 else
3984 {
3986 }
3987 }
3988
3989 uint32 hitMask = PROC_HIT_NORMAL;
3990
3991 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3992 {
3993 if (ihit->missCondition != SPELL_MISS_NONE)
3994 continue;
3995
3996 if (!ihit->crit)
3997 continue;
3998
3999 hitMask |= PROC_HIT_CRITICAL;
4000 break;
4001 }
4002
4005 }
4006
4007 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
4008 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
4009 {
4010 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4011 // in case delayed spell remove item at cast delay start
4012 TakeCastItem();
4013
4014 // Okay, maps created, now prepare flags
4015 m_immediateHandled = false;
4017 SetDelayStart(0);
4018
4021
4022 // remove all applied mods at this point
4023 // dont allow user to use them twice in case spell did not reach current target
4024 if (modOwner)
4025 modOwner->RemoveSpellMods(this);
4026
4027 // Xinef: why do we keep focus after spell is sent to air?
4028 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
4029 // Xinef: we get focused to it out of nowhere...
4030 if (Creature* creatureCaster = m_caster->ToCreature())
4031 creatureCaster->ReleaseFocus(this);
4032 }
4033 else
4034 {
4035 // Immediate spell, no big deal
4037 }
4038
4039 if (resetAttackTimers)
4040 {
4041 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4042 {
4043 resetAttackTimers = false;
4044 }
4045
4046 if (resetAttackTimers)
4047 {
4049
4051 {
4053 }
4054
4056 }
4057 }
4058
4060
4061 if (modOwner)
4062 modOwner->SetSpellModTakingSpell(this, false);
4063
4064 if (std::vector<int32> const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4065 {
4066 for (int32 id : *spell_triggered)
4067 {
4068 if (id < 0)
4070 else
4072 }
4073 }
4074
4075 // Interrupt Spell casting
4076 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4078 if (Unit* target = m_targets.GetUnitTarget())
4079 if (target->IsCreature())
4080 m_caster->CastSpell(target, 32747, true);
4081
4082 if (m_caster->IsPlayer())
4085
4086 sScriptMgr->OnSpellCast(this, m_caster, m_spellInfo, skipCheck);
4087
4088 SetExecutedCurrently(false);
4089
4090 // Call CreatureAI hook on successful cast
4091 if (Creature* caster = m_caster->ToCreature())
4092 if (caster->IsAIEnabled)
4093 caster->AI()->OnSpellCast(GetSpellInfo());
4094}
@ 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:999
#define sScriptMgr
Definition ScriptMgr.h:743
@ SPELL_ATTR7_CAN_CAUSE_INTERRUPT
Definition SharedDefines.h:640
@ SPELL_EFFECT_SUMMON_PET
Definition SharedDefines.h:822
@ SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS
Definition SharedDefines.h:461
@ SPELL_ATTR1_DISMISS_PET_FIRST
Definition SharedDefines.h:407
@ SPELL_ATTR3_SUPPRESS_TARGET_PROCS
Definition SharedDefines.h:498
@ SPELL_DAMAGE_CLASS_NONE
Definition SharedDefines.h:1549
@ SPELL_MISS_NONE
Definition SharedDefines.h:1523
SpellCastResult
Definition SharedDefines.h:936
@ SPELL_FAILED_DONT_REPORT
Definition SharedDefines.h:964
@ SPELL_CAST_OK
Definition SharedDefines.h:1126
@ SPELL_AURA_MOD_CHARM
Definition SpellAuraDefines.h:69
@ SPELL_AURA_IGNORE_MELEE_RESET
Definition SpellAuraDefines.h:335
@ TRIGGERED_IGNORE_POWER_AND_REAGENT_COST
Will ignore Spell and Category cooldowns.
Definition SpellDefines.h:136
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition SpellDefines.h:137
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition SpellDefines.h:143
@ TARGET_FLAG_TRADE_ITEM
Definition SpellInfo.h:59
@ TARGET_FLAG_UNIT
Definition SpellInfo.h:48
@ PROC_HIT_CRITICAL
Definition SpellMgr.h:258
@ PROC_HIT_NORMAL
Definition SpellMgr.h:257
@ PROC_SPELL_PHASE_CAST
Definition SpellMgr.h:248
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
Definition SpellMgr.h:131
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_POS
Definition SpellMgr.h:125
@ PROC_FLAG_DONE_SPELL_NONE_DMG_CLASS_NEG
Definition SpellMgr.h:128
@ PROC_FLAG_NONE
Definition SpellMgr.h:108
@ PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_NEG
Definition SpellMgr.h:134
@ SPELL_STATE_DELAYED
Definition Spell.h:241
@ SPELL_STATE_FINISHED
Definition Spell.h:239
@ UNIT_STATE_CASTING
Definition UnitDefines.h:188
Definition Creature.h:47
uint32 GetEntry() const
Definition Object.h:117
bool IsCreature() const
Definition Object.h:205
Creature * ToCreature()
Definition Object.h:206
Definition Pet.h:41
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition PlayerUpdates.cpp:2181
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition Player.cpp:10256
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition Player.cpp:14237
void RemoveSpellMods(Spell *spell)
Definition Player.cpp:10182
Pet * GetPet() const
Definition Player.cpp:9132
bool GetCommandStatus(uint32 command) const
Definition Player.h:1202
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:9282
TradeData * GetTradeData() const
Definition Player.h:1400
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition Player.cpp:3683
WorldObject * GetObjectTarget() const
Definition Spell.cpp:311
void UpdateTradeSlotItem()
Definition Spell.cpp:348
ObjectGuid GetObjectTargetGUID() const
Definition Spell.cpp:316
Item * GetItemTarget() const
Definition Spell.h:151
uint32 GetTargetMask() const
Definition Spell.h:129
Unit * GetUnitTarget() const
Definition Spell.cpp:232
float Speed
Definition SpellInfo.h:394
bool IsChanneled() const
Definition SpellInfo.cpp:1288
uint32 CalcCastTime(Unit *caster=nullptr, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2752
SpellInfo const * GetSpellInfo() const
Definition Spell.h:593
void CallScriptAfterCastHandlers()
Definition Spell.cpp:8640
void PrepareTriggersExecutedOnHit()
Definition Spell.cpp:8846
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:4096
void SendSpellGo()
Definition Spell.cpp:4799
void TakeReagents()
Definition Spell.cpp:5534
void SetExecutedCurrently(bool yes)
Definition Spell.h:578
void SendInterrupted(uint8 result)
Definition Spell.cpp:5176
void PrepareScriptHitHandlers()
Definition Spell.cpp:8672
void CallScriptOnCastHandlers()
Definition Spell.cpp:8627
void cancel(bool bySelf=false)
Definition Spell.cpp:3703
void SendSpellCooldown()
Definition Spell.cpp:4346
void CallScriptBeforeCastHandlers()
Definition Spell.cpp:8614
void HandleLaunchPhase()
Definition Spell.cpp:8308
bool UpdatePointers()
Definition Spell.cpp:7938
void SetDelayStart(uint64 m_time)
Definition Spell.h:580
std::list< TargetInfo > m_UniqueTargetInfo
Definition Spell.h:707
void SelectSpellTargets()
Definition Spell.cpp:829
void TakePower()
Definition Spell.cpp:5317
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition Spell.cpp:4671
bool IsTriggered() const
Definition Spell.h:568
void TakeCastItem()
Definition Spell.cpp:5254
SpellCastResult CheckCast(bool strict, uint32 *param1=nullptr, uint32 *param2=nullptr)
Definition Spell.cpp:5662
bool IsAutoActionResetSpell() const
Definition Spell.cpp:8152
void finish(bool ok=true)
Definition Spell.cpp:4478
Definition TradeData.h:36
Definition Unit.h:665
bool HasOffhandWeaponForAttack() const
Definition Unit.h:991
void ClearUnitState(uint32 f)
Definition Unit.h:738
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1429
Unit * GetCharm() const
Definition Unit.cpp:7817
std::vector< AuraEffect * > AuraEffectList
Definition Unit.h:681
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:4282
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:1361
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:5189
static void ProcSkillsAndAuras(Unit *actor, Unit *victim, uint32 procAttacker, uint32 procVictim, uint32 procEx, uint32 amount, WeaponAttackType attType=BASE_ATTACK, SpellInfo const *procSpellInfo=nullptr, SpellInfo const *procAura=nullptr, int8 procAuraEffectIndex=-1, Spell const *procSpell=nullptr, DamageInfo *damageInfo=nullptr, HealInfo *healInfo=nullptr, uint32 procPhase=2)
Definition Unit.cpp:6807
bool HasUnitState(const uint32 f) const
Definition Unit.h:737
void SetInFront(WorldObject const *target)
Definition Unit.cpp:16449
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 ( )
4270{
4271 // Take for real after all targets are processed
4273 {
4275 }
4276
4277 // Real add combo points from effects
4279 {
4280 // remove Premed-like effects unless they were caused by ourselves
4281 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4283 {
4285 }
4286
4288 }
4289
4291 {
4293 }
4294
4297 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4298 {
4299 // Xinef: Properly clear infinite cooldowns in some cases
4300 if (ihit->targetGUID == m_caster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4303 }
4304
4305 // Handle procs on finish
4306 if (m_originalCaster)
4307 {
4308 uint32 procAttacker = m_procAttacker;
4309 if (!procAttacker)
4310 {
4311 bool IsPositive = m_spellInfo->IsPositive();
4313 {
4315 }
4316 else
4317 {
4319 }
4320 }
4321
4322 uint32 hitMask = PROC_HIT_NORMAL;
4323 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4324 {
4325 if (ihit->missCondition != SPELL_MISS_NONE)
4326 continue;
4327
4328 if (!ihit->crit)
4329 continue;
4330
4331 hitMask |= PROC_HIT_CRITICAL;
4332 break;
4333 }
4334
4335 // For trap activation, pass the original target (trap triggerer) so proc trigger spells
4336 // like Entrapment can find a valid target to cast on
4337 Unit* finishVictim = nullptr;
4338 if (procAttacker & PROC_FLAG_DONE_TRAP_ACTIVATION)
4339 finishVictim = GetOriginalTarget();
4340
4343 }
4344}
@ 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:11278
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:7933
bool IsNextMeleeSwingSpell() const
Definition Spell.cpp:8142
void SetLastExtraAttackSpell(uint32 spellId)
Definition Unit.h:1010
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Unit.cpp:7762
void ClearComboPoints()
Definition Unit.cpp:13264
void AddComboPoints(Unit *target, int8 count)
Definition Unit.cpp:13238
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition Unit.cpp:5397

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

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

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

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
2567{
2568 m_destTargets[effIndex] = dest;
2569}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject target,
uint32  effectMask 
)
protected
2476{
2477 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2478 {
2479 if (!m_spellInfo->Effects[effIndex].IsEffect())
2480 effectMask &= ~(1 << effIndex);
2481 else
2482 {
2483 switch (m_spellInfo->Effects[effIndex].Effect)
2484 {
2488 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2489 effectMask &= ~(1 << effIndex);
2490 break;
2491 default:
2492 break;
2493 }
2494 }
2495 }
2496
2497 if (!effectMask)
2498 return;
2499
2500 ObjectGuid targetGUID = go->GetGUID();
2501
2502 // Lookup target in already in list
2503 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2504 {
2505 if (targetGUID == ihit->targetGUID) // Found in list
2506 {
2507 ihit->effectMask |= effectMask; // Add only effect mask
2508 return;
2509 }
2510 }
2511
2512 // This is new target calculate data for him
2513
2514 GOTargetInfo target;
2515 target.targetGUID = targetGUID;
2516 target.effectMask = effectMask;
2517 target.processed = false; // Effects not apply on target
2518
2519 // Spell have speed - need calculate incoming time
2520 if (m_spellInfo->Speed > 0.0f)
2521 {
2522 // calculate spell incoming interval
2523 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2524 if (dist < 5.0f)
2525 dist = 5.0f;
2526 target.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
2527 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2528 m_delayMoment = target.timeDelay;
2529 }
2530 else
2531 target.timeDelay = 0LL;
2532
2533 // Add target to list
2534 m_UniqueGOTargetInfo.push_back(target);
2535}
std::uint64_t uint64
Definition Define.h:106
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
Definition SharedDefines.h:1597
@ SPELL_EFFECT_GAMEOBJECT_REPAIR
Definition SharedDefines.h:854
@ SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE
Definition SharedDefines.h:855
@ SPELL_EFFECT_GAMEOBJECT_DAMAGE
Definition SharedDefines.h:853
Definition ObjectGuid.h:121
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:1299

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
2538{
2539 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2540 if (!m_spellInfo->Effects[effIndex].IsEffect())
2541 effectMask &= ~(1 << effIndex);
2542
2543 // no effects left
2544 if (!effectMask)
2545 return;
2546
2547 // Lookup target in already in list
2548 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2549 {
2550 if (item == ihit->item) // Found in list
2551 {
2552 ihit->effectMask |= effectMask; // Add only effect mask
2553 return;
2554 }
2555 }
2556
2557 // This is new target add data
2558
2559 ItemTargetInfo target;
2560 target.item = item;
2561 target.effectMask = effectMask;
2562
2563 m_UniqueItemInfo.push_back(target);
2564}

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)
2342{
2343 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2344 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2345 effectMask &= ~(1 << effIndex);
2346
2347 // no effects left
2348 if (!effectMask)
2349 return;
2350
2351 if (checkIfValid)
2352 {
2353 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2354 if (res != SPELL_CAST_OK)
2355 return;
2356 }
2357
2358 // Check for effect immune skip if immuned
2359 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2360 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex, m_caster))
2361 effectMask &= ~(1 << effIndex);
2362
2363 ObjectGuid targetGUID = target->GetGUID();
2364
2365 // Lookup target in already in list
2366 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2367 {
2368 if (targetGUID == ihit->targetGUID) // Found in list
2369 {
2370 ihit->effectMask |= effectMask; // Immune effects removed from mask
2371 ihit->scaleAura = false;
2372 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2373 {
2374 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2375 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2376 ihit->scaleAura = true;
2377 }
2378
2379 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2380 return;
2381 }
2382 }
2383
2384 // This is new target calculate data for him
2385
2386 // Get spell hit result on target
2387 TargetInfo targetInfo;
2388 targetInfo.targetGUID = targetGUID; // Store target GUID
2389 targetInfo.effectMask = effectMask; // Store all effects not immune
2390 targetInfo.processed = false; // Effects not apply on target
2391 targetInfo.alive = target->IsAlive();
2392 targetInfo.damage = 0;
2393 targetInfo.damageBeforeTakenMods = 0;
2394 targetInfo.crit = false;
2395 targetInfo.scaleAura = false;
2396 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2397 {
2398 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2399 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2400 targetInfo.scaleAura = true;
2401 }
2402
2403 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2404
2405 // Calculate hit result
2406 if (m_originalCaster)
2407 {
2408 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2409 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2410 {
2411 targetInfo.missCondition = SPELL_MISS_NONE;
2412 }
2413 }
2414 else
2415 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2416
2417 // Spell have speed - need calculate incoming time
2418 // Incoming time is zero for self casts. At least I think so.
2419 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2420 {
2421 // calculate spell incoming interval
2423 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2424
2425 if (dist < 5.0f)
2426 dist = 5.0f;
2427 targetInfo.timeDelay = (uint64) std::floor(dist / m_spellInfo->Speed * 1000.0f);
2428
2429 // Calculate minimum incoming time
2430 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2431 m_delayMoment = targetInfo.timeDelay;
2432 }
2433 else
2434 targetInfo.timeDelay = 0LL;
2435
2436 // If target reflect spell back to caster
2437 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2438 {
2439 // Calculate reflected spell result on caster
2441
2442 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2443 targetInfo.reflectResult = SPELL_MISS_PARRY;
2444
2445 // Increase time interval for reflected spells by 1.5
2447 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2448
2450
2451 // HACK: workaround check for succubus seduction case
2453 if (m_caster->IsPet())
2454 {
2455 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(m_caster->GetEntry());
2456 switch (ci->family)
2457 {
2459 {
2460 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2461 cancel();
2462 }
2463 break;
2464 return;
2465 }
2466 }
2467 }
2468 else
2469 targetInfo.reflectResult = SPELL_MISS_NONE;
2470
2471 // Add target to list
2472 m_UniqueTargetInfo.push_back(targetInfo);
2473}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:27
#define sObjectMgr
Definition ObjectMgr.h:1730
@ CREATURE_FAMILY_SUCCUBUS
Definition SharedDefines.h:2658
@ SPELL_MISS_PARRY
Definition SharedDefines.h:1527
@ SPELL_MISS_IMMUNE
Definition SharedDefines.h:1530
@ SPELL_MISS_EVADE
Definition SharedDefines.h:1529
@ SPELL_MISS_REFLECT
Definition SharedDefines.h:1534
@ SPELL_FLAG_REFLECTED
Definition Spell.h:94
void AddEventAtOffset(BasicEvent *event, Milliseconds offset, uint8 eventGroup=0)
Definition EventProcessor.h:108
Definition Spell.h:865
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:8000
bool IsPet() const
Definition Unit.h:798
bool IsAlive() const
Definition Unit.h:1793
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spell, bool canReflect=false)
Definition Unit.cpp:3631
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index, Unit const *caster=nullptr) const
Definition Unit.cpp:10114
uint8 GetLevel() const
Definition Unit.h:1104
EventProcessor m_Events
Definition Object.h:742
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
910{
911 if (m_targets.HasDst())
912 {
913 if (m_targets.HasTraj())
914 {
915 float speed = m_targets.GetSpeedXY();
916 if (speed > 0.0f)
917 return (uint64)std::floor(m_targets.GetDist2d() / speed * 1000.0f);
918 }
919 else if (m_spellInfo->Speed > 0.0f)
920 {
921 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
922 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
923 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
924 }
925 }
926
927 return 0;
928}
bool HasTraj() const
Definition Spell.h:178
bool HasDst() const
Definition Spell.h:177
float GetSpeedXY() const
Definition Spell.h:186
float GetDist2d() const
Definition Spell.h:185
WorldLocation const * GetDstPos() const
Definition Spell.cpp:401
float GetExactDist(float x, float y, float z) const
Definition Position.h:182

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

Referenced by RecalculateDelayMomentForDst(), and SelectSpellTargets().

◆ CalculateJumpSpeeds()

void Spell::CalculateJumpSpeeds ( uint8  i,
float  dist,
float &  speedxy,
float &  speedz 
)
protected
1155{
1157 if (Creature* creature = m_caster->ToCreature())
1158 runSpeed *= creature->GetCreatureTemplate()->speed_run;
1159
1160 float multiplier = m_spellInfo->Effects[i].ValueMultiplier;
1161 if (multiplier <= 0.0f)
1162 multiplier = 1.0f;
1163
1164 speedXY = std::min(runSpeed * 3.0f * multiplier, std::max(28.0f, m_caster->GetSpeed(MOVE_RUN) * 4.0f));
1165
1166 float duration = dist / speedXY;
1167 float durationSqr = duration * duration;
1168 float minHeight = m_spellInfo->Effects[i].MiscValue ? m_spellInfo->Effects[i].MiscValue / 10.0f : 0.5f; // Lower bound is blizzlike
1169 float maxHeight = m_spellInfo->Effects[i].MiscValueB ? m_spellInfo->Effects[i].MiscValueB / 10.0f : 1000.0f; // Upper bound is unknown
1170 float height;
1171 if (durationSqr < minHeight * 8 / Movement::gravity)
1172 height = minHeight;
1173 else if (durationSqr > maxHeight * 8 / Movement::gravity)
1174 height = maxHeight;
1175 else
1176 height = Movement::gravity * durationSqr / 8;
1177
1178 speedZ = std::sqrt(2 * Movement::gravity * height);
1179}
@ MOVE_RUN
Definition UnitDefines.h:357
float baseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:80
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:93
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:11299
bool IsControlledByPlayer() const
Definition Unit.h:1308
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:11595
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
8641{
8642 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8643 {
8644 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8645 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8646 for (; hookItr != hookItrEnd; ++hookItr)
8647 (*hookItr).Call(*scritr);
8648
8649 (*scritr)->_FinishScriptCall();
8650 }
8651}
@ 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
8753{
8754 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8755 {
8756 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
8757 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
8758 for (; hookItr != hookItrEnd; ++hookItr)
8759 (*hookItr).Call(*scritr);
8760
8761 (*scritr)->_FinishScriptCall();
8762 }
8763}
@ 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
8615{
8616 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8617 {
8618 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8619 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8620 for (; hookItr != hookItrEnd; ++hookItr)
8621 (*hookItr).Call(*scritr);
8622
8623 (*scritr)->_FinishScriptCall();
8624 }
8625}
@ 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
8727{
8728 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8729 {
8730 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
8731 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
8732 for (; hookItr != hookItrEnd; ++hookItr)
8733 (*hookItr).Call(*scritr, missInfo);
8734
8735 (*scritr)->_FinishScriptCall();
8736 }
8737}
@ 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
8654{
8656 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8657 {
8658 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8659 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8660 for (; hookItr != hookItrEnd; ++hookItr)
8661 {
8662 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8663 if (retVal == SPELL_CAST_OK)
8664 retVal = tempResult;
8665 }
8666
8667 (*scritr)->_FinishScriptCall();
8668 }
8669 return retVal;
8670}
@ 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
8794{
8795 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8796 {
8797 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
8798 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
8799 for (; hookItr != hookItrEnd; ++hookItr)
8800 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8801 hookItr->Call(*scritr, target);
8802
8803 (*scritr)->_FinishScriptCall();
8804 }
8805}
@ 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(), SelectImplicitNearbyTargets(), SelectImplicitTargetDestTargets(), and SelectImplicitTrajTargets().

◆ CallScriptEffectHandlers()

bool Spell::CallScriptEffectHandlers ( SpellEffIndex  effIndex,
SpellEffectHandleMode  mode 
)
protected
8679{
8680 // execute script effect handler hooks and check if effects was prevented
8681 bool preventDefault = false;
8682 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8683 {
8684 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8685 SpellScriptHookType hookType;
8686 switch (mode)
8687 {
8689 effItr = (*scritr)->OnEffectLaunch.begin();
8690 effEndItr = (*scritr)->OnEffectLaunch.end();
8692 break;
8694 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8695 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8697 break;
8699 effItr = (*scritr)->OnEffectHit.begin();
8700 effEndItr = (*scritr)->OnEffectHit.end();
8702 break;
8704 effItr = (*scritr)->OnEffectHitTarget.begin();
8705 effEndItr = (*scritr)->OnEffectHitTarget.end();
8707 break;
8708 default:
8709 ABORT();
8710 return false;
8711 }
8712 (*scritr)->_PrepareScriptCall(hookType);
8713 for (; effItr != effEndItr; ++effItr)
8714 // effect execution can be prevented
8715 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
8716 (*effItr).Call(*scritr, effIndex);
8717
8718 if (!preventDefault)
8719 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
8720
8721 (*scritr)->_FinishScriptCall();
8722 }
8723 return preventDefault;
8724}
#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
8766{
8767 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8768 {
8769 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
8770 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
8771 for (; hookItr != hookItrEnd; ++hookItr)
8772 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8773 hookItr->Call(*scritr, targets);
8774
8775 (*scritr)->_FinishScriptCall();
8776 }
8777}
@ 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
8780{
8781 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8782 {
8783 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
8784 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
8785 for (; hookItr != hookItrEnd; ++hookItr)
8786 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
8787 hookItr->Call(*scritr, target);
8788
8789 (*scritr)->_FinishScriptCall();
8790 }
8791}
@ 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
8628{
8629 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8630 {
8631 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8632 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8633 for (; hookItr != hookItrEnd; ++hookItr)
8634 (*hookItr).Call(*scritr);
8635
8636 (*scritr)->_FinishScriptCall();
8637 }
8638}
@ 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
8740{
8741 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8742 {
8743 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
8744 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
8745 for (; hookItr != hookItrEnd; ++hookItr)
8746 (*hookItr).Call(*scritr);
8747
8748 (*scritr)->_FinishScriptCall();
8749 }
8750}
@ 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)
7034{
7035 ObjectGuid targetguid = target->GetGUID();
7036
7037 for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
7038 {
7039 if (!spellEffectInfo.IsAura())
7040 continue;
7041
7042 AuraType const& auraType = spellEffectInfo.ApplyAuraName;
7043 Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(auraType);
7044 for (Unit::AuraEffectList::const_iterator auraIt = auras.begin(); auraIt != auras.end(); ++auraIt)
7045 {
7046 if (GetSpellInfo()->Id == (*auraIt)->GetSpellInfo()->Id)
7047 return false;
7048
7049 switch (sSpellMgr->CheckSpellGroupStackRules(GetSpellInfo(), (*auraIt)->GetSpellInfo()))
7050 {
7052 return false;
7054 if (GetCaster() == (*auraIt)->GetCaster())
7055 return false;
7056 break;
7057 case SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT: // this one has further checks, but i don't think they're necessary for autocast logic
7059 if (abs(spellEffectInfo.BasePoints) <= abs((*auraIt)->GetAmount()))
7060 return false;
7061 break;
7063 default:
7064 break;
7065 }
7066 }
7067 }
7068
7069 SpellCastResult result = CheckPetCast(target);
7070
7071 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7072 {
7074 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7075 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7076 if (ihit->targetGUID == targetguid)
7077 return true;
7078 }
7079 return false; //target invalid
7080}
@ 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:6840

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)
3704{
3706 return;
3707
3708 uint32 oldState = m_spellState;
3710
3711 m_autoRepeat = false;
3712 switch (oldState)
3713 {
3717
3718 if (m_caster->IsPlayer())
3719 {
3721 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3722 }
3723 [[fallthrough]];
3726 break;
3728 if (!bySelf)
3729 {
3730 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3731 if ((*ihit).missCondition == SPELL_MISS_NONE)
3732 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3733 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3734
3737
3740 }
3741
3743 ArenaSpectator::SendCommand_Spell(m_caster->FindMap(), m_caster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3744
3745 // spell is canceled-take mods and clear list
3746 if (Player* player = m_caster->GetSpellModOwner())
3747 player->RemoveSpellMods(this);
3748
3749 m_appliedMods.clear();
3750 break;
3751 default:
3752 break;
3753 }
3754
3756 if (m_selfContainer && *m_selfContainer == this)
3757 *m_selfContainer = nullptr;
3758
3759 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3761 {
3763 }
3764
3765 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3767
3768 //set state back so finish will be processed
3769 m_spellState = oldState;
3770
3771 sScriptMgr->OnSpellCastCancel(this, m_caster, m_spellInfo, bySelf);
3772
3773 finish(false);
3774}
@ 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:15816
void SendChannelUpdate(uint32 time)
Definition Spell.cpp:5193
void CancelGlobalCooldown()
Definition Spell.cpp:8981
void SetReferencedFromCurrent(bool yes)
Definition Spell.h:576
UsedSpellMods m_appliedMods
Definition Spell.h:560
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:6601
bool RemoveDynObject(uint32 spellId)
Definition Unit.cpp:6545
void SendCommand_Spell(T *o, ObjectGuid targetGUID, char const *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
8982{
8984 return;
8985
8986 // Cancel global cooldown when interrupting current cast
8988 return;
8989
8990 // Only players or controlled units have global cooldown
8991 if (m_caster->GetCharmInfo())
8993 else if (m_caster->IsPlayer())
8995}
@ CURRENT_GENERIC_SPELL
Definition Unit.h:557
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition CharmInfo.cpp:424
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition Player.h:1831
uint32 StartRecoveryTime
Definition SpellInfo.h:375
CharmInfo * GetCharmInfo()
Definition Unit.h:1282
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:1577
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
8831{
8832 // Relentless strikes, proc only from first effect
8833 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
8834 return effMask & (1 << EFFECT_0);
8835
8836 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
8837 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
8838 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8839 {
8840 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
8841 return true;
8842 }
8843 return effMask;
8844}
@ EFFECT_0
Definition SharedDefines.h:31
@ TARGET_UNIT_CASTER
Definition SharedDefines.h:1414
@ SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET
Definition SharedDefines.h:519

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

Referenced by DoAllEffectOnTarget(), and DoTriggersOnSpellHit().

◆ CanOpenLock()

SpellCastResult Spell::CanOpenLock ( uint32  effIndex,
uint32  lockid,
SkillType skillid,
int32 reqSkillValue,
int32 skillValue 
)
protected
8446{
8447 if (!lockId) // possible case for GO and maybe for items.
8448 return SPELL_CAST_OK;
8449
8450 // Get LockInfo
8451 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8452
8453 if (!lockInfo)
8455
8456 bool reqKey = false; // some locks not have reqs
8457
8458 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8459 {
8460 switch (lockInfo->Type[j])
8461 {
8462 // check key item (many fit cases can be)
8463 case LOCK_KEY_ITEM:
8464 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8465 return SPELL_CAST_OK;
8466 reqKey = true;
8467 break;
8468 // check key skill (only single first fit case can be)
8469 case LOCK_KEY_SKILL:
8470 {
8471 reqKey = true;
8472
8473 // wrong locktype, skip
8474 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8475 continue;
8476
8477 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8478
8479 if (skillId != SKILL_NONE)
8480 {
8481 reqSkillValue = lockInfo->Skill[j];
8482
8483 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8484 skillValue = m_CastItem || !m_caster->IsPlayer() ?
8485 0 : m_caster->ToPlayer()->GetSkillValue(skillId);
8486
8487 // skill bonus provided by casting spell (mostly item spells)
8488 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8489 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8491 {
8492 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8493 }
8494
8495 if (skillValue < reqSkillValue)
8497 }
8498
8499 return SPELL_CAST_OK;
8500 }
8501 case LOCK_KEY_SPELL:
8502 {
8503 if (m_spellInfo->Id == lockInfo->Index[j])
8504 {
8505 return SPELL_CAST_OK;
8506 }
8507 reqKey = true;
8508 break;
8509 }
8510 }
8511 }
8512
8513 if (reqKey)
8515
8516 return SPELL_CAST_OK;
8517}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
#define MAX_LOCK_CASE
Definition DBCStructure.h:1305
@ TARGET_GAMEOBJECT_ITEM_TARGET
Definition SharedDefines.h:1434
LockType
Definition SharedDefines.h:2595
@ LOCK_KEY_ITEM
Definition SharedDefines.h:2589
@ LOCK_KEY_SKILL
Definition SharedDefines.h:2590
@ LOCK_KEY_SPELL
Definition SharedDefines.h:2591
@ SPELL_FAILED_BAD_TARGETS
Definition SharedDefines.h:949
@ SPELL_FAILED_LOW_CASTLEVEL
Definition SharedDefines.h:986
SkillType SkillByLockType(LockType locktype)
Definition SharedDefines.h:3253
@ SKILL_NONE
Definition SharedDefines.h:3097
@ SKILL_LOCKPICKING
Definition SharedDefines.h:3208
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:5610
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)
3777{
3778 Player* modOwner = m_caster->GetSpellModOwner();
3779 Spell* lastMod = nullptr;
3780 if (modOwner)
3781 {
3782 lastMod = modOwner->m_spellModTakingSpell;
3783 if (lastMod)
3784 modOwner->SetSpellModTakingSpell(lastMod, false);
3785 }
3786
3787 _cast(skipCheck);
3788
3789 if (lastMod)
3790 modOwner->SetSpellModTakingSpell(lastMod, true);
3791}
Spell * m_spellModTakingSpell
Definition Player.h:2605
Definition Spell.h:298
void _cast(bool skipCheck)
Definition Spell.cpp:3793

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
5663{
5664 // check death state
5667
5668 // Spectator check
5669 if (m_caster->IsPlayer())
5670 if (((Player const*)m_caster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5671 return SPELL_FAILED_NOT_HERE;
5672
5674
5675 sScriptMgr->OnSpellCheckCast(this, strict, res);
5676
5677 if (res != SPELL_CAST_OK)
5678 return res;
5679
5680 // check cooldowns to prevent cheating
5682 {
5683 if (m_caster->IsPlayer())
5684 {
5685 //can cast triggered (by aura only?) spells while have this flag
5688
5690 {
5693 else
5695 }
5696
5697 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5700 }
5703 }
5704
5706 {
5709 }
5710
5711 // Check global cooldown
5714
5715 // only triggered spells can be processed an ended battleground
5716 if (!IsTriggered() && m_caster->IsPlayer())
5718 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5720
5721 if (m_caster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5722 {
5724 !m_caster->IsOutdoors())
5726
5730 }
5731
5732 // only check at first call, Stealth auras are already removed at second call
5733 // for now, ignore triggered spells
5735 {
5736 bool checkForm = true;
5737 // Ignore form req aura
5739 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5740 {
5741 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5742 continue;
5743 checkForm = false;
5744 break;
5745 }
5746 if (checkForm)
5747 {
5748 // Cannot be used in this stance/form
5750 if (shapeError != SPELL_CAST_OK)
5751 return shapeError;
5752
5755 }
5756 }
5757
5759 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5760 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5762
5763 bool reqCombat = true;
5765 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5766 {
5767 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5768 {
5769 m_needComboPoints = false;
5770 if ((*j)->GetMiscValue() == 1)
5771 {
5772 reqCombat = false;
5773 break;
5774 }
5775 }
5776 }
5777
5778 // caster state requirements
5779 // not for triggered spells (needed by execute)
5781 {
5786
5787 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5792
5793 if (reqCombat && m_caster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5795 }
5796
5797 // Xinef: exploit protection
5799 {
5800 if (m_caster->IsPlayer() && m_caster->GetMap()->IsDungeon())
5801 if (InstanceScript* instanceScript = m_caster->GetInstanceScript())
5802 if (instanceScript->IsEncounterInProgress())
5803 {
5804 if (Group* group = m_caster->ToPlayer()->GetGroup())
5805 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5806 if (Player* member = itr->GetSource())
5807 if (member->IsInMap(m_caster))
5808 if (Unit* victim = member->GetVictim())
5809 if (victim->IsInCombat() && m_caster->GetDistance(victim) < m_caster->GetVisibilityRange())
5810 {
5811 m_caster->EngageWithTarget(victim);
5812 break;
5813 }
5815 }
5816 }
5817
5818 // cancel autorepeat spells if cast start when moving
5819 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
5820 if (m_caster->IsPlayer() && m_caster->ToPlayer()->isMoving() && !IsTriggered())
5821 {
5822 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
5825 return SPELL_FAILED_MOVING;
5826 }
5827
5828 Vehicle* vehicle = m_caster->GetVehicle();
5830 {
5831 uint16 checkMask = 0;
5832 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
5833 {
5834 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
5836 {
5837 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
5838 if (shapeShiftEntry && (shapeShiftEntry->flags1 & SHAPESHIFT_FLAG_STANCE) == 0)
5839 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
5840 break;
5841 }
5842 }
5843
5846
5847 if (!checkMask)
5848 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
5849
5850 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
5851 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(m_caster);
5853 && (vehicleSeat->m_flags & checkMask) != checkMask && m_caster->IsPlayer())
5855 }
5856
5857 // check spell cast conditions from database
5858 {
5861 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
5862 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
5863 {
5864 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
5865 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
5866 {
5870 }
5871 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
5874 }
5875 }
5876
5877 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
5878 // those spells may have incorrect target entries or not filled at all (for example 15332)
5879 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
5880 // also, such casts shouldn't be sent to client
5881 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
5883 {
5884 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
5885 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
5887 {
5889 if (castResult != SPELL_CAST_OK)
5890 return castResult;
5891 }
5892 }
5893
5894 if (Unit* target = m_targets.GetUnitTarget())
5895 {
5896 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
5897 if (castResult != SPELL_CAST_OK)
5898 return castResult;
5899
5900 if (target != m_caster)
5901 {
5902 // Must be behind the target
5903 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), m_caster))
5905
5906 // Target must be facing you
5907 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
5909
5912 {
5913 bool castedByGameobject = false;
5914 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5916 {
5917 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5918 }
5919 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5920 {
5921 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5922 {
5923 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5924 }
5925 }
5926
5927 if (castedByGameobject)
5928 {
5929 // If spell casted by gameobject then ignore M2 models
5930 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5931 }
5932
5934 {
5936 }
5937 }
5938 }
5939 }
5940
5941 // Check for line of sight for spells with dest
5942 if (m_targets.HasDst())
5943 {
5944 float x, y, z;
5945 m_targets.GetDstPos()->GetPosition(x, y, z);
5946
5949 {
5950 bool castedByGameobject = false;
5951 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
5953 {
5954 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
5955 }
5956 else if (m_caster->GetEntry() == WORLD_TRIGGER)
5957 {
5958 if (TempSummon* tempSummon = m_caster->ToTempSummon())
5959 {
5960 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
5961 }
5962 }
5963
5964 if (castedByGameobject)
5965 {
5966 // If spell casted by gameobject then ignore M2 models
5967 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
5968 }
5969
5971 {
5973 }
5974 }
5975 }
5976
5977 // check pet presence
5978 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
5979 {
5980 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
5981 {
5983 {
5984 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
5986 else
5987 return SPELL_FAILED_NO_PET;
5988 }
5989 break;
5990 }
5991 }
5992 // Spell casted only on battleground
5994 if (!m_caster->ToPlayer()->InBattleground())
5996
5997 // do not allow spells to be cast in arenas
5998 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
5999 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
6002 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
6003 if (mapEntry->IsBattleArena())
6005
6006 // zone check
6008 {
6009 uint32 zone, area;
6010 m_caster->GetZoneAndAreaId(zone, area);
6011
6013 m_caster->IsPlayer() ? m_caster->ToPlayer() : nullptr);
6014 if (locRes != SPELL_CAST_OK)
6015 return locRes;
6016 }
6017
6018 // not let players cast spells at mount (and let do it to creatures)
6021 {
6022 if (m_caster->IsInFlight())
6024 else
6026 }
6027
6028 SpellCastResult castResult = SPELL_CAST_OK;
6029
6030 // always (except passive spells) check items (focus object can be required for any type casts)
6031 if (!m_spellInfo->IsPassive())
6032 {
6033 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
6034 castResult = CheckSpellFocus();
6035 if (castResult != SPELL_CAST_OK)
6036 return castResult;
6037
6038 castResult = CheckItems();
6039 if (castResult != SPELL_CAST_OK)
6040 return castResult;
6041 }
6042
6043 // Triggered spells also have range check
6045 castResult = CheckRange(strict);
6046 if (castResult != SPELL_CAST_OK)
6047 return castResult;
6048
6050 {
6051 castResult = CheckPower();
6052 if (castResult != SPELL_CAST_OK)
6053 return castResult;
6054 }
6055
6057 {
6058 return SPELL_CAST_OK;
6059 }
6060
6061 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6063 {
6065 if (castResult != SPELL_CAST_OK)
6066 return castResult;
6067
6068 // 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).
6070 {
6071 auto const& mechanicList = m_caster->m_spellImmune[IMMUNITY_MECHANIC];
6072 if (mechanicList.count(m_spellInfo->Mechanic) > 0)
6074 }
6075 }
6076
6077 // script hook
6078 castResult = CallScriptCheckCastHandlers();
6079 if (castResult != SPELL_CAST_OK)
6080 return castResult;
6081
6082 bool hasDispellableAura = false;
6083 bool hasNonDispelEffect = false;
6084 uint32 dispelMask = 0;
6085 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6086 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6087 {
6089 {
6090 hasDispellableAura = true;
6091 break;
6092 }
6093
6094 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6095 }
6096 else if (m_spellInfo->Effects[i].IsEffect())
6097 {
6098 hasNonDispelEffect = true;
6099 break;
6100 }
6101
6102 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6103 {
6104 if (Unit* target = m_targets.GetUnitTarget())
6105 {
6106 // Xinef: do not allow to cast on hostile targets in sanctuary
6107 if (!m_caster->IsFriendlyTo(target))
6108 {
6109 if (m_caster->IsInSanctuary() || target->IsInSanctuary())
6110 {
6111 // Xinef: fix for duels
6112 Player* player = m_caster->ToPlayer();
6113 if (!player || !player->duel || target != player->duel->Opponent)
6115 }
6116 }
6117
6118 DispelChargesList dispelList;
6119 target->GetDispellableAuraList(m_caster, dispelMask, dispelList, m_spellInfo);
6120
6121 if (dispelList.empty())
6123 }
6124 }
6125
6126 uint8 approximateAuraEffectMask = 0;
6127 uint8 nonAuraEffectMask = 0;
6128 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6129 {
6130 // for effects of spells that have only one target
6131 switch (m_spellInfo->Effects[i].Effect)
6132 {
6134 {
6135 if (!m_caster->IsPlayer())
6137
6138 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6139 break;
6140
6141 Pet* pet = m_caster->ToPlayer()->GetPet();
6142
6143 if (!pet)
6144 return SPELL_FAILED_NO_PET;
6145
6146 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6147
6148 if (!learn_spellproto)
6150
6151 if (m_spellInfo->SpellLevel > pet->GetLevel())
6152 return SPELL_FAILED_LOWLEVEL;
6153
6154 break;
6155 }
6157 {
6158 // check target only for unit target case
6160 {
6161 if (!m_caster->IsPlayer())
6163
6164 Pet* pet = unitTarget->ToPet();
6165 if (!pet || pet->GetOwner() != m_caster)
6167
6168 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6169
6170 if (!learn_spellproto)
6172
6173 if (m_spellInfo->SpellLevel > pet->GetLevel())
6174 return SPELL_FAILED_LOWLEVEL;
6175 }
6176 break;
6177 }
6179 {
6180 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6181 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6182 if (m_caster->HasAura(gp->SpellId))
6184 break;
6185 }
6187 {
6188 if (!m_caster->IsPlayer())
6190
6191 Item* foodItem = m_targets.GetItemTarget();
6192 if (!foodItem)
6194
6195 Pet* pet = m_caster->ToPlayer()->GetPet();
6196
6197 if (!pet)
6198 return SPELL_FAILED_NO_PET;
6199
6200 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6202
6203 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6205
6206 if (m_caster->IsInCombat() || pet->IsInCombat())
6208
6209 break;
6210 }
6213 {
6214 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6215 if (m_caster->IsPlayer())
6216 if (Unit* target = m_targets.GetUnitTarget())
6217 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6219 break;
6220 }
6222 {
6224 {
6226 }
6227
6229 {
6230 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6231 if (strict && m_caster->IsScriptOverriden(m_spellInfo, 6953))
6233 }
6235 {
6236 // Exception for Master's Call
6237 if (m_spellInfo->Id != 54216)
6238 {
6239 return SPELL_FAILED_ROOTED;
6240 }
6241 }
6242 if (m_caster->IsPlayer())
6243 if (Unit* target = m_targets.GetUnitTarget())
6244 if (!target->IsAlive())
6246 // Xinef: Pass only explicit unit target spells
6247 // pussywizard:
6248 if (sDisableMgr->IsPathfindingEnabled(m_caster->FindMap()) && m_spellInfo->NeedsExplicitUnitTarget())
6249 {
6250 Unit* target = m_targets.GetUnitTarget();
6251 if (!target)
6253
6254 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6255 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6257
6258 float objSize = target->GetCombatReach();
6259 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6260
6261 m_preGeneratedPath = std::make_unique<PathGenerator>(m_caster);
6262 m_preGeneratedPath->SetPathLengthLimit(range);
6263
6264 // first try with raycast, if it fails fall back to normal path
6265 bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
6266 if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT)
6267 return SPELL_FAILED_NOPATH;
6268 else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE))
6269 return SPELL_FAILED_NOPATH;
6270 else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line
6271 return SPELL_FAILED_NOPATH;
6272
6273 m_preGeneratedPath->ShortenPathUntilDist(G3D::Vector3(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ()), objSize); // move back
6274 }
6275 if (Player* player = m_caster->ToPlayer())
6276 player->SetCanTeleport(true);
6277 break;
6278 }
6280 {
6283
6286
6287 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6288 if (!creature->IsCritter() && !creature->loot.isLooted())
6290
6291 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6292
6293 int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
6294 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6295 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6296 if (ReqValue > skillValue)
6298
6299 break;
6300 }
6302 {
6303 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6304 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6305 break;
6306
6307 if (!m_caster->IsPlayer() // only players can open locks, gather etc.
6308 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6309 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6311
6312 Item* pTempItem = nullptr;
6314 {
6315 if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData())
6316 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6317 }
6320
6321 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6322 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6324 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6326
6327 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6328 if (GameObject* go = m_targets.GetGOTarget())
6329 {
6330 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6331 {
6333 }
6334 }
6335 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6337 {
6338 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6339 {
6340 if (!m_caster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6342 }
6343 else if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6346 }
6347
6348 // get the lock entry
6349 uint32 lockId = 0;
6350 if (GameObject* go = m_targets.GetGOTarget())
6351 {
6352 lockId = go->GetGOInfo()->GetLockId();
6353 if (!lockId)
6355 }
6356 else if (Item* itm = m_targets.GetItemTarget())
6357 lockId = itm->GetTemplate()->LockID;
6358
6359 SkillType skillId = SKILL_NONE;
6360 int32 reqSkillValue = 0;
6361 int32 skillValue = 0;
6362
6363 // check lock compatibility
6364 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6365 if (res != SPELL_CAST_OK)
6366 return res;
6367
6368 // chance for fail at lockpicking attempt
6369 // second check prevent fail at rechecks
6370 // herbalism and mining cannot fail as of patch 3.1.0
6371 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6372 {
6373 // chance for failure in orange lockpick
6374 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6375 {
6377 }
6378 }
6379 break;
6380 }
6382 {
6383 Unit* unitCaster = m_caster->ToUnit();
6384 if (!unitCaster)
6385 {
6387 }
6388
6389 Creature* pet = unitCaster->GetGuardianPet();
6390 if (pet)
6391 {
6392 if (pet->IsAlive())
6393 {
6395 }
6396 }
6397 else if (Player* playerCaster = m_caster->ToPlayer())
6398 {
6399 PetStable& petStable = playerCaster->GetOrInitPetStable();
6400 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6401 {
6402 return SPELL_FAILED_NO_PET;
6403 }
6404 }
6405
6406 break;
6407 }
6408 // This is generic summon effect
6410 {
6411 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6412 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6413 break;
6414 switch (SummonProperties->Category)
6415 {
6417 if (m_caster->GetPetGUID())
6419 [[fallthrough]];
6421 if (m_caster->GetCharmGUID())
6423 break;
6424 }
6425 break;
6426 }
6428 {
6430 {
6435 }
6436 break;
6437 }
6439 {
6440 Unit* unitCaster = m_caster->ToUnit();
6441 if (!unitCaster)
6443
6445 {
6446 if (m_caster->GetPetGUID())
6448 if (m_caster->GetCharmGUID())
6450 }
6451
6453 if (Pet* pet = m_caster->ToPlayer()->GetPet())
6454 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6455
6456 Player* playerCaster = unitCaster->ToPlayer();
6457 if (playerCaster && playerCaster->GetPetStable())
6458 {
6459 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6460 if (info.first)
6461 {
6462 if (info.first->Type == HUNTER_PET)
6463 {
6464 if (!info.first->Health)
6465 {
6466 playerCaster->SendTameFailure(PET_TAME_DEAD);
6468 }
6469
6470 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6471 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6472 {
6473 // if problem in exotic pet
6474 if (creatureInfo && creatureInfo->IsTameable(true))
6476 else
6478
6480 }
6481 }
6482 }
6483 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6484 {
6487 }
6488 }
6489 break;
6490 }
6492 {
6493 if (!m_caster->IsPlayer())
6495 if (!m_caster->GetTarget())
6497
6499 if (!target || (!target->IsInSameRaidWith(m_caster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6501
6502 // Xinef: Implement summon pending error
6503 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6505
6506 // check if our map is dungeon
6507 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6508 if (map->IsDungeon())
6509 {
6510 uint32 mapId = m_caster->GetMap()->GetId();
6511 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6512 /*if (map->IsRaid())
6513 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6514 if (targetBind->perm && targetBind != m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6515 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6516
6517 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6518 if (!instance)
6520 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6522 }
6523 break;
6524 }
6525 // RETURN HERE
6527 {
6528 if (!m_caster->IsPlayer())
6530
6531 Player* playerCaster = m_caster->ToPlayer();
6532 //
6533 if (!(playerCaster->GetTarget()))
6535
6537
6538 if (!target ||
6539 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6541
6542 // Xinef: Implement summon pending error
6543 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6545
6546 break;
6547 }
6548 case SPELL_EFFECT_LEAP:
6550 {
6551 //Do not allow to cast it before BG starts.
6552 if (m_caster->IsPlayer())
6553 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6554 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6556 break;
6557 }
6559 {
6562
6563 bool found = false;
6565 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6566 {
6567 if (itr->second->GetBase()->IsPassive())
6568 continue;
6569
6570 if (!itr->second->IsPositive())
6571 continue;
6572
6573 found = true;
6574 break;
6575 }
6576
6577 if (!found)
6579
6580 break;
6581 }
6583 {
6585 {
6586 if (m_caster->IsPlayer())
6587 return SPELL_FAILED_ROOTED;
6588 else
6590 }
6591 break;
6592 }
6593 // xinef: do not allow to use leaps while rooted
6594 case SPELL_EFFECT_JUMP:
6596 {
6598 return SPELL_FAILED_ROOTED;
6599 break;
6600 }
6602 if (!sScriptMgr->CanSelectSpecTalent(this))
6604 // can't change during already started arena/battleground
6605 if (m_caster->IsPlayer())
6606 if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
6607 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6609 break;
6610 default:
6611 break;
6612 }
6613
6614 if (m_spellInfo->Effects[i].IsAura())
6615 approximateAuraEffectMask |= 1 << i;
6616 else if (m_spellInfo->Effects[i].IsEffect())
6617 nonAuraEffectMask |= 1 << i;
6618 }
6619
6620 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6621 {
6622 switch (m_spellInfo->Effects[i].ApplyAuraName)
6623 {
6624 case SPELL_AURA_DUMMY:
6625 break;
6627 {
6628 if (!m_caster->IsPlayer())
6629 return SPELL_FAILED_NO_PET;
6630
6631 Pet* pet = m_caster->ToPlayer()->GetPet();
6632 if (!pet)
6633 return SPELL_FAILED_NO_PET;
6634
6635 if (pet->GetCharmerGUID())
6636 return SPELL_FAILED_CHARMED;
6637 break;
6638 }
6642 {
6643 if (m_caster->GetCharmerGUID())
6644 return SPELL_FAILED_CHARMED;
6645
6646 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6648 {
6649 if (m_caster->GetPetGUID())
6651
6652 if (m_caster->GetCharmGUID())
6654 }
6655 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6656 {
6657 if (m_caster->GetCharmGUID())
6659 }
6660
6661 if (Unit* target = m_targets.GetUnitTarget())
6662 {
6663 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6665
6666 // Allow SPELL_AURA_MOD_POSSESS to work on mounted players,
6667 // but keep the old restriction for everything else.
6668 if (target->IsMounted())
6669 {
6670 if (!(target->IsPlayer() && m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS))
6672 }
6673
6674 if (target->GetCharmerGUID())
6675 return SPELL_FAILED_CHARMED;
6676
6677 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6679
6680 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6682
6683 int32 damage = CalculateSpellDamage(i, target);
6684 if (damage && int32(target->GetLevel()) > damage)
6686 }
6687
6688 break;
6689 }
6690 case SPELL_AURA_MOUNTED:
6691 {
6692 // Disallow casting flying mounts in water
6695
6696 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6697 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6698 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6699 if (it)
6700 allowMount = it->AllowMount;
6701 if (m_caster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6703
6706
6707 // xinef: dont allow to cast mounts in specific transforms
6708 if (m_caster->getTransForm())
6709 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(m_caster->getTransForm()))
6710 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6711 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6713
6714 break;
6715 }
6717 {
6718 if (!m_targets.GetUnitTarget())
6720
6721 // can be casted at non-friendly unit or own pet/charm
6724
6725 break;
6726 }
6727 case SPELL_AURA_FLY:
6729 {
6730 // Xinef: added water check
6731 if (m_caster->IsInWater())
6733
6734 // not allow cast fly spells if not have req. skills (all spells is self target)
6735 // allow always ghost flight spells
6737 {
6738 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6739 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6740 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6741 return SPELL_FAILED_NOT_HERE;
6742 }
6743 break;
6744 }
6746 {
6747 if (m_spellInfo->Effects[i].IsTargetingArea())
6748 break;
6749
6750 if (!m_caster->IsPlayer() || m_CastItem)
6751 break;
6752
6753 if (!m_targets.GetUnitTarget())
6755
6758
6759 break;
6760 }
6761 case SPELL_AURA_HOVER:
6762 {
6764 {
6766 }
6767 break;
6768 }
6770 {
6771 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.
6772 {
6774 }
6775 break;
6776 }
6777 default:
6778 break;
6779 }
6780
6781 // check if target already has the same type, but more powerful aura
6782 if (!nonAuraEffectMask && (approximateAuraEffectMask & (1 << i)) && !m_spellInfo->IsTargetingArea())
6783 if (Unit* target = m_targets.GetUnitTarget())
6784 if (!target->IsHighestExclusiveAuraEffect(m_spellInfo, AuraType(m_spellInfo->Effects[i].ApplyAuraName),
6785 m_spellInfo->Effects[i].CalcValue(m_caster, &m_spellValue->EffectBasePoints[i]), approximateAuraEffectMask, false))
6787 }
6788
6789 // check trade slot case (last, for allow catch any another cast problems)
6791 {
6792 if (m_CastItem)
6794
6795 if (!m_caster->IsPlayer())
6797
6798 TradeData* my_trade = m_caster->ToPlayer()->GetTradeData();
6799
6800 if (!my_trade)
6802
6804 if (slot != TRADE_SLOT_NONTRADED)
6806
6807 if (!IsTriggered())
6808 if (my_trade->GetSpell())
6810 }
6811
6812 // check if caster has at least 1 combo point on target for spells that require combo points
6814 {
6816 {
6818 {
6820 }
6821 }
6822 else
6823 {
6824 if (!m_caster->GetComboPoints())
6825 {
6827 }
6828 }
6829 }
6830
6831 // xinef: check relic cooldown
6835
6836 // all ok
6837 return SPELL_CAST_OK;
6838}
#define SPECTATOR_SPELL_BINDSIGHT
Definition ArenaSpectator.h:38
#define sBattlefieldMgr
Definition BattlefieldMgr.h:79
@ STATUS_WAIT_LEAVE
Definition Battleground.h:194
@ STATUS_IN_PROGRESS
Definition Battleground.h:193
constexpr auto IN_MILLISECONDS
Definition Common.h:53
constexpr auto MINUTE
Definition Common.h:47
#define sConditionMgr
Definition ConditionMgr.h:296
@ CONDITION_SOURCE_TYPE_SPELL
Definition ConditionMgr.h:143
std::list< Condition * > ConditionList
Definition ConditionMgr.h:240
@ VEHICLE_SEAT_FLAG_CAN_CAST_MOUNT_SPELL
Definition DBCEnums.h:456
@ VEHICLE_SEAT_FLAG_UNCONTROLLED
Definition DBCEnums.h:457
@ VEHICLE_SEAT_FLAG_CAN_ATTACK
Definition DBCEnums.h:458
Difficulty
Definition DBCEnums.h:266
@ AREA_FLAG_NO_FLY_ZONE
Definition DBCEnums.h:262
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
DBCStorage< SpellShapeshiftFormEntry > sSpellShapeshiftFormStore(SpellShapeshiftFormEntryfmt)
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< GlyphPropertiesEntry > sGlyphPropertiesStore(GlyphPropertiesfmt)
DBCStorage< AreaTableEntry > sAreaTableStore(AreaTableEntryfmt)
std::uint16_t uint16
Definition Define.h:108
#define sDisableMgr
Definition DisableMgr.h:88
@ GO_STATE_READY
Definition GameObjectData.h:709
@ INVTYPE_RELIC
Definition ItemTemplate.h:284
LineOfSightChecks
Definition Map.h:108
@ LINEOFSIGHT_ALL_CHECKS
Definition Map.h:115
@ PATHFIND_NOPATH
Definition PathGenerator.h:50
@ PATHFIND_SHORT
Definition PathGenerator.h:52
@ PATHFIND_INCOMPLETE
Definition PathGenerator.h:49
@ HUNTER_PET
Definition PetDefines.h:33
@ PLAYER_ALLOW_ONLY_ABILITY
Definition Player.h:482
int32 irand(int32 min, int32 max)
Definition Random.cpp:37
@ GAMEOBJECT_TYPE_TRAP
Definition SharedDefines.h:1570
@ GAMEOBJECT_TYPE_DOOR
Definition SharedDefines.h:1564
Powers
Definition SharedDefines.h:256
@ POWER_MANA
Definition SharedDefines.h:257
@ SPELL_ATTR7_DEBUG_SPELL
Definition SharedDefines.h:632
@ SPELL_EFFECT_LEAP
Definition SharedDefines.h:795
@ SPELL_EFFECT_POWER_BURN
Definition SharedDefines.h:828
@ SPELL_EFFECT_STUCK
Definition SharedDefines.h:850
@ SPELL_EFFECT_SUMMON_RAF_FRIEND
Definition SharedDefines.h:918
@ SPELL_EFFECT_APPLY_GLYPH
Definition SharedDefines.h:840
@ SPELL_EFFECT_FEED_PET
Definition SharedDefines.h:867
@ SPELL_EFFECT_SUMMON_PLAYER
Definition SharedDefines.h:851
@ SPELL_EFFECT_JUMP_DEST
Definition SharedDefines.h:808
@ SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER
Definition SharedDefines.h:809
@ SPELL_EFFECT_RESURRECT_PET
Definition SharedDefines.h:875
@ SPELL_EFFECT_LEAP_BACK
Definition SharedDefines.h:904
@ SPELL_EFFECT_SUMMON
Definition SharedDefines.h:794
@ SPELL_EFFECT_POWER_DRAIN
Definition SharedDefines.h:774
@ SPELL_EFFECT_RESURRECT
Definition SharedDefines.h:784
@ SPELL_EFFECT_CHARGE
Definition SharedDefines.h:862
@ SPELL_EFFECT_RESURRECT_NEW
Definition SharedDefines.h:879
@ SPELL_EFFECT_TALENT_SPEC_SELECT
Definition SharedDefines.h:928
@ SPELL_EFFECT_LEARN_SPELL
Definition SharedDefines.h:802
@ SPELL_EFFECT_JUMP
Definition SharedDefines.h:807
@ SPELL_EFFECT_SKINNING
Definition SharedDefines.h:861
@ SPELL_EFFECT_CREATE_TAMED_PET
Definition SharedDefines.h:919
@ SPELL_EFFECT_OPEN_LOCK
Definition SharedDefines.h:799
@ SPELL_EFFECT_STEAL_BENEFICIAL_BUFF
Definition SharedDefines.h:892
@ SPELL_EFFECT_LEARN_PET_SPELL
Definition SharedDefines.h:823
@ SPELL_PREVENTION_TYPE_NONE
Definition SharedDefines.h:1557
@ SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT
Definition SharedDefines.h:581
@ TARGET_UNIT_PET
Definition SharedDefines.h:1418
@ TARGET_GAMEOBJECT_TARGET
Definition SharedDefines.h:1431
@ SPELL_ATTR2_IGNORE_LINE_OF_SIGHT
Definition SharedDefines.h:446
@ SPELL_ATTR1_INITIATE_COMBAT
Definition SharedDefines.h:416
@ SPELL_ATTR3_ONLY_BATTLEGROUNDS
Definition SharedDefines.h:492
@ PET_TAME_NOPET_AVAILABLE
Definition SharedDefines.h:3939
@ PET_TAME_DEAD
Definition SharedDefines.h:3942
@ PET_TAME_CANT_CONTROL_EXOTIC
Definition SharedDefines.h:3944
@ CLASS_WARLOCK
Definition SharedDefines.h:134
@ IMMUNITY_MECHANIC
Definition SharedDefines.h:1403
@ SPELLFAMILY_WARRIOR
Definition SharedDefines.h:3788
SpellCustomErrors
Definition SharedDefines.h:1130
@ SPELL_CUSTOM_ERROR_GM_ONLY
Definition SharedDefines.h:1196
SpellAttr0
Definition SharedDefines.h:369
@ SPELL_ATTR0_ONLY_INDOORS
Definition SharedDefines.h:384
@ SPELL_ATTR0_AURA_IS_DEBUFF
Definition SharedDefines.h:396
@ SPELL_ATTR0_ONLY_OUTDOORS
Definition SharedDefines.h:385
@ SPELL_ATTR0_ALLOW_WHILE_MOUNTED
Definition SharedDefines.h:394
@ SPELL_ATTR0_PASSIVE
Definition SharedDefines.h:376
@ SPELL_ATTR0_ALLOW_CAST_WHILE_DEAD
Definition SharedDefines.h:393
@ SPELL_ATTR0_ONLY_STEALTHED
Definition SharedDefines.h:387
AuraStateType
Definition SharedDefines.h:1276
DispelType
Definition SharedDefines.h:1374
@ SPELL_FAILED_TARGET_NOT_LOOTED
Definition SharedDefines.h:1058
@ SPELL_FAILED_NOT_INFRONT
Definition SharedDefines.h:998
@ SPELL_FAILED_MOVING
Definition SharedDefines.h:988
@ SPELL_FAILED_NOT_MOUNTED
Definition SharedDefines.h:1001
@ SPELL_FAILED_AFFECTING_COMBAT
Definition SharedDefines.h:938
@ SPELL_FAILED_CASTER_AURASTATE
Definition SharedDefines.h:959
@ SPELL_FAILED_NOTHING_TO_DISPEL
Definition SharedDefines.h:1023
@ SPELL_FAILED_NOT_KNOWN
Definition SharedDefines.h:1000
@ SPELL_FAILED_FOOD_LOWLEVEL
Definition SharedDefines.h:972
@ SPELL_FAILED_NOT_HERE
Definition SharedDefines.h:997
@ SPELL_FAILED_ROOTED
Definition SharedDefines.h:1040
@ SPELL_FAILED_WRONG_PET_FOOD
Definition SharedDefines.h:1072
@ SPELL_FAILED_CUSTOM_ERROR
Definition SharedDefines.h:1109
@ SPELL_FAILED_SUMMON_PENDING
Definition SharedDefines.h:1120
@ SPELL_FAILED_DAMAGE_IMMUNE
Definition SharedDefines.h:1083
@ SPELL_FAILED_BAD_IMPLICIT_TARGETS
Definition SharedDefines.h:948
@ SPELL_FAILED_TRY_AGAIN
Definition SharedDefines.h:1069
@ SPELL_FAILED_NO_COMBO_POINTS
Definition SharedDefines.h:1015
@ SPELL_FAILED_ALREADY_HAVE_SUMMON
Definition SharedDefines.h:944
@ SPELL_FAILED_ALREADY_OPEN
Definition SharedDefines.h:945
@ SPELL_FAILED_NOT_TRADING
Definition SharedDefines.h:1008
@ SPELL_FAILED_NOTHING_TO_STEAL
Definition SharedDefines.h:1024
@ SPELL_FAILED_NO_MOUNTS_ALLOWED
Definition SharedDefines.h:1020
@ SPELL_FAILED_NOT_IN_BATTLEGROUND
Definition SharedDefines.h:1103
@ SPELL_FAILED_NOT_BEHIND
Definition SharedDefines.h:994
@ SPELL_FAILED_ALREADY_HAVE_CHARM
Definition SharedDefines.h:943
@ SPELL_FAILED_TARGET_NOT_IN_INSTANCE
Definition SharedDefines.h:1074
@ SPELL_FAILED_HIGHLEVEL
Definition SharedDefines.h:973
@ SPELL_FAILED_LOWLEVEL
Definition SharedDefines.h:985
@ SPELL_FAILED_NOT_READY
Definition SharedDefines.h:1004
@ SPELL_FAILED_ONLY_BATTLEGROUNDS
Definition SharedDefines.h:1079
@ SPELL_FAILED_NOT_IN_ARENA
Definition SharedDefines.h:1088
@ SPELL_FAILED_ITEM_ALREADY_ENCHANTED
Definition SharedDefines.h:979
@ SPELL_FAILED_ONLY_STEALTHED
Definition SharedDefines.h:1032
@ SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED
Definition SharedDefines.h:1055
@ SPELL_FAILED_ONLY_ABOVEWATER
Definition SharedDefines.h:1025
@ SPELL_FAILED_AURA_BOUNCED
Definition SharedDefines.h:946
@ SPELL_FAILED_CANT_BE_CHARMED
Definition SharedDefines.h:950
@ SPELL_FAILED_CASTER_DEAD
Definition SharedDefines.h:960
@ SPELL_FAILED_NOT_ON_MOUNTED
Definition SharedDefines.h:1092
@ SPELL_FAILED_ITEM_ENCHANT_TRADE_WINDOW
Definition SharedDefines.h:1119
@ SPELL_FAILED_TARGET_CANNOT_BE_RESURRECTED
Definition SharedDefines.h:1123
@ SPELL_FAILED_TARGET_UNSKINNABLE
Definition SharedDefines.h:1063
@ SPELL_FAILED_NOT_SHAPESHIFT
Definition SharedDefines.h:1005
@ SPELL_FAILED_UNIQUE_GLYPH
Definition SharedDefines.h:1113
@ SPELL_FAILED_ONLY_OUTDOORS
Definition SharedDefines.h:1030
@ SPELL_FAILED_CHARMED
Definition SharedDefines.h:961
@ SPELL_FAILED_LINE_OF_SIGHT
Definition SharedDefines.h:984
@ SPELL_FAILED_SPELL_IN_PROGRESS
Definition SharedDefines.h:1042
@ SPELL_FAILED_NO_PET
Definition SharedDefines.h:1021
@ SPELL_FAILED_NOPATH
Definition SharedDefines.h:993
@ SPELL_FAILED_SPELL_UNAVAILABLE
Definition SharedDefines.h:1044
@ SPELL_FAILED_ONLY_INDOORS
Definition SharedDefines.h:1027
@ SPELL_FAILED_NOT_ON_TAXI
Definition SharedDefines.h:1002
@ SPELL_FAILED_TARGET_FRIENDLY
Definition SharedDefines.h:1052
@ SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS
Definition SharedDefines.h:535
@ SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND
Definition SharedDefines.h:534
@ SUMMON_CATEGORY_PET
Definition SharedDefines.h:3518
@ SUMMON_CATEGORY_PUPPET
Definition SharedDefines.h:3519
SkillType
Definition SharedDefines.h:3096
@ SKILL_MINING
Definition SharedDefines.h:3152
@ SKILL_HERBALISM
Definition SharedDefines.h:3148
@ SPELL_ATTR6_ALLOW_WHILE_RIDING_VEHICLE
Definition SharedDefines.h:604
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
Definition SpellAuraDefines.h:325
@ SPELL_AURA_MOD_SHAPESHIFT
Definition SpellAuraDefines.h:99
@ SPELL_AURA_MOD_IGNORE_SHAPESHIFT
Definition SpellAuraDefines.h:338
@ SPELL_AURA_PERIODIC_MANA_LEECH
Definition SpellAuraDefines.h:127
@ SPELL_AURA_MOD_POSSESS_PET
Definition SpellAuraDefines.h:191
@ SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS
Definition SpellAuraDefines.h:190
@ SPELL_AURA_DUMMY
Definition SpellAuraDefines.h:67
@ SPELL_AURA_FLY
Definition SpellAuraDefines.h:264
@ SPELL_AURA_HOVER
Definition SpellAuraDefines.h:169
@ SPELL_AURA_MOUNTED
Definition SpellAuraDefines.h:141
@ SPELL_AURA_AOE_CHARM
Definition SpellAuraDefines.h:240
@ SPELL_AURA_MOD_POSSESS
Definition SpellAuraDefines.h:65
@ SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
Definition SpellAuraDefines.h:270
@ SPELL_AURA_BLOCK_SPELL_FAMILY
Definition SpellAuraDefines.h:360
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition SpellDefines.h:61
@ AURA_INTERRUPT_FLAG_MOUNT
Definition SpellDefines.h:60
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition SpellDefines.h:135
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition SpellDefines.h:145
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition SpellDefines.h:146
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition SpellDefines.h:144
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition SpellDefines.h:134
@ TRIGGERED_IGNORE_EFFECTS
Periodic aura tick wont be reset on override.
Definition SpellDefines.h:153
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition SpellDefines.h:147
@ TARGET_FLAG_UNIT_ENEMY
Definition SpellInfo.h:54
@ TARGET_FLAG_ITEM
Definition SpellInfo.h:51
@ SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER
Definition SpellInfo.h:193
@ SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET
Definition SpellInfo.h:194
#define SPELL_RELIC_COOLDOWN
Definition SpellMgr.h:37
@ SPELL_FLAG_REDIRECTED
Definition Spell.h:95
TradeSlots
Definition TradeData.h:28
@ TRADE_SLOT_NONTRADED
Definition TradeData.h:31
@ MOVEMENTFLAG_FALLING_FAR
Definition UnitDefines.h:385
@ CLASS_CONTEXT_PET
Definition UnitDefines.h:243
@ UNIT_FLAG2_ALLOW_CHEAT_SPELLS
Definition UnitDefines.h:313
@ SHAPESHIFT_FLAG_STANCE
Definition UnitDefines.h:107
@ UNIT_STATE_ROOT
Definition UnitDefines.h:183
@ UNIT_STATE_CHARGING
Definition UnitDefines.h:190
@ UNIT_FLAG_SKINNABLE
Definition UnitDefines.h:283
#define WORLD_TRIGGER
Definition Unit.h:38
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition Unit.h:79
Definition Battlefield.h:196
bool CanFlyIn() const
Return if we can use mount in battlefield.
Definition Battlefield.h:336
Definition Battleground.h:303
Loot loot
Definition Creature.h:231
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:207
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition Creature.cpp:2957
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:177
Definition InstanceScript.h:143
bool IsLocked() const
Definition Item.h:253
ItemTemplate const * GetTemplate() const
Definition Item.cpp:545
bool IsPotion() const
Definition Item.h:337
bool IsDungeon() const
Definition Map.h:299
bool IsBattlegroundOrArena() const
Definition Map.h:307
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:2419
uint32 GetId() const
Definition Map.h:234
Difficulty GetDifficulty() const
Definition Map.h:294
uint64 GetRawValue() const
Definition ObjectGuid.h:145
bool IsPlayer() const
Definition ObjectGuid.h:172
bool IsGameObject() const
Definition ObjectGuid.h:175
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:2546
bool IsInSameRaidWith(Player const *p) const
Definition Player.h:1913
bool CanTameExoticPets() const
Definition Player.h:2219
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition Player.cpp:13527
bool InBattleground() const
Definition Player.h:2298
PetStable * GetPetStable()
Definition Player.h:1226
Battleground * GetBattleground(bool create=false) const
Definition Player.cpp:12430
WorldSession * GetSession() const
Definition Player.h:2030
bool HasSpellCooldown(uint32 spell_id) const override
Definition Player.cpp:16697
uint32 GetLastPotionId()
Definition Player.h:1838
Group * GetGroup()
Definition Player.h:2516
bool IsGameMaster() const
Definition Player.h:1178
time_t GetSummonExpireTimer() const
Definition Player.h:1118
bool Satisfy(DungeonProgressionRequirements const *ar, uint32 target_map, bool report=false)
Definition PlayerStorage.cpp:6852
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:1125
std::unique_ptr< DuelInfo > duel
Definition Player.h:1905
Item * GetItemByGuid(ObjectGuid guid) const
Definition PlayerStorage.cpp:411
GameObject * GetGOTarget() const
Definition Spell.cpp:264
ObjectGuid GetItemTargetGUID() const
Definition Spell.h:150
AuraType ApplyAuraName
Definition SpellInfo.h:275
int32 MiscValue
Definition SpellInfo.h:284
uint32 PreventionType
Definition SpellInfo.h:414
uint32 CasterAuraSpell
Definition SpellInfo.h:367
SpellCastResult CheckShapeshift(uint32 form) const
Definition SpellInfo.cpp:1444
uint32 Mechanic
Definition SpellInfo.h:347
uint32 GetDispelMask() const
Definition SpellInfo.cpp:1948
uint32 GetRecoveryTime() const
Definition SpellInfo.cpp:2798
bool IsSelfCast() const
Definition SpellInfo.cpp:1122
uint32 CasterAuraState
Definition SpellInfo.h:363
bool CanBeUsedInCombat() const
Definition SpellInfo.cpp:1264
uint32 CasterAuraStateNot
Definition SpellInfo.h:365
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player *player=nullptr, bool strict=true) const
Definition SpellInfo.cpp:1499
SpellSchoolMask GetSchoolMask() const
Definition SpellInfo.cpp:1894
int32 AreaGroupId
Definition SpellInfo.h:415
float GetMaxRange(bool positive=false, Unit *caster=nullptr, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2723
uint32 GetExplicitTargetMask() const
Definition SpellInfo.cpp:1962
bool NeedsExplicitUnitTarget() const
Definition SpellInfo.cpp:1065
uint32 ExcludeCasterAuraSpell
Definition SpellInfo.h:369
bool IsTargetingArea() const
Definition SpellInfo.cpp:1057
uint32 SpellFamilyName
Definition SpellInfo.h:411
uint32 AuraInterruptFlags
Definition SpellInfo.h:377
SpellCastResult CheckExplicitTarget(Unit const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition SpellInfo.cpp:1844
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition Spell.h:801
SpellCastResult CheckSpellFocus()
Definition Spell.cpp:7818
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition Spell.cpp:8445
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition Spell.h:491
SpellCastResult CheckPower()
Definition Spell.cpp:7174
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition Spell.cpp:6876
SpellCastResult CallScriptCheckCastHandlers()
Definition Spell.cpp:8653
SpellCastResult CheckItems(uint32 *param1=nullptr, uint32 *param2=nullptr)
Definition Spell.cpp:7219
SpellCastResult CheckRange(bool strict)
Definition Spell.cpp:7082
bool HasGlobalCooldown() const
Definition Spell.cpp:8925
Definition TemporarySummon.h:50
uint32 GetSpell() const
Definition TradeData.h:49
bool IsVehicle() const
Definition Unit.h:801
Vehicle * GetVehicle() const
Definition Unit.h:1926
SpellImmuneContainer m_spellImmune[MAX_SPELL_IMMUNITY]
Definition Unit.h:2089
Unit * GetOwner() const
Definition Unit.cpp:7746
Pet * ToPet()
Definition Unit.h:730
virtual bool HasSpellCooldown(uint32) const
Definition Unit.h:1336
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1957
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition Unit.h:1337
bool IsInDisallowedMountForm() const
Definition Unit.cpp:17312
bool HasUnitFlag2(UnitFlags2 flags) const
Definition Unit.h:754
bool IsInSanctuary() const
Definition Unit.h:1044
virtual bool IsClass(Classes unitClass, ClassContext context=CLASS_CONTEXT_NONE) const
Definition Unit.h:845
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition Unit.cpp:6128
float GetCombatReach() const override
Definition Unit.h:878
UnitFlags GetUnitFlags() const
Definition Unit.h:747
TempSummon * ToTempSummon()
Definition Unit.h:732
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:6017
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition Unit.h:688
bool IsInFlight() const
Definition Unit.h:1709
void SendTameFailure(uint8 result)
Definition Unit.cpp:15979
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition Unit.cpp:5901
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:775
virtual bool IsInWater() const
Definition Unit.cpp:4551
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition Unit.cpp:7693
bool isMoving() const
Definition Unit.h:1712
void EngageWithTarget(Unit *who)
Definition Unit.cpp:7565
ObjectGuid GetCharmGUID() const
Definition Unit.h:722
VisibleAuraMap const * GetVisibleAuras()
Definition Unit.h:1540
bool IsMounted() const
Definition Unit.h:1886
Unit * GetVictim() const
Definition Unit.h:904
bool IsCritter() const
Definition Unit.h:834
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:7302
ObjectGuid GetOwnerGUID() const
Definition Unit.h:714
bool IsHighestExclusiveAuraEffect(SpellInfo const *spellInfo, AuraType auraType, int32 effectAmount, uint8 auraEffectMask, bool removeOtherAuraApplications=false)
Definition Unit.cpp:4600
uint8 GetComboPoints(Unit const *who=nullptr) const
Definition Unit.h:1015
ObjectGuid GetCharmerGUID() const
Definition Unit.h:720
uint32 getTransForm() const
Definition Unit.h:1968
virtual bool HasActivePowerType(Powers power)
Definition Unit.h:1133
void RemoveMovementImpairingAuras(bool withRoot)
Definition Unit.cpp:5521
bool IsTotem() const
Definition Unit.h:800
Guardian * GetGuardianPet() const
Definition Unit.cpp:7797
ObjectGuid GetTarget() const
Definition Unit.h:862
bool IsInCombat() const
Definition Unit.h:936
ObjectGuid GetPetGUID() const
Definition Unit.h:724
Definition Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition Vehicle.cpp:621
uint32 GetMapId() const
Definition Position.h:281
Map * GetMap() const
Definition Object.h:631
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1242
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:1407
bool IsOutdoors() const
Definition Object.cpp:3191
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition Object.cpp:1386
float GetVisibilityRange() const
Definition Object.cpp:1705
uint32 GetAreaId() const
Definition Object.cpp:3174
uint32 GetZoneId() const
Definition Object.cpp:3166
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:3182
uint32 GetRecruiterId() const
Definition WorldSession.h:651
uint32 GetAccountId() const
Definition WorldSession.h:479
Seconds GetGameTime()
Definition GameTime.cpp:38
Player * FindPlayer(ObjectGuid const guid)
Definition ObjectAccessor.cpp:269
Definition DBCStructure.h:519
Definition ConditionMgr.h:185
Condition * mLastFailedCondition
Definition ConditionMgr.h:187
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition ConditionMgr.h:186
uint32 ErrorType
Definition ConditionMgr.h:208
uint8 ConditionTarget
Definition ConditionMgr.h:212
uint32 ErrorTextId
Definition ConditionMgr.h:209
SkillType GetRequiredLootSkill() const
Definition CreatureData.h:252
bool IsTameable(bool exotic) const
Definition CreatureData.h:269
uint32 type
Definition GameObjectData.h:34
Definition DBCStructure.h:1024
Definition Map.h:126
bool AllowMount
Definition Map.h:129
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
6877{
6878 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
6880 return SPELL_CAST_OK;
6881
6882 uint8 school_immune = 0;
6883 uint64 mechanic_immune = 0;
6884 uint32 dispel_immune = 0;
6885
6886 // Check if the spell grants school or mechanic immunity.
6887 // We use bitmasks so the loop is done only once and not on every aura check below.
6889 {
6890 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6891 {
6892 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
6893 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
6894 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
6895 mechanic_immune |= 1ULL << uint32(m_spellInfo->Effects[i].MiscValue);
6896 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
6897 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6898 }
6899 // immune movement impairment and loss of control
6900 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
6901 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)
6903 }
6904
6906
6907 // Glyph of Pain Suppression
6908 // there is no other way to handle it
6909 if (m_spellInfo->Id == 33206 && !m_caster->HasAura(63248))
6910 usableInStun = false;
6911
6912 // Check whether the cast should be prevented by any state you might have.
6913 SpellCastResult prevented_reason = SPELL_CAST_OK;
6914 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
6915 uint32 unitflag = m_caster->GetUnitFlags(); // Get unit state
6916
6917 // Xinef: if spell is triggered check preventionType only
6918 if (!preventionOnly)
6919 {
6920 if (unitflag & UNIT_FLAG_STUNNED)
6921 {
6922 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
6923 if (usableInStun)
6924 {
6925 bool foundNotStun = false;
6926 uint64 mask = (1ULL << MECHANIC_STUN) | (1ULL << MECHANIC_FREEZE) | (1ULL << MECHANIC_HORROR);
6927 // Barkskin should skip sleep effects, sap and fears
6928 if (m_spellInfo->Id == 22812)
6929 mask |= 1ULL << MECHANIC_SAPPED | 1ULL << MECHANIC_HORROR | 1ULL << MECHANIC_SLEEP;
6930 // Hand of Freedom, can be used while sapped and while under fear-mechanic stuns (e.g. Intimidating Shout primary target)
6931 if (m_spellInfo->Id == 1044)
6932 mask |= (1ULL << MECHANIC_SAPPED) | (1ULL << MECHANIC_FEAR);
6934 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
6935 {
6936 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
6937 {
6938 foundNotStun = true;
6939 break;
6940 }
6941 }
6942 if (foundNotStun)
6943 prevented_reason = SPELL_FAILED_STUNNED;
6944 }
6945 else
6946 prevented_reason = SPELL_FAILED_STUNNED;
6947 }
6949 prevented_reason = SPELL_FAILED_CONFUSED;
6951 prevented_reason = SPELL_FAILED_FLEEING;
6952 }
6953
6954 // Xinef: if there is no prevented_reason, check prevention types
6955 if (prevented_reason == SPELL_CAST_OK)
6956 {
6958 prevented_reason = SPELL_FAILED_SILENCED;
6960 prevented_reason = SPELL_FAILED_PACIFIED;
6961 }
6962
6963 // Attr must make flag drop spell totally immune from all effects
6964 if (prevented_reason != SPELL_CAST_OK)
6965 {
6966 if (school_immune || mechanic_immune || dispel_immune)
6967 {
6968 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
6970 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
6971 {
6972 Aura const* aura = itr->second->GetBase();
6973 SpellInfo const* auraInfo = aura->GetSpellInfo();
6974 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
6975 continue;
6976 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
6977 continue;
6978 if (auraInfo->GetDispelMask() & dispel_immune)
6979 continue;
6980
6981 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
6982 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
6983 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6984 {
6985 if (AuraEffect* part = aura->GetEffect(i))
6986 {
6987 switch (part->GetAuraType())
6988 {
6990 {
6991 uint64 mask = 1ULL << MECHANIC_STUN;
6992 // Barkskin should skip sleep effects, sap and fears
6993 if (m_spellInfo->Id == 22812)
6994 mask |= 1ULL << MECHANIC_SAPPED | 1ULL << MECHANIC_HORROR | 1ULL << MECHANIC_SLEEP;
6995 // Hand of Freedom, can be used while sapped and while under fear-mechanic stuns (e.g. Intimidating Shout primary target)
6996 if (m_spellInfo->Id == 1044)
6997 mask |= (1ULL << MECHANIC_SAPPED) | (1ULL << MECHANIC_FEAR);
6998
6999 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
7000 return SPELL_FAILED_STUNNED;
7001 break;
7002 }
7005 return SPELL_FAILED_CONFUSED;
7006 break;
7009 return SPELL_FAILED_FLEEING;
7010 break;
7015 return SPELL_FAILED_PACIFIED;
7017 return SPELL_FAILED_SILENCED;
7018 break;
7019 default:
7020 break;
7021 }
7022 }
7023 }
7024 }
7025 }
7026 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
7027 else
7028 return prevented_reason;
7029 }
7030 return SPELL_CAST_OK;
7031}
constexpr uint64 IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
Definition SharedDefines.h:1354
@ SPELL_PREVENTION_TYPE_SILENCE
Definition SharedDefines.h:1558
@ SPELL_PREVENTION_TYPE_PACIFY
Definition SharedDefines.h:1559
@ SPELL_ATTR5_ALLOW_WHILE_STUNNED
Definition SharedDefines.h:558
@ SPELL_ATTR5_ALLOW_WHILE_FLEEING
Definition SharedDefines.h:572
@ SPELL_ATTR5_ALLOW_WHILE_CONFUSED
Definition SharedDefines.h:573
@ SPELL_ATTR1_IMMUNITY_PURGES_EFFECT
Definition SharedDefines.h:422
@ SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS
Definition SharedDefines.h:423
@ MECHANIC_FEAR
Definition SharedDefines.h:1318
@ MECHANIC_STUN
Definition SharedDefines.h:1325
@ MECHANIC_FREEZE
Definition SharedDefines.h:1326
@ MECHANIC_SLEEP
Definition SharedDefines.h:1323
@ MECHANIC_SAPPED
Definition SharedDefines.h:1343
@ MECHANIC_HORROR
Definition SharedDefines.h:1337
@ SPELL_FAILED_STUNNED
Definition SharedDefines.h:1045
@ SPELL_FAILED_CONFUSED
Definition SharedDefines.h:963
@ SPELL_FAILED_SILENCED
Definition SharedDefines.h:1041
@ SPELL_FAILED_FLEEING
Definition SharedDefines.h:971
@ SPELL_FAILED_PACIFIED
Definition SharedDefines.h:1035
@ SPELL_ATTR6_NOT_AN_ATTACK
Definition SharedDefines.h:594
@ SPELL_AURA_DISPEL_IMMUNITY
Definition SpellAuraDefines.h:104
@ SPELL_AURA_MOD_FEAR
Definition SpellAuraDefines.h:70
@ SPELL_AURA_MOD_PACIFY
Definition SpellAuraDefines.h:88
@ SPELL_AURA_MOD_SILENCE
Definition SpellAuraDefines.h:90
@ SPELL_AURA_SCHOOL_IMMUNITY
Definition SpellAuraDefines.h:102
@ SPELL_AURA_MECHANIC_IMMUNITY
Definition SpellAuraDefines.h:140
@ SPELL_AURA_MOD_PACIFY_SILENCE
Definition SpellAuraDefines.h:123
@ SPELL_AURA_MOD_CONFUSE
Definition SpellAuraDefines.h:68
@ SPELL_AURA_MOD_STUN
Definition SpellAuraDefines.h:75
@ UNIT_FLAG_STUNNED
Definition UnitDefines.h:275
@ UNIT_FLAG_PACIFIED
Definition UnitDefines.h:274
@ UNIT_FLAG_CONFUSED
Definition UnitDefines.h:279
@ UNIT_FLAG_FLEEING
Definition UnitDefines.h:280
@ UNIT_FLAG_SILENCED
Definition UnitDefines.h:270
Definition SpellAuraEffects.h:39
Definition SpellAuras.h:87
AuraEffect * GetEffect(uint8 effIndex) const
Definition SpellAuras.h:176
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:100
uint64 GetAllEffectsMechanicMask() const
Definition SpellInfo.cpp:1899
boost::container::flat_multimap< uint32, AuraApplication * > AuraApplicationMap
Definition Unit.h:674
AuraApplicationMap & GetAppliedAuras()
Definition Unit.h:1384

References SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), Unit::GetAuraEffectsByType(), SpellInfo::GetDispelMask(), Aura::GetEffect(), SpellInfo::GetSchoolMask(), Aura::GetSpellInfo(), Unit::GetUnitFlags(), SpellInfo::HasAttribute(), Unit::HasAura(), SpellInfo::Id, IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK, m_caster, m_spellInfo, MAX_SPELL_EFFECTS, MECHANIC_FEAR, MECHANIC_FREEZE, MECHANIC_HORROR, MECHANIC_SAPPED, MECHANIC_SLEEP, MECHANIC_STUN, SpellInfo::PreventionType, SPELL_ATTR1_IMMUNITY_PURGES_EFFECT, SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS, SPELL_ATTR5_ALLOW_WHILE_CONFUSED, SPELL_ATTR5_ALLOW_WHILE_FLEEING, SPELL_ATTR5_ALLOW_WHILE_STUNNED, SPELL_ATTR6_NOT_AN_ATTACK, SPELL_AURA_DISPEL_IMMUNITY, SPELL_AURA_MECHANIC_IMMUNITY, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_PACIFY, SPELL_AURA_MOD_PACIFY_SILENCE, SPELL_AURA_MOD_SILENCE, SPELL_AURA_MOD_STUN, SPELL_AURA_SCHOOL_IMMUNITY, SPELL_CAST_OK, SPELL_FAILED_CONFUSED, SPELL_FAILED_FLEEING, SPELL_FAILED_PACIFIED, SPELL_FAILED_SILENCED, SPELL_FAILED_STUNNED, SPELL_PREVENTION_TYPE_PACIFY, SPELL_PREVENTION_TYPE_SILENCE, UNIT_FLAG_CONFUSED, UNIT_FLAG_FLEEING, UNIT_FLAG_PACIFIED, UNIT_FLAG_SILENCED, and UNIT_FLAG_STUNNED.

Referenced by CheckCast().

◆ CheckDst()

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

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

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8587{
8588 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8590}
#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
8001{
8002 switch (m_spellInfo->Effects[eff].ApplyAuraName)
8003 {
8008 if (target->IsCreature() && target->IsVehicle())
8009 return false;
8010 if (target->IsMounted() && m_spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_MOD_POSSESS)
8011 return false;
8012 if (target->GetCharmerGUID())
8013 return false;
8014 if (int32 damage = CalculateSpellDamage(eff, target))
8015 if ((int32)target->GetLevel() > damage)
8016 return false;
8017 break;
8018 default:
8019 break;
8020 }
8021
8022 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
8023 // 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
8024 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)))
8025 return true;
8026
8027 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
8030 {
8031 return true;
8032 }
8033
8035 //Check targets for LOS visibility (except spells without range limitations)
8036 switch (m_spellInfo->Effects[eff].Effect)
8037 {
8039 // player far away, maybe his corpse near?
8040 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
8041 {
8043 return false;
8044
8046 if (!corpse)
8047 return false;
8048
8049 if (target->GetGUID() != corpse->GetOwnerGUID())
8050 return false;
8051
8053 return false;
8054 }
8055 break;
8057 {
8059 {
8060 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
8061 return true;
8062
8063 return false;
8064 }
8065
8067 if (!corpse)
8068 return false;
8069
8070 if (target->GetGUID() != corpse->GetOwnerGUID())
8071 return false;
8072
8074 return false;
8075
8077 return false;
8078 }
8079 break;
8081 if (!m_caster->IsPlayer() || !target->IsPlayer())
8082 return false;
8083 if (m_caster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != m_caster->ToPlayer()->GetSession()->GetAccountId())
8084 return false;
8085 if (m_caster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
8086 return false;
8087 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
8088 return false;
8089 break;
8090 default: // normal case
8091 {
8092 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8093 GameObject* gobCaster = nullptr;
8095 {
8097 }
8098 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8099 {
8100 if (TempSummon* tempSummon = m_caster->ToTempSummon())
8101 {
8102 gobCaster = tempSummon->GetSummonerGameObject();
8103 }
8104 }
8105
8106 if (gobCaster)
8107 {
8108 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8109 {
8110 return true;
8111 }
8112
8113 // If spell casted by gameobject then ignore M2 models
8114 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8115 }
8116
8117 if (target != m_caster)
8118 {
8119 if (m_targets.HasDst())
8120 {
8121 float x = m_targets.GetDstPos()->GetPositionX();
8122 float y = m_targets.GetDstPos()->GetPositionY();
8123 float z = m_targets.GetDstPos()->GetPositionZ();
8124
8125 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8126 {
8127 return false;
8128 }
8129 }
8131 {
8132 return false;
8133 }
8134 }
8135 break;
8136 }
8137 }
8138
8139 return true;
8140}
@ 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:206
Definition Corpse.h:49
ObjectGuid GetOwnerGUID() const
Definition Corpse.h:68
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:875
ObjectGuid GetCorpseTargetGUID() const
Definition Spell.cpp:281
bool IsARecruiter() const
Definition WorldSession.h:652
#define sWorld
Definition World.h:318
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:203
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.
7220{
7221 Player* player = m_caster->ToPlayer();
7222 if (!player)
7223 {
7224 // Non-player case: Check if creature is disarmed
7226 {
7228 }
7229
7230 return SPELL_CAST_OK;
7231 }
7232
7233 if (!m_CastItem)
7234 {
7235 if (m_castItemGUID)
7237 }
7238 else
7239 {
7240 uint32 itemid = m_CastItem->GetEntry();
7241 if (!player->HasItemCount(itemid))
7243
7244 ItemTemplate const* proto = m_CastItem->GetTemplate();
7245 if (!proto)
7247
7248 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7249 if (proto->Spells[i].SpellCharges)
7250 if (m_CastItem->GetSpellCharges(i) == 0)
7252
7253 // consumable cast item checks
7255 {
7256 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7257 SpellCastResult failReason = SPELL_CAST_OK;
7258 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7259 {
7260 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7261 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7262 continue;
7263
7264 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7265 {
7267 {
7269 continue;
7270 }
7271 else
7272 {
7273 failReason = SPELL_CAST_OK;
7274 break;
7275 }
7276 }
7277
7278 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7279 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7280 {
7281 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7282 {
7284 continue;
7285 }
7286
7287 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7289 {
7291 continue;
7292 }
7293 else
7294 {
7295 failReason = SPELL_CAST_OK;
7296 break;
7297 }
7298 }
7299 }
7300 if (failReason != SPELL_CAST_OK)
7301 return failReason;
7302 }
7303 }
7304
7305 // check target item
7307 {
7308 if (!m_caster->IsPlayer())
7310
7311 if (!m_targets.GetItemTarget())
7313
7316 }
7317 // if not item target then required item must be equipped
7318 else
7319 {
7320 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7321 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7324 }
7325
7326 // do not take reagents for these item casts
7328 {
7330 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7331 if (!checkReagents)
7332 if (Item* targetItem = m_targets.GetItemTarget())
7333 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
7334 checkReagents = true;
7335
7336 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7337 if (checkReagents)
7338 {
7339 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7340 {
7341 if (m_spellInfo->Reagent[i] <= 0)
7342 continue;
7343
7344 uint32 itemid = m_spellInfo->Reagent[i];
7345 uint32 itemcount = m_spellInfo->ReagentCount[i];
7346
7347 // if CastItem is also spell reagent
7348 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7349 {
7350 ItemTemplate const* proto = m_CastItem->GetTemplate();
7351 if (!proto)
7353 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7354 {
7355 // CastItem will be used up and does not count as reagent
7356 int32 charges = m_CastItem->GetSpellCharges(s);
7357 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7358 {
7359 ++itemcount;
7360 break;
7361 }
7362 }
7363 }
7364 if (!player->HasItemCount(itemid, itemcount))
7365 return SPELL_FAILED_REAGENTS;
7366 }
7367 }
7368
7369 // check totem-item requirements (items presence in inventory)
7370 uint32 totems = 2;
7371 for (int i = 0; i < 2; ++i)
7372 {
7373 if (m_spellInfo->Totem[i] != 0)
7374 {
7375 if (player->HasItemCount(m_spellInfo->Totem[i]))
7376 {
7377 totems -= 1;
7378 continue;
7379 }
7380 }
7381 else
7382 totems -= 1;
7383 }
7384 if (totems != 0)
7385 return SPELL_FAILED_TOTEMS; //0x7C
7386
7387 // Check items for TotemCategory (items presence in inventory)
7389 for (int i = 0; i < 2; ++i)
7390 {
7391 if (m_spellInfo->TotemCategory[i] != 0)
7392 {
7394 {
7395 TotemCategory -= 1;
7396 continue;
7397 }
7398 }
7399 else
7400 TotemCategory -= 1;
7401 }
7402 if (TotemCategory != 0)
7403 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7404 }
7405
7406 // special checks for spell effects
7407 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7408 {
7409 switch (m_spellInfo->Effects[i].Effect)
7410 {
7413 {
7414 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7415 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7416 if (target->IsPlayer() && !IsTriggered())
7417 {
7418 // 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,
7419 // so we need to make sure there is at least one free space in the player's inventory
7421 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7422 {
7423 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7425 }
7426
7427 if (m_spellInfo->Effects[i].ItemType)
7428 {
7429 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7430 if (!itemTemplate)
7432
7433 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7434 ItemPosCountVec dest;
7435 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7436 if (msg != EQUIP_ERR_OK)
7437 {
7439 if (!itemTemplate->ItemLimitCategory)
7440 {
7441 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7443 }
7444 else
7445 {
7446 // Conjure Food/Water/Refreshment spells
7449 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7450 {
7451 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7453 }
7454 else
7455 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7456
7458 }
7459 }
7460 }
7461 }
7462 break;
7463 }
7465 {
7466 if (player->GetFreeInventorySpace() == 0)
7467 {
7468 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7470 }
7471 break;
7472 }
7474 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7476 {
7477 // cannot enchant vellum for other player
7480 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7483 ItemPosCountVec dest;
7484 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7485 if (msg != EQUIP_ERR_OK)
7486 {
7487 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7489 }
7490 }
7491 [[fallthrough]];
7493 {
7494 Item* targetItem = m_targets.GetItemTarget();
7495 if (!targetItem)
7497
7498 // Apply item level restriction
7500 {
7501 uint32 requiredLevel = targetItem->GetTemplate()->RequiredLevel;
7502 if (!requiredLevel)
7503 requiredLevel = targetItem->GetTemplate()->ItemLevel;
7504
7505 if (requiredLevel < m_spellInfo->BaseLevel)
7506 return SPELL_FAILED_LOWLEVEL;
7507 }
7508
7509 if (m_CastItem && m_spellInfo->MaxLevel > 0 && targetItem->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7511
7512 bool isItemUsable = false;
7513 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7514 {
7515 ItemTemplate const* proto = targetItem->GetTemplate();
7516 if (proto->Spells[e].SpellId && (
7519 {
7520 isItemUsable = true;
7521 break;
7522 }
7523 }
7524
7525 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7526 // do not allow adding usable enchantments to items that have use effect already
7527 if (enchantEntry)
7528 {
7529 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7530 {
7531 switch (enchantEntry->type[s])
7532 {
7534 if (isItemUsable)
7536 break;
7538 {
7539 uint32 numSockets = 0;
7540 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7541 if (targetItem->GetTemplate()->Socket[socket].Color)
7542 ++numSockets;
7543
7544 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7546 break;
7547 }
7548 }
7549 }
7550 }
7551
7552 // Not allow enchant in trade slot for some enchant type
7553 if (targetItem->GetOwner() != m_caster)
7554 {
7555 if (!enchantEntry)
7556 return SPELL_FAILED_ERROR;
7557 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7559 }
7560 break;
7561 }
7563 {
7564 Item* item = m_targets.GetItemTarget();
7565 if (!item)
7567 // Not allow enchant in trade slot for some enchant type
7568 if (item->GetOwner() != m_caster)
7569 {
7570 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7571 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7572 if (!pEnchant)
7573 return SPELL_FAILED_ERROR;
7574 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7576 }
7577
7578 // Apply item level restriction
7580 {
7581 uint32 requiredLevel = item->GetTemplate()->RequiredLevel;
7582 if (!requiredLevel)
7583 requiredLevel = item->GetTemplate()->ItemLevel;
7584
7585 if (requiredLevel < m_spellInfo->BaseLevel)
7586 return SPELL_FAILED_LOWLEVEL;
7587 }
7588
7591
7592 break;
7593 }
7595 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7596 break;
7598 {
7599 if (!m_targets.GetItemTarget())
7601
7602 // prevent disenchanting in trade slot
7605
7606 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7607 if (!itemProto)
7609
7610 uint32 item_quality = itemProto->Quality;
7611 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7612 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7613 if (item_disenchantskilllevel == uint32(-1))
7615 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7617 if (item_quality > 4 || item_quality < 2)
7619 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7621 if (!itemProto->DisenchantID)
7623 break;
7624 }
7626 {
7627 Item* item = m_targets.GetItemTarget();
7628 if (!item)
7630 //ensure item is a prospectable ore
7633 //prevent prospecting in trade slot
7634 if (item->GetOwnerGUID() != m_caster->GetGUID())
7636 //Check for enough skill in jewelcrafting
7637 uint32 item_prospectingskilllevel = item->GetTemplate()->RequiredSkillRank;
7638 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7640 //make sure the player has the required ores in inventory
7641 if (item->GetCount() < 5)
7642 {
7643 if (param1 && param2)
7644 {
7645 *param1 = item->GetEntry();
7646 *param2 = 5;
7647 }
7649 }
7650
7653
7654 break;
7655 }
7657 {
7658 Item* item = m_targets.GetItemTarget();
7659 if (!item)
7661 //ensure item is a millable herb
7662 if (!(item->GetTemplate()->HasFlag(ITEM_FLAG_IS_MILLABLE)))
7664 //prevent milling in trade slot
7665 if (item->GetOwnerGUID() != m_caster->GetGUID())
7667 //Check for enough skill in inscription
7668 uint32 item_millingskilllevel = item->GetTemplate()->RequiredSkillRank;
7669 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7671 //make sure the player has the required herbs in inventory
7672 if (item->GetCount() < 5)
7673 {
7674 if (param1 && param2)
7675 {
7676 *param1 = item->GetEntry();
7677 *param2 = 5;
7678 }
7680 }
7681
7684
7685 break;
7686 }
7689 {
7690 if (!m_caster->IsPlayer())
7692
7694 break;
7695
7697 if (!pItem || pItem->IsBroken())
7699
7700 switch (pItem->GetTemplate()->SubClass)
7701 {
7703 {
7704 uint32 ammo = pItem->GetEntry();
7705 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7706 return SPELL_FAILED_NO_AMMO;
7707 };
7708 break;
7712 {
7714 if (!ammo)
7715 {
7716 // Requires No Ammo
7717 if (m_caster->HasAura(46699))
7718 break; // skip other checks
7719
7720 return SPELL_FAILED_NO_AMMO;
7721 }
7722
7723 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7724 if (!ammoProto)
7725 return SPELL_FAILED_NO_AMMO;
7726
7727 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7728 return SPELL_FAILED_NO_AMMO;
7729
7730 // check ammo ws. weapon compatibility
7731 switch (pItem->GetTemplate()->SubClass)
7732 {
7735 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7736 return SPELL_FAILED_NO_AMMO;
7737 break;
7739 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
7740 return SPELL_FAILED_NO_AMMO;
7741 break;
7742 default:
7743 return SPELL_FAILED_NO_AMMO;
7744 }
7745
7746 if (!m_caster->ToPlayer()->HasItemCount(ammo))
7747 {
7749 return SPELL_FAILED_NO_AMMO;
7750 }
7751 };
7752 break;
7754 break;
7755 default:
7756 break;
7757 }
7758 break;
7759 }
7761 {
7762 uint32 item_id = m_spellInfo->Effects[i].ItemType;
7763 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
7764
7765 if (!pProto)
7767
7768 if (Item* pitem = player->GetItemByEntry(item_id))
7769 {
7770 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
7771 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
7773 }
7774 break;
7775 }
7776 default:
7777 break;
7778 }
7779 }
7780
7781 // check weapon presence in slots for main/offhand weapons
7782 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
7783 {
7784 // main hand weapon required
7786 {
7788
7789 // skip spell if no weapon in slot or broken
7790 if (!item || item->IsBroken())
7792
7793 // skip spell if weapon not fit to triggered spell
7796 }
7797
7798 // offhand hand weapon required
7800 {
7802
7803 // skip spell if no weapon in slot or broken
7804 if (!item || item->IsBroken())
7806
7807 // skip spell if weapon not fit to triggered spell
7810 }
7811
7813 }
7814
7815 return SPELL_CAST_OK;
7816}
@ 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:758
@ EFFECT_1
Definition SharedDefines.h:32
@ MAX_POWERS
Definition SharedDefines.h:264
@ SPELL_EFFECT_DISENCHANT
Definition SharedDefines.h:865
@ SPELL_EFFECT_PROSPECTING
Definition SharedDefines.h:893
@ SPELL_EFFECT_ENCHANT_HELD_ITEM
Definition SharedDefines.h:858
@ SPELL_EFFECT_ENCHANT_ITEM
Definition SharedDefines.h:819
@ SPELL_EFFECT_WEAPON_DAMAGE
Definition SharedDefines.h:824
@ SPELL_EFFECT_HEAL
Definition SharedDefines.h:776
@ SPELL_EFFECT_MILLING
Definition SharedDefines.h:924
@ SPELL_EFFECT_CREATE_MANA_GEM
Definition SharedDefines.h:832
@ SPELL_EFFECT_CREATE_ITEM_2
Definition SharedDefines.h:923
@ SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL
Definition SharedDefines.h:783
@ SPELL_EFFECT_ENERGIZE
Definition SharedDefines.h:796
@ SPELL_EFFECT_CREATE_RANDOM_ITEM
Definition SharedDefines.h:825
@ SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC
Definition SharedDefines.h:922
@ SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY
Definition SharedDefines.h:820
@ SPELL_EFFECT_CREATE_ITEM
Definition SharedDefines.h:790
@ SPELL_ATTR2_ALLOW_LOW_LEVEL_BUFF
Definition SharedDefines.h:447
@ SPELL_ATTR3_REQUIRES_MAIN_HAND_WEAPON
Definition SharedDefines.h:491
@ SPELLFAMILY_MAGE
Definition SharedDefines.h:3787
TotemCategory
Definition SharedDefines.h:3316
@ SPELL_FAILED_CANT_BE_MILLED
Definition SharedDefines.h:953
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND
Definition SharedDefines.h:968
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS
Definition SharedDefines.h:966
@ SPELL_FAILED_ITEM_AT_MAX_CHARGES
Definition SharedDefines.h:1116
@ SPELL_FAILED_TARGET_NOT_PLAYER
Definition SharedDefines.h:1059
@ SPELL_FAILED_ALREADY_AT_FULL_POWER
Definition SharedDefines.h:941
@ SPELL_FAILED_NOT_TRADEABLE
Definition SharedDefines.h:1007
@ SPELL_FAILED_ITEM_NOT_READY
Definition SharedDefines.h:982
@ SPELL_FAILED_NO_CHARGES_REMAIN
Definition SharedDefines.h:1013
@ SPELL_FAILED_ITEM_GONE
Definition SharedDefines.h:980
@ SPELL_FAILED_NO_AMMO
Definition SharedDefines.h:1012
@ SPELL_FAILED_ITEM_NOT_FOUND
Definition SharedDefines.h:981
@ SPELL_FAILED_EQUIPPED_ITEM
Definition SharedDefines.h:965
@ SPELL_FAILED_ALREADY_AT_FULL_HEALTH
Definition SharedDefines.h:939
@ SPELL_FAILED_ON_USE_ENCHANT
Definition SharedDefines.h:1107
@ SPELL_FAILED_TOTEMS
Definition SharedDefines.h:1068
@ SPELL_FAILED_ERROR
Definition SharedDefines.h:969
@ SPELL_FAILED_REAGENTS
Definition SharedDefines.h:1037
@ SPELL_FAILED_MAX_SOCKETS
Definition SharedDefines.h:1121
@ SPELL_FAILED_CANT_BE_DISENCHANTED
Definition SharedDefines.h:951
@ SPELL_FAILED_TOO_MANY_OF_ITEM
Definition SharedDefines.h:1066
@ SPELL_FAILED_NEED_MORE_ITEMS
Definition SharedDefines.h:992
@ SPELL_FAILED_CANT_BE_PROSPECTED
Definition SharedDefines.h:954
@ SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND
Definition SharedDefines.h:967
@ SPELL_FAILED_TOTEM_CATEGORY
Definition SharedDefines.h:1067
@ SKILL_INSCRIPTION
Definition SharedDefines.h:3235
@ SKILL_ENCHANTING
Definition SharedDefines.h:3187
@ SKILL_JEWELCRAFTING
Definition SharedDefines.h:3218
@ PLAYER_AMMO_ID
Definition UpdateFields.h:369
uint32 GetEnchantmentId(EnchantmentSlot slot) const
Definition Item.h:304
int32 GetSpellCharges(uint8 index=0) const
Definition Item.h:317
bool IsBroken() const
Definition Item.h:257
bool IsWeaponVellum() const
Definition Item.h:338
bool IsArmorVellum() const
Definition Item.h:339
Player * GetOwner() const
Definition Item.cpp:550
ObjectGuid GetOwnerGUID() const
Definition Item.h:231
uint32 GetCount() const
Definition Item.h:272
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition Item.cpp:885
bool HaveLootFor(uint32 loot_id) const
Definition LootMgr.h:224
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:298
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition Player.cpp:12772
uint32 GetFreeInventorySpace() const
Definition PlayerStorage.cpp:470
Item * GetItemByEntry(uint32 entry) const
Definition PlayerStorage.cpp:3440
bool HasItemCount(uint32 item, uint32 count=1, bool inBankAlso=false) const
Definition PlayerStorage.cpp:659
bool HasItemTotemCategory(uint32 TotemCategory) const
Definition PlayerStorage.cpp:860
bool CanNoReagentCast(SpellInfo const *spellInfo) const
Definition Player.cpp:12847
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition PlayerStorage.cpp:4098
InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec &dest, uint32 item, uint32 count, uint32 *no_space_count=nullptr) const
Definition Player.h:1304
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:1115
bool CanUseAttackType(WeaponAttackType attacktype) const
Definition Unit.h:993
uint32 GetMaxPower(Powers power) const
Definition Unit.h:1137
void SetUInt32Value(uint16 index, uint32 value)
Definition Unit.cpp:17367
uint32 GetPower(Powers power) const
Definition Unit.h:1136
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)
6841{
6842 if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
6844
6845 // dead owner (pets still alive when owners ressed?)
6846 if (Unit* owner = m_caster->GetCharmerOrOwner())
6847 if (!owner->IsAlive() && m_caster->GetEntry() != 30230) // Rise Ally
6849
6850 if (!target && m_targets.GetUnitTarget())
6851 target = m_targets.GetUnitTarget();
6852
6854 {
6855 if (!target)
6857 m_targets.SetUnitTarget(target);
6858 }
6859
6860 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
6862
6863 // cooldown
6864 if (Creature const* creatureCaster = m_caster->ToCreature())
6865 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
6867
6868 // Check if spell is affected by GCD
6872
6873 return CheckCast(true);
6874}
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition CharmInfo.cpp:397
void SetUnitTarget(Unit *target)
Definition Spell.cpp:239
int32 CalcPowerCost(Unit const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2803
uint32 StartRecoveryCategory
Definition SpellInfo.h:374

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

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

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7175{
7176 // item cast not used power
7177 if (m_CastItem)
7178 return SPELL_CAST_OK;
7179
7180 //While .cheat power is enabled dont check if we need power to cast the spell
7181 if (m_caster->IsPlayer())
7182 {
7184 {
7185 return SPELL_CAST_OK;
7186 }
7187 }
7188
7189 // health as power used - need check health amount
7191 {
7194 return SPELL_CAST_OK;
7195 }
7196 // Check valid power type
7198 {
7199 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7200 return SPELL_FAILED_UNKNOWN;
7201 }
7202
7203 //check rune cost only if a spell has PowerType == POWER_RUNE
7205 {
7207 if (failReason != SPELL_CAST_OK)
7208 return failReason;
7209 }
7210
7211 // Check power amount
7214 return SPELL_FAILED_NO_POWER;
7215 else
7216 return SPELL_CAST_OK;
7217}
@ CHEAT_POWER
Definition Player.h:1000
@ 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:5411
uint32 GetHealth() const
Definition Unit.h:1109

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)
7083{
7084 // Don't check for instant cast spells
7085 if (!strict && m_casttime == 0)
7086 return SPELL_CAST_OK;
7087
7088 uint32 range_type = 0;
7089
7091 {
7092 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7093 // these are triggered by other spells - possibly we should omit range check in that case?
7094 if (m_spellInfo->RangeEntry->ID == 1)
7095 return SPELL_CAST_OK;
7096
7097 range_type = m_spellInfo->RangeEntry->Flags;
7098 }
7099
7100 Unit* target = m_targets.GetUnitTarget();
7101 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7102 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7103
7104 // xinef: hack for npc shooters
7105 if (min_range && GetCaster()->IsCreature() && !GetCaster()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7106 range_type = SPELL_RANGE_RANGED;
7107
7108 if (Player* modOwner = m_caster->GetSpellModOwner())
7109 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7110
7111 // xinef: dont check max_range to strictly after cast
7112 if (range_type != SPELL_RANGE_MELEE && !strict)
7113 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7114
7115 if (target)
7116 {
7117 if (target != m_caster)
7118 {
7119 // A vehicle passenger can neither turn nor move, and their stored position and
7120 // orientation can be stale; never fail range or facing against the vehicle
7121 // carrying them (e.g. Yogg-Saron's Constrictor Tentacle grab).
7122 bool const targetIsVehicleBase = m_caster->GetVehicleBase() == target;
7123
7124 // Xinef: Spells with 5yd range can hit target 9yd away?
7125 if (range_type == SPELL_RANGE_MELEE)
7126 {
7127 float real_max_range = max_range;
7128
7129 if (m_caster->GetLeewayBonusRange(target) > 0.0f)
7130 real_max_range -= MIN_MELEE_REACH; // less strict when leeway applies
7131 else
7132 real_max_range -= 2 * MIN_MELEE_REACH;
7133
7134 if (!targetIsVehicleBase && !m_caster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7136 }
7137 else if (!targetIsVehicleBase && !m_caster->IsWithinCombatRange(target, max_range))
7138 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7139
7140 if (!targetIsVehicleBase && m_caster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc(static_cast<float>(M_PI), target) && !m_caster->IsWithinBoundaryRadius(target))
7142 }
7143
7144 // Check min range - for ranged spells, min range is the spell's min range + melee range (no leeway)
7145 if (range_type == SPELL_RANGE_RANGED)
7146 {
7147 float minRangeCombined = min_range + m_caster->GetMeleeRange(target);
7148 if (m_caster->IsWithinRange(target, minRangeCombined))
7150 }
7151 else if (min_range > 0 && m_caster->IsWithinCombatRange(target, min_range))
7153 }
7154
7155 if (GameObject* goTarget = m_targets.GetGOTarget())
7156 {
7157 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7158 {
7160 }
7161 }
7162
7163 if (m_targets.HasDst() && !m_targets.HasTraj())
7164 {
7167 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7169 }
7170
7171 return SPELL_CAST_OK;
7172}
#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(Unit const *obj) const
Definition Unit.cpp:820
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition Unit.cpp:766
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:11911
Unit * GetVehicleBase() const
Definition Unit.cpp:15016
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:11891
bool IsWithinRange(Unit const *obj, float dist) const
Definition Unit.cpp:805
float GetMeleeRange(Unit const *target) const
Definition Unit.cpp:799
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition Object.cpp:1349
float GetLeewayBonusRadius() const
Definition Object.cpp:1786
float GetLeewayBonusRange(Unit const *target) const
Definition Object.cpp:1772
bool HasInArc(float arcangle, Position const *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(), WorldObject::GetLeewayBonusRadius(), WorldObject::GetLeewayBonusRange(), Unit::GetMeleeRange(), Unit::GetSpellMaxRangeForTarget(), Unit::GetSpellMinRangeForTarget(), Unit::GetSpellModOwner(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleBase(), SpellCastTargets::HasDst(), Position::HasInArc(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellRangeEntry::ID, 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)
5412{
5413 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5414 return SPELL_CAST_OK;
5415
5416 if (!m_caster->IsPlayer())
5417 return SPELL_CAST_OK;
5418
5419 Player* player = m_caster->ToPlayer();
5420 //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)
5421 if (player->GetCommandStatus(CHEAT_POWER))
5422 {
5423 return SPELL_CAST_OK;
5424 }
5425
5427 return SPELL_CAST_OK;
5428
5429 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5430
5431 if (!src)
5432 return SPELL_CAST_OK;
5433
5434 if (src->NoRuneCost())
5435 return SPELL_CAST_OK;
5436
5437 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5438
5439 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5440 {
5441 runeCost[i] = src->RuneCost[i];
5442 if (Player* modOwner = m_caster->GetSpellModOwner())
5443 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5444 }
5445
5446 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5447
5448 for (uint32 i = 0; i < MAX_RUNES; ++i)
5449 {
5450 RuneType rune = player->GetCurrentRune(i);
5451 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5452 runeCost[rune]--;
5453 }
5454
5455 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5456 if (runeCost[i] > 0)
5457 runeCost[RUNE_DEATH] += runeCost[i];
5458
5459 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5460 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5461
5462 return SPELL_CAST_OK;
5463}
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:2556
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition Player.cpp:1348
RuneType GetCurrentRune(uint8 index) const
Definition Player.h:2555
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
8808{
8809 // Skip if there are not any script
8810 if (!m_loadedScripts.size())
8811 return true;
8812
8813 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
8814 {
8815 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
8816 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
8817 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8818 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8819 return false;
8820
8821 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
8822 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
8823 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
8824 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
8825 return false;
8826 }
8827 return true;
8828}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
7819{
7820 // check spell focus object
7822 {
7824 Cell cell(p);
7825
7826 GameObject* ok = nullptr;
7829
7831 Map& map = *m_caster->GetMap();
7832 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
7833
7834 if (!ok)
7836
7837 focusObject = ok; // game object found in range
7838 }
7839 return SPELL_CAST_OK;
7840}
@ SPELL_FAILED_REQUIRES_SPELL_FOCUS
Definition SharedDefines.h:1039
Definition GridNotifiers.h:680
Definition Map.h:168
void Visit(Cell const &cell, TypeContainerVisitor< T, CONTAINER > &visitor)
Definition Map.h:778
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:342
Definition Cell.h:45

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

Referenced by CheckCast().

◆ CheckSrc()

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

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

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2333{
2334 m_UniqueTargetInfo.clear();
2335 m_UniqueGOTargetInfo.clear();
2336 m_UniqueItemInfo.clear();
2337 m_delayMoment = 0;
2339}
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 ( )
7843{
7844 if (!m_caster)// || !m_caster->IsPlayer())
7845 return;
7846
7847 //if (m_spellState == SPELL_STATE_DELAYED)
7848 // return; // spell is active and can't be time-backed
7849
7850 if (isDelayableNoMore()) // Spells may only be delayed twice
7851 return;
7852
7854 return;
7855
7856 // spells not loosing casting time (slam, dynamites, bombs..)
7857 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
7858 // return;
7859
7860 //check pushback reduce
7861 int32 delaytime = 500; // spellcasting delay is normally 500ms
7862 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7865 if (delayReduce >= 100)
7866 return;
7867
7868 AddPct(delaytime, -delayReduce);
7869
7870 if (m_timer + delaytime > m_casttime)
7871 {
7872 delaytime = m_casttime - m_timer;
7874 }
7875 else
7876 m_timer += delaytime;
7877
7878 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
7879
7880 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
7881 data << m_caster->GetPackGUID();
7882 data << uint32(delaytime);
7883
7884 m_caster->SendMessageToSet(&data, true);
7885}
#define LOG_DEBUG(filterType__,...)
Definition Log.h:157
@ SPELL_ATTR6_NO_PUSHBACK
Definition SharedDefines.h:607
@ SPELL_AURA_REDUCE_PUSHBACK
Definition SpellAuraDefines.h:212
@ SPELLMOD_NOT_LOSE_CASTING_TIME
Definition SpellDefines.h:85
T AddPct(T &base, U pct)
Definition Util.h:58
PackedGuid const & GetPackGUID() const
Definition Object.h:116
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition Player.cpp:9996
bool isDelayableNoMore()
Definition Spell.h:649
int32 GetTotalAuraModifier(AuraType auratype) const
Definition Unit.cpp:6303
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:2166
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 ( )
7888{
7890 return;
7891
7892 if (isDelayableNoMore()) // Spells may only be delayed twice
7893 return;
7894
7896 return;
7897
7898 //check pushback reduce
7899 // should be affected by modifiers, not take the dbc duration.
7900 int32 duration = ((m_channeledDuration > 0) ? m_channeledDuration : m_spellInfo->GetDuration());
7901
7902 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
7903 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
7906 if (delayReduce >= 100)
7907 return;
7908
7909 AddPct(delaytime, -delayReduce);
7910
7911 if (m_timer <= delaytime)
7912 {
7913 delaytime = m_timer;
7914 m_timer = 0;
7915 }
7916 else
7917 m_timer -= delaytime;
7918
7919 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
7920
7921 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7922 if ((*ihit).missCondition == SPELL_MISS_NONE)
7923 if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
7924 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
7925
7926 // partially interrupt persistent area auras
7928 dynObj->Delay(delaytime);
7929
7931}
T CalculatePct(T base, U pct)
Definition Util.h:52
Definition DynamicObject.h:35
uint32 getState() const
Definition Spell.h:496
DynamicObject * GetDynObject(uint32 spellId)
Definition Unit.cpp:6532

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

◆ DoAllEffectOnLaunchTarget()

void Spell::DoAllEffectOnLaunchTarget ( TargetInfo targetInfo,
float *  multiplier 
)
protected
8383{
8384 Unit* unit = nullptr;
8385 // In case spell hit target, do all effect on that target
8386 if (targetInfo.missCondition == SPELL_MISS_NONE)
8387 unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8388 // In case spell reflect from target, do all effect on caster (if hit)
8389 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8390 unit = m_caster;
8391 if (!unit)
8392 return;
8393
8394 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8395 {
8396 if (targetInfo.effectMask & (1 << i))
8397 {
8398 m_damage = 0;
8399 m_healing = 0;
8401
8402 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8403
8404 if (m_damage > 0)
8405 {
8406 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8407 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8408 {
8411 if (m_caster->IsPlayer())
8412 {
8413 uint32 targetAmount = m_UniqueTargetInfo.size();
8414 if (targetAmount > 10)
8415 m_damage = m_damage * 10 / targetAmount;
8416 }
8417 }
8418 }
8419
8420 if (m_applyMultiplierMask & (1 << i))
8421 {
8423 m_damageMultipliers[i] *= multiplier[i];
8424 }
8425 targetInfo.damage += m_damage;
8427 }
8428 }
8429
8430 // xinef: totem's inherit owner crit chance and dancing rune weapon
8431 Unit* caster = m_caster;
8432 if (m_caster->IsTotem() || m_caster->GetEntry() == 27893)
8433 {
8434 if (Unit* owner = m_caster->GetOwner())
8435 caster = owner;
8436 }
8437 else if (m_originalCaster)
8438 caster = m_originalCaster;
8439
8440 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8441 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8442 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8443}
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:9213
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:9123
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, bool npcCaster) const
Definition Unit.cpp:16328

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
3318{
3319 if (target->processed) // Check target
3320 return;
3321 target->processed = true; // Target checked in apply effects procedure
3322
3323 uint32 effectMask = target->effectMask;
3324 if (!effectMask)
3325 return;
3326
3327 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3328 if (!go)
3329 return;
3330
3333
3334 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3335 if (effectMask & (1 << effectNumber))
3336 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3337
3338 // xinef: inform ai about spellhit
3340
3342
3344}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition GameObjectAI.h:66
GameObjectAI * AI() const
Definition GameObject.h:307
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition Spell.cpp:8726
void CallScriptOnHitHandlers()
Definition Spell.cpp:8739
void CallScriptAfterHitHandlers()
Definition Spell.cpp:8752

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
3347{
3348 uint32 effectMask = target->effectMask;
3349 if (!target->item || !effectMask)
3350 return;
3351
3354
3355 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3356 if (effectMask & (1 << effectNumber))
3357 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3358
3360
3362}

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

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

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

◆ DoCreateItem()

void Spell::DoCreateItem ( uint8  effIndex,
uint32  itemId 
)
1657{
1658 if (!unitTarget)
1659 return;
1660
1661 Player* player = unitTarget->ToPlayer();
1662 if (!player)
1663 {
1664 return;
1665 }
1666
1667 uint32 newitemid = itemId;
1668
1669 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1670 if (!pProto)
1671 {
1672 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1673 return;
1674 }
1675
1676 uint32 addNumber = damage;
1677
1678 // bg reward have some special in code work
1679 bool SelfCast = true;
1680 switch (m_spellInfo->Id)
1681 {
1686 case SPELL_WS_MARK_TIE:
1689 SelfCast = true;
1690 break;
1692 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1693 addNumber = 3;
1694 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1695 addNumber = 2;
1696 else
1697 addNumber = 1;
1698 SelfCast = true;
1699 break;
1700 }
1701
1702 if (addNumber < 1)
1703 addNumber = 1;
1704 if (addNumber > pProto->GetMaxStackSize())
1705 addNumber = pProto->GetMaxStackSize();
1706
1707 /* == gem perfection handling == */
1708
1709 // the chance of getting a perfect result
1710 float perfectCreateChance = 0.0f;
1711
1712 // the resulting perfect item if successful
1713 uint32 perfectItemType = itemId;
1714
1715 // get perfection capability and chance
1716 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1717 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1718 newitemid = perfectItemType; // the perfect item replaces the regular one
1719
1720 /* == gem perfection handling over == */
1721
1722 /* == profession specialization handling == */
1723
1724 // init items_count to 1, since 1 item will be created regardless of specialization
1725 int32 itemsCount = 1;
1726 float additionalCreateChance = 0.0f;
1727 int32 additionalMaxNum = 0;
1728 // get the chance and maximum number for creating extra items
1729 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1730 {
1731 // roll with this chance till we roll not to create or we create the max num
1732 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1733 ++itemsCount;
1734 }
1735
1736 // really will be created more items
1737 addNumber *= itemsCount;
1738
1739 /* == profession specialization handling over == */
1740
1741 // can the player store the new item?
1742 ItemPosCountVec dest;
1743 uint32 no_space = 0;
1744 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1745 if (msg != EQUIP_ERR_OK)
1746 {
1747 // convert to possible store amount
1749 addNumber -= no_space;
1750 else
1751 {
1752 // if not created by another reason from full inventory or unique items amount limitation
1753 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1754 return;
1755 }
1756 }
1757
1758 if (addNumber)
1759 {
1760 // create the new item and store it
1761 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1762
1763 // was it successful? return error if not
1764 if (!pItem)
1765 {
1766 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1767 return;
1768 }
1769
1770 // set the "Crafted by ..." property of the item
1771 if (m_caster->IsPlayer() && pItem->GetTemplate()->HasSignature())
1772 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1773
1774 // send info to the client
1775 player->SendNewItem(pItem, addNumber, true, SelfCast);
1776
1777 sScriptMgr->OnPlayerCreateItem(player, pItem, addNumber);
1778
1779 // we succeeded in creating at least one item, so a levelup is possible
1780 if (SelfCast)
1782 }
1783}
@ SPELL_WS_MARK_WINNER
Definition Battleground.h:97
@ SPELL_AV_MARK_LOSER
Definition Battleground.h:101
@ SPELL_WS_MARK_TIE
Definition Battleground.h:98
@ SPELL_WS_MARK_LOSER
Definition Battleground.h:96
@ SPELL_AB_MARK_LOSER
Definition Battleground.h:99
@ SPELL_WG_MARK_WINNER
Definition Battleground.h:105
@ SPELL_AB_MARK_WINNER
Definition Battleground.h:100
@ SPELL_AV_MARK_WINNER
Definition Battleground.h:102
@ EQUIP_ERR_ITEM_NOT_FOUND
Definition Item.h:70
@ EQUIP_ERR_CANT_CARRY_MORE_OF_THIS
Definition Item.h:64
bool canCreateExtraItems(Player *player, uint32 spellId, float &additionalChance, int32 &newMaxOrEntry)
Definition SkillExtraItems.cpp:226
bool CanCreatePerfectItem(Player *player, uint32 spellId, float &perfectCreateChance, uint32 &perfectItemType)
Definition SkillExtraItems.cpp:202
@ ITEM_FIELD_CREATOR
Definition UpdateFields.h:37
void SetGuidValue(uint16 index, ObjectGuid value)
Definition Object.cpp:716
bool UpdateCraftSkill(uint32 spellid)
Definition PlayerUpdates.cpp:829
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition PlayerStorage.cpp:4822
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, bool refund=false)
Definition PlayerStorage.cpp:2606
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
2994{
2995 if (!unit || !effectMask)
2996 return SPELL_MISS_EVADE;
2997
2998 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
3000 {
3001 return SPELL_MISS_IMMUNE;
3002 }
3003
3004 // disable effects to which unit is immune
3005 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
3006 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3007 {
3008 if (effectMask & (1 << effectNumber))
3009 {
3010 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber, m_caster))
3011 effectMask &= ~(1 << effectNumber);
3012 // Xinef: Buggs out polymorph
3013 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
3014 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
3015 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
3016 {
3017 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3018 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3019
3020 if (debuff_resist_chance > 0)
3021 if (irand(0,10000) <= (debuff_resist_chance * 100))
3022 {
3023 effectMask &= ~(1 << effectNumber);
3024 returnVal = SPELL_MISS_RESIST;
3025 }
3026 }*/
3027 }
3028 }
3029 if (!effectMask)
3030 return returnVal;
3031
3032 if (unit->IsPlayer())
3033 {
3037 }
3038
3039 if (m_caster->IsPlayer())
3040 {
3043 }
3044
3045 if (m_caster != unit)
3046 {
3047 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3048 // Xinef: Also check evade state
3049 if (m_spellInfo->Speed > 0.0f)
3050 {
3051 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
3052 return SPELL_MISS_EVADE;
3053
3055 return SPELL_MISS_EVADE;
3056 }
3057
3058 if (m_caster->_IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3059 {
3061 }
3062 else if (m_caster->IsFriendlyTo(unit))
3063 {
3064 // for delayed spells ignore negative spells (after duel end) for friendly targets
3066 if (!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
3067 return SPELL_MISS_EVADE;
3068
3069 // assisting case, healing and resurrection
3071 {
3074 m_caster->ToPlayer()->UpdatePvP(true);
3075 }
3076
3077 // xinef: triggered spells should not prolong combat
3079 {
3082 unit->GetThreatMgr().ForwardThreatForAssistingMe(m_originalCaster, 0.0f, nullptr, true);
3083 }
3084 }
3085 }
3086
3087 uint8 aura_effmask = 0;
3088 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3089 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3090 aura_effmask |= 1 << i;
3091
3092 Unit* originalCaster = GetOriginalCaster();
3093 if (!originalCaster)
3094 originalCaster = m_caster;
3095
3096 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3097 // Xinef: Do not increase diminishing level for self cast
3099 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3100 if (((m_spellFlags & SPELL_FLAG_REFLECTED) && !(unit->HasReflectSpellsAura())) || (aura_effmask && m_diminishGroup && unit != m_caster && (!m_caster->IsCreature() || !m_caster->ToCreature()->isWorldBoss())))
3101 {
3104
3105 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3106
3107 // Increase Diminishing on unit, current informations for actually casts will use values above
3108 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3110 {
3111 // Do not apply diminish return if caster is NPC
3113 {
3115 }
3116 }
3117 }
3118
3121
3122 if (aura_effmask)
3123 {
3124 // Select rank for aura with level requirements only in specific cases
3125 // 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
3126 SpellInfo const* aurSpellInfo = m_spellInfo;
3127 int32 basePoints[3];
3128 if (scaleAura)
3129 {
3131 ASSERT(aurSpellInfo);
3132 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3133 {
3134 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3135 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3136 {
3137 aurSpellInfo = m_spellInfo;
3138 break;
3139 }
3140 }
3141 }
3142
3143 if (m_originalCaster)
3144 {
3145 bool refresh = false;
3147 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3148 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3149
3150 // xinef: if aura was not refreshed, add proc ex
3151 if (!refresh)
3153
3154 if (m_spellAura)
3155 {
3156 // Set aura stack amount to desired value
3158 {
3159 if (!refresh)
3161 else
3163 }
3164
3165 // Now Reduce spell duration using data received at spell hit
3166 int32 duration = m_spellAura->GetMaxDuration();
3167 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3168
3169 // Xinef: if unit == caster - test versus original unit if available
3170 float diminishMod = 1.0f;
3171 if (unit == m_caster && m_targets.GetUnitTarget())
3173 else
3174 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3175
3176 // unit is immune to aura if it was diminished to 0 duration
3177 if (diminishMod == 0.0f)
3178 {
3181 return SPELL_MISS_IMMUNE;
3182 bool found = false;
3183 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3184 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3185 found = true;
3186 if (!found)
3187 return SPELL_MISS_IMMUNE;
3188 }
3189 else
3190 {
3191 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3192
3193 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3195 positive = aurApp->IsPositive();
3196
3197 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3198
3199 // xinef: haste affects duration of those spells twice
3202
3203 if (m_spellValue->AuraDuration != 0)
3204 {
3205 if (m_spellAura->GetMaxDuration() != -1)
3206 {
3208 }
3209
3211 }
3212 else if (duration != m_spellAura->GetMaxDuration())
3213 {
3214 m_spellAura->SetMaxDuration(duration);
3215 m_spellAura->SetDuration(duration);
3216 }
3217
3218 // xinef: apply relic cooldown, imo best place to add this
3221
3224 }
3225 }
3226 }
3227 }
3228
3229 int8 sanct_effect = -1;
3230
3231 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3232 {
3233 // handle sanctuary effects after aura apply!
3234 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3235 {
3236 sanct_effect = effectNumber;
3237 continue;
3238 }
3239
3240 if (effectMask & (1 << effectNumber))
3241 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3242 }
3243
3244 if (sanct_effect >= 0 && (effectMask & (1 << sanct_effect)))
3245 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3246
3247 return SPELL_MISS_NONE;
3248}
@ CREATURE_FLAG_EXTRA_OBEYS_TAUNT_DIMINISHING_RETURNS
Definition CreatureData.h:65
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition CreatureData.h:66
@ ACHIEVEMENT_TIMED_TYPE_SPELL_CASTER
Definition DBCEnums.h:112
@ ACHIEVEMENT_TIMED_TYPE_SPELL_TARGET
Definition DBCEnums.h:113
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2
Definition DBCEnums.h:181
@ ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET
Definition DBCEnums.h:142
@ ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2
Definition DBCEnums.h:217
@ DIMINISHING_TAUNT
Definition SharedDefines.h:3509
@ SPELL_EFFECT_SANCTUARY
Definition SharedDefines.h:845
@ SPELL_EFFECT_APPLY_AURA
Definition SharedDefines.h:772
@ SPELL_ATTR5_SPELL_HASTE_AFFECTS_PERIODIC
Definition SharedDefines.h:568
DiminishingReturnsType
Definition SharedDefines.h:3482
@ DRTYPE_PLAYER
Definition SharedDefines.h:3484
@ DRTYPE_ALL
Definition SharedDefines.h:3485
@ SPELL_AURA_PERIODIC_HASTE
Definition SpellAuraDefines.h:379
@ SPELL_AURA_MOD_STEALTH
Definition SpellAuraDefines.h:79
@ AURA_INTERRUPT_FLAG_HITBYSPELL
Definition SpellDefines.h:43
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition SpellDefines.h:152
@ SPELL_ATTR0_CU_DONT_BREAK_STEALTH
Definition SpellInfo.h:183
int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellInfo const *spellproto)
Definition SpellMgr.cpp:324
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellInfo const *spellproto, bool triggered)
Definition SpellMgr.cpp:107
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition SpellMgr.cpp:294
@ PROC_EX_NO_AURA_REFRESH
Definition SpellMgr.h:219
@ UNIT_STATE_ATTACK_PLAYER
Definition UnitDefines.h:187
@ UNIT_FLAG_NON_ATTACKABLE
Definition UnitDefines.h:258
@ UNIT_FLAG_PLAYER_CONTROLLED
Definition UnitDefines.h:260
@ UNIT_MOD_CAST_SPEED
Definition UpdateFields.h:137
Definition SpellAuras.h:37
int32 GetMaxDuration() const
Definition SpellAuras.h:129
void SetStackAmount(uint8 num)
Definition SpellAuras.cpp:942
AuraApplication const * GetApplicationOfTarget(ObjectGuid guid) const
Definition SpellAuras.h:184
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition SpellAuras.cpp:2761
void _RegisterForTargets()
Definition SpellAuras.h:121
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition SpellAuras.cpp:968
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:270
void SetDuration(int32 duration, bool withMods=false)
Definition SpellAuras.cpp:815
void SetMaxDuration(int32 duration)
Definition SpellAuras.h:130
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
void InheritCombatStatesFrom(Unit const *who)
Definition CombatManager.cpp:270
bool isWorldBoss() const
Definition Creature.h:124
bool IsInEvadeMode() const
Definition Creature.h:138
float GetFloatValue(uint16 index) const
Definition Object.cpp:310
uint32 StackAmount
Definition SpellInfo.h:395
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition SpellInfo.cpp:2928
Unit * GetOriginalCaster() const
Definition Spell.h:591
Definition SpellAuras.h:289
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition Unit.cpp:6057
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition Unit.cpp:11751
void IncrDiminishing(DiminishingGroup group)
Definition Unit.cpp:11777
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition Unit.cpp:13660
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:748
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition Unit.cpp:11791
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask)
Definition Unit.cpp:11617
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition Unit.h:1338
bool HasReflectSpellsAura() const
Definition Unit.h:1816
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition Unit.h:1310
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition Unit.cpp:10104
CombatManager & GetCombatManager()
Definition Unit.h:954
bool IsHostileTo(Unit const *unit) const
Definition Unit.cpp:7297
bool _IsValidAttackTarget(Unit const *target, SpellInfo const *bySpell, WorldObject const *obj=nullptr) const
Definition Unit.cpp:10745
ObjectGuid GetCharmerOrOwnerGUID() const
Definition Unit.h:1296
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::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
3251{
3252 // Apply additional spell effects to target
3254 if (m_preCastSpell)
3255 {
3256 // Avenging Wrath - also apply Immune Shield Marker
3257 if (m_preCastSpell == 61987)
3258 m_caster->CastSpell(unit, 61988, true);
3259
3260 // Fearie Fire (Feral) - damage
3261 if (m_preCastSpell == 60089)
3262 m_caster->CastSpell(unit, m_preCastSpell, true);
3263 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3264 // Blizz seems to just apply aura without bothering to cast
3266 }
3267
3268 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3269 // this is executed after spell proc spells on target hit
3270 // spells are triggered for each hit spell target
3271 // info confirmed with retail sniffs of permafrost and shadow weaving
3272 if (!m_hitTriggerSpells.empty())
3273 {
3274 int _duration = 0;
3275 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3276 {
3277 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3278 {
3279 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3280 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3281
3282 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3283 // set duration of current aura to the triggered spell
3284 if (i->triggeredSpell->GetDuration() == -1)
3285 {
3286 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3287 {
3288 // get duration from aura-only once
3289 if (!_duration)
3290 {
3291 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3292 _duration = aur ? aur->GetDuration() : -1;
3293 }
3294 triggeredAur->SetDuration(std::max(triggeredAur->GetDuration(), _duration));
3295 }
3296 }
3297 }
3298 }
3299 }
3300
3301 // trigger linked auras remove/apply
3303 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3304 {
3305 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3306 if (*i < 0)
3307 {
3308 unit->RemoveAurasDueToSpell(-(*i));
3309 }
3310 else
3311 {
3312 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3313 }
3314 }
3315}
bool roll_chance_i(int chance)
Definition Random.h:63
@ SPELL_LINK_HIT
Definition SpellMgr.h:100
int32 GetDuration() const
Definition SpellAuras.h:133
HitTriggerSpellList m_hitTriggerSpells
Definition Spell.h:779
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5877
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:15137

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)
4254{
4256 return;
4257
4258 if (!gameObjTarget)
4259 return;
4260
4261 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4262 switch (action)
4263 {
4269 break;
4270 case GameObjectActions::Disturb: // What's the difference with Open?
4272 if (Unit* unitCaster = m_caster->ToUnit())
4273 gameObjTarget->Use(unitCaster);
4274 break;
4276 if (Unit* unitCaster = m_caster->ToUnit())
4277 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4278 [[fallthrough]];
4282 break;
4286 break;
4289 break;
4293 break;
4297 break;
4299 if (Unit* unitCaster = m_caster->ToUnit())
4300 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4301 break;
4306 {
4307 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4308
4309 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4310
4311 uint32 artKitValue = 0;
4312 if (templateAddon)
4313 artKitValue = templateAddon->artKits[artKitIndex];
4314
4315 if (artKitValue == 0)
4316 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4317 else
4318 gameObjTarget->SetGoArtKit(artKitValue);
4319
4320 break;
4321 }
4323 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4324 break;
4325 default:
4326 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4327 break;
4328 }
4329}
GameObjectActions
Definition GameObject.h:76
#define LOG_FATAL(filterType__,...)
Definition Log.h:141
@ GO_FLAG_NOT_SELECTABLE
Definition SharedDefines.h:1611
@ GO_FLAG_LOCKED
Definition SharedDefines.h:1608
@ GAMEOBJECT_FLAGS
Definition UpdateFields.h:399
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=nullptr)
Definition GameObject.cpp:1413
void SetGoArtKit(uint8 artkit)
Definition GameObject.cpp:1427
void SendCustomAnim(uint32 anim)
Definition GameObject.cpp:2148
void ResetDoorOrButton()
Definition GameObject.cpp:1403
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:1463
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:831
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition Object.cpp:885
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)
5794{
5796 return;
5797
5798 if (!m_caster->IsPlayer())
5799 return;
5800
5801 Player* player = m_caster->ToPlayer();
5802
5804 return;
5805
5806 // needed later
5808
5809 uint32 count = damage;
5810 if (count == 0) count = 1;
5811 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
5812 {
5813 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
5814 {
5815 if (m_spellInfo->Id == 45529)
5816 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
5817 continue;
5818 player->SetRuneCooldown(j, 0);
5819 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
5820 --count;
5821 }
5822 }
5823
5824 // Blood Tap
5825 if (m_spellInfo->Id == 45529 && count > 0)
5826 {
5827 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
5828 {
5829 // Check if both runes are on cd as that is the only time when this needs to come into effect
5830 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)))
5831 {
5832 // Should always update the rune with the lowest cd
5833 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
5834 l++;
5835 player->SetRuneCooldown(l, 0);
5836 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
5837 --count;
5838 }
5839 else
5840 break;
5841 }
5842 }
5843
5844 // Empower rune weapon
5845 if (m_spellInfo->Id == 47568)
5846 {
5847 // Need to do this just once
5848 if (effIndex != 0)
5849 return;
5850
5851 for (uint32 i = 0; i < MAX_RUNES; ++i)
5852 {
5853 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
5854 {
5855 player->SetRuneCooldown(i, 0);
5856 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
5857 }
5858 }
5859 }
5860
5861 // is needed to push through to the client that the rune is active
5862 //player->ResyncRunes(MAX_RUNES);
5863 m_caster->CastSpell(m_caster, 47804, true);
5864}
@ RUNE_FROST
Definition Player.h:398
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition Player.h:2564
uint8 GetRunesState() const
Definition Player.h:2553
void SetGracePeriod(uint8 index, uint32 period)
Definition Player.h:2565
RuneType GetBaseRune(uint8 index) const
Definition Player.h:2554

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)
6172{
6174 return;
6175
6176 if (!unitTarget)
6177 return;
6178
6179 if (Player* player = unitTarget->ToPlayer())
6180 {
6181 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6182 }
6183}

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

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4090{
4092 {
4093 return;
4094 }
4095
4096 if (!unitTarget || damage <= 0)
4097 {
4098 return;
4099 }
4100
4102}
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)
4674{
4676 {
4677 return;
4678 }
4679
4680 if (!unitTarget || !unitTarget->IsAlive())
4681 {
4682 return;
4683 }
4684
4686
4688}
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition Spell.cpp:5118
void AddExtraAttacks(uint32 count)
Definition Unit.cpp:2932

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

◆ EffectAddFarsight()

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

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

◆ EffectAddHonor()

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

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

◆ EffectApplyAreaAura()

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

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)
4332{
4334 return;
4335
4337 return;
4338
4339 Player* player = m_caster->ToPlayer();
4340
4341 // glyph sockets level requirement
4342 uint8 minLevel = 0;
4343 switch (m_glyphIndex)
4344 {
4345 case 0:
4346 case 1:
4347 minLevel = 15;
4348 break;
4349 case 2:
4350 minLevel = 50;
4351 break;
4352 case 3:
4353 minLevel = 30;
4354 break;
4355 case 4:
4356 minLevel = 70;
4357 break;
4358 case 5:
4359 minLevel = 80;
4360 break;
4361 }
4362 if (minLevel && m_caster->GetLevel() < minLevel)
4363 {
4365 return;
4366 }
4367
4368 // apply new one
4369 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4370 {
4371 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4372 {
4373 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4374 {
4375 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4376 {
4378 return; // glyph slot mismatch
4379 }
4380 }
4381
4382 // remove old glyph aura
4383 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4384 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4385 {
4386 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4387
4388 // Removed any triggered auras
4389 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4390 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4391 {
4392 Aura* aura = iter->second;
4393 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4394 {
4395 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4396 {
4397 player->RemoveOwnedAura(iter);
4398 continue;
4399 }
4400 }
4401 ++iter;
4402 }
4403
4404 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4405 }
4406
4407 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4409 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4410 player->SendTalentsInfoData(false);
4411 }
4412 }
4413}
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:2775
void SendTalentsInfoData(bool pet)
Definition Player.cpp:14829
void SendLearnPacket(uint32 spellId, bool learn)
Definition Player.cpp:3128
uint32 GetGlyph(uint8 slot) const
Definition Player.h:1792
uint32 GetGlyphSlot(uint8 slot) const
Definition Player.h:1783
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition Player.h:1784
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4983
boost::container::flat_multimap< uint32, Aura * > AuraMap
Definition Unit.h:670
AuraMap & GetOwnedAuras()
Definition Unit.h:1374
bool PlayerLoading() const
Definition WorldSession.h:427
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)
6305{
6307 return;
6308
6309 if (!unitTarget)
6310 return;
6311
6312 Player* player = unitTarget->ToPlayer();
6313 if (!player)
6314 {
6315 return;
6316 }
6317
6318 WorldLocation homeLoc;
6319 uint32 areaId = player->GetAreaId();
6320
6321 if (m_spellInfo->Effects[effIndex].MiscValue)
6322 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6323
6324 if (m_targets.HasDst())
6325 homeLoc.WorldRelocate(*destTarget);
6326 else
6327 {
6328 homeLoc = player->GetWorldLocation();
6329 }
6330
6331 player->SetHomebind(homeLoc, areaId);
6332
6333 // binding
6334 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6335 data << float(homeLoc.GetPositionX());
6336 data << float(homeLoc.GetPositionY());
6337 data << float(homeLoc.GetPositionZ());
6338 data << uint32(homeLoc.GetMapId());
6339 data << uint32(areaId);
6340 player->SendDirectMessage(&data);
6341
6342 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6343 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6344 // zone update
6345 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6346 data << m_caster->GetGUID();
6347 data << uint32(areaId);
6348 player->SendDirectMessage(&data);
6349}
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5852
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition PlayerStorage.cpp:4968
Definition Position.h:256
void WorldRelocate(WorldLocation const &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)
4700{
4702 return;
4703
4704 if (m_caster->IsPlayer())
4705 m_caster->ToPlayer()->SetCanBlock(true);
4706}
void SetCanBlock(bool value)
Definition Player.cpp:13434

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.

6232{
6234 return;
6235
6236 if (!m_caster->IsPlayer())
6237 return;
6238
6239 Player* p_caster = m_caster->ToPlayer();
6240 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6241 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6242
6243 for (; n_buttons; --n_buttons, ++button_id)
6244 {
6245 ActionButton const* ab = p_caster->GetActionButton(button_id);
6246 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6247 continue;
6248
6251 uint32 spell_id = ab->GetAction();
6252 if (!spell_id)
6253 continue;
6254
6255 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6256 if (!spellInfo)
6257 continue;
6258
6259 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6260 continue;
6261
6263 continue;
6264
6265 uint32 cost = spellInfo->CalcPowerCost(m_caster, spellInfo->GetSchoolMask(), this);
6266 if (m_caster->GetPower(POWER_MANA) < cost)
6267 continue;
6268
6270 m_caster->CastSpell(m_caster, spell_id, triggerFlags);
6271 }
6272}
@ 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:5811
bool HasSpell(uint32 spell) const override
Definition Player.cpp:4039
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)
4919{
4921 {
4922 if (!unitTarget)
4923 return;
4924
4925 ObjectGuid targetGUID = ObjectGuid::Empty;
4926 Player* player = m_caster->ToPlayer();
4927 if (player)
4928 {
4929 // charge changes fall time
4931
4933 {
4934 targetGUID = unitTarget->GetGUID();
4935 }
4936 }
4937
4938 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
4939 // Spell is not using explicit target - no generated path
4940 if (!m_preGeneratedPath)
4941 {
4943 m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
4944 }
4945 else
4946 {
4947 m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
4948 }
4949
4950 if (player)
4951 {
4952 sScriptMgr->AnticheatSetUnderACKmount(player);
4953 }
4954 }
4955}
#define SPEED_CHARGE
Definition MotionMaster.h:135
@ EVENT_CHARGE
Definition SharedDefines.h:3560
void MoveCharge(float x, float y, float z, float speed=SPEED_CHARGE, uint32 id=EVENT_CHARGE, Movement::PointsArray const *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:741
static ObjectGuid const Empty
Definition ObjectGuid.h:123
void SetFallInformation(uint32 time, float z)
Definition Player.h:2383
MotionMaster * GetMotionMaster()
Definition Unit.h:1758
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition Object.cpp:2942
float m_positionZ
Definition Position.h:57
float m_positionX
Definition Position.h:55
float m_positionY
Definition Position.h:56
float GetRelativeAngle(Position const *pos) const
Definition Position.h:201

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

◆ EffectChargeDest()

◆ EffectCreateItem()

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

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

◆ EffectCreateItem2()

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

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

◆ EffectCreateRandomItem()

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

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

◆ EffectCreateTamedPet()

void Spell::EffectCreateTamedPet ( SpellEffIndex  effIndex)
5867{
5869 return;
5870
5872 return;
5873
5874 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5875 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
5876 if (!pet)
5877 return;
5878
5879 // add to world
5880 pet->GetMap()->AddToMap(pet->ToCreature(), true);
5881
5882 // unitTarget has pet now
5883 unitTarget->SetMinion(pet, true);
5884
5885 pet->InitTalentForLevel();
5886
5887 if (unitTarget->IsPlayer())
5888 {
5891 }
5892}
@ CLASS_HUNTER
Definition SharedDefines.h:128
bool AddToMap(T *, bool checkTransport=false)
Definition Map.cpp:307
void InitTalentForLevel()
Definition Pet.cpp:2210
void SavePetToDB(PetSaveMode mode)
Definition Pet.cpp:502
void PetSpellInitialize()
Definition Player.cpp:9735
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:7831
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition Unit.cpp:13763

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)
5270{
5272 return;
5273
5274 int32 mana = 0;
5275 for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot)
5276 {
5277 if (!m_caster->m_SummonSlot[slot])
5278 continue;
5279
5281 if (totem && totem->IsTotem())
5282 {
5283 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5284 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5285 if (spellInfo)
5286 {
5287 mana += spellInfo->ManaCost;
5289 }
5290 totem->ToTotem()->UnSummon();
5291 }
5292 }
5293 ApplyPct(mana, damage);
5294 if (mana)
5295 m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true);
5296}
#define MAX_TOTEM_SLOT
Definition SharedDefines.h:3555
@ SUMMON_SLOT_TOTEM_FIRE
Definition SharedDefines.h:3545
@ UNIT_CREATED_BY_SPELL
Definition UpdateFields.h:138
T ApplyPct(T &base, U pct)
Definition Util.h:64
Creature * GetCreature(ObjectGuid const &guid)
Definition Map.cpp:2414
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:731
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:1418
uint32 GetCreateMana() const
Definition Unit.h:1149
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)
5895{
5897 return;
5898
5899 if (!unitTarget)
5900 return;
5901
5902 Player* player = unitTarget->ToPlayer();
5903 if (!player)
5904 {
5905 return;
5906 }
5907
5908 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
5909 if (sTaxiNodesStore.LookupEntry(nodeid))
5910 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
5911}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition TaxiHandler.cpp:153

References effectHandleMode, SpellInfo::Effects, Player::GetSession(), m_spellInfo, WorldSession::SendDiscoverNewTaxiNode(), SPELL_EFFECT_HANDLE_HIT_TARGET, sTaxiNodesStore, Object::ToPlayer(), and unitTarget.

◆ EffectDisEnchant()

void Spell::EffectDisEnchant ( SpellEffIndex  effIndex)
4469{
4471 return;
4472
4474 return;
4475
4476 if (Player* caster = m_caster->ToPlayer())
4477 {
4478 caster->UpdateCraftSkill(m_spellInfo->Id);
4479 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4480 }
4481
4482 // item will be removed at disenchanting end
4483}
@ 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)
4555{
4557 return;
4558
4559 if (!unitTarget || !unitTarget->IsPet())
4560 return;
4561
4562 Pet* pet = unitTarget->ToPet();
4563
4564 ExecuteLogEffectUnsummonObject(effIndex, pet);
4566}
@ 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:5164

References effectHandleMode, ExecuteLogEffectUnsummonObject(), Unit::IsPet(), PET_SAVE_NOT_IN_SLOT, Pet::Remove(), SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::ToPet(), and unitTarget.

◆ EffectDispel()

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

References Unit::CastCustomSpell(), damage, EFFECT_1, effectHandleMode, SpellInfo::Effects, ThreatManager::ForwardThreatForAssistingMe(), SpellInfo::GetCategory(), Unit::GetDispellableAuraList(), SpellInfo::GetDispelMask(), Object::GetGUID(), Unit::GetOwner(), Object::GetPackGUID(), Unit::GetThreatMgr(), SpellInfo::Id, Unit::IsFriendlyTo(), m_caster, m_spellInfo, Unit::RemoveAurasDueToSpellByDispel(), roll_chance_i(), WorldObject::SendMessageToSet(), SMSG_DISPEL_FAILED, SMSG_SPELLDISPELLOG, SPELL_EFFECT_HANDLE_HIT_TARGET, SPELLCATEGORY_DEVOUR_MAGIC, SPELLFAMILY_WARLOCK, SpellInfo::SpellFamilyName, unitTarget, and urand().

◆ EffectDispelMechanic()

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

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

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving.

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

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

◆ EffectDualWield()

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

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

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4105{
4107 return;
4108
4109 if (!unitTarget || !m_caster->IsPlayer() || !unitTarget->IsPlayer())
4110 return;
4111
4112 Player* caster = m_caster->ToPlayer();
4113 Player* target = unitTarget->ToPlayer();
4114
4115 // caster or target already have requested duel
4116 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4117 return;
4118
4119 // Players can only fight a duel in zones with this flag
4120 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4121 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4122 {
4123 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4124 return;
4125 }
4126
4127 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4128 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4129 {
4130 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4131 return;
4132 }
4133
4134 //CREATE DUEL FLAG OBJECT
4135 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4136 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4137
4138 Map* map = m_caster->GetMap();
4139 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), m_caster->GetOrientation());
4140 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4141 map, m_caster->GetPhaseMask(),
4145 m_caster->GetOrientation(), rotation, 0, GO_STATE_READY))
4146 {
4147 delete pGameObj;
4148 return;
4149 }
4150
4153 int32 duration = m_spellInfo->GetDuration();
4154 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4155 pGameObj->SetSpellId(m_spellInfo->Id);
4156
4157 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4158
4159 m_caster->AddGameObject(pGameObj);
4160 map->AddToMap(pGameObj, true);
4161 //END
4162
4163 // Send request
4164 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4165 data << pGameObj->GetGUID();
4166 data << caster->GetGUID();
4167 caster->SendDirectMessage(&data);
4168 target->SendDirectMessage(&data);
4169
4170 // create duel-info
4171 bool isMounted = (GetSpellInfo()->Id == 62875);
4172 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4173 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4174
4175 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4176 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4177
4178 sScriptMgr->OnPlayerDuelRequest(target, caster);
4179}
@ 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:1287
void SetSpellId(uint32 id)
Definition GameObject.h:177
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:643
bool HasIgnore(ObjectGuid const &ignore_guid) const
Definition SocialMgr.cpp:194
PlayerSocial * GetSocial()
Definition Player.h:1158
void ExecuteLogEffectSummonObject(uint8 effIndex, WorldObject *obj)
Definition Spell.cpp:5158
Definition Transport.h:120
uint32 GetFaction() const
Definition Unit.h:852
void AddGameObject(GameObject *gameObj)
Definition Unit.cpp:6583
uint32 GetPhaseMask() const
Definition Object.h:517
@ SMSG_DUEL_REQUESTED
Definition Opcodes.h:389
uint32 flags
Definition DBCStructure.h:524
float GetOrientation() const
Definition Position.h:124

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

◆ EffectDummy()

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

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)
5299{
5301 return;
5302
5303 if (!unitTarget)
5304 return;
5305
5306 Player* player = unitTarget->ToPlayer();
5307 if (!player)
5308 {
5309 return;
5310 }
5311
5312 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5313
5314 // -1 means all player equipped items and -2 all items
5315 if (slot < 0)
5316 {
5317 player->DurabilityPointsLossAll(damage, (slot < -1));
5319 return;
5320 }
5321
5322 // invalid slot value
5323 if (slot >= INVENTORY_SLOT_BAG_END)
5324 return;
5325
5326 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5327 {
5328 player->DurabilityPointsLoss(item, damage);
5329 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5330 }
5331}
@ INVENTORY_SLOT_BAG_END
Definition Player.h:687
#define INVENTORY_SLOT_BAG_0
Definition Player.h:657
Item * GetItemByPos(uint16 pos) const
Definition PlayerStorage.cpp:445
void DurabilityPointsLossAll(int32 points, bool inventory)
Definition Player.cpp:4836
void DurabilityPointsLoss(Item *item, int32 points)
Definition Player.cpp:4862
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition Spell.cpp:5132

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

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

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

◆ EffectEnchantItemPerm()

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

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

◆ EffectEnchantItemPrismatic()

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

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

◆ EffectEnchantItemTmp()

void Spell::EffectEnchantItemTmp ( SpellEffIndex  effIndex)
2986{
2988 return;
2989
2990 if (!m_caster->IsPlayer())
2991 return;
2992
2993 Player* p_caster = m_caster->ToPlayer();
2994
2995 // Rockbiter Weapon apply to both weapon
2996 if (!itemTarget)
2997 return;
2999 {
3000 uint32 spell_id = 0;
3001
3002 // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
3003 // Note: damage calculated (correctly) with rounding int32(float(v)) but
3004 // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
3005 switch (damage)
3006 {
3007 // Rank 1
3008 case 2:
3009 spell_id = 36744;
3010 break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
3011 // Rank 2
3012 case 4:
3013 spell_id = 36753;
3014 break; // 0% [ 7% == 4, 14% == 4]
3015 case 5:
3016 spell_id = 36751;
3017 break; // 20%
3018 // Rank 3
3019 case 6:
3020 spell_id = 36754;
3021 break; // 0% [ 7% == 6, 14% == 6]
3022 case 7:
3023 spell_id = 36755;
3024 break; // 20%
3025 // Rank 4
3026 case 9:
3027 spell_id = 36761;
3028 break; // 0% [ 7% == 6]
3029 case 10:
3030 spell_id = 36758;
3031 break; // 14%
3032 case 11:
3033 spell_id = 36760;
3034 break; // 20%
3035 default:
3036 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: Damage {} not handled in S'RW", damage);
3037 return;
3038 }
3039
3040 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
3041 if (!spellInfo)
3042 {
3043 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: unknown spell id {}", spell_id);
3044 return;
3045 }
3046
3047 for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
3048 {
3049 if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j)))
3050 {
3051 if (item->IsFitToSpellRequirements(m_spellInfo))
3052 {
3053 Spell* spell = new Spell(m_caster, spellInfo, TRIGGERED_FULL_MASK);
3054 SpellCastTargets targets;
3055 targets.SetItemTarget(item);
3056 spell->prepare(&targets);
3057 }
3058 }
3059 }
3060 return;
3061 }
3062 if (!itemTarget)
3063 return;
3064
3065 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3066
3067 if (!enchant_id)
3068 {
3069 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, effIndex);
3070 return;
3071 }
3072
3073 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3074 if (!pEnchant)
3075 {
3076 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id {} ", m_spellInfo->Id, effIndex, enchant_id);
3077 return;
3078 }
3079
3080 // Enchantment duration
3081 uint32 duration = 3600; // Default 1 hour
3082
3083 // Exceptions
3084 if (m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN) // Shaman weapon enchants
3085 duration = 1800; // 30 mins
3086 else
3087 {
3088 switch (m_spellInfo->Id)
3089 {
3090 case 37360: // Consecrated Weapon
3091 duration = 300; // 5 mins
3092 break;
3093 case 8087: // Shiny Bauble
3094 case 8088: // Nightcrawlers
3095 case 8089: // Aquadynamic Fish Attractor
3096 case 8090: // Bright Baubles
3097 case 8532: // Aquadynamic Fish Lens
3098 case 9092: // Flesh Eating Worm
3099 case 43699: // Fishing Hat Lure
3100 case 45731: // Sharpened Fish Hook
3101 duration = 600; // 10 mins
3102 break;
3103 case 3594: // Shadow Oil
3104 case 3595: // Frost Oil
3105 case 6650: // Instant Toxin
3106 case 38615: // Bloodboil Poison
3107 // Explicitly listing Rockbiter Weapon because it isn't caught by spellfamily check
3108 case 36744: // Rockbiter Weapon Rank 1
3109 case 36753: // Rockbiter Weapon Rank 2
3110 case 36751: // Rockbiter Weapon Rank 2
3111 case 36754: // Rockbiter Weapon Rank 3
3112 case 36755: // Rockbiter Weapon Rank 3
3113 case 36761: // Rockbiter Weapon Rank 4
3114 case 36758: // Rockbiter Weapon Rank 4
3115 case 36760: // Rockbiter Weapon Rank 4
3116 duration = 1800; // 30 mins
3117 break;
3118 default:
3119 break;
3120 }
3121 }
3122
3123 // item can be in trade slot and have owner diff. from caster
3124 Player* item_owner = itemTarget->GetOwner();
3125 if (!item_owner)
3126 return;
3127
3128 // remove old enchanting before applying new if equipped
3130
3131 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, pEnchant->charges, m_caster->GetGUID());
3132
3133 // add new enchanting if equipped
3135
3136 if (item_owner != p_caster && p_caster->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
3137 {
3138 LOG_GM(p_caster->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(temp): {} (SpellID: {} EncID: {}) on {}'s item: {} (Entry: {})",
3139 p_caster->GetName(), p_caster->GetSession()->GetAccountId(),
3140 m_spellInfo->SpellName[0], m_spellInfo->Id, enchant_id,
3141 item_owner->GetName(), itemTarget->GetTemplate()->Name1, itemTarget->GetEntry());
3142 }
3143
3144 item_owner->RemoveTradeableItem(itemTarget);
3146}
@ SPELLFAMILY_SHAMAN
Definition SharedDefines.h:3795
WeaponAttackType
Definition Unit.h:215
Definition Spell.h:121
SpellCastResult prepare(SpellCastTargets const *targets, AuraEffect const *triggeredByAura=nullptr)
Definition Spell.cpp:3452

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

◆ EffectEnergize()

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

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

◆ EffectEnergizePct()

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

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

◆ EffectEnvironmentalDMG()

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

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

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

◆ EffectForceCast()

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

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

◆ EffectForceDeselect()

void Spell::EffectForceDeselect ( SpellEffIndex  effIndex)
4779{
4781 return;
4782
4783 // xinef: clear focus
4785
4787 data << m_caster->GetGUID();
4788
4790 Acore::MessageDistDelivererToHostile notifier(m_caster, &data, dist);
4791 Cell::VisitObjects(m_caster, notifier, dist);
4792
4793 // xinef: we should also force pets to remove us from current target
4794 Unit::AttackerSet attackerSet;
4795 for (Unit::AttackerSet::const_iterator itr = m_caster->getAttackers().begin(); itr != m_caster->getAttackers().end(); ++itr)
4796 if ((*itr)->IsCreature() && !(*itr)->CanHaveThreatList())
4797 attackerSet.insert(*itr);
4798
4799 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
4800 (*itr)->AttackStop();
4801
4802 // Xinef: Mirror images code Initialize Images
4803 if (m_spellInfo->Id == 58836)
4804 {
4805 std::vector<Unit*> images;
4806 for (Unit::ControlSet::const_iterator itr = m_caster->m_Controlled.begin(); itr != m_caster->m_Controlled.end(); ++itr)
4807 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
4808 images.push_back(*itr);
4809
4810 if (images.empty())
4811 return;
4812
4813 UnitList targets;
4814 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, m_caster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4817 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4818 {
4819 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4820 continue;
4821
4822 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
4823 {
4824 if (spell->m_targets.GetUnitTargetGUID() == m_caster->GetGUID())
4825 {
4826 SpellInfo const* si = spell->GetSpellInfo();
4827 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4828 {
4829 Creature* c = (*iter)->ToCreature();
4830 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4831 continue;
4832 }
4833
4834 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4835 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4836 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4837 {
4838 // at least one effect truly targets an unit, interrupt the spell
4839 interrupt = true;
4840 break;
4841 }
4842
4843 if (interrupt)
4844 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
4845 }
4846 }
4847 }
4848 }
4849}
#define VISIBILITY_COMPENSATION
Definition ObjectDefines.h:26
@ CREATURE_ELITE_WORLDBOSS
Definition SharedDefines.h:2967
@ SPELL_ATTR6_IGNORE_PHASE_SHIFT
Definition SharedDefines.h:605
@ TARGET_OBJECT_TYPE_UNIT
Definition SpellInfo.h:102
@ TARGET_OBJECT_TYPE_UNIT_AND_DEST
Definition SpellInfo.h:103
std::list< Unit * > UnitList
Definition Unit.h:78
Definition GridNotifiers.h:884
bool IsDungeonBoss() const
Definition Creature.cpp:3301
ControlSet m_Controlled
Definition Unit.h:2074
void SendClearTarget()
Definition Unit.cpp:16260
@ SMSG_CLEAR_TARGET
Definition Opcodes.h:989
Definition GridNotifiers.h:166
Definition GridNotifiers.h:446
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)
5939{
5941 return;
5942
5943 if (!gameObjTarget)
5944 return;
5945
5946 Unit* caster = m_originalCaster;
5947 if (!caster)
5948 return;
5949
5950 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
5952 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
5953 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
5955}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition GameObject.cpp:2303
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition Unit.cpp:7095
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)
5969{
5971 return;
5972
5974 return;
5975
5978}
GameObjectDestructibleState
Definition SharedDefines.h:1630
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition GameObject.cpp:2366

References effectHandleMode, SpellInfo::Effects, gameObjTarget, Unit::GetCharmerOrOwnerPlayerOrPlayerItself(), m_originalCaster, m_spellInfo, GameObject::SetDestructibleState(), and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectHeal()

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

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

◆ EffectHealMaxHealth()

void Spell::EffectHealMaxHealth ( SpellEffIndex  effIndex)
3727{
3729 return;
3730
3731 if (!unitTarget || !unitTarget->IsAlive())
3732 return;
3733
3735 {
3737 return;
3738 }
3739
3740 int32 addhealth = 0;
3741
3742 // damage == 0 - heal for caster max health
3743 if (damage == 0)
3744 addhealth = m_caster->GetMaxHealth();
3745 else
3746 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3747
3748 m_healing += addhealth;
3749}
uint32 GetMaxHealth() const
Definition Unit.h:1110

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

◆ EffectHealMechanical()

void Spell::EffectHealMechanical ( SpellEffIndex  effIndex)

◆ EffectHealPct()

◆ EffectHealthLeech()

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

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

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

◆ EffectInstaKill()

void Spell::EffectInstaKill ( SpellEffIndex  effIndex)
276{
278 return;
279
280 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->HasAura(27827)) // Spirit of redemption doesn't make you death, but can cause infinite loops
281 return;
282
283 if (unitTarget->IsPlayer())
285 return;
286
287 if (m_caster == unitTarget) // prevent interrupt message
288 finish();
289
290 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
291 data << m_caster->GetGUID();
292 data << unitTarget->GetGUID();
293 data << uint32(m_spellInfo->Id);
294 m_caster->SendMessageToSet(&data, true);
295
297}
@ CHEAT_GOD
Definition Player.h:997
@ 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:982
@ 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
3752{
3754 return;
3755
3756 if (!unitTarget || !unitTarget->IsAlive())
3757 return;
3758
3760 // also exist case: apply cooldown to interrupted cast only and to all spells
3761 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3763 {
3765 {
3766 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3767 // check if we can interrupt spell
3768 if ((spell->getState() == SPELL_STATE_CASTING
3769 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3773 {
3774 if (m_originalCaster)
3775 {
3777 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3778 }
3779 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3781 }
3782 }
3783 }
3784}
@ 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:562
CurrentSpellTypes
Definition Unit.h:555
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:558
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:559
uint32 ChannelInterruptFlags
Definition SpellInfo.h:378
uint32 InterruptFlags
Definition SpellInfo.h:376
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition Spell.cpp:5125
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:4240
int32 CalcSpellDuration(SpellInfo const *spellProto)
Definition Unit.cpp:11600
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition Unit.h:1585

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

◆ EffectJump()

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

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

◆ EffectJumpDest()

void Spell::EffectJumpDest ( SpellEffIndex  effIndex)
1092{
1094 return;
1095
1096 if (m_caster->IsInFlight())
1097 return;
1098
1099 if (!m_targets.HasDst() || m_caster->GetVehicle())
1100 return;
1101
1102 // Init dest coordinates
1103 float x, y, z;
1104 destTarget->GetPosition(x, y, z);
1105 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1106 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1107 return;
1108
1109 float speedXY, speedZ;
1110 float dist = m_caster->GetExactDist2d(x, y);
1111 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1112
1113 // Override, calculations are incorrect
1114 if (m_spellInfo->Id == 49376) // feral charge
1115 {
1116 speedXY = pow(speedZ * 10, 8);
1118
1119 if (Player* player = m_caster->ToPlayer())
1120 {
1121 player->SetCanTeleport(true);
1122 }
1123
1124 if (m_caster->IsPlayer())
1125 {
1126 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1127 }
1128
1129 return;
1130 }
1131
1132 if (m_spellInfo->Id == 57604) // death grip
1133 {
1134 speedZ = 3.0f;
1135 speedXY = 50.0f;
1136 }
1137
1138 // crash fix?
1139 if (speedXY < 1.0f)
1140 speedXY = 1.0f;
1141
1142 if (Player* player = m_caster->ToPlayer())
1143 {
1144 player->SetCanTeleport(true);
1145 }
1146 m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1147
1148 if (m_caster->IsPlayer())
1149 {
1150 sScriptMgr->AnticheatSetUnderACKmount(m_caster->ToPlayer());
1151 }
1152}
#define INVALID_HEIGHT
Definition GridTerrainData.h:27
@ UNIT_FIELD_TARGET
Definition UpdateFields.h:92
ObjectGuid GetGuidValue(uint16 index) const
Definition Object.cpp:330
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)
5731{
5733 return;
5734
5735 if (!unitTarget)
5736 return;
5737
5739 if (!player)
5740 {
5741 return;
5742 }
5743
5744 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
5745 if (!creatureEntry)
5746 {
5747 if (m_spellInfo->Id == 42793) // Burn Body
5748 creatureEntry = 24008; // Fallen Combatant
5749 }
5750
5751 if (creatureEntry)
5752 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
5753}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition Player.cpp:13015

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)
5717{
5719 return;
5720
5721 if (!unitTarget)
5722 return;
5723
5725 {
5726 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
5727 }
5728}

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

◆ EffectKnockBack()

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

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

◆ EffectLeap()

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

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

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)
3319{
3321 return;
3322
3323 if (!unitTarget)
3324 return;
3325
3326 if (unitTarget->ToPlayer())
3327 {
3328 EffectLearnSpell(effIndex);
3329 return;
3330 }
3331 Pet* pet = unitTarget->ToPet();
3332 if (!pet)
3333 return;
3334
3335 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3336 if (!learn_spellproto)
3337 return;
3338
3339 pet->learnSpell(learn_spellproto->Id);
3341 pet->GetOwner()->PetSpellInitialize();
3342}
bool learnSpell(uint32 spell_id)
Definition Pet.cpp:1897
void EffectLearnSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:2565

References effectHandleMode, EffectLearnSpell(), SpellInfo::Effects, Pet::GetOwner(), SpellInfo::Id, Pet::learnSpell(), m_spellInfo, PET_SAVE_AS_CURRENT, Player::PetSpellInitialize(), Pet::SavePetToDB(), SPELL_EFFECT_HANDLE_HIT_TARGET, sSpellMgr, Unit::ToPet(), Object::ToPlayer(), and unitTarget.

Referenced by EffectLearnSpell().

◆ EffectLearnSkill()

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

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

◆ EffectLearnSpell()

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

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)
5540{
5542 return;
5543
5544 if (!m_caster->IsPlayer())
5545 return;
5546
5547 Player* p_caster = m_caster->ToPlayer();
5549 return;
5550
5551 if (itemTarget->GetCount() < 5)
5552 return;
5553
5554 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5555 {
5556 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5557 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5558 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5559 }
5560
5562}
@ LOOT_MILLING
Definition LootMgr.h:87
@ CONFIG_SKILL_MILLING
Definition WorldConfig.h:48
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition Player.cpp:7973
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition PlayerUpdates.cpp:767

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)
5369{
5371 return;
5372
5373 if (!unitTarget)
5374 return;
5375
5377}
void ModifyThreatByPercent(Unit *target, int32 percent)
Definition ThreatManager.h:150

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

◆ EffectNULL()

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

References LOG_DEBUG.

Referenced by EffectPull().

◆ EffectOpenLock()

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

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

◆ EffectPersistentAA()

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

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)
6133{
6135 return;
6136
6137 if (!unitTarget)
6138 return;
6139
6140 Player* player = unitTarget->ToPlayer();
6141 if (!player)
6142 {
6143 return;
6144 }
6145
6146 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6147
6148 if (!sSoundEntriesStore.LookupEntry(soundid))
6149 {
6150 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6151 return;
6152 }
6153
6155}
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)
6186{
6188 return;
6189
6190 if (!unitTarget)
6191 return;
6192
6193 Player* player = unitTarget->ToPlayer();
6194 if (!player)
6195 {
6196 return;
6197 }
6198
6199 switch (m_spellInfo->Id)
6200 {
6201 case 58730: // Restricted Flight Area
6202 case 58600: // Restricted Flight Area
6204 break;
6205 default:
6206 break;
6207 }
6208
6209 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6210
6211 if (!sSoundEntriesStore.LookupEntry(soundId))
6212 {
6213 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6214 return;
6215 }
6216
6217 player->PlayDirectSound(soundId, player);
6218}
@ LANG_ZONE_NOFLYZONE
Definition Language.h:764
Definition Chat.h:37
void SendNotification(std::string_view str)
Definition Chat.cpp:113
void PlayDirectSound(uint32 sound_id, Player *target=nullptr)
Definition Object.cpp:3011

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

◆ EffectPowerBurn()

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

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

◆ EffectPowerDrain()

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

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

◆ EffectProficiency()

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

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

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)

◆ EffectPull()

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

References EffectNULL().

◆ EffectPullTowards()

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

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)
5756{
5758 return;
5759
5760 if (!unitTarget)
5761 return;
5762
5763 if (Player* player = unitTarget->ToPlayer())
5764 {
5765 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
5766 }
5767}

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

◆ EffectQuestStart()

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

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

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)
5930{
5932 return;
5933
5934 if (unitTarget)
5936}
void RegisterRedirectThreat(uint32 spellId, ObjectGuid const &victim, uint32 pct)
== REDIRECT SYSTEM ==
Definition ThreatManager.cpp:826

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

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6221{
6223 return;
6224
6225 if (!unitTarget)
6226 return;
6227 // there may be need of specifying casterguid of removed auras
6228 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6229}

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

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6121{
6123 return;
6124
6125 if (!unitTarget || !unitTarget->IsCreature() ||
6127 return;
6128
6130}
@ 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:897
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)
4724{
4726 return;
4727
4728 if (!unitTarget)
4729 return;
4730
4731 Player* player = unitTarget->ToPlayer();
4732 if (!player)
4733 {
4734 return;
4735 }
4736
4737 float repChange = static_cast<float>(damage);
4738
4739 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4740
4741 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4742 if (!factionEntry)
4743 return;
4744
4745 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4746 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4747}
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:6028
ReputationMgr & GetReputationMgr()
Definition Player.h:2155
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)
4642{
4644 return;
4645
4646 if (!unitTarget)
4647 return;
4648
4649 if (!unitTarget)
4650 return;
4651
4652 Player* target = unitTarget->ToPlayer();
4653 if (!target)
4654 {
4655 return;
4656 }
4657
4658 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4659 return;
4660
4661 if (target->isResurrectRequested()) // already have one active request
4662 return;
4663
4664 uint32 health = target->CountPctFromMaxHealth(damage);
4666
4667 ExecuteLogEffectResurrect(effIndex, target);
4668
4670 SendResurrectRequest(target);
4671}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition Player.h:1843
bool isResurrectRequested() const
Definition Player.h:1855
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition Spell.cpp:5170
void SendResurrectRequest(Player *target)
Definition Spell.cpp:5232

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

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

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

◆ EffectSchoolDMG()

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

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

References BATTLEGROUND_SA, Unit::CastSpell(), Corpse, damage, BattlegroundSA::DefendersPortalTeleport(), Creature::DespawnOrUnsummon(), Player::DestroyItemCount(), EFFECT_0, EFFECT_1, effectHandleMode, SpellInfo::Effects, WorldObject::FindNearestGameObject(), Unit::GetAura(), WorldObject::GetMap(), 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, Object::ToCreature(), Object::ToPlayer(), Unit::ToTempSummon(), unitTarget, and TempSummon::UnSummon().

◆ EffectSelfResurrect()

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

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

◆ EffectSendEvent()

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

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

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5565{
5567 return;
5568
5569 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5570}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

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

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

◆ EffectSkinPlayerCorpse()

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

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

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6158{
6160 return;
6161
6162 if (!unitTarget)
6163 return;
6164
6165 if (Player* player = unitTarget->ToPlayer())
6166 {
6167 player->UpdateSpecCount(damage);
6168 }
6169}

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

◆ EffectSpiritHeal()

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

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

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

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

◆ EffectStuck()

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

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

◆ EffectSummonChangeItem()

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

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)
4569{
4571 return;
4572
4573 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4574
4575 uint8 slot = 0;
4576 switch (m_spellInfo->Effects[effIndex].Effect)
4577 {
4579 slot = 0;
4580 break;
4582 slot = 1;
4583 break;
4585 slot = 2;
4586 break;
4588 slot = 3;
4589 break;
4590 default:
4591 return;
4592 }
4593
4594 if (m_caster)
4595 {
4596 ObjectGuid guid = m_caster->m_ObjectSlot[slot];
4597 if (guid)
4598 {
4599 if (GameObject* gameObject = m_caster->GetMap()->GetGameObject(guid))
4600 {
4601 // Recast case - null spell id to make auras not be removed on object remove from world
4602 if (m_spellInfo->Id == gameObject->GetSpellId())
4603 gameObject->SetSpellId(0);
4604 m_caster->RemoveGameObject(gameObject, true);
4605 }
4606 m_caster->m_ObjectSlot[slot].Clear();
4607 }
4608 }
4609
4610 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4611
4612 float x, y, z;
4613 // If dest location if present
4614 if (m_targets.HasDst())
4615 destTarget->GetPosition(x, y, z);
4616 // Summon in random point all other units if location present
4617 else
4619
4620 Map* map = m_caster->GetMap();
4621 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), m_caster->GetOrientation());
4622 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), rotation, 0, GO_STATE_READY))
4623 {
4624 delete pGameObj;
4625 return;
4626 }
4627
4628 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->GetLevel());
4629 int32 duration = m_spellInfo->GetDuration();
4630 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4631 pGameObj->SetSpellId(m_spellInfo->Id);
4632 m_caster->AddGameObject(pGameObj);
4633
4634 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4635
4636 map->AddToMap(pGameObj, true);
4637
4638 m_caster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4639}
#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)
3787{
3789 return;
3790
3791 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3792
3793 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3794
3795 WorldObject* target = focusObject;
3796 if (!target)
3797 target = m_caster;
3798
3799 float x, y, z;
3800 if (m_targets.HasDst())
3801 destTarget->GetPosition(x, y, z);
3802 else
3804
3805 Map* map = target->GetMap();
3806
3807 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), target->GetOrientation());
3808 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), rotation, 100, GO_STATE_READY))
3809 {
3810 delete pGameObj;
3811 return;
3812 }
3813
3814 int32 duration = m_spellInfo->GetDuration();
3815
3816 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3817 pGameObj->SetSpellId(m_spellInfo->Id);
3818
3819 ExecuteLogEffectSummonObject(effIndex, pGameObj);
3820
3821 // Wild object not have owner and check clickable by players
3822 map->AddToMap(pGameObj, true);
3823
3824 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
3825 if (Player* player = m_caster->ToPlayer())
3826 if (Battleground* bg = player->GetBattleground())
3827 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
3828
3829 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
3830 {
3831 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
3832 linkedTrap->SetSpellId(m_spellInfo->Id);
3833 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
3834 }
3835}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition SharedDefines.h:1590
@ TEAM_ALLIANCE
Definition SharedDefines.h:748
@ TEAM_HORDE
Definition SharedDefines.h:749
GameObject * GetLinkedTrap()
Definition GameObject.cpp:2761
GameobjectTypes GetGoType() const
Definition GameObject.h:203

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

◆ EffectSummonPet()

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

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)
4222{
4223 // workaround - this effect should not use target map
4225 return;
4226
4227 if (!unitTarget)
4228 return;
4229
4230 Player* player = unitTarget->ToPlayer();
4231 if (!player)
4232 {
4233 return;
4234 }
4235
4236 // Evil Twin (ignore player summon, but hide this for summoner)
4237 // Xinef: Unit Target may be on other map!!!, Need workaround
4238 if (unitTarget->HasAura(23445))
4239 return;
4240
4241 float x, y, z;
4242 m_caster->GetPosition(x, y, z);
4243
4244 player->SetSummonPoint(m_caster->GetMapId(), x, y, z);
4245
4246 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4247 data << m_caster->GetGUID(); // summoner guid
4248 data << uint32(m_caster->GetZoneId()); // summoner zone
4249 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4250 player->SendDirectMessage(&data);
4251}
#define MAX_PLAYER_SUMMON_DELAY
Definition Player.h:923
void SetSummonPoint(uint32 mapid, float x, float y, float z, uint32 delay=0, bool asSpectator=false)
Definition Player.cpp:16682
@ 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)
6352{
6354 return;
6355
6356 if (!m_caster->IsPlayer())
6357 return;
6358
6359 if (!unitTarget)
6360 return;
6361
6362 Player* player = unitTarget->ToPlayer();
6363 if (!player)
6364 {
6365 return;
6366 }
6367
6368 float x, y, z;
6369 m_caster->GetPosition(x, y, z);
6371 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6372 data << m_caster->GetGUID();
6373 data << uint32(m_caster->GetZoneId());
6374 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6375 player->SendDirectMessage(&data);
6376}

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

◆ EffectSummonType()

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

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

◆ EffectTameCreature()

void Spell::EffectTameCreature ( SpellEffIndex  effIndex)
3149{
3151 return;
3152
3153 if (m_caster->GetPetGUID())
3154 return;
3155
3156 if (!unitTarget)
3157 return;
3158
3159 if (!unitTarget->IsCreature())
3160 return;
3161
3162 Creature* creatureTarget = unitTarget->ToCreature();
3163
3164 if (creatureTarget->IsPet())
3165 return;
3166
3168 return;
3169
3170 // cast finish successfully
3171 //SendChannelUpdate(0);
3172 finish();
3173
3174 Pet* pet = m_caster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3175 if (!pet) // in very specific state like near world end/etc.
3176 return;
3177
3178 // "kill" original creature
3179 creatureTarget->DespawnOrUnsummon();
3180
3181 uint8 level = (creatureTarget->GetLevel() < (m_caster->GetLevel() - 5)) ? (m_caster->GetLevel() - 5) : creatureTarget->GetLevel();
3182
3183 // prepare visual effect for levelup
3184 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3185
3186 // add to world
3187 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3188
3189 // visual effect for levelup
3190 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3191
3192 // caster have pet now
3193 m_caster->SetMinion(pet, true);
3194
3195 pet->InitTalentForLevel();
3196
3197 if (m_caster->IsPlayer())
3198 {
3201 }
3202}
@ 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)
3345{
3347 return;
3348
3349 if (!unitTarget)
3350 return;
3351
3352 // xinef: Hand of Reckoning, cast before checking canhavethreatlist. fixes damage against pets
3353 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != m_caster)
3354 m_caster->CastSpell(unitTarget, 67485, true);
3355
3357 {
3359 return;
3360 }
3361
3363 if (mgr.GetCurrentVictim() == m_caster)
3364 {
3366 return;
3367 }
3368
3369 if (!mgr.IsThreatListEmpty())
3371}
Definition ThreatManager.h:90
Unit * GetCurrentVictim()
Definition ThreatManager.cpp:248
bool IsThreatListEmpty(bool includeOffline=false) const
Definition ThreatManager.cpp:271
void MatchUnitThreatToHighestThreat(Unit *target)
Definition ThreatManager.cpp:497
bool CanHaveThreatList(bool skipAliveCheck=false) const
Definition Unit.cpp:11431

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

◆ EffectTeleportUnits()

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

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

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3711{
3713 return;
3714
3715 if (!unitTarget || !unitTarget->IsAlive() || !m_caster->IsAlive())
3716 return;
3717
3718 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3720 return;
3721
3722 // SPELL_EFFECT_THREAT adds flat threat that should not be modified by threat reduction
3724}
void AddThreat(Unit *target, float amount, SpellInfo const *spell=nullptr, bool ignoreModifiers=false, bool ignoreRedirects=false)
== AFFECT MY THREAT LIST ==
Definition ThreatManager.cpp:392

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

◆ EffectTitanGrip()

void Spell::EffectTitanGrip ( SpellEffIndex  effIndex)
5914{
5916 return;
5917
5918 if (m_caster->IsPlayer())
5919 {
5920 if (Aura* aur = m_caster->GetAura(49152))
5921 aur->RecalculateAmountOfEffects();
5922 else
5923 m_caster->CastSpell(unitTarget, 49152, true); // damage reduction
5924
5926 }
5927}
void SetCanTitanGrip(bool value)
Definition Player.cpp:13443

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

◆ EffectTradeSkill()

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

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

◆ EffectTransmitted()

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

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(), Unit::RemoveGameObjectsByType(), Object::SetGuidValue(), GameObject::SetOwnerGUID(), GameObject::SetRespawnTime(), GameObject::SetSpellId(), sObjectMgr, SpellInfo::Speed, SPELL_EFFECT_HANDLE_HIT, Object::ToPlayer(), GameObjectTemplate::type, UNIT_FIELD_CHANNEL_OBJECT, and urand().

◆ EffectTriggerMissileSpell()

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

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

◆ EffectTriggerRitualOfSummoning()

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

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

◆ EffectTriggerSpell()

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

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

◆ EffectUnlearnSpecialization()

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

References effectHandleMode, SpellInfo::Effects, Object::GetGUID(), LOG_DEBUG, m_caster, m_spellInfo, Player::removeSpell(), SPEC_MASK_ALL, SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectUntrainTalents()

void Spell::EffectUntrainTalents ( SpellEffIndex  effIndex)
2771{
2773 return;
2774
2775 if (!unitTarget || m_caster->IsPlayer())
2776 return;
2777
2778 if (ObjectGuid guid = m_caster->GetGUID()) // the trainer is the caster
2780}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition Player.cpp:9104

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

◆ EffectUnused()

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

◆ EffectWeaponDmg()

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

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 
)
5147{
5148 InitEffectExecuteData(effIndex);
5149 *m_effectExecuteData[effIndex] << uint32(entry);
5150}
void InitEffectExecuteData(uint8 effIndex)
Definition Spell.cpp:8569

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5153{
5154 InitEffectExecuteData(effIndex);
5155 *m_effectExecuteData[effIndex] << uint32(entry);
5156}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit victim,
int32  itemId,
int32  slot 
)
5133{
5134 InitEffectExecuteData(effIndex);
5135 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5136 *m_effectExecuteData[effIndex] << int32(itemId);
5137 *m_effectExecuteData[effIndex] << int32(slot);
5138}

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

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit victim,
uint32  attCount 
)
5119{
5120 InitEffectExecuteData(effIndex);
5121 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5122 *m_effectExecuteData[effIndex] << uint32(attCount);
5123}

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

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit victim,
uint32  spellId 
)
5126{
5127 InitEffectExecuteData(effIndex);
5128 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5129 *m_effectExecuteData[effIndex] << uint32(spellId);
5130}

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

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object obj 
)
5141{
5142 InitEffectExecuteData(effIndex);
5143 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5144}

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

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit target 
)
5171{
5172 InitEffectExecuteData(effIndex);
5173 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5174}

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 
)
5110{
5111 InitEffectExecuteData(effIndex);
5112 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5113 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5114 *m_effectExecuteData[effIndex] << uint32(PowerType);
5115 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5116}

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 
)
5165{
5166 InitEffectExecuteData(effIndex);
5167 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5168}

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

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4479{
4480 if (!m_caster)
4481 return;
4482
4484 return;
4486
4487 // FindMap() check: pending spell events are destroyed after the caster has left the map,
4488 // where resolving a unit-summoned caster's owner through ObjectAccessor would assert
4489 if (Player* modOwner = (m_caster && m_caster->FindMap()) ? m_caster->GetSpellModOwner() : nullptr)
4490 modOwner->SetSpellModTakingSpell(this, false);
4491
4492 if (m_spellInfo->IsChanneled())
4494
4497
4498 // Unsummon summon as possessed creatures on spell cancel
4500 {
4501 if (Unit* charm = m_caster->GetCharm())
4502 if (charm->IsCreature()
4503 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4504 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4505 ((Puppet*)charm)->UnSummon();
4506 }
4507
4508 if (Creature* creatureCaster = m_caster->ToCreature())
4509 creatureCaster->ReleaseFocus(this);
4510
4511 if (ok)
4512 {
4515 }
4516 else
4517 {
4518 if (m_caster->IsPlayer())
4519 {
4520 // Xinef: Restore spell mods in case of fail cast
4522
4523 // Xinef: Reset cooldown event in case of fail cast
4526 }
4527
4528 return;
4529 }
4530
4531 // pussywizard:
4534
4536 {
4537 // Unsummon statue
4539 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4540 if (spellInfo && spellInfo->SpellIconID == 2056)
4541 {
4542 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", m_caster->GetGUID().ToString(), m_spellInfo->Id);
4544 return;
4545 }
4546 }
4547
4548 // potions disabled by client, send event "not in combat" if need
4551
4552 // Take mods after trigger spell (needed for 14177 to affect 48664)
4553 // mods are taken only on succesfull cast and independantly from targets of the spell
4554 if (Player* player = m_caster->GetSpellModOwner())
4555 player->RemoveSpellMods(this);
4556
4557 // xinef: clear reactive auras states after spell cast
4560
4561 // Stop Attack for some spells
4564}
@ ENCOUNTER_CREDIT_CAST_SPELL
Definition Map.h:164
@ 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:2918
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition PlayerUpdates.cpp:1564
Definition TemporarySummon.h:125
virtual void setDeathState(DeathState s, bool despawn=false)
Definition Unit.cpp:11372
void UpdateInterruptMask()
Definition Unit.cpp:884
void ModifyAuraState(AuraStateType flag, bool apply)
Definition Unit.cpp:7643
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition Unit.cpp:7499

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
8565{
8567}
void SendLogExecute()
Definition Spell.cpp:5075

References SendLogExecute().

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

◆ GetCaster()

Unit * Spell::GetCaster ( ) const
inline

◆ GetCastTime()

int32 Spell::GetCastTime ( ) const
inline

◆ GetCastTimeRemaining()

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

References m_timer.

◆ GetCurrentContainer()

CurrentSpellTypes Spell::GetCurrentContainer ( ) const

◆ GetDebugInfo()

std::string Spell::GetDebugInfo ( ) const
protected
9028{
9029 std::stringstream sstr;
9030 sstr << std::boolalpha
9031 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
9032 << " State: " << getState();
9033 return sstr.str();
9034}

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
7934{
7936}
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 
)
2085{
2086 // this function selects which containers need to be searched for spell target
2088
2089 // filter searchers based on searched object type
2090 switch (objType)
2091 {
2098 break;
2102 break;
2103 default:
2104 break;
2105 }
2107 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2111 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2113 retMask &= ~GRID_MAP_TYPE_MASK_PLAYER;
2114
2115 if (condList)
2116 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2117 return retMask;
2118}
@ 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
612{ return m_spellSchoolMask; }

References m_spellSchoolMask.

Referenced by Unit::IsImmunedToSpell().

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

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 ( )
4097{
4098 // start channeling if applicable
4099 if (m_spellInfo->IsChanneled())
4100 {
4101 int32 duration = m_spellInfo->GetDuration();
4103 duration = -1;
4104
4105 if (duration > 0)
4106 {
4107 // First mod_duration then haste - see Missile Barrage
4108 // Apply duration mod
4109 if (Player* modOwner = m_caster->GetSpellModOwner())
4110 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4111
4112 // Apply haste mods
4114 duration = int32(duration * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4115
4118 m_channeledDuration = duration;
4119 SendChannelStart(duration);
4120 }
4121 else if (duration == -1)
4122 {
4125 SendChannelStart(duration);
4126 }
4127 }
4128
4130
4131 // process immediate effects (items, ground, etc.) also initialize some variables
4133
4134 // Sync persistent area aura duration with hasted channel duration
4137 {
4140 }
4141
4142 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4143 DoAllEffectOnTarget(&(*ihit));
4144
4145 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4146 DoAllEffectOnTarget(&(*ihit));
4147
4149
4150 // spell is finished, perform some last features of the spell here
4152
4153 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4154 TakeCastItem();
4155
4156 // handle ammo consumption for Hunter's volley spell
4158 TakeAmmo();
4159
4161 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4162}
@ DYNOBJ_AURA_TYPE
Definition SpellAuraDefines.h:386
AuraObjectType GetType() const
Definition SpellAuras.cpp:425
void SendChannelStart(uint32 duration)
Definition Spell.cpp:5208
void TakeAmmo()
Definition Spell.cpp:5381
void AddInterruptMask(uint32 mask)
Definition Unit.h:1605

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 
)
5637{
5639 return;
5640
5641 effectHandleMode = mode;
5642 unitTarget = pUnitTarget;
5643 itemTarget = pItemTarget;
5644 gameObjTarget = pGOTarget;
5646
5647 uint8 eff = m_spellInfo->Effects[i].Effect;
5648
5649 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5650
5651 // we do not need DamageMultiplier here.
5652 damage = CalculateSpellDamage(i, nullptr);
5653
5654 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5655
5656 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5657 {
5658 (this->*SpellEffects[eff])((SpellEffIndex)i);
5659 }
5660}
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:8678
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
8309{
8310 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8311 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8312 {
8313 // don't do anything for empty effect
8314 if (!m_spellInfo->Effects[i].IsEffect())
8315 continue;
8316
8317 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8318 }
8319
8320 float multiplier[MAX_SPELL_EFFECTS];
8321 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8322 if (m_applyMultiplierMask & (1 << i))
8323 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8324
8327 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8328 {
8329 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8330 usesAmmo = false;
8331 }
8332
8334
8335 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8336 {
8337 TargetInfo& target = *ihit;
8338
8339 uint32 mask = target.effectMask;
8340 if (!mask)
8341 continue;
8342
8343 // do not consume ammo anymore for Hunter's volley spell
8345 usesAmmo = false;
8346
8347 if (usesAmmo)
8348 {
8349 bool ammoTaken = false;
8350 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8351 {
8352 if (!(mask & 1 << i))
8353 continue;
8354 switch (m_spellInfo->Effects[i].Effect)
8355 {
8361 ammoTaken = true;
8362 TakeAmmo();
8363 }
8364 if (ammoTaken)
8365 break;
8366 }
8367 }
8368
8370 {
8371 Unit* targetUnit = m_caster->GetGUID() == target.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target.targetGUID);
8372 if (targetUnit && !m_originalCaster->IsFriendlyTo(targetUnit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)) && (m_spellInfo->HasInitialAggro() || targetUnit->IsEngaged()))
8373 m_originalCaster->SetInCombatWith(targetUnit, true);
8374 }
8375
8376 DoAllEffectOnLaunchTarget(target, multiplier);
8377 }
8378
8380}
@ 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:8382

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 ( )
5584{
5585 if (m_UniqueTargetInfo.empty())
5586 return;
5587
5589 return;
5590
5592
5593 float threat = 0.0f;
5594 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5595 {
5596 if (threatEntry->apPctMod != 0.0f)
5597 threat += threatEntry->apPctMod * unitCaster->GetTotalAttackPowerValue(BASE_ATTACK);
5598
5599 threat += threatEntry->flatMod;
5600 }
5602 threat += m_spellInfo->SpellLevel;
5603
5604 // past this point only multiplicative effects occur
5605 if (threat == 0.0f)
5606 return;
5607
5608 // 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
5609 threat /= m_UniqueTargetInfo.size();
5610
5611 for (auto& ihit : m_UniqueTargetInfo)
5612 {
5613 float threatToAdd = threat;
5614 if (ihit.missCondition != SPELL_MISS_NONE)
5615 threatToAdd = 0.0f;
5616
5617 Unit* target = ObjectAccessor::GetUnit(*unitCaster, ihit.targetGUID);
5618 if (!target)
5619 continue;
5620
5621 // positive spells distribute threat among all units that are in combat with target, like healing
5623 target->GetThreatMgr().ForwardThreatForAssistingMe(unitCaster, threatToAdd, m_spellInfo);
5624 // for negative spells threat gets distributed among affected targets
5625 // ignoreModifiers=true because flat SpellThreatEntry threat should not have modifiers applied twice
5626 else
5627 {
5628 if (!target->CanHaveThreatList())
5629 continue;
5630 target->GetThreatMgr().AddThreat(unitCaster, threatToAdd, m_spellInfo, true);
5631 }
5632 }
5633 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()));
5634}
@ 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
8179{
8180 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8181 if (itr->effectMask & (1 << effect))
8182 return true;
8183
8184 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8185 if (itr->effectMask & (1 << effect))
8186 return true;
8187
8188 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8189 if (itr->effectMask & (1 << effect))
8190 return true;
8191
8192 return false;
8193}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8570{
8571 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8572 if (!m_effectExecuteData[effIndex])
8573 {
8574 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8575 // first dword - target counter
8576 *m_effectExecuteData[effIndex] << uint32(1);
8577 }
8578 else
8579 {
8580 // increase target counter by one
8581 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8582 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8583 }
8584}

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

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

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

◆ IsAutoActionResetSpell()

bool Spell::IsAutoActionResetSpell ( ) const
Todo:
changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all?
8153{
8156 {
8157 return false;
8158 }
8159
8161 {
8162 return false;
8163 }
8164
8165 return true;
8166}
@ 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
8301{
8302 if (target->IsAlive())
8304
8306}
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 ( )
8593{
8594 if (_scriptsLoaded)
8595 return;
8596 _scriptsLoaded = true;
8597 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8598 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8599 {
8600 if (!(*itr)->_Load(this))
8601 {
8602 std::list<SpellScript*>::iterator bitr = itr;
8603 ++itr;
8604 delete (*bitr);
8605 m_loadedScripts.erase(bitr);
8606 continue;
8607 }
8608 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8609 (*itr)->Register();
8610 ++itr;
8611 }
8612}

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 ( )
8998{
8999 if (!m_caster || !m_caster->IsInWorld())
9000 return;
9001
9002 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
9003
9004 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
9005 // can succeed with a lockId of 0
9006 if (m_spellInfo->Id == 21651)
9007 {
9008 if (GameObject* go = m_targets.GetGOTarget())
9009 {
9010 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
9011 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
9012 {
9013 Spell* visual = new Spell(m_caster, spellInfo, TRIGGERED_NONE);
9014 visual->prepare(&m_targets);
9015 }
9016 }
9017 }
9018}
@ LOCKTYPE_SLOW_OPEN
Definition SharedDefines.h:2612
@ TRIGGERED_NONE
Definition SpellDefines.h:133

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

Referenced by prepare().

◆ prepare()

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

m_castItemGUID &&

3453{
3454 if (m_CastItem)
3455 {
3457 }
3458 else
3459 {
3461 }
3462
3463 InitExplicitTargets(*targets);
3464
3465 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3466 {
3467 finish(false);
3468 return SPELL_FAILED_UNKNOWN;
3469 }
3470
3471 // Fill aura scaling information
3473 {
3474 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3475 {
3476 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3479 {
3480 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3482 {
3483 m_auraScaleMask |= (1 << i);
3484 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3485 {
3486 m_auraScaleMask = 0;
3487 break;
3488 }
3489 }
3490 }
3491 }
3492 }
3493
3495
3496 if (triggeredByAura)
3497 {
3498 m_triggeredByAuraSpell.Init(triggeredByAura);
3499 }
3500
3501 // create and add update event for this spell
3502 _spellEvent = new SpellEvent(this);
3504
3505 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, m_caster))
3506 {
3508 finish(false);
3510 }
3511
3512 //Prevent casting at cast another spell (ServerSide check)
3514 {
3516 finish(false);
3518 }
3519
3520 LoadScripts();
3521
3522 OnSpellLaunch();
3523
3525
3526 // Set combo point requirement
3528 m_needComboPoints = false;
3529
3530 SpellCastResult result = CheckCast(true);
3531 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3532 {
3533 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3534 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3535 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3536 // a possible alternative sollution for those would be validating aura target on unit state change
3537 if (m_caster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3538 {
3540 triggeredByAura->GetBase()->SetDuration(0);
3541 }
3542
3543 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3545 {
3546 SendCastResult(result);
3547
3548 finish(false);
3549 return result;
3550 }
3551 }
3552
3553 // Prepare data for triggers
3554 prepareDataForTriggerSystem(triggeredByAura);
3555
3556 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3558
3559 if (m_caster->IsPlayer())
3561 m_casttime = 0;
3562
3563 // don't allow channeled spells / spells with cast time to be casted while moving
3564 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3566 {
3567 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3569 {
3571 finish(false);
3572 return SPELL_FAILED_MOVING;
3573 }
3574 }
3575
3576 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3577 if (m_CastItem)
3578 {
3579 bool selectTargets = false;
3580 bool nearbyDest = false;
3581
3582 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3583 {
3584 if (!m_spellInfo->Effects[i].IsEffect())
3585 continue;
3586
3587 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3588 {
3589 selectTargets = false;
3590 break;
3591 }
3592
3593 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3594 {
3595 nearbyDest = true;
3596 }
3597
3598 // xinef: by default set it to false, and to true if any valid target is found
3599 selectTargets = true;
3600 }
3601
3602 if (selectTargets)
3603 {
3605 _spellTargetsSelected = true;
3606 bool spellFailed = false;
3607
3608 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3609 {
3610 // no valid nearby target unit or game object found; check if nearby destination type
3611 if (nearbyDest)
3612 {
3613 if (!m_targets.HasDst())
3614 {
3615 // no valid target destination
3616 spellFailed = true;
3617 }
3618 }
3619 else
3620 {
3621 spellFailed = true;
3622 }
3623 }
3624
3625 if (spellFailed)
3626 {
3628 finish(false);
3630 }
3631 }
3632 }
3633
3634 // set timer base at cast time
3635 ReSetTimer();
3636
3637 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());
3638
3639 // prevent exploit that allows to cast spell while sitting
3642
3643 //Containers for channeled spells have to be set
3644 //TODO:Apply this to all casted spells if needed
3645 // Why check duration? 29350: channelled triggers channelled
3647 cast(true);
3648 else
3649 {
3650 // stealth must be removed at cast starting (at show channel bar)
3651 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3653 {
3654 // Farsight spells exception
3655 uint32 exceptSpellId = 0;
3657 {
3658 exceptSpellId = m_spellInfo->Id;
3659 }
3660
3663 }
3664
3667
3668 // Call CreatureAI hook OnSpellStart for spells with cast time or channeled spells
3669 if (m_casttime > 0 || m_spellInfo->IsChanneled())
3670 if (Creature* caster = m_caster->ToCreature())
3671 if (caster->IsAIEnabled)
3672 caster->AI()->OnSpellStart(GetSpellInfo());
3673
3674 // set target for proper facing
3675 // channels that allow actions must not lock target and facing, the creature keeps fighting while channeling
3677 {
3680 {
3681 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3682 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3684 }
3685 }
3686
3687 //item: first cast may destroy item and second cast causes crash
3688 // xinef: removed !m_spellInfo->StartRecoveryTime
3689 // second los check failed in events
3690 // xinef: removed itemguid check, currently there is no such item in database
3692 cast(true);
3693
3696 }
3697
3698 sScriptMgr->OnSpellPrepare(this, m_caster, m_spellInfo);
3699
3700 return SPELL_CAST_OK;
3701}
@ CHEAT_CASTTIME
Definition Player.h:998
@ 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:3568
Definition Spell.cpp:519
bool IsActionAllowedChannel() const
Definition SpellInfo.cpp:1293
int32 GetMaxDuration() const
Definition SpellInfo.cpp:2745
uint32 Attributes
Definition SpellInfo.h:348
bool IsBreakingStealth() const
Definition SpellInfo.cpp:1303
void LoadScripts()
Definition Spell.cpp:8592
void cast(bool skipCheck=false)
Definition Spell.cpp:3776
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition Spell.cpp:2248
void SendSpellStart()
Definition Spell.cpp:4719
void TriggerGlobalCooldown()
Definition Spell.cpp:8936
void OnSpellLaunch()
Definition Spell.cpp:8997
CurrentSpellTypes GetCurrentContainer() const
Definition Spell.cpp:7988
void ReSetTimer()
Definition Spell.h:565
void InitExplicitTargets(SpellCastTargets const &targets)
Definition Spell.cpp:726
void SetCurrentCastedSpell(Spell *pSpell)
Definition Unit.cpp:4133
bool IsSitState() const
Definition Unit.cpp:13102
void Init(AuraEffect const *aurEff)
Definition Spell.cpp:9020

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
2249{
2250 //==========================================================================================
2251 // Now fill data for trigger system, need know:
2252 // can spell trigger another or not (m_canTrigger)
2253 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2254 //==========================================================================================
2255
2257 // Get data for type of attack and fill base info for trigger
2258 switch (m_spellInfo->DmgClass)
2259 {
2262 if (m_attackType == OFF_ATTACK)
2264 else
2267 break;
2269 // Auto attack
2271 {
2274 }
2275 else // Ranged spell attack
2276 {
2279 }
2280 break;
2281 default:
2284 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2285 {
2288 }
2289 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2290 // Because spell positivity is dependant on target
2291 }
2293
2294 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2296 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2297 m_spellInfo->Id == 57879 || // Snake Trap - done this way to avoid double proc
2298 m_spellInfo->SpellFamilyFlags[2] & 0x00024000)) // Explosive and Immolation Trap
2299 {
2301
2302 // also fill up other flags (TargetInfo::DoDamageAndTriggers only fills up flag if both are not set)
2305 }
2306
2307 /* Effects which are result of aura proc from triggered spell cannot proc
2308 to prevent chain proc of these spells */
2309
2310 // Hellfire Effect - trigger as DOT
2312 {
2315 }
2316
2317 // Ranged autorepeat attack is set as triggered spell - ignore it
2319 {
2326 }
2327 // Totem casts require spellfamilymask defined in spell_proc to proc
2330}
@ 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
8673{
8674 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8675 (*scritr)->_InitHit();
8676}

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
8847{
8850 {
8851 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
8852 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
8854 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
8855 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
8857 }
8858
8861 {
8863 {
8864 if (m_spellInfo->SpellFamilyFlags[1] & 0x40000000)
8865 {
8867 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
8868 {
8869 if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
8870 {
8871 m_preCastSpell = 26017;
8872 break;
8873 }
8874 else if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
8875 m_preCastSpell = 67;
8876 }
8877 }
8878 break;
8879 }
8880 case SPELLFAMILY_DRUID:
8881 {
8882 // Faerie Fire (Feral)
8884 m_preCastSpell = 60089;
8885
8886 break;
8887 }
8888 }
8889
8890 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
8891 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
8892 // and to correctly calculate proc chance when combopoints are present
8894 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
8895 {
8896 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
8897 continue;
8898 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
8899 uint32 auraSpellIdx = (*i)->GetEffIndex();
8900 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
8901 {
8902 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
8903 // this possibly needs fixing
8904 int32 auraBaseAmount = (*i)->GetBaseAmount();
8905 // proc chance is stored in effect amount
8906 int32 chance = m_caster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
8907 // build trigger and add to the list
8908 HitTriggerSpell spellTriggerInfo;
8909 spellTriggerInfo.triggeredSpell = spellInfo;
8910 spellTriggerInfo.triggeredByAura = auraSpellInfo;
8911 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
8912 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
8913 m_hitTriggerSpells.push_back(spellTriggerInfo);
8914 }
8915 }
8916}
@ 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 ( )
931{
934}
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition EventProcessor.cpp:145
uint64 CalculateDelayMomentForDst() const
Definition Spell.cpp:909
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,
SpellTargetReferenceTypes  referenceType = TARGET_REFERENCE_TYPE_CASTER 
)
2142{
2143 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2144 if (!containerTypeMask)
2145 return;
2146 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList, searchReason, referenceType);
2147 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2148 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2149}
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition Spell.cpp:2084
Definition GridNotifiers.h:262

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 
)
2152{
2153 // max dist for jump target selection
2154 float jumpRadius = 0.0f;
2155 switch (m_spellInfo->DmgClass)
2156 {
2158 // 7.5y for multi shot
2159 jumpRadius = 7.5f;
2160 break;
2162 // 10y for swipe, cleave and similar
2163 jumpRadius = 10.0f;
2164 break;
2167 // 12.5y for chain heal spell since 3.2 patch
2168 if (isChainHeal)
2169 jumpRadius = 12.5f;
2170 // 10y as default for magic chain spells
2171 else
2172 jumpRadius = 10.0f;
2173 break;
2174 }
2175
2176 // per-spell override from spell_jump_distance table
2177 if (m_spellInfo->JumpDistance > 0.0f)
2178 jumpRadius = m_spellInfo->JumpDistance;
2179
2180 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2184
2185 // max dist which spell can reach
2186 float searchRadius = jumpRadius;
2187 if (isBouncingFar)
2188 searchRadius *= chainTargets;
2189
2191 std::list<WorldObject*> tempTargets;
2192 SearchAreaTargets(tempTargets, searchRadius, chainSource, m_caster, objectType, selectType, condList, Acore::WorldObjectSpellAreaTargetSearchReason::Chain);
2193 tempTargets.remove(target);
2194
2195 // remove targets which are always invalid for chain spells
2196 // for some spells allow only chain targets in front of caster (swipe for example)
2197 if (!isBouncingFar)
2198 tempTargets.remove_if([this](WorldObject* target) { return !m_caster->HasInArc(static_cast<float>(M_PI), target); });
2199
2200 while (chainTargets)
2201 {
2202 // try to get unit for next chain jump
2203 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2204 // get unit with highest hp deficit in dist
2205 if (isChainHeal)
2206 {
2207 uint32 maxHPDeficit = 0;
2208 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2209 {
2210 if (Unit* unit = (*itr)->ToUnit())
2211 {
2212 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2213 if (deficit > maxHPDeficit && chainSource->IsWithinDist(unit, jumpRadius) && chainSource->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2214 {
2215 foundItr = itr;
2216 maxHPDeficit = deficit;
2217 }
2218 }
2219 }
2220 }
2221 // get closest object
2222 else
2223 {
2224 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2225 {
2226 if (foundItr == tempTargets.end())
2227 {
2228 if ((!isBouncingFar || chainSource->IsWithinDist(*itr, jumpRadius)) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2229 foundItr = itr;
2230 }
2231 else if (chainSource->GetDistanceOrder(*itr, *foundItr) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2232 foundItr = itr;
2233 }
2234 }
2235 // not found any valid target - chain ends
2236 if (foundItr == tempTargets.end())
2237 break;
2238
2240 chainSource = *foundItr;
2241
2242 targets.push_back(*foundItr);
2243 tempTargets.erase(foundItr);
2244 --chainTargets;
2245 }
2246}
@ 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, SpellTargetReferenceTypes referenceType=TARGET_REFERENCE_TYPE_CASTER)
Definition Spell.cpp:2141
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition Object.cpp:1441
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1376

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 
)
2130{
2131 WorldObject* target = nullptr;
2132 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2133 if (!containerTypeMask)
2134 return nullptr;
2135 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2137 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2138 return target;
2139}
Definition GridNotifiers.h:242

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 
)
2122{
2123 if (!containerMask)
2124 return;
2125
2126 Cell::VisitObjects(pos->GetPositionX(), pos->GetPositionY(), referer->GetMap(), searcher, radius);
2127}

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

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 processedEffectMask 
)
937{
938 if (!targetType.GetTarget())
939 return;
940
941 uint32 effectMask = 1 << effIndex;
942 // set the same target list for all effects
943 // some spells appear to need this, however this requires more research
944 switch (targetType.GetSelectionCategory())
945 {
949 {
950 // targets for effect already selected
951 if (effectMask & processedEffectMask)
952 {
953 return;
954 }
955
956 auto const& effects = GetSpellInfo()->Effects;
957
958 // choose which targets we can select at once
959 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
960 {
961 if (effects[j].IsEffect() &&
962 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
963 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
964 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
965 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
967 {
968 effectMask |= 1 << j;
969 }
970 }
971 processedEffectMask |= effectMask;
972 break;
973 }
974 default:
975 break;
976 }
977
978 switch (targetType.GetSelectionCategory())
979 {
981 SelectImplicitChannelTargets(effIndex, targetType);
982 break;
984 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
985 break;
987 SelectImplicitConeTargets(effIndex, targetType, effectMask);
988 break;
990 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
991 break;
993 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
994 CheckDst();
995
996 SelectImplicitTrajTargets(effIndex, targetType);
997 break;
999 switch (targetType.GetObjectType())
1000 {
1002 switch (targetType.GetReferenceType())
1003 {
1006 break;
1007 default:
1008 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
1009 break;
1010 }
1011 break;
1013 switch (targetType.GetReferenceType())
1014 {
1016 SelectImplicitCasterDestTargets(effIndex, targetType);
1017 break;
1019 SelectImplicitTargetDestTargets(effIndex, targetType);
1020 break;
1022 SelectImplicitDestDestTargets(effIndex, targetType);
1023 break;
1024 default:
1025 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1026 break;
1027 }
1028 break;
1029 default:
1030 switch (targetType.GetReferenceType())
1031 {
1033 SelectImplicitCasterObjectTargets(effIndex, targetType);
1034 break;
1036 SelectImplicitTargetObjectTargets(effIndex, targetType);
1037 break;
1038 default:
1039 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1040 break;
1041 }
1042 break;
1043 }
1044 break;
1046 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1047 break;
1048 default:
1049 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1050 break;
1051 }
1052}
@ 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:1772
void CheckDst()
Definition Spell.h:506
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1918
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1232
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1735
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1300
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1054
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1855
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1808
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1110
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition Spell.cpp:8807
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1389

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
2002{
2003 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
2005 switch (m_spellInfo->Effects[effIndex].Effect)
2006 {
2010 {
2012
2014
2015 if (target && target->ToPlayer())
2016 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2017 }
2018 return;
2019 default:
2020 break;
2021 }
2022
2023 // select spell implicit targets based on effect type
2024 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2025 return;
2026
2027 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
2028
2029 if (!targetMask)
2030 return;
2031
2032 WorldObject* target = nullptr;
2033
2034 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2035 {
2036 // add explicit object target or self to the target map
2038 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
2040 {
2042 target = unitTarget;
2043 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2044 {
2045 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2046 {
2048 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2049 target = owner;
2050 }
2051 }
2052 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2053 target = m_caster;
2054 }
2055 if (targetMask & TARGET_FLAG_ITEM_MASK)
2056 {
2058 AddItemTarget(itemTarget, 1 << effIndex);
2059 return;
2060 }
2061 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2062 target = m_targets.GetGOTarget();
2063 break;
2064 // add self to the target map
2066 if (targetMask & TARGET_FLAG_UNIT_MASK)
2067 target = m_caster;
2068 break;
2069 default:
2070 break;
2071 }
2072
2074
2075 if (target)
2076 {
2077 if (target->ToUnit())
2078 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2079 else if (target->ToGameObject())
2080 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2081 }
2082}
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition SpellInfo.h:145
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition SpellInfo.h:144
@ TARGET_FLAG_ITEM_MASK
Definition SpellInfo.h:73
GameObject * ToGameObject()
Definition Object.h:214
Corpse * GetCorpseTarget() const
Definition Spell.cpp:294
Definition SpellInfo.h:238
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition Spell.cpp:2475
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition Spell.cpp:2341
void AddItemTarget(Item *item, uint32 effectMask)
Definition Spell.cpp:2537
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8779

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 ( )
797{
798 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
799 if (Unit* target = m_targets.GetUnitTarget())
800 {
801 // check for explicit target redirection, for Grounding Totem for example
805 {
806 Unit* redirect;
807 switch (m_spellInfo->DmgClass)
808 {
811 break;
815 break;
816 default:
817 redirect = nullptr;
818 break;
819 }
820 if (redirect && (redirect != target))
821 {
822 m_targets.SetUnitTarget(redirect);
824 }
825 }
826 }
827}
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo=nullptr)
Definition Unit.cpp:8209
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition Unit.cpp:8171

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 
)
1301{
1302 Unit* referer = nullptr;
1303 switch (targetType.GetReferenceType())
1304 {
1308 referer = m_caster;
1309 break;
1311 referer = m_targets.GetUnitTarget();
1312 break;
1314 {
1315 // find last added target for this effect
1316 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1317 {
1318 if (ihit->effectMask & (1 << effIndex))
1319 {
1320 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1321 break;
1322 }
1323 }
1324 break;
1325 }
1326 default:
1327 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1328 return;
1329 }
1330 if (!referer)
1331 return;
1332
1333 Position const* center = nullptr;
1334 switch (targetType.GetReferenceType())
1335 {
1337 center = m_targets.GetSrcPos();
1338 break;
1340 center = m_targets.GetDstPos();
1341 break;
1345 center = referer;
1346 break;
1347 default:
1348 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1349 return;
1350 }
1351
1352 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1353 std::list<WorldObject*> targets;
1354 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1355 switch (targetType.GetTarget())
1356 {
1360 radius += m_caster->GetLeewayBonusRadius();
1361 break;
1362 default:
1363 break;
1364 }
1365
1366 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions, Acore::WorldObjectSpellAreaTargetSearchReason::Area, targetType.GetReferenceType());
1367
1368 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1369
1370 if (!targets.empty())
1371 {
1372 // Other special target selection goes here
1373 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1374 {
1376 Acore::Containers::RandomResize(targets, maxTargets);
1377 }
1378
1379 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1380 {
1381 if (Unit* unitTarget = (*itr)->ToUnit())
1382 AddUnitTarget(unitTarget, effMask, false);
1383 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1384 AddGOTarget(gObjTarget, effMask);
1385 }
1386 }
1387}
@ TARGET_UNIT_CASTER_AREA_PARTY
Definition SharedDefines.h:1428
@ TARGET_UNIT_SRC_AREA_ENEMY
Definition SharedDefines.h:1424
@ TARGET_UNIT_CASTER_AREA_RAID
Definition SharedDefines.h:1464
@ SPELL_AURA_MOD_MAX_AFFECTED_TARGETS
Definition SpellAuraDefines.h:340
@ TARGET_REFERENCE_TYPE_SRC
Definition SpellInfo.h:93
@ TARGET_REFERENCE_TYPE_LAST
Definition SpellInfo.h:92
Position const * GetSrcPos() const
Definition Spell.cpp:362
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8765
int32 GetTotalAuraModifierByAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition Unit.cpp:6403
void RandomResize(C &container, std::size_t requestedSize)
Definition Containers.h:79
float RadiusMod
Definition Spell.h:227
uint32 MaxAffectedTargets
Definition Spell.h:226

References AddGOTarget(), AddUnitTarget(), Acore::Area, ASSERT, CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellCastTargets::GetDstPos(), WorldObject::GetLeewayBonusRadius(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetReferenceType(), SpellCastTargets::GetSrcPos(), SpellImplicitTargetInfo::GetTarget(), 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, TARGET_UNIT_CASTER_AREA_PARTY, TARGET_UNIT_CASTER_AREA_RAID, TARGET_UNIT_SRC_AREA_ENEMY, Object::ToGameObject(), Object::ToUnit(), and unitTarget.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterDestTargets()

void Spell::SelectImplicitCasterDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
Todo:
fix this check
1390{
1392
1393 switch (targetType.GetTarget())
1394 {
1395 case TARGET_DEST_CASTER:
1397 break;
1398 case TARGET_DEST_HOME:
1399 if (Player* playerCaster = m_caster->ToPlayer())
1400 dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
1401 break;
1402 case TARGET_DEST_DB:
1403 if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
1404 {
1407 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1408 else if (st->target_mapId == m_caster->GetMapId())
1409 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1410 }
1411 else
1412 {
1413 LOG_DEBUG("spells.aura", "SPELL: unknown target coordinates for spell ID {}", m_spellInfo->Id);
1414 if (WorldObject* target = m_targets.GetObjectTarget())
1415 dest = SpellDestination(*target);
1416 }
1417 break;
1419 {
1420 float min_dis = m_spellInfo->GetMinRange(true);
1421 float max_dis = m_spellInfo->GetMaxRange(true);
1422 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
1423 float x, y, z, angle;
1424 angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1425 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing
1427
1428 float ground = m_caster->GetMapHeight(x, y, z, true);
1429 float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
1430 LiquidData const& liquidData = m_caster->GetMap()->GetLiquidData(m_caster->GetPhaseMask(), x, y, z, m_caster->GetCollisionHeight(), {});
1431 if (liquidData.Status)
1432 liquidLevel = liquidData.Level;
1433
1434 if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1435 {
1438 finish(false);
1439 return;
1440 }
1441
1442 if (ground + 0.75 > liquidLevel)
1443 {
1446 finish(false);
1447 return;
1448 }
1449
1450 if (!m_caster->IsWithinLOS(x, y, z))
1451 {
1454 finish(false);
1455 return;
1456 }
1457
1458 dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
1459 break;
1460 }
1462 {
1463 float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1464 Map* map = m_caster->GetMap();
1465 uint32 phasemask = m_caster->GetPhaseMask();
1466 float collisionHeight = m_caster->GetCollisionHeight();
1467 float destz = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f;
1468
1469 Position pos;
1470 Position lastpos;
1471 m_caster->GetPosition(startx, starty, startz, starto);
1472 pos.Relocate(startx, starty, startz, starto);
1473 float destx = pos.GetPositionX() + distance * cos(pos.GetOrientation());
1474 float desty = pos.GetPositionY() + distance * sin(pos.GetOrientation());
1475
1476 // Added GROUND_HEIGHT_TOLERANCE to account for cases where, during a jump,
1477 // the Z position may be slightly below the vmap ground level.
1478 // Without this tolerance, a ray trace might incorrectly attempt to find ground
1479 // beneath the actual surface.
1480 //
1481 // Example:
1482 // actual vmap ground: -56.342392
1483 // Z position: -56.347195
1484 float searchGroundZPos = pos.GetPositionZ()+GROUND_HEIGHT_TOLERANCE;
1485 float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), searchGroundZPos);
1486
1487 bool isCasterInWater = m_caster->IsInWater();
1488 if (!m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1489 {
1490 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1491 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;
1492 float maxtravelDistZ = 2.65f;
1493 float overdistance = 0.0f;
1494 float totalpath = 0.0f;
1495 float beforewaterz = 0.0f;
1496 bool inwater = false;
1497 bool wcol = false;
1498 const float step = 2.0f;
1499 const uint8 numChecks = std::ceil(std::fabs(distance / step));
1500 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1501 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1502 int j = 1;
1503 for (; j < (numChecks + 1); j++)
1504 {
1505 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1506 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1507 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1508 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1509
1510 if (j < 2)
1511 {
1512 prevZ = pos.GetPositionZ();
1513 }
1514 else
1515 {
1516 prevZ = tstZ;
1517 }
1518
1519 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1520 ground = tstZ;
1521
1522 if (!isCasterInWater)
1523 {
1524 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1525 {
1526 if (!(beforewaterz != 0.0f))
1527 {
1528 beforewaterz = prevZ;
1529 }
1530 tstZ = beforewaterz;
1531 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1532 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1533 }
1534 }
1535 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1536 {
1537 prevZ = pos.GetPositionZ();
1538 tstZ = pos.GetPositionZ();
1539 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1540
1541 inwater = true;
1542 if (inwater && (fabs(tstZ - ground) < 2.0f))
1543 {
1544 wcol = true;
1545 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1546 }
1547
1548 // if (j < 2)
1549 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1550 // else
1551 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1552 }
1553
1554 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1555 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1556 {
1557 if (inwater && !IsInWater)
1558 inwater = false;
1559
1560 // highest available point
1561 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1562 // upper or floor
1563 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1564 //lower than floor
1565 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1566
1567 //distance of rays, will select the shortest in 3D
1568 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1569 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1570 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1571 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1572 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1573 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1574
1575 if (srange1 < srange2)
1576 {
1577 tstZ = tstZ1;
1578 srange = srange1;
1579 }
1580 else if (srange3 < srange2)
1581 {
1582 tstZ = tstZ3;
1583 srange = srange3;
1584 }
1585 else
1586 {
1587 tstZ = tstZ2;
1588 srange = srange2;
1589 }
1590
1591 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1592 }
1593
1594 destx = tstX;
1595 desty = tstY;
1596 destz = tstZ;
1597
1598 totalpath += srange;
1599
1600 if (totalpath > distance)
1601 {
1602 overdistance = totalpath - distance;
1603 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1604 }
1605
1606 bool col = m_caster->GetMap()->GetMapCollisionData().GetStaticTree().GetObjectHitPos(prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1607 // check dynamic collision
1608 bool dcol = m_caster->GetMap()->GetMapCollisionData().GetDynamicTree().GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1609
1610 // collision occured
1611 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1612 {
1613 if ((overdistance > 0.0f) && (overdistance < 1.f))
1614 {
1615 destx = prevX + overdistance * cos(pos.GetOrientation());
1616 desty = prevY + overdistance * sin(pos.GetOrientation());
1617 //LOG_ERROR("spells", "(collision) collision occured 1");
1618 }
1619 else
1620 {
1621 // move back a bit
1622 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1623 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1624 //LOG_ERROR("spells", "(collision) collision occured 2");
1625 }
1626
1627 // highest available point
1628 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1629 // upper or floor
1630 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1631 //lower than floor
1632 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1633
1634 //distance of rays, will select the shortest in 3D
1635 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1636 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1637 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1638
1639 if (srange1 < srange2)
1640 destz = destz1;
1641 else if (srange3 < srange2)
1642 destz = destz3;
1643 else
1644 destz = destz2;
1645
1646 if (inwater && destz < prevZ && !wcol)
1647 destz = prevZ;
1648 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1649
1650 // Don't make the player move backward from the xy adjustments by collisions.
1651 if ((DELTA_X > 0 && startx > destx) || (DELTA_X < 0 && startx < destx) ||
1652 (DELTA_Y > 0 && starty > desty) || (DELTA_Y < 0 && starty < desty))
1653 {
1654 destx = startx;
1655 desty = starty;
1656 destz = startz;
1657 }
1658
1659 break;
1660 }
1661 // we have correct destz now
1662 }
1663
1664 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1665 dest = SpellDestination(lastpos);
1666 }
1667 else
1668 {
1669 float z = pos.GetPositionZ();
1670 bool col = m_caster->GetMap()->GetMapCollisionData().GetStaticTree().GetObjectHitPos(pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1671 // check dynamic collision
1672 bool dcol = m_caster->GetMap()->GetMapCollisionData().GetDynamicTree().GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1673
1674 // collision occured
1675 if (col || dcol)
1676 {
1677 // move back a bit
1678 destx = destx - (0.6 * cos(pos.GetOrientation()));
1679 desty = desty - (0.6 * sin(pos.GetOrientation()));
1680 }
1681
1682 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1683 dest = SpellDestination(lastpos);
1684 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1685 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1686 }
1687 break;
1688 }
1689 default:
1690 {
1691 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1692 float angle = targetType.CalcDirectionAngle();
1693 float objSize = m_caster->GetCombatReach();
1694
1695 switch (targetType.GetTarget())
1696 {
1698 dist = PET_FOLLOW_DIST;
1699 break;
1701 if (dist > objSize)
1702 dist = objSize + (dist - objSize) * float(rand_norm());
1703 break;
1708 {
1709 static float const DefaultTotemDistance = 3.0f;
1710 if (!m_spellInfo->Effects[effIndex].HasRadius())
1711 dist = DefaultTotemDistance;
1712 break;
1713 }
1714 default:
1715 break;
1716 }
1717
1718 if (dist < objSize)
1719 {
1720 dist = objSize;
1721 }
1722
1723 Position pos = dest._position;
1724 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1725
1726 dest.Relocate(pos);
1727 break;
1728 }
1729 }
1730
1731 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1732 m_targets.SetDst(dest);
1733}
#define VMAP_INVALID_HEIGHT_VALUE
Definition IVMapMgr.h:51
@ SPELL_EFFECT_BIND
Definition SharedDefines.h:777
@ SPELL_EFFECT_TELEPORT_UNITS
Definition SharedDefines.h:771
@ TARGET_DEST_CASTER_RANDOM
Definition SharedDefines.h:1480
@ TARGET_DEST_DB
Definition SharedDefines.h:1426
@ TARGET_DEST_CASTER_FRONT_LEAP
Definition SharedDefines.h:1463
@ TARGET_DEST_CASTER_FRONT_LEFT
Definition SharedDefines.h:1452
@ TARGET_DEST_CASTER_BACK_RIGHT
Definition SharedDefines.h:1450
@ TARGET_DEST_CASTER_FISHING
Definition SharedDefines.h:1447
@ TARGET_DEST_CASTER_BACK_LEFT
Definition SharedDefines.h:1451
@ TARGET_DEST_CASTER_SUMMON
Definition SharedDefines.h:1440
@ TARGET_DEST_CASTER
Definition SharedDefines.h:1427
@ TARGET_DEST_CASTER_FRONT_RIGHT
Definition SharedDefines.h:1449
@ TARGET_DEST_CASTER_36
Definition SharedDefines.h:1444
@ TARGET_DEST_HOME
Definition SharedDefines.h:1422
float const GROUND_HEIGHT_TOLERANCE
Definition SharedDefines.h:26
@ SPELL_FAILED_TOO_SHALLOW
Definition SharedDefines.h:1093
@ MOVEMENTFLAG_FALLING
Definition UnitDefines.h:384
bool GetObjectHitPos(uint32 phasemask, float x1, float y1, float z1, float x2, float y2, float z2, float &rx, float &ry, float &rz, float modifyDist) const
Definition MapCollisionData.cpp:163
DynamicVMapCollisionData & GetDynamicTree()
Definition MapCollisionData.h:82
StaticVMapCollisionData & GetStaticTree()
Definition MapCollisionData.h:84
LiquidData const GetLiquidData(uint32 phaseMask, float x, float y, float z, float collisionHeight, Optional< uint8 > ReqLiquidType)
Definition Map.cpp:1314
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition Map.cpp:1166
MapCollisionData & GetMapCollisionData()
Definition Map.h:573
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition Map.cpp:1593
void CallScriptDestinationTargetSelectHandlers(SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:8793
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:17151
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition Object.cpp:3140
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:2747
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 
)
1809{
1810 WorldObject* target = nullptr;
1811 bool checkIfValid = true;
1812
1813 switch (targetType.GetTarget())
1814 {
1815 case TARGET_UNIT_CASTER:
1816 target = m_caster;
1817 checkIfValid = false;
1818 break;
1819 case TARGET_UNIT_MASTER:
1820 target = m_caster->GetCharmerOrOwner();
1821 break;
1822 case TARGET_UNIT_PET:
1823 target = m_caster->GetGuardianPet();
1824 if (!target)
1825 target = m_caster->GetCharm();
1826 break;
1828 if (m_caster->IsSummon())
1829 target = m_caster->ToTempSummon()->GetSummonerUnit();
1830 break;
1832 target = m_caster->GetVehicleBase();
1833 break;
1843 target = m_caster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1844 break;
1845 default:
1846 break;
1847 }
1848
1849 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1850
1851 if (target && target->ToUnit())
1852 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1853}
@ TARGET_UNIT_PASSENGER_1
Definition SharedDefines.h:1505
@ TARGET_UNIT_PASSENGER_6
Definition SharedDefines.h:1510
@ TARGET_UNIT_VEHICLE
Definition SharedDefines.h:1502
@ TARGET_UNIT_PASSENGER_2
Definition SharedDefines.h:1506
@ TARGET_UNIT_PASSENGER_4
Definition SharedDefines.h:1508
@ TARGET_UNIT_PASSENGER_7
Definition SharedDefines.h:1511
@ TARGET_UNIT_MASTER
Definition SharedDefines.h:1435
@ TARGET_UNIT_PASSENGER_5
Definition SharedDefines.h:1509
@ TARGET_UNIT_PASSENGER_3
Definition SharedDefines.h:1507
@ TARGET_UNIT_SUMMONER
Definition SharedDefines.h:1500
@ TARGET_UNIT_PASSENGER_0
Definition SharedDefines.h:1504
Unit * GetSummonerUnit() const
Definition TemporarySummon.cpp:44
Unit * GetPassenger(int8 seatId) const
Definition Vehicle.cpp:239

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject target,
uint32  effMask 
)
1878{
1879 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1880 if (Player* modOwner = m_caster->GetSpellModOwner())
1881 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1882
1883 if (maxTargets > 1)
1884 {
1885 // mark damage multipliers as used
1886 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1887 if (effMask & (1 << k))
1888 m_damageMultipliers[k] = 1.0f;
1889 m_applyMultiplierMask |= effMask;
1890
1891 std::list<WorldObject*> targets;
1892 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1893 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1894
1895 // Chain primary target is added earlier
1896 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1897
1898 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1899 if (Unit* unitTarget = (*itr)->ToUnit())
1900 AddUnitTarget(unitTarget, effMask, false);
1901 }
1902}
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition SharedDefines.h:1453
@ SPELLMOD_JUMP_TARGETS
Definition SpellDefines.h:93
void SearchChainTargets(std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
Definition Spell.cpp:2151

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

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitConeTargets()

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

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitDestDestTargets()

void Spell::SelectImplicitDestDestTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1773{
1774 // set destination to caster if no dest provided
1775 // can only happen if previous destination target could not be set for some reason
1776 // (not found nearby target, or channel target for example
1777 // maybe we should abort the spell in such case?
1778 CheckDst();
1779
1781
1782 switch (targetType.GetTarget())
1783 {
1787 case TARGET_DEST_DEST:
1788 return;
1789 default:
1790 {
1791 float angle = targetType.CalcDirectionAngle();
1792 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1793 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1794 dist *= float(rand_norm());
1795
1796 Position pos = dest._position;
1797 m_caster->MovePosition(pos, dist, angle);
1798
1799 dest.Relocate(pos);
1800 break;
1801 }
1802 }
1803
1804 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1805 m_targets.ModDst(dest);
1806}
@ TARGET_DEST_DYNOBJ_ENEMY
Definition SharedDefines.h:1436
@ TARGET_DEST_DEST_RANDOM
Definition SharedDefines.h:1494
@ TARGET_DEST_DEST
Definition SharedDefines.h:1495
@ TARGET_DEST_DYNOBJ_NONE
Definition SharedDefines.h:1496
@ TARGET_DEST_DYNOBJ_ALLY
Definition SharedDefines.h:1437
void ModDst(Position const &pos)
Definition Spell.cpp:436
SpellDestination const * GetDst() const
Definition Spell.cpp:396
void MovePosition(Position &pos, float dist, float angle)
Definition Object.cpp:2897

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 
)
1111{
1112 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1113 {
1114 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
1115 return;
1116 }
1117
1118 float range = 0.0f;
1119 switch (targetType.GetCheckType())
1120 {
1121 case TARGET_CHECK_ENEMY:
1122 range = m_spellInfo->GetMaxRange(false, m_caster, this);
1123 break;
1124 case TARGET_CHECK_ALLY:
1125 case TARGET_CHECK_PARTY:
1126 case TARGET_CHECK_RAID:
1128 range = m_spellInfo->GetMaxRange(true, m_caster, this);
1129 break;
1130 case TARGET_CHECK_ENTRY:
1133 break;
1134 default:
1135 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
1136 break;
1137 }
1138
1139 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1140
1141 // handle emergency case - try to use other provided targets if no conditions provided
1142 if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
1143 {
1144 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);
1145 switch (targetType.GetObjectType())
1146 {
1149 {
1150 if (focusObject)
1151 AddGOTarget(focusObject, effMask);
1152 return;
1153 }
1154 break;
1157 {
1158 if (focusObject)
1159 {
1161 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1162 m_targets.SetDst(dest);
1163 }
1164 return;
1165 }
1166 break;
1167 default:
1168 break;
1169 }
1170 }
1171
1172 WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
1173 if (!target)
1174 {
1175 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1176 return;
1177 }
1178
1179 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1180 if (!target)
1181 {
1182 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set nullptr target, effect {}", m_spellInfo->Id, effIndex);
1183 return;
1184 }
1185
1186 switch (targetType.GetObjectType())
1187 {
1189 {
1190 if (Unit* unit = target->ToUnit())
1191 {
1192 AddUnitTarget(unit, effMask, true, false);
1193 // xinef: important! if channeling spell have nearby entry, it has no unitTarget by default
1194 // and if channeled spell has target 77, it requires unitTarget, set it here!
1195 // xinef: if we have NO unit target
1196 if (!m_targets.GetUnitTarget())
1197 {
1199 }
1200 }
1201 else
1202 {
1203 //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);
1204 return;
1205 }
1206 break;
1207 }
1209 if (GameObject* gobjTarget = target->ToGameObject())
1210 AddGOTarget(gobjTarget, effMask);
1211 else
1212 {
1213 //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);
1214 return;
1215 }
1216 break;
1218 {
1219 SpellDestination dest(*target);
1220 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1221 m_targets.SetDst(dest);
1222 break;
1223 }
1224 default:
1225 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
1226 break;
1227 }
1228
1229 SelectImplicitChainTargets(effIndex, targetType, target, effMask);
1230}
@ 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:2129
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition Spell.cpp:1877

References AddGOTarget(), AddUnitTarget(), ASSERT, CallScriptDestinationTargetSelectHandlers(), 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 
)
1736{
1738
1739 SpellDestination dest(*target);
1740
1741 switch (targetType.GetTarget())
1742 {
1745 break;
1746 default:
1747 {
1748 float angle = targetType.CalcDirectionAngle();
1749 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1750 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1751 {
1752 dist *= float(rand_norm());
1753 }
1754
1755 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1756 {
1758 }
1759
1760 Position pos = dest._position;
1761 target->MovePositionToFirstCollision(pos, dist, angle);
1762
1763 dest.Relocate(pos);
1764 break;
1765 }
1766 }
1767
1768 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1769 m_targets.SetDst(dest);
1770}
@ TARGET_DEST_TARGET_ANY
Definition SharedDefines.h:1471
@ TARGET_DEST_TARGET_BACK
Definition SharedDefines.h:1473
@ TARGET_DEST_TARGET_RANDOM
Definition SharedDefines.h:1482
@ TARGET_DEST_TARGET_ENEMY
Definition SharedDefines.h:1461
@ UNIT_FIELD_BOUNDINGRADIUS
Definition UpdateFields.h:122

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

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitTargetObjectTargets()

void Spell::SelectImplicitTargetObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1856{
1857 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1858
1860
1861 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1862
1863 if (target)
1864 {
1865 if (Unit* unit = target->ToUnit())
1866 AddUnitTarget(unit, 1 << effIndex, true, false);
1867 else if (GameObject* gobj = target->ToGameObject())
1868 AddGOTarget(gobj, 1 << effIndex);
1869
1870 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1871 }
1872 // Script hook can remove object target and we would wrongly land here
1873 else if (Item* item = m_targets.GetItemTarget())
1874 AddItemTarget(item, 1 << effIndex);
1875}

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 
)
1919{
1920 if (!m_targets.HasTraj())
1921 return;
1922
1923 float dist2d = m_targets.GetDist2d();
1924 if (!dist2d)
1925 return;
1926
1927 Position srcPos = *m_targets.GetSrcPos();
1929 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - srcPos.m_positionZ;
1930
1931 std::list<WorldObject*> targets;
1932 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, &srcPos, m_caster, m_spellInfo, targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1934 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, &srcPos, dist2d);
1935 if (targets.empty())
1936 return;
1937
1939
1940 float b = tangent(m_targets.GetElevation());
1941 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1942 if (a > -0.0001f)
1943 a = 0.f;
1944
1945 // We should check if triggered spell has greater range (which is true in many cases, and initial spell has too short max range)
1946 // limit max range to 300 yards, sometimes triggered spells can have 50000yds
1947 float bestDist = m_spellInfo->GetMaxRange(false);
1948 if (SpellInfo const* triggerSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell))
1949 bestDist = std::min(std::max(bestDist, triggerSpellInfo->GetMaxRange(false)), std::min(dist2d, 300.0f));
1950
1951 // GameObjects don't cast traj
1952 Unit* unitCaster = ASSERT_NOTNULL(m_caster->ToUnit());
1953 for (auto itr = targets.begin(); itr != targets.end(); ++itr)
1954 {
1955 if (m_spellInfo->CheckTarget(unitCaster, *itr, true) != SPELL_CAST_OK)
1956 continue;
1957
1958 if (Unit* unit = (*itr)->ToUnit())
1959 {
1960 if (unitCaster == *itr || unitCaster->IsOnVehicle(unit) || unit->GetVehicle())
1961 continue;
1962
1963 if (Creature* creatureTarget = unit->ToCreature())
1964 {
1965 if (!(creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_COLLIDE_WITH_MISSILES))
1966 continue;
1967 }
1968 }
1969
1970 float const size = std::max((*itr)->GetCombatReach(), 1.0f);
1971 float const objDist2d = srcPos.GetExactDist2d(*itr);
1972 float const dz = (*itr)->GetPositionZ() - srcPos.m_positionZ;
1973
1974 float const horizontalDistToTraj = std::fabs(objDist2d * std::sin(srcPos.GetRelativeAngle(*itr)));
1975 float const sizeFactor = std::cos((horizontalDistToTraj / size) * (M_PI / 2.0f));
1976 float const distToHitPoint = std::max(objDist2d * std::cos(srcPos.GetRelativeAngle(*itr)) - size * sizeFactor, 0.0f);
1977 float const height = distToHitPoint * (a * distToHitPoint + b);
1978
1979 if (fabs(dz - height) > size + b / 2.0f + TRAJECTORY_MISSILE_SIZE)
1980 continue;
1981
1982 if (distToHitPoint < bestDist)
1983 {
1984 bestDist = distToHitPoint;
1985 break;
1986 }
1987 }
1988
1989 if (dist2d > bestDist)
1990 {
1991 float x = m_targets.GetSrcPos()->m_positionX + std::cos(unitCaster->GetOrientation()) * bestDist;
1992 float y = m_targets.GetSrcPos()->m_positionY + std::sin(unitCaster->GetOrientation()) * bestDist;
1993 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
1994
1995 SpellDestination dest(x, y, z, unitCaster->GetOrientation());
1996 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1997 m_targets.ModDst(dest);
1998 }
1999}
#define ASSERT_NOTNULL(pointer)
Definition Errors.h:85
@ CREATURE_TYPE_FLAG_COLLIDE_WITH_MISSILES
Definition SharedDefines.h:2708
float tangent(float x)
Definition Spell.cpp:1904
#define TRAJECTORY_MISSILE_SIZE
Definition Spell.h:51
Definition Object.h:806
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 ( )
830{
831 // select targets for cast phase
833
834 uint32 processedAreaEffectsMask = 0;
835 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
836 {
837 // not call for empty effect.
838 // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
839 if (!m_spellInfo->Effects[i].IsEffect())
840 continue;
841
842 // set expected type of implicit targets to be sent to client
843 uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
844 if (implicitTargetMask & TARGET_FLAG_UNIT)
846 if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
848
849 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
850 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
851
852 // Select targets of effect based on effect type
853 // those are used when no valid target could be added for spell effect based on spell target type
854 // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
855 // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
856 // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
858
859 if (m_targets.HasDst())
861
863 {
864 // maybe do this for all spells?
865 if (!focusObject && m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
866 {
868 finish(false);
869 return;
870 }
871
872 uint8 mask = (1 << i);
873 for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
874 {
875 if (ihit->effectMask & mask)
876 {
878 break;
879 }
880 }
881 }
882 else if (m_auraScaleMask)
883 {
884 bool checkLvl = !m_UniqueTargetInfo.empty();
885 m_UniqueTargetInfo.erase(std::remove_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) -> bool
886 {
887 // remove targets which did not pass min level check
888 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
889 {
890 if (!targetInfo.scaleAura && targetInfo.targetGUID != m_caster->GetGUID())
891 return true;
892 }
893
894 return false;
895 }), std::end(m_UniqueTargetInfo));
896
897 if (checkLvl && m_UniqueTargetInfo.empty())
898 {
900 finish(false);
901 }
902 }
903 }
904
905 if (uint64 dstDelay = CalculateDelayMomentForDst())
906 m_delayMoment = dstDelay;
907}
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:936
void SelectExplicitTargets()
Definition Spell.cpp:796
void AddDestTarget(SpellDestination const &dest, uint32 effIndex)
Definition Spell.cpp:2566
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition Spell.cpp:2001

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
4672{
4673 if (result == SPELL_CAST_OK)
4674 return;
4675
4676 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4677 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4678
4679 caster->SendDirectMessage(&data);
4680}
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition Spell.cpp:4566
@ 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_only_for_flight::OnUse(), item_petrov_cluster_bombs::OnUse(), prepare(), SelectImplicitCasterDestTargets(), SelectSpellTargets(), and SendCastResult().

◆ SendCastResult() [2/2]

void Spell::SendCastResult ( SpellCastResult  result)
4683{
4684 if (result == SPELL_CAST_OK)
4685 return;
4686
4687 if (!m_caster->IsPlayer() || m_caster->IsCharmed())
4688 return;
4689
4690 if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4691 return;
4692
4693 // 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
4695 result = SPELL_FAILED_DONT_REPORT;
4696
4698}
@ 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:1311

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)
5209{
5210 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5211 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5212 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5213 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5214
5215 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5216 data << m_caster->GetPackGUID();
5217 data << uint32(m_spellInfo->Id);
5218 data << uint32(duration);
5219
5220 m_caster->SendMessageToSet(&data, true);
5221
5224
5225 m_timer = duration;
5226 if (channelTarget)
5228
5230}
@ 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)
5177{
5178 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5179 data << m_caster->GetPackGUID();
5180 data << uint8(m_cast_count);
5181 data << uint32(m_spellInfo->Id);
5182 data << uint8(result);
5183 m_caster->SendMessageToSet(&data, true);
5184
5185 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5186 data << m_caster->GetPackGUID();
5187 data << uint8(m_cast_count);
5188 data << uint32(m_spellInfo->Id);
5189 data << uint8(result);
5190 m_caster->SendMessageToSet(&data, true);
5191}
@ 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 ( )
5076{
5077 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5078
5079 data << m_caster->GetPackGUID();
5080
5081 data << uint32(m_spellInfo->Id);
5082
5083 uint8 effCount = 0;
5084 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5085 {
5086 if (m_effectExecuteData[i])
5087 ++effCount;
5088 }
5089
5090 if (!effCount)
5091 return;
5092
5093 data << uint32(effCount);
5094 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5095 {
5096 if (!m_effectExecuteData[i])
5097 continue;
5098
5099 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5100
5101 data.append(*m_effectExecuteData[i]);
5102
5103 delete m_effectExecuteData[i];
5104 m_effectExecuteData[i] = nullptr;
5105 }
5106 m_caster->SendMessageToSet(&data, true);
5107}
@ SMSG_SPELLLOGEXECUTE
Definition Opcodes.h:618

References ByteBuffer::append(), SpellInfo::Effects, Object::GetPackGUID(), SpellInfo::Id, m_caster, m_effectExecuteData, m_spellInfo, MAX_SPELL_EFFECTS, WorldObject::SendMessageToSet(), and SMSG_SPELLLOGEXECUTE.

Referenced by FinishTargetProcessing().

◆ SendLoot()

void Spell::SendLoot ( ObjectGuid  guid,
LootType  loottype 
)
protected
2028{
2029 Player* player = m_caster->ToPlayer();
2030 if (!player)
2031 return;
2032
2033 if (gameObjTarget)
2034 {
2035 // Players shouldn't be able to loot gameobjects that are currently despawned
2036 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2037 {
2038 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2039 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2040 return;
2041 }
2042 // special case, already has GossipHello inside so return and avoid calling twice
2044 {
2046 return;
2047 }
2048
2049 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2050 return;
2051
2052 if (gameObjTarget->AI()->GossipHello(player, false))
2053 return;
2054
2055 switch (gameObjTarget->GetGoType())
2056 {
2058 gameObjTarget->UseDoorOrButton(0, false, player);
2059 return;
2061 gameObjTarget->UseDoorOrButton(0, false, player);
2062
2063 // Xinef: properly link possible traps
2064 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2065 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2066 return;
2070 return;
2071
2073 // triggering linked GO
2076 return;
2077
2079 // triggering linked GO
2080 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->chest.linkedTrapId)
2082
2083 // Don't return, let loots been taken
2084 default:
2085 break;
2086 }
2087 }
2088
2089 // Send loot
2090 player->SendLoot(guid, loottype);
2091}
@ GAMEOBJECT_TYPE_SPELL_FOCUS
Definition SharedDefines.h:1572
@ GAMEOBJECT_TYPE_QUESTGIVER
Definition SharedDefines.h:1566
virtual bool GossipHello(Player *, bool)
Definition GameObjectAI.h:54
bool isSpawned() const
Definition GameObject.h:190
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition GameObject.cpp:1369
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::@236::@245 spellFocus
struct GameObjectTemplate::@236::@240 questgiver
uint32 linkedTrapId
Definition GameObjectData.h:91
struct GameObjectTemplate::@236::@241 chest

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)
4701{
4702 if (result == SPELL_CAST_OK)
4703 return;
4704
4705 Unit* owner = m_caster->GetCharmerOrOwner();
4706 if (!owner)
4707 return;
4708
4709 Player* player = owner->ToPlayer();
4710 if (!player)
4711 return;
4712
4713 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4715
4716 player->SendDirectMessage(&data);
4717}
@ 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)
5233{
5234 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5235 // for player resurrections the name is looked up by guid
5236 std::string const sentName(m_caster->IsPlayer()
5237 ? ""
5238 : m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()));
5239
5240 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5241 data << m_caster->GetGUID();
5242 data << uint32(sentName.size() + 1);
5243
5244 data << sentName;
5245 data << uint8(0); // null terminator
5246
5247 data << uint8(m_caster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5248 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5250 data << uint32(0);
5251 target->SendDirectMessage(&data);
5252}
@ 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 ( )
4347{
4348 // xinef: properly add creature cooldowns
4349 if (!m_caster->IsPlayer())
4350 {
4352 {
4353 // xinef: this should be added here
4354 //m_caster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4355
4356 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4359 {
4360 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4361 data << m_caster->GetGUID();
4363 data << uint32(m_spellInfo->Id);
4365 player->SendDirectMessage(&data);
4366 }
4367 }
4368 return;
4369 }
4370
4371 Player* _player = m_caster->ToPlayer();
4372
4373 // mana/health/etc potions, disabled by client (until combat out as declarate)
4375 {
4376 // need in some way provided data for Spell::finish SendCooldownEvent
4377 _player->SetLastPotionId(m_CastItem->GetEntry());
4378 return;
4379 }
4380
4381 // have infinity cooldown but set at aura apply
4382 // do not set cooldown for triggered spells (needed by reincarnation)
4387 return;
4388
4390}
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition Unit.h:632
void SetLastPotionId(uint32 item_id)
Definition Player.h:1839
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition Player.cpp:11080
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 ( )
4800{
4801 // not send invisible spell casting
4802 if (!IsNeedSendToClient(true))
4803 return;
4804
4805 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4806
4807 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4808
4809 // triggered spells with spell visual != 0
4811 castFlags |= CAST_FLAG_PENDING;
4812
4814 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4815
4816 // should only be sent to self, but the current messaging doesn't make that possible
4817 if (m_caster->IsPlayer() || m_caster->IsPet())
4818 {
4819 switch (m_spellInfo->PowerType)
4820 {
4821 case POWER_HEALTH:
4822 break;
4823 case POWER_RUNE:
4824 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4825 break;
4826 default:
4827 if (m_powerCost != 0)
4828 {
4829 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4830 }
4831 break;
4832 }
4833 }
4834
4835 if ((m_caster->IsPlayer())
4839 {
4840 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4841 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4842 }
4843
4845 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4846
4847 if (m_targets.HasTraj())
4848 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4849
4851 castFlags |= CAST_FLAG_NO_GCD;
4852
4853 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4854 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4855 {
4856 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4857 {
4858 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4859 {
4860 realCasterGUID = casterGameobject->GetPackGUID();
4861 }
4862 }
4863 }
4864
4865 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
4866
4867 if (m_CastItem)
4868 data << m_CastItem->GetPackGUID();
4869 else
4870 data << realCasterGUID;
4871
4872 data << realCasterGUID;
4873 data << uint8(m_cast_count); // pending spell cast?
4874 data << uint32(m_spellInfo->Id); // spellId
4875 data << uint32(castFlags); // cast flags
4876 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
4877
4878 WriteSpellGoTargets(&data);
4879
4880 m_targets.Write(data);
4881
4882 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4884
4885 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
4886 {
4887 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
4888 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
4889 if (Player* player = m_caster->ToPlayer())
4890 {
4891 uint8 runeMaskInitial = m_runesState;
4892 uint8 runeMaskAfterCast = player->GetRunesState();
4893 data << uint8(runeMaskInitial); // runes state before
4894 data << uint8(runeMaskAfterCast); // runes state after
4895 for (uint8 i = 0; i < MAX_RUNES; ++i)
4896 {
4897 uint8 mask = (1 << i);
4898 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
4899 {
4900 // float casts ensure the division is performed on floats as we need float result
4901 float baseCd = float(player->GetRuneBaseCooldown(i, true));
4902 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
4903 }
4904 }
4905 }
4906 }
4907 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
4908 {
4909 data << m_targets.GetElevation();
4911 }
4912
4913 if (castFlags & CAST_FLAG_PROJECTILE)
4914 WriteAmmoToPacket(&data);
4915
4916 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
4917 {
4918 data << uint32(0);
4919 data << uint32(0);
4920 }
4921
4923 {
4924 data << uint8(0);
4925 }
4926
4927 m_caster->SendMessageToSet(&data, true);
4928}
@ 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:267
void Write(ByteBuffer &data)
Definition Spell.cpp:179
SpellCastTimesEntry const * CastTimeEntry
Definition SpellInfo.h:371
void WriteSpellGoTargets(WorldPacket *data)
Writes miss and hit targets for a SMSG_SPELL_GO packet.
Definition Spell.cpp:5015
void WriteAmmoToPacket(WorldPacket *data)
Definition Spell.cpp:4930
bool IsNeedSendToClient(bool go) const
Definition Spell.cpp:8168
@ 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 ( )
4720{
4721 if (!IsNeedSendToClient(false))
4722 return;
4723
4724 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4725
4726 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4727
4729 castFlags |= CAST_FLAG_PENDING;
4730
4732 castFlags |= CAST_FLAG_PROJECTILE;
4733
4734 if (m_caster->IsPlayer() || m_caster->IsPet())
4735 {
4736 switch (m_spellInfo->PowerType)
4737 {
4738 case POWER_HEALTH:
4739 break;
4740 case POWER_RUNE:
4741 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4742 break;
4743 default:
4744 if (m_powerCost != 0)
4745 {
4746 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4747 }
4748 break;
4749 }
4750 }
4751
4753 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4754
4755 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4756 if (TempSummon const* tempSummon = m_caster->ToTempSummon())
4757 {
4758 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4759 {
4760 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4761 {
4762 realCasterGUID = casterGameobject->GetPackGUID();
4763 }
4764 }
4765 }
4766
4767 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4768 if (m_CastItem)
4769 data << m_CastItem->GetPackGUID();
4770 else
4771 data << realCasterGUID;
4772
4773 data << realCasterGUID;
4774 data << uint8(m_cast_count); // pending spell cast?
4775 data << uint32(m_spellInfo->Id); // spellId
4776 data << uint32(castFlags); // cast flags
4777 data << int32(m_timer); // delay?
4778
4779 m_targets.Write(data);
4780
4781 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4783
4784 if (castFlags & CAST_FLAG_PROJECTILE)
4785 WriteAmmoToPacket(&data);
4786
4787 if (castFlags & CAST_FLAG_UNKNOWN_23)
4788 {
4789 data << uint32(0);
4790 data << uint32(0);
4791 }
4792
4793 m_caster->SendMessageToSet(&data, true);
4794
4797}
@ 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 
)
8520{
8521 switch (mod)
8522 {
8524 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8525 break;
8527 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8528 break;
8530 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8531 break;
8533 m_spellValue->RadiusMod = (float)value / 10000;
8534 break;
8537 break;
8540 break;
8542 m_spellValue->AuraDuration = value;
8543 break;
8545 m_spellValue->ForcedCritResult = (bool)value;
8546 break;
8548 m_spellValue->MiscVal[0] = value;
8549 break;
8551 m_spellValue->MiscVal[1] = value;
8552 break;
8554 m_spellValue->MiscVal[2] = value;
8555 break;
8556 }
8557}
@ 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(), spell_yogg_saron_sanity::ModSanityStacks(), 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
5981{
5982 Unit* caster = m_originalCaster;
5983 if (!caster)
5984 return;
5985
5986 if (caster->IsTotem())
5987 caster = caster->ToTotem()->GetOwner();
5988 else if (caster->IsPet())
5989 if (Unit* owner = caster->GetOwner())
5990 caster = owner;
5991
5992 // in another case summon new
5993 uint8 summonLevel = caster->GetLevel();
5994
5995 // level of pet summoned using engineering item based at engineering skill level
5996 if (m_CastItem && caster->IsPlayer())
5997 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
5998 {
5999 // xinef: few special cases
6000 if (proto->RequiredSkill == SKILL_ENGINEERING)
6001 {
6002 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
6003 summonLevel = skill202 / 5;
6004 }
6005
6006 switch (m_spellInfo->Id)
6007 {
6008 // Dragon's Call
6009 case 13049:
6010 summonLevel = 55;
6011 break;
6012
6013 // Cleansed Timberling Heart: Summon Timberling
6014 case 5666:
6015 summonLevel = 7;
6016 break;
6017
6018 // Glowing Cat Figurine: Summon Ghost Saber
6019 case 6084:
6020 // minLevel 19, maxLevel 20
6021 summonLevel = 20;
6022 break;
6023
6024 // Spiked Collar: Summon Felhunter
6025 case 8176:
6026 summonLevel = 30;
6027 break;
6028
6029 // Dog Whistle: Summon Tracking Hound
6030 case 9515:
6031 summonLevel = 30;
6032 break;
6033
6034 // Barov Peasant Caller: Death by Peasant
6035 case 18307:
6036 case 18308:
6037 summonLevel = 60;
6038 break;
6039
6040 // Thornling Seed: Plant Thornling
6041 case 22792:
6042 summonLevel = 60;
6043 break;
6044
6045 // Cannonball Runner: Summon Crimson Cannon
6046 case 6251:
6047 summonLevel = 61;
6048 break;
6049 }
6050 }
6051
6052 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6053
6054 float radius = 5.0f;
6055 int32 duration = m_spellInfo->GetDuration();
6056
6057 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6058 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6059
6060 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6061 Map* map = caster->GetMap();
6062 TempSummon* summon = nullptr;
6063
6064 uint32 currMinionsCount = m_caster->m_Controlled.size();
6065 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6066
6067 for (uint32 count = 0; count < numGuardians; ++count)
6068 {
6069 Position pos;
6070
6071 // xinef: do not use precalculated position for effect summon pet in this function
6072 // it means it was cast by NPC and should have its position overridden unless the
6073 // target position is specified in the DB AND the effect has no or zero radius
6074 if ((totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6075 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6076 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6077 {
6078 pos = *destTarget;
6079 }
6080 else
6081 {
6082 // randomize position
6083 pos = m_caster->GetRandomPoint(*destTarget, radius);
6084 }
6085
6086 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6087 if (!summon)
6088 return;
6089
6090 // xinef: set calculated level
6091 summon->SetLevel(summonLevel);
6092
6093 // if summonLevel changed, set stats for calculated level
6094 if (summonLevel != caster->GetLevel())
6095 {
6096 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6097 }
6098
6099 // xinef: if we have more than one guardian, change follow angle
6100 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6101 ((Minion*)summon)->SetFollowAngle(m_caster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6102 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6103 // ((Minion*)summon)->SetFollowAngle(m_caster->GetAngle(summon));
6104
6105 // xinef: move this here, some auras are added in initstatsforlevel!
6106 if (!summon->IsInCombat() && !summon->IsTrigger())
6107 {
6108 // summon->AI()->EnterEvadeMode();
6109 summon->GetMotionMaster()->Clear(false);
6111 }
6112
6113 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6114 summon->SetFaction(caster->GetFaction());
6115
6117 }
6118}
@ SKILL_ENGINEERING
Definition SharedDefines.h:3156
@ CONFIG_MAX_PLAYER_LEVEL
Definition WorldConfig.h:195
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition WorldConfig.h:244
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:12334
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 ( )
5382{
5384 {
5386
5387 // wands don't have ammo
5388 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5389 return;
5390
5391 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5392 {
5393 if (pItem->GetMaxStackCount() == 1)
5394 {
5395 // decrease durability for non-stackable throw weapon
5397 }
5398 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5399 {
5400 // decrease items amount for stackable throw weapon
5401 uint32 count = 1;
5402 m_caster->ToPlayer()->DestroyItemCount(pItem, count, true);
5403 }
5404 }
5405 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5407 m_caster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5408 }
5409}
@ INVTYPE_THROWN
Definition ItemTemplate.h:281
@ EQUIPMENT_SLOT_RANGED
Definition Player.h:679
@ SPELL_ATTR6_DO_NOT_CONSUME_RESOURCES
Definition SharedDefines.h:597
@ CONFIG_ENABLE_INFINITEAMMO
Definition WorldConfig.h:151
uint32 GetMaxStackCount() const
Definition Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition Player.cpp:4892

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 ( )
5255{
5256 if (!m_CastItem || !m_caster->IsPlayer())
5257 return;
5258
5259 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5261 return;
5262
5263 ItemTemplate const* proto = m_CastItem->GetTemplate();
5264
5265 if (!proto)
5266 {
5267 // This code is to avoid a crash
5268 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5269 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5270 return;
5271 }
5272
5273 bool expendable = false;
5274 bool withoutCharges = false;
5275
5276 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5277 {
5278 if (proto->Spells[i].SpellId)
5279 {
5280 // item has limited charges
5281 if (proto->Spells[i].SpellCharges)
5282 {
5283 if (proto->Spells[i].SpellCharges < 0)
5284 expendable = true;
5285
5286 int32 charges = m_CastItem->GetSpellCharges(i);
5287
5288 // item has charges left
5289 if (charges)
5290 {
5291 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5292 if (proto->Stackable == 1)
5293 m_CastItem->SetSpellCharges(i, charges);
5295 }
5296
5297 // all charges used
5298 withoutCharges = (charges == 0);
5299 }
5300 }
5301 }
5302
5303 if (expendable && withoutCharges)
5304 {
5305 uint32 count = 1;
5306 m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5307
5308 // prevent crash at access to deleted m_targets.GetItemTarget
5310 m_targets.SetItemTarget(nullptr);
5311
5312 m_CastItem = nullptr;
5314 }
5315}
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 ( )
5318{
5320 return;
5321
5322 //Don't take power if the spell is cast while .cheat power is enabled.
5323 if (m_caster->IsPlayer())
5325 return;
5326
5328 bool hit = true;
5329 if (m_caster->IsPlayer())
5330 {
5332 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5333 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5334 if (ihit->targetGUID == targetGUID)
5335 {
5336 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5337 {
5338 hit = false;
5339 //lower spell cost on fail (by talent aura)
5340 if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner())
5341 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5342 }
5343 break;
5344 }
5345 }
5346
5347 if (PowerType == POWER_RUNE)
5348 {
5349 TakeRunePower(hit);
5350 return;
5351 }
5352
5353 if (!m_powerCost)
5354 return;
5355
5356 // health as power used
5357 if (PowerType == POWER_HEALTH)
5358 {
5360 return;
5361 }
5362
5363 if (PowerType >= MAX_POWERS)
5364 {
5365 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5366 return;
5367 }
5368
5369 if (hit)
5371 else
5373
5374 // Set the five second timer
5375 if (PowerType == POWER_MANA && m_powerCost > 0)
5376 {
5378 }
5379}
@ SPELL_MISS_ABSORB
Definition SharedDefines.h:1533
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition SpellDefines.h:106
void TakeRunePower(bool didHit)
Definition Spell.cpp:5465
int32 ModifyHealth(int32 val)
Definition Unit.cpp:10974
void SetLastManaUse(uint32 spellCastTime)
Definition Unit.h:1152

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 ( )
5535{
5536 if (!m_caster->IsPlayer())
5537 return;
5538
5539 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5540
5541 // do not take reagents for these item casts
5542 if (castItemTemplate && castItemTemplate->HasFlag(ITEM_FLAG_NO_REAGENT_COST))
5543 return;
5544
5545 Player* p_caster = m_caster->ToPlayer();
5546 if (p_caster->CanNoReagentCast(m_spellInfo))
5547 return;
5548
5549 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5550 {
5551 if (m_spellInfo->Reagent[x] <= 0)
5552 continue;
5553
5554 uint32 itemid = m_spellInfo->Reagent[x];
5555 uint32 itemcount = m_spellInfo->ReagentCount[x];
5556
5557 // if CastItem is also spell reagent
5558 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5559 {
5560 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5561 {
5562 // CastItem will be used up and does not count as reagent
5563 int32 charges = m_CastItem->GetSpellCharges(s);
5564 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5565 {
5566 ++itemcount;
5567 break;
5568 }
5569 }
5570
5571 m_CastItem = nullptr;
5573 }
5574
5575 // if GetItemTarget is also spell reagent
5576 if (m_targets.GetItemTargetEntry() == itemid)
5577 m_targets.SetItemTarget(nullptr);
5578
5579 p_caster->DestroyItemCount(itemid, itemcount, true);
5580 }
5581}
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)
5466{
5468 return;
5469
5470 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5471 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5472 return;
5473
5474 Player* player = m_caster->ToPlayer();
5475 m_runesState = player->GetRunesState(); // store previous state
5476
5477 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5478
5479 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5480 {
5481 runeCost[i] = runeCostData->RuneCost[i];
5482 if (Player* modOwner = m_caster->GetSpellModOwner())
5483 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5484 }
5485
5486 runeCost[RUNE_DEATH] = 0; // calculated later
5487
5488 for (uint32 i = 0; i < MAX_RUNES; ++i)
5489 {
5490 RuneType rune = player->GetCurrentRune(i);
5491 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5492 {
5493 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5494 player->SetLastUsedRune(rune);
5495 runeCost[rune]--;
5496 }
5497 }
5498
5499 // Xinef: firstly consume death runes of base type
5500 // Xinef: in second loop consume all available
5501 for (uint8 loop = 0; loop < 2; ++loop)
5502 {
5503 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5504 if (runeCost[RUNE_DEATH] > 0)
5505 {
5506 for (uint8 i = 0; i < MAX_RUNES; ++i)
5507 {
5508 RuneType rune = player->GetCurrentRune(i);
5509 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5510 {
5511 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5512 player->SetLastUsedRune(rune);
5513 runeCost[rune]--;
5514 if (!loop)
5515 runeCost[player->GetBaseRune(i)]--;
5516
5517 // keep Death Rune type if missed
5518 if (didHit)
5519 player->RestoreBaseRune(i);
5520
5521 if (runeCost[RUNE_DEATH] == 0)
5522 break;
5523 }
5524 }
5525 }
5526 }
5527
5528 // you can gain some runic power when use runes
5529 if (didHit)
5530 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5531 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5532}
@ 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:409
void SetLastUsedRune(RuneType type)
Definition Player.h:2561
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition Player.cpp:13677
void RestoreBaseRune(uint8 index)
Definition Player.cpp:13706
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
8937{
8939 if (!gcd)
8940 {
8941 // Xinef: fix for charmed pet spells with no cooldown info
8943 gcd = MIN_GCD;
8944 else
8945 return;
8946 }
8947
8948 if (m_caster->IsPlayer())
8950 return;
8951
8952 // Global cooldown can't leave range 1..1.5 secs
8953 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
8954 // but as tests show are not affected by any spell mods.
8956 {
8957 // gcd modifier auras are applied only to own spells and only players have such mods
8958 if (m_caster->IsPlayer())
8960
8961 // Apply haste rating
8964 {
8965 gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
8966 }
8967
8968 if (gcd < MIN_GCD)
8969 gcd = MIN_GCD;
8970 else if (gcd > MAX_GCD)
8971 gcd = MAX_GCD;
8972 }
8973
8974 // Only players or controlled units have global cooldown
8975 if (m_caster->GetCharmInfo())
8977 else if (m_caster->IsPlayer())
8979}
@ SPELLMOD_GLOBAL_COOLDOWN
Definition SpellDefines.h:97
@ MIN_GCD
Definition Spell.cpp:8921
@ MAX_GCD
Definition Spell.cpp:8922
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)
4393{
4394 // update pointers based at it's GUIDs
4395 if (!UpdatePointers())
4396 {
4397 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4398 cancel();
4399 return;
4400 }
4401
4403 {
4404 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4405 cancel();
4406 return;
4407 }
4408
4409 // check if the player caster has moved before the spell finished
4410 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4411 if ((m_caster->IsPlayer() && m_timer != 0) &&
4414 {
4415 // don't cancel for melee, autorepeat, triggered and instant spells
4417 cancel(true);
4418 }
4419
4420 switch (m_spellState)
4421 {
4423 {
4424 if (m_timer > 0)
4425 {
4426 if (difftime >= (uint32)m_timer)
4427 m_timer = 0;
4428 else
4429 m_timer -= difftime;
4430 }
4431
4432 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4433 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4434 cast(!m_casttime);
4435 break;
4436 }
4438 {
4439 if (m_timer)
4440 {
4441 if (m_timer > 0)
4442 {
4443 if (difftime >= (uint32)m_timer)
4444 m_timer = 0;
4445 else
4446 m_timer -= difftime;
4447 }
4448 }
4449
4450 if (m_timer == 0)
4451 {
4453
4454 finish();
4455
4456 // 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
4457 if (Creature* creatureCaster = m_caster->ToCreature())
4458 if (creatureCaster->IsAIEnabled)
4459 creatureCaster->AI()->OnChannelFinished(m_spellInfo);
4460 }
4461 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4462 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4463 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4464 // Xinef: so the aura can be removed in different updates for all units
4465 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4466 {
4467 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4469 finish();
4470 }
4471 break;
4472 }
4473 default:
4474 break;
4475 }
4476}
bool UpdateChanneledTargetList()
Definition Spell.cpp:3364

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
3365{
3366 // Not need check return true
3368 return true;
3369
3370 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3371 uint8 channelAuraMask = 0;
3372 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3374 channelAuraMask |= 1 << i;
3375
3376 channelAuraMask &= channelTargetEffectMask;
3377
3378 float range = 0;
3379 if (channelAuraMask)
3380 {
3382 if (range == 0)
3383 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3384 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3385 {
3386 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3387 break;
3388 }
3389
3390 if (Player* modOwner = m_caster->GetSpellModOwner())
3391 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3392
3393 // xinef: add little tolerance level
3394 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3395 }
3396
3397 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3398 {
3399 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3400 {
3401 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3402
3403 if (!unit)
3404 continue;
3405
3406 if (IsValidDeadOrAliveTarget(unit))
3407 {
3408 if (channelAuraMask & ihit->effectMask)
3409 {
3411 {
3412 if (m_caster != unit)
3413 {
3414 if (!m_caster->IsWithinDistInMap(unit, range))
3415 {
3416 ihit->effectMask &= ~aurApp->GetEffectMask();
3417 unit->RemoveAura(aurApp);
3418 continue;
3419 }
3420 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3423 }
3424 }
3425 else // aura is dispelled
3426 continue;
3427 }
3428
3429 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3430 }
3431 }
3432 }
3433
3434 // Xinef: not all effects are covered, remove applications from all targets
3435 if (channelTargetEffectMask != 0)
3436 {
3437 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3438 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3439 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3440 if (IsValidDeadOrAliveTarget(unit))
3442 {
3443 ihit->effectMask &= ~aurApp->GetEffectMask();
3444 unit->RemoveAura(aurApp);
3445 }
3446 }
3447
3448 // is all effects from m_needAliveTargetMask have alive targets
3449 return channelTargetEffectMask == 0;
3450}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition SharedDefines.h:421
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition Spell.cpp:8300
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition Unit.cpp:5858
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition Unit.cpp:16043
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1381

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 ( )
7939{
7942 else
7943 {
7946 m_originalCaster = nullptr;
7947 }
7948
7950 {
7952 // cast item not found, somehow the item is no longer where we expected
7953 if (!m_CastItem)
7954 return false;
7955 }
7956 else
7957 m_CastItem = nullptr;
7958
7960
7961 // further actions done only for dest targets
7962 if (!m_targets.HasDst())
7963 return true;
7964
7965 // cache last transport
7966 WorldObject* transport = nullptr;
7967
7968 // update effect destinations (in case of moved transport dest target)
7969 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
7970 {
7971 SpellDestination& dest = m_destTargets[effIndex];
7972 if (!dest._transportGUID)
7973 continue;
7974
7975 if (!transport || transport->GetGUID() != dest._transportGUID)
7977
7978 if (transport)
7979 {
7980 dest._position.Relocate(transport);
7982 }
7983 }
7984
7985 return true;
7986}
void Update(Unit *caster)
Definition Spell.cpp:479
WorldObject * GetWorldObject(WorldObject const &, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:139
void RelocateOffset(Position const &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)
4931{
4932 uint32 ammoInventoryType = 0;
4933 uint32 ammoDisplayID = 0;
4934
4935 if (m_caster->IsPlayer())
4936 {
4938 if (pItem)
4939 {
4940 ammoInventoryType = pItem->GetTemplate()->InventoryType;
4941 if (ammoInventoryType == INVTYPE_THROWN)
4942 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
4943 else
4944 {
4946 if (ammoID)
4947 {
4948 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
4949 if (pProto)
4950 {
4951 ammoDisplayID = pProto->DisplayInfoID;
4952 ammoInventoryType = pProto->InventoryType;
4953 }
4954 }
4955 else if (m_caster->HasAura(46699)) // Requires No Ammo
4956 {
4957 ammoDisplayID = 5996; // normal arrow
4958 ammoInventoryType = INVTYPE_AMMO;
4959 }
4960 }
4961 }
4962 }
4963 else
4964 {
4965 uint32 nonRangedAmmoDisplayID = 0;
4966 uint32 nonRangedAmmoInventoryType = 0;
4967 for (uint8 i = 0; i < 3; ++i)
4968 {
4970 {
4971 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
4972 {
4973 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
4974 {
4975 switch (itemEntry->SubclassID)
4976 {
4978 ammoDisplayID = itemEntry->DisplayInfoID;
4979 ammoInventoryType = itemEntry->InventoryType;
4980 break;
4983 ammoDisplayID = 5996; // is this need fixing?
4984 ammoInventoryType = INVTYPE_AMMO;
4985 break;
4987 ammoDisplayID = 5998; // is this need fixing?
4988 ammoInventoryType = INVTYPE_AMMO;
4989 break;
4990 default:
4991 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
4992 nonRangedAmmoInventoryType = itemEntry->InventoryType;
4993 break;
4994 }
4995
4996 if (ammoDisplayID)
4997 break;
4998 }
4999 }
5000 }
5001 }
5002
5003 if (!ammoDisplayID && !ammoInventoryType)
5004 {
5005 ammoDisplayID = nonRangedAmmoDisplayID;
5006 ammoInventoryType = nonRangedAmmoInventoryType;
5007 }
5008 }
5009
5010 *data << uint32(ammoDisplayID);
5011 *data << uint32(ammoInventoryType);
5012}
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
4567{
4568 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4569 data << uint32(spellInfo->Id);
4570 data << uint8(result); // problem
4571 switch (result)
4572 {
4574 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4575 break;
4576 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4577 // hardcode areas limitation case
4578 switch (spellInfo->Id)
4579 {
4580 case 41617: // Cenarion Mana Salve
4581 case 41619: // Cenarion Healing Salve
4582 data << uint32(3905);
4583 break;
4584 case 41618: // Bottled Nethergon Energy
4585 case 41620: // Bottled Nethergon Vapor
4586 data << uint32(3842);
4587 break;
4588 case 45373: // Bloodberry Elixir
4589 data << uint32(4075);
4590 break;
4591 default: // default case (don't must be)
4592 data << uint32(0);
4593 break;
4594 }
4595 break;
4597 if (spellInfo->Totem[0])
4598 data << uint32(spellInfo->Totem[0]);
4599 if (spellInfo->Totem[1])
4600 data << uint32(spellInfo->Totem[1]);
4601 break;
4603 if (spellInfo->TotemCategory[0])
4604 data << uint32(spellInfo->TotemCategory[0]);
4605 if (spellInfo->TotemCategory[1])
4606 data << uint32(spellInfo->TotemCategory[1]);
4607 break;
4611 data << uint32(spellInfo->EquippedItemClass);
4612 data << uint32(spellInfo->EquippedItemSubClassMask);
4613 break;
4615 {
4616 uint32 item = 0;
4617 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4618 if (spellInfo->Effects[eff].ItemType)
4619 item = spellInfo->Effects[eff].ItemType;
4620 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4621 if (proto && proto->ItemLimitCategory)
4622 data << uint32(proto->ItemLimitCategory);
4623 break;
4624 }
4626 data << uint32(customError);
4627 break;
4629 {
4630 uint32 missingItem = 0;
4631 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4632 {
4633 if (spellInfo->Reagent[i] <= 0)
4634 continue;
4635
4636 uint32 itemid = spellInfo->Reagent[i];
4637 uint32 itemcount = spellInfo->ReagentCount[i];
4638
4639 if (!caster->HasItemCount(itemid, itemcount))
4640 {
4641 missingItem = itemid;
4642 break;
4643 }
4644 }
4645
4646 data << uint32(missingItem); // first missing item
4647 break;
4648 }
4650 data << uint32(spellInfo->Mechanic);
4651 break;
4653 data << uint32(spellInfo->EquippedItemSubClassMask);
4654 break;
4656 data << uint32(0); // Item entry
4657 data << uint32(0); // Count
4658 break;
4660 data << uint32(0); // SkillLine.dbc Id
4661 data << uint32(0); // Amount
4662 break;
4664 data << uint32(0); // Skill level
4665 break;
4666 default:
4667 break;
4668 }
4669}
@ 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.

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

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