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 (WorldObject *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, WorldObject *referer, Position const *pos, float radius)
 
WorldObject * SearchNearbyTarget (float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList=nullptr)
 
void SearchAreaTargets (std::list< WorldObject * > &targets, float range, Position const *position, WorldObject *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
 
WorldObject * GetCaster () const
 
Unit * GetOriginalCaster () const
 
Unit * GetUnitCasterForEffectHandlers () const
 
Unit * GetOriginalTarget () 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
 
Item * m_CastItem
 
Item * m_weaponItem
 
ObjectGuid m_castItemGUID
 
uint8 m_cast_count
 
uint32 m_glyphIndex
 
uint32 m_preCastSpell
 
SpellCastTargets m_targets
 
SpellCustomErrors m_customError
 
Unit * m_comboTarget
 
int8 m_comboPointGain
 
UsedSpellMods m_appliedMods
 

Protected Types

typedef std::list< HitTriggerSpell > HitTriggerSpellList
 

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

WorldObject *const m_caster
 
SpellValue *const m_spellValue
 
ObjectGuid m_originalCasterGUID
 
Unit * m_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]
 
Unit * unitTarget
 
Item * itemTarget
 
GameObject * gameObjTarget
 
WorldLocation * destTarget
 
int32 damage
 
SpellEffectHandleMode effectHandleMode
 
Unit * m_reflectionTarget
 
ObjectGuid m_reflectionTargetGuid
 
Position m_reflectionTargetPosition
 
Aura * m_spellAura
 
DiminishingLevels m_diminishLevel
 
DiminishingGroup m_diminishGroup
 
GameObject * focusObject
 
int32 m_damage
 
int32 m_healing
 
int32 m_damageBeforeTakenMods
 
uint32 m_procAttacker
 
uint32 m_procVictim
 
uint32 m_procEx
 
std::list< TargetInfo > m_UniqueTargetInfo
 
uint8 m_channelTargetEffectMask
 
std::list< GOTargetInfo > m_UniqueGOTargetInfo
 
std::list< ItemTargetInfo > m_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< PathGenerator > m_preGeneratedPath
 
bool _spellTargetsSelected
 
ByteBuffer * m_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 ( WorldObject *  caster,
SpellInfo const *  info,
TriggerCastFlags  triggerFlags,
ObjectGuid  originalCasterGUID = ObjectGuid::Empty,
bool  skipCheck = false 
)
608 :
609 m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)),
610 m_caster((info->HasAttribute(SPELL_ATTR6_ORIGINATE_FROM_CONTROLLER) && caster->ToUnit() && caster->ToUnit()->GetCharmerOrOwner()) ? caster->ToUnit()->GetCharmerOrOwner() : caster)
612{
614 m_skipCheck = skipCheck;
615 m_selfContainer = nullptr;
617 m_executedCurrently = false;
620 m_comboTarget = nullptr;
621 m_delayStart = 0;
623
625 m_auraScaleMask = 0;
626 memset(m_damageMultipliers, 0, sizeof(m_damageMultipliers));
627
628 // Get data for type of attack
629 switch (m_spellInfo->DmgClass)
630 {
634 else
636 break;
639 break;
640 default:
641 // Wands
644 else
646 break;
647 }
648
649 m_spellSchoolMask = info->GetSchoolMask(); // Can be override for some spell (wand shoot for example)
650
651 if (Player const* playerCaster = m_caster->ToPlayer())
652 {
653 // wand case
655 if ((playerCaster->getClassMask() & CLASSMASK_WAND_USERS) != 0)
656 if (Item* pItem = playerCaster->GetWeaponForAttack(RANGED_ATTACK))
657 m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetTemplate()->Damage[0].DamageType);
658 }
659
660 if (originalCasterGUID)
661 m_originalCasterGUID = originalCasterGUID;
662 else
664
667 else
668 {
671 m_originalCaster = nullptr;
672 }
673
675 _triggeredCastFlags = triggerFlags;
676 if (info->HasAttribute(SPELL_ATTR4_ALLOW_CAST_WHILE_CASTING))
678
679 m_CastItem = nullptr;
680
681 unitTarget = nullptr;
682 itemTarget = nullptr;
683 gameObjTarget = nullptr;
684 destTarget = nullptr;
685 damage = 0;
686 m_reflectionTarget = nullptr;
691 m_damage = 0;
692 m_healing = 0;
694 m_procAttacker = 0;
695 m_procVictim = 0;
696 m_procEx = 0;
697 focusObject = nullptr;
698 m_cast_count = 0;
699 m_glyphIndex = 0;
700 m_preCastSpell = 0;
701 m_spellAura = nullptr;
702 _scriptsLoaded = false;
703
704 //Auto Shot & Shoot (wand)
706
707 m_runesState = 0;
708 m_powerCost = 0; // setup to correct value in Spell::prepare, must not be used before.
709 m_casttime = 0; // setup to correct value in Spell::prepare, must not be used before.
710 m_timer = 0; // will set to castime in prepare
711 m_channeledDuration = 0; // will be setup in Spell::handle_immediate
712 m_immediateHandled = false;
713
715
717
718 // Determine if spell can be reflected back to the caster
719 // Patch 1.2 notes: Spell Reflection no longer reflects abilities
723
725 memset(m_effectExecuteData, 0, MAX_SPELL_EFFECTS * sizeof(ByteBuffer*));
726
727 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
729
730 // xinef:
731 _spellTargetsSelected = false;
732
733 m_weaponItem = nullptr;
734}
#define MAX_SPELL_EFFECTS
Definition DBCStructure.h:1673
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:140
@ TRIGGERED_CAST_DIRECTLY
Will ignore combo point requirement.
Definition SpellDefines.h:149
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will ignore aura scaling.
Definition SpellDefines.h:147
#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
Player * ToPlayer()
Definition Object.h:208
bool IsInWorld() const
Definition Object.h:115
static ObjectGuid GetGUID(Object const *o)
Definition Object.h:120
Unit * ToUnit()
Definition Object.h:216
Definition Player.h:1086
bool IsPassive() const
Definition SpellInfo.cpp:1143
bool NeedsComboPoints() const
Definition SpellInfo.cpp:1311
bool HasAttribute(SpellAttr0 attribute) const
Definition SpellInfo.h:441
bool HasEffect(SpellEffects effect) const
Definition SpellInfo.cpp:889
bool IsPositive() const
Definition SpellInfo.cpp:1282
bool IsAutoRepeatRangedSpell() const
Definition SpellInfo.cpp:1328
uint32 DmgClass
Definition SpellInfo.h:413
bool IsRangedWeaponSpell() const
Definition SpellInfo.cpp:1321
Unit * m_comboTarget
Definition Spell.h:557
int8 m_comboPointGain
Definition Spell.h:558
GameObject * gameObjTarget
Definition Spell.h:677
bool m_referencedFromCurrentSpell
Definition Spell.h:668
bool m_canReflect
Definition Spell.h:644
uint32 m_procVictim
Definition Spell.h:703
Unit * m_originalCaster
Definition Spell.h:630
bool m_needComboPoints
Definition Spell.h:670
uint64 m_delayStart
Definition Spell.h:662
bool _scriptsLoaded
Definition Spell.h:754
TriggerCastFlags _triggeredCastFlags
Definition Spell.h:795
int32 damage
Definition Spell.h:679
SpellEffectHandleMode effectHandleMode
Definition Spell.h:680
int32 m_channeledDuration
Definition Spell.h:643
Aura * m_spellAura
Definition Spell.h:685
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition Spell.h:729
uint8 m_delayAtDamageCount
Definition Spell.h:651
WeaponAttackType m_attackType
Definition Spell.h:640
bool m_immediateHandled
Definition Spell.h:665
uint32 m_spellState
Definition Spell.h:791
ObjectGuid m_originalCasterGUID
Definition Spell.h:628
WorldObject *const m_caster
Definition Spell.h:624
void CleanupTargetList()
Definition Spell.cpp:2386
int32 m_timer
Definition Spell.h:792
int32 m_casttime
Definition Spell.h:642
Item * itemTarget
Definition Spell.h:676
uint8 m_cast_count
Definition Spell.h:539
int32 m_damage
Definition Spell.h:695
bool m_executedCurrently
Definition Spell.h:669
DiminishingLevels m_diminishLevel
Definition Spell.h:688
float m_damageMultipliers[3]
Definition Spell.h:672
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition Spell.h:809
uint8 m_auraScaleMask
Definition Spell.h:803
int32 m_damageBeforeTakenMods
Definition Spell.h:697
SpellCustomErrors m_customError
Definition Spell.h:543
uint8 m_spellFlags
Definition Spell.h:646
bool m_skipCheck
Definition Spell.h:802
int32 m_healing
Definition Spell.h:696
uint32 m_glyphIndex
Definition Spell.h:540
uint8 m_channelTargetEffectMask
Definition Spell.h:711
Item * m_weaponItem
Definition Spell.h:537
Unit * unitTarget
Definition Spell.h:675
SpellSchoolMask m_spellSchoolMask
Definition Spell.h:639
Unit * m_reflectionTarget
Definition Spell.h:681
SpellEvent * _spellEvent
Definition Spell.h:794
bool _spellTargetsSelected
Definition Spell.h:807
ObjectGuid m_reflectionTargetGuid
Definition Spell.h:682
uint32 m_preCastSpell
Definition Spell.h:541
WorldLocation * destTarget
Definition Spell.h:678
Spell ** m_selfContainer
Definition Spell.h:634
uint8 m_applyMultiplierMask
Definition Spell.h:671
DiminishingGroup m_diminishGroup
Definition Spell.h:689
uint32 m_procEx
Definition Spell.h:704
Item * m_CastItem
Definition Spell.h:536
SpellValue *const m_spellValue
Definition Spell.h:626
int32 m_powerCost
Definition Spell.h:641
uint32 m_procAttacker
Definition Spell.h:702
GameObject * focusObject
Definition Spell.h:692
SpellInfo const *const m_spellInfo
Definition Spell.h:535
uint8 m_runesState
Definition Spell.h:649
bool m_autoRepeat
Definition Spell.h:648
Unit * GetCharmerOrOwner() const
Definition Unit.h:1291
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, Object::GetGUID(), SpellInfo::GetSchoolMask(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::IsAutoRepeatRangedSpell(), Object::IsInWorld(), SpellInfo::IsPassive(), SpellInfo::IsPositive(), SpellInfo::IsRangedWeaponSpell(), itemTarget, m_applyMultiplierMask, m_attackType, m_auraScaleMask, m_autoRepeat, m_canReflect, m_cast_count, m_caster, m_CastItem, m_casttime, m_channeledDuration, m_channelTargetEffectMask, m_comboPointGain, m_comboTarget, m_customError, m_damage, m_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(), Object::ToUnit(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and unitTarget.

Referenced by Creature::HasSpellFocus().

◆ ~Spell()

Spell::~Spell ( )
737{
738 // FindMap() check: pending spell events are destroyed after the caster has left the map,
739 // where resolving a unit-summoned caster's owner through ObjectAccessor would assert
740 if (Player* modOwner = (m_caster && m_caster->FindMap()) ? m_caster->GetSpellModOwner() : nullptr)
741 if (modOwner->m_spellModTakingSpell == this)
742 modOwner->SetSpellModTakingSpell(this, false);
743
744 // unload scripts
745 while (!m_loadedScripts.empty())
746 {
747 std::list<SpellScript*>::iterator itr = m_loadedScripts.begin();
748 (*itr)->_Unload();
749 delete (*itr);
750 m_loadedScripts.erase(itr);
751 }
752
754 {
755 // Clean the reference to avoid later crash.
756 // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case.
757 LOG_ERROR("spells", "Spell::~Spell: deleting spell for spell ID {}. However, spell still referenced.", m_spellInfo->Id);
758 *m_selfContainer = nullptr;
759 }
760
761 delete m_spellValue;
762
764}
#define LOG_ERROR(filterType__,...)
Definition Log.h:145
uint32 Id
Definition SpellInfo.h:344
void CheckEffectExecuteData()
Definition Spell.cpp:8870
std::list< SpellScript * > m_loadedScripts
Definition Spell.h:769
Map * FindMap() const
Definition Object.h:638
virtual Player * GetSpellModOwner() const
Definition Object.cpp:3351

References CheckEffectExecuteData(), WorldObject::FindMap(), WorldObject::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

3912{
3913 Unit* unitCaster = m_caster->ToUnit();
3914 // update pointers base at GUIDs to prevent access to non-existed already object
3915 if (!UpdatePointers())
3916 {
3917 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3918 cancel();
3919 return;
3920 }
3921
3922 // cancel at lost explicit target during cast
3924 {
3925 cancel();
3926 return;
3927 }
3928
3929 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3931 {
3932 if (unitCaster->IsPlayer() && !m_spellInfo->HasEffect(SPELL_EFFECT_SUMMON_PET))
3933 if (Pet* pet = unitCaster->ToPlayer()->GetPet())
3934 unitCaster->ToPlayer()->RemovePet(pet, PET_SAVE_AS_CURRENT);
3935
3936 if (Unit* charm = unitCaster->GetCharm())
3937 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, unitCaster->GetGUID());
3938 }
3939
3940 if (Player* playerCaster = m_caster->ToPlayer())
3941 {
3942 // now that we've done the basic check, now run the scripts
3943 // should be done before the spell is actually executed
3944 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3945
3946 // As of 3.0.2 pets begin attacking their owner's target immediately
3947 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3948 // This prevents spells such as Hunter's Mark from triggering pet attack
3949 // xinef: take into account SPELL_ATTR3_SUPPRESS_TARGET_PROCS
3951 if (!playerCaster->m_Controlled.empty())
3952 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3953 if (Unit* pet = *itr)
3954 if (pet->IsAlive() && pet->IsCreature())
3955 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3956 }
3957
3959
3961 if (unitCaster && unitCaster->IsCreature() && m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget())
3962 unitCaster->SetInFront(m_targets.GetObjectTarget());
3963
3965
3966 Player* modOwner = m_caster->GetSpellModOwner();
3967 // skip check if done already (for instant cast spells for example)
3968 if (!skipCheck)
3969 {
3970 SpellCastResult castResult = CheckCast(false);
3971 if (castResult != SPELL_CAST_OK)
3972 {
3973 SendCastResult(castResult);
3974 SendInterrupted(0);
3975
3976 finish(false);
3977 SetExecutedCurrently(false);
3978 return;
3979 }
3980
3981 // additional check after cast bar completes (must not be in CheckCast)
3982 // if trade not complete then remember it in trade data
3984 {
3985 if (unitCaster && unitCaster->IsPlayer())
3986 {
3987 if (TradeData* my_trade = unitCaster->ToPlayer()->GetTradeData())
3988 {
3989 if (!my_trade->IsInAcceptProcess())
3990 {
3991 // Spell will be casted at completing the trade. Silently ignore at this place
3992 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
3994 SendInterrupted(0);
3995
3996 finish(false);
3997 SetExecutedCurrently(false);
3998 return;
3999 }
4000 }
4001 }
4002 }
4003 }
4004
4005 if (modOwner)
4006 modOwner->SetSpellModTakingSpell(this, true);
4007
4010
4011 if (modOwner)
4012 modOwner->SetSpellModTakingSpell(this, false);
4013
4014 // Spell may be finished after target map check
4016 {
4017 SendInterrupted(0);
4018 finish(false);
4019 SetExecutedCurrently(false);
4020 return;
4021 }
4022
4023 if (modOwner)
4024 modOwner->SetSpellModTakingSpell(this, true);
4025
4027
4029
4030 if (modOwner)
4031 modOwner->SetSpellModTakingSpell(this, false);
4032
4033 // traded items have trade slot instead of guid in m_itemTargetGUID
4034 // set to real guid to be sent later to the client
4036
4037 if (unitCaster && unitCaster->IsPlayer())
4038 {
4040 {
4043 }
4044
4046 }
4047
4049 {
4050 // Powers have to be taken before SendSpellGo
4051 TakePower();
4052 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
4053 }
4054 else if (Item* targetItem = m_targets.GetItemTarget())
4055 {
4057 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
4058 TakeReagents();
4059 }
4060
4062
4063 // CAST SPELL
4064 if (modOwner)
4065 modOwner->SetSpellModTakingSpell(this, true);
4066
4068
4070
4071 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
4072 SendSpellGo();
4073
4074 bool resetAttackTimers = unitCaster && IsAutoActionResetSpell() && !m_spellInfo->HasAttribute(SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS);
4075 if (resetAttackTimers)
4076 {
4078 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
4079 {
4080 if ((*i)->IsAffectedOnSpell(m_spellInfo))
4081 {
4082 resetAttackTimers = false;
4083 break;
4084 }
4085 }
4086 }
4087
4088 // CAST -> HIT -> FINISH ordering: fire CAST before handle_immediate so an aura
4089 // applied during HIT (e.g. Arcane Potency from Clearcasting) isn't consumed by
4090 // the same cast. Triggered spells skip this so periodic ticks (Blizzard etc.)
4091 // don't burn cast-charge buffs.
4092 if (m_originalCaster && !IsTriggered())
4093 {
4094 uint32 procAttacker = m_procAttacker;
4095 if (!procAttacker)
4096 {
4097 bool IsPositive = m_spellInfo->IsPositive();
4099 {
4101 }
4102 else
4103 {
4105 }
4106 }
4107
4108 uint32 hitMask = PROC_HIT_NORMAL;
4109
4110 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4111 {
4112 if (ihit->missCondition != SPELL_MISS_NONE)
4113 continue;
4114
4115 if (!ihit->crit)
4116 continue;
4117
4118 hitMask |= PROC_HIT_CRITICAL;
4119 break;
4120 }
4121
4124 }
4125
4126 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
4127 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
4128 {
4129 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4130 // in case delayed spell remove item at cast delay start
4131 TakeCastItem();
4132
4133 // Okay, maps created, now prepare flags
4134 m_immediateHandled = false;
4136 SetDelayStart(0);
4137
4138 if (unitCaster && unitCaster->HasUnitState(UNIT_STATE_CASTING) && !unitCaster->IsNonMeleeSpellCast(false, false, true))
4140
4141 // remove all applied mods at this point
4142 // dont allow user to use them twice in case spell did not reach current target
4143 if (modOwner)
4144 modOwner->RemoveSpellMods(this);
4145
4146 // Xinef: why do we keep focus after spell is sent to air?
4147 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
4148 // Xinef: we get focused to it out of nowhere...
4149 if (Creature* creatureCaster = unitCaster ? unitCaster->ToCreature() : nullptr)
4150 creatureCaster->ReleaseFocus(this);
4151 }
4152 else
4153 {
4154 // Immediate spell, no big deal
4156 }
4157
4158 if (resetAttackTimers)
4159 {
4160 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4161 {
4162 resetAttackTimers = false;
4163 }
4164
4165 if (resetAttackTimers)
4166 {
4167 unitCaster->resetAttackTimer(BASE_ATTACK);
4168
4169 if (unitCaster->HasOffhandWeaponForAttack())
4170 {
4171 unitCaster->resetAttackTimer(OFF_ATTACK);
4172 }
4173
4174 unitCaster->resetAttackTimer(RANGED_ATTACK);
4175 }
4176 }
4177
4179
4180 if (modOwner)
4181 modOwner->SetSpellModTakingSpell(this, false);
4182
4183 if (std::vector<int32> const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4184 {
4185 for (int32 id : *spell_triggered)
4186 {
4187 if (id < 0)
4188 {
4189 if (unitCaster)
4190 unitCaster->RemoveAurasDueToSpell(-id);
4191 }
4192 else
4194 }
4195 }
4196
4197 // Interrupt Spell casting
4198 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4200 if (Unit* target = m_targets.GetUnitTarget())
4201 if (target->IsCreature())
4202 m_caster->CastSpell(target, 32747, true);
4203
4204 if (unitCaster && unitCaster->IsPlayer())
4205 if (unitCaster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN))
4206 unitCaster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
4207
4208 sScriptMgr->OnSpellCast(this, unitCaster, m_spellInfo, skipCheck);
4209
4210 SetExecutedCurrently(false);
4211
4212 // Call CreatureAI hook on successful cast
4213 if (Creature* caster = unitCaster ? unitCaster->ToCreature() : nullptr)
4214 if (caster->IsAIEnabled)
4215 caster->AI()->OnSpellCast(GetSpellInfo());
4216}
@ 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:766
@ 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:144
@ TRIGGERED_IGNORE_CAST_ITEM
Will ignore power and reagent cost.
Definition SpellDefines.h:145
@ TRIGGERED_IGNORE_SET_FACING
Will ignore interruptible aura's at cast.
Definition SpellDefines.h:151
@ 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
bool IsPlayer() const
Definition Object.h:207
uint32 GetEntry() const
Definition Object.h:123
bool IsCreature() const
Definition Object.h:211
Creature * ToCreature()
Definition Object.h:212
Definition Pet.h:41
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1=0, uint32 miscValue2=0, Unit *unit=nullptr)
Definition PlayerUpdates.cpp:2236
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition Player.cpp:10264
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition Player.cpp:14266
void RemoveSpellMods(Spell *spell)
Definition Player.cpp:10202
Pet * GetPet() const
Definition Player.cpp:9149
bool GetCommandStatus(uint32 command) const
Definition Player.h:1202
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:9299
TradeData * GetTradeData() const
Definition Player.h:1400
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition Player.cpp:3695
WorldObject * GetObjectTarget() const
Definition Spell.cpp:348
void UpdateTradeSlotItem()
Definition Spell.cpp:385
ObjectGuid GetObjectTargetGUID() const
Definition Spell.cpp:353
Item * GetItemTarget() const
Definition Spell.h:151
uint32 GetTargetMask() const
Definition Spell.h:129
Unit * GetUnitTarget() const
Definition Spell.cpp:269
uint32 CalcCastTime(WorldObject *caster=nullptr, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2778
float Speed
Definition SpellInfo.h:394
bool IsChanneled() const
Definition SpellInfo.cpp:1301
SpellInfo const * GetSpellInfo() const
Definition Spell.h:596
void CallScriptAfterCastHandlers()
Definition Spell.cpp:8924
void PrepareTriggersExecutedOnHit()
Definition Spell.cpp:9130
bool HasTriggeredCastFlag(TriggerCastFlags flag) const
Definition Spell.h:569
SpellCastTargets m_targets
Definition Spell.h:542
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition Spell.h:800
void handle_immediate()
Definition Spell.cpp:4218
void SendSpellGo()
Definition Spell.cpp:4946
void TakeReagents()
Definition Spell.cpp:5715
void SetExecutedCurrently(bool yes)
Definition Spell.h:578
void SendInterrupted(uint8 result)
Definition Spell.cpp:5325
void PrepareScriptHitHandlers()
Definition Spell.cpp:8956
void CallScriptOnCastHandlers()
Definition Spell.cpp:8911
void cancel(bool bySelf=false)
Definition Spell.cpp:3809
void SendSpellCooldown()
Definition Spell.cpp:4475
void CallScriptBeforeCastHandlers()
Definition Spell.cpp:8898
void HandleLaunchPhase()
Definition Spell.cpp:8582
bool UpdatePointers()
Definition Spell.cpp:8202
void SetDelayStart(uint64 m_time)
Definition Spell.h:580
std::list< TargetInfo > m_UniqueTargetInfo
Definition Spell.h:710
void SelectSpellTargets()
Definition Spell.cpp:869
void TakePower()
Definition Spell.cpp:5482
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition Spell.cpp:4809
bool IsTriggered() const
Definition Spell.h:568
void TakeCastItem()
Definition Spell.cpp:5415
SpellCastResult CheckCast(bool strict, uint32 *param1=nullptr, uint32 *param2=nullptr)
Definition Spell.cpp:5849
bool IsAutoActionResetSpell() const
Definition Spell.cpp:8418
void finish(bool ok=true)
Definition Spell.cpp:4612
Definition TradeData.h:36
Definition Unit.h:665
bool HasOffhandWeaponForAttack() const
Definition Unit.h:996
void ClearUnitState(uint32 f)
Definition Unit.h:738
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1433
Unit * GetCharm() const
Definition Unit.cpp:7558
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:4017
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4936
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:6554
bool HasUnitState(const uint32 f) const
Definition Unit.h:737
void SetInFront(WorldObject const *target)
Definition Unit.cpp:16062
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition Unit.cpp:769
Definition Object.h:482
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={})
Definition Object.cpp:3271
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(), WorldObject::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(), WorldObject::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(), Object::ToUnit(), 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 ( )
4395{
4396 Unit* unitCaster = m_caster->ToUnit();
4397 if (!unitCaster)
4398 return;
4399
4400 // Take for real after all targets are processed
4402 {
4403 unitCaster->ClearComboPoints();
4404 }
4405
4406 // Real add combo points from effects
4408 {
4409 // remove Premed-like effects unless they were caused by ourselves
4410 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4412 {
4414 }
4415
4417 }
4418
4420 {
4422 }
4423
4425 if (unitCaster->GetCharmerOrOwnerPlayerOrPlayerItself())
4426 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4427 {
4428 // Xinef: Properly clear infinite cooldowns in some cases
4429 if (ihit->targetGUID == unitCaster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4430 if (unitCaster->IsPlayer() && m_spellInfo->IsCooldownStartedOnEvent())
4431 unitCaster->ToPlayer()->SendCooldownEvent(m_spellInfo);
4432 }
4433
4434 // Handle procs on finish
4435 if (m_originalCaster)
4436 {
4437 uint32 procAttacker = m_procAttacker;
4438 if (!procAttacker)
4439 {
4440 bool IsPositive = m_spellInfo->IsPositive();
4442 {
4444 }
4445 else
4446 {
4448 }
4449 }
4450
4451 uint32 hitMask = PROC_HIT_NORMAL;
4452 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4453 {
4454 if (ihit->missCondition != SPELL_MISS_NONE)
4455 continue;
4456
4457 if (!ihit->crit)
4458 continue;
4459
4460 hitMask |= PROC_HIT_CRITICAL;
4461 break;
4462 }
4463
4464 // For trap activation, pass the original target (trap triggerer) so proc trigger spells
4465 // like Entrapment can find a valid target to cast on
4466 Unit* finishVictim = nullptr;
4467 if (procAttacker & PROC_FLAG_DONE_TRAP_ACTIVATION)
4468 finishVictim = GetOriginalTarget();
4469
4472 }
4473}
@ 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:11287
bool IsCooldownStartedOnEvent() const
Definition SpellInfo.cpp:1257
bool HasAura(AuraType aura) const
Definition SpellInfo.cpp:906
bool IsAutoRepeat() const
Definition Spell.h:563
Unit * GetOriginalTarget() const
Definition Spell.cpp:8197
bool IsNextMeleeSwingSpell() const
Definition Spell.cpp:8408
void SetLastExtraAttackSpell(uint32 spellId)
Definition Unit.h:1015
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Unit.cpp:7503
void ClearComboPoints()
Definition Unit.cpp:12869
void AddComboPoints(Unit *target, int8 count)
Definition Unit.cpp:12843
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition Unit.cpp:5144

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, Object::ToPlayer(), and Object::ToUnit().

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4367{
4368 m_spellAura = nullptr;
4369 // initialize Diminishing Returns Data
4372
4373 // handle some immediate features of the spell here
4375
4377
4378 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4379 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4380 {
4381 // don't do anything for empty effect
4382 if (!m_spellInfo->Effects[j].IsEffect())
4383 continue;
4384
4385 // call effect handlers to handle destination hit
4386 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4387 }
4388
4389 // process items
4390 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4391 DoAllEffectOnTarget(&(*ihit));
4392}
@ SPELL_EFFECT_HANDLE_HIT
Definition Spell.h:248
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition SpellInfo.h:417
void HandleThreatSpells()
Definition Spell.cpp:5768
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition Spell.cpp:5823
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition Spell.h:727
void DoAllEffectOnTarget(TargetInfo *target)
Definition Spell.cpp:2627

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
2623{
2624 m_destTargets[effIndex] = dest;
2625}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject *  target,
uint32  effectMask 
)
protected
2532{
2533 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2534 {
2535 if (!m_spellInfo->Effects[effIndex].IsEffect())
2536 effectMask &= ~(1 << effIndex);
2537 else
2538 {
2539 switch (m_spellInfo->Effects[effIndex].Effect)
2540 {
2544 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2545 effectMask &= ~(1 << effIndex);
2546 break;
2547 default:
2548 break;
2549 }
2550 }
2551 }
2552
2553 if (!effectMask)
2554 return;
2555
2556 ObjectGuid targetGUID = go->GetGUID();
2557
2558 // Lookup target in already in list
2559 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2560 {
2561 if (targetGUID == ihit->targetGUID) // Found in list
2562 {
2563 ihit->effectMask |= effectMask; // Add only effect mask
2564 return;
2565 }
2566 }
2567
2568 // This is new target calculate data for him
2569
2570 GOTargetInfo target;
2571 target.targetGUID = targetGUID;
2572 target.effectMask = effectMask;
2573 target.processed = false; // Effects not apply on target
2574
2575 // Spell have speed - need calculate incoming time
2576 if (m_spellInfo->Speed > 0.0f)
2577 {
2578 // calculate spell incoming interval
2579 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2580 if (dist < 5.0f)
2581 dist = 5.0f;
2582 target.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
2583 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2584 m_delayMoment = target.timeDelay;
2585 }
2586 else
2587 target.timeDelay = 0LL;
2588
2589 // Add target to list
2590 m_UniqueGOTargetInfo.push_back(target);
2591}
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:663
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition Spell.h:720
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:1304

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
2594{
2595 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2596 if (!m_spellInfo->Effects[effIndex].IsEffect())
2597 effectMask &= ~(1 << effIndex);
2598
2599 // no effects left
2600 if (!effectMask)
2601 return;
2602
2603 // Lookup target in already in list
2604 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2605 {
2606 if (item == ihit->item) // Found in list
2607 {
2608 ihit->effectMask |= effectMask; // Add only effect mask
2609 return;
2610 }
2611 }
2612
2613 // This is new target add data
2614
2615 ItemTargetInfo target;
2616 target.item = item;
2617 target.effectMask = effectMask;
2618
2619 m_UniqueItemInfo.push_back(target);
2620}

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)
2396{
2397 Unit* unitCaster = m_caster->ToUnit();
2398 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2399 if (!m_spellInfo->Effects[effIndex].IsEffect() || !CheckEffectTarget(target, effIndex))
2400 effectMask &= ~(1 << effIndex);
2401
2402 // no effects left
2403 if (!effectMask)
2404 return;
2405
2406 if (checkIfValid)
2407 {
2408 SpellCastResult res = m_spellInfo->CheckTarget(m_caster, target, implicit);
2409 if (res != SPELL_CAST_OK)
2410 return;
2411 }
2412
2413 // Check for effect immune skip if immuned
2414 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2415 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex, unitCaster))
2416 effectMask &= ~(1 << effIndex);
2417
2418 ObjectGuid targetGUID = target->GetGUID();
2419
2420 // Lookup target in already in list
2421 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2422 {
2423 if (targetGUID == ihit->targetGUID) // Found in list
2424 {
2425 ihit->effectMask |= effectMask; // Immune effects removed from mask
2426 ihit->scaleAura = false;
2427 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2428 {
2429 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2430 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2431 ihit->scaleAura = true;
2432 }
2433
2434 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2435 return;
2436 }
2437 }
2438
2439 // This is new target calculate data for him
2440
2441 // Get spell hit result on target
2442 TargetInfo targetInfo;
2443 targetInfo.targetGUID = targetGUID; // Store target GUID
2444 targetInfo.effectMask = effectMask; // Store all effects not immune
2445 targetInfo.processed = false; // Effects not apply on target
2446 targetInfo.alive = target->IsAlive();
2447 targetInfo.damage = 0;
2448 targetInfo.damageBeforeTakenMods = 0;
2449 targetInfo.crit = false;
2450 targetInfo.scaleAura = false;
2451 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2452 {
2453 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2454 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2455 targetInfo.scaleAura = true;
2456 }
2457
2458 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2459
2460 // Calculate hit result
2461 if (m_originalCaster)
2462 {
2463 targetInfo.missCondition = m_originalCaster->SpellHitResult(target, this, m_canReflect);
2464 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2465 {
2466 targetInfo.missCondition = SPELL_MISS_NONE;
2467 }
2468 }
2469 else
2470 targetInfo.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
2471
2472 // Spell have speed - need calculate incoming time
2473 // Incoming time is zero for self casts. At least I think so.
2474 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2475 {
2476 // calculate spell incoming interval
2478 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2479
2480 if (dist < 5.0f)
2481 dist = 5.0f;
2482 targetInfo.timeDelay = (uint64) std::floor(dist / m_spellInfo->Speed * 1000.0f);
2483
2484 // Calculate minimum incoming time
2485 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2486 m_delayMoment = targetInfo.timeDelay;
2487 }
2488 else
2489 targetInfo.timeDelay = 0LL;
2490
2491 // If target reflect spell back to caster
2492 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2493 {
2494 // Calculate reflected spell result on caster
2495 targetInfo.reflectResult = unitCaster ? unitCaster->SpellHitResult(unitCaster, this, m_canReflect) : SPELL_MISS_NONE;
2496
2497 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2498 targetInfo.reflectResult = SPELL_MISS_PARRY;
2499
2500 // Increase time interval for reflected spells by 1.5
2501 if (unitCaster)
2502 unitCaster->m_Events.AddEventAtOffset(new ReflectEvent(unitCaster, targetInfo.targetGUID, m_spellInfo), Milliseconds(targetInfo.timeDelay));
2503 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2504
2506
2507 // HACK: workaround check for succubus seduction case
2509 if (unitCaster && unitCaster->IsPet())
2510 {
2511 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(unitCaster->GetEntry());
2512 switch (ci->family)
2513 {
2515 {
2516 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2517 cancel();
2518 }
2519 break;
2520 return;
2521 }
2522 }
2523 }
2524 else
2525 targetInfo.reflectResult = SPELL_MISS_NONE;
2526
2527 // Add target to list
2528 m_UniqueTargetInfo.push_back(targetInfo);
2529}
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:27
#define sObjectMgr
Definition ObjectMgr.h:1731
@ 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:868
Definition SpellInfo.h:340
uint32 SpellLevel
Definition SpellInfo.h:384
SpellInfo const * GetFirstRankSpell() const
Definition SpellInfo.cpp:2934
SpellCastResult CheckTarget(WorldObject const *caster, WorldObject const *target, bool implicit=true) const
Definition SpellInfo.cpp:1677
uint32 SpellIconID
Definition SpellInfo.h:404
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition Spell.cpp:8265
bool IsPet() const
Definition Unit.h:798
bool IsAlive() const
Definition Unit.h:1796
uint8 GetLevel() const
Definition Unit.h:1109
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index, WorldObject const *caster=nullptr) const
Definition Unit.cpp:9859
EventProcessor m_Events
Definition Object.h:749
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spellInfo, bool canReflect=false)
Definition Object.cpp:3682
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, WorldObject::SpellHitResult(), SpellInfo::SpellIconID, SpellInfo::SpellLevel, sScriptMgr, TargetInfo::targetGUID, TargetInfo::timeDelay, and Object::ToUnit().

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

◆ CalculateDelayMomentForDst()

uint64 Spell::CalculateDelayMomentForDst ( ) const
950{
951 if (m_targets.HasDst())
952 {
953 if (m_targets.HasTraj())
954 {
955 float speed = m_targets.GetSpeedXY();
956 if (speed > 0.0f)
957 return (uint64)std::floor(m_targets.GetDist2d() / speed * 1000.0f);
958 }
959 else if (m_spellInfo->Speed > 0.0f)
960 {
961 // We should not subtract caster size from dist calculation (fixes execution time desync with animation on client, eg. Malleable Goo cast by PP)
962 float dist = m_caster->GetExactDist(*m_targets.GetDstPos());
963 return (uint64)std::floor(dist / m_spellInfo->Speed * 1000.0f);
964 }
965 }
966
967 return 0;
968}
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:438
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
1226{
1227 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1228 ASSERT(unitCaster);
1229 float runSpeed = unitCaster->IsControlledByPlayer() ? playerBaseMoveSpeed[MOVE_RUN] : baseMoveSpeed[MOVE_RUN];
1230 if (Creature* creature = unitCaster->ToCreature())
1231 runSpeed *= creature->GetCreatureTemplate()->speed_run;
1232
1233 float multiplier = m_spellInfo->Effects[i].ValueMultiplier;
1234 if (multiplier <= 0.0f)
1235 multiplier = 1.0f;
1236
1237 speedXY = std::min(runSpeed * 3.0f * multiplier, std::max(28.0f, unitCaster->GetSpeed(MOVE_RUN) * 4.0f));
1238
1239 float duration = dist / speedXY;
1240 float durationSqr = duration * duration;
1241 float minHeight = m_spellInfo->Effects[i].MiscValue ? m_spellInfo->Effects[i].MiscValue / 10.0f : 0.5f; // Lower bound is blizzlike
1242 float maxHeight = m_spellInfo->Effects[i].MiscValueB ? m_spellInfo->Effects[i].MiscValueB / 10.0f : 1000.0f; // Upper bound is unknown
1243 float height;
1244 if (durationSqr < minHeight * 8 / Movement::gravity)
1245 height = minHeight;
1246 else if (durationSqr > maxHeight * 8 / Movement::gravity)
1247 height = maxHeight;
1248 else
1249 height = Movement::gravity * durationSqr / 8;
1250
1251 speedZ = std::sqrt(2 * Movement::gravity * height);
1252}
#define ASSERT
Definition Errors.h:68
@ MOVE_RUN
Definition UnitDefines.h:357
float baseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:80
float playerBaseMoveSpeed[MAX_MOVE_TYPE]
Definition Unit.cpp:93
Unit * GetUnitCasterForEffectHandlers() const
Definition Spell.cpp:8461
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:11047
bool IsControlledByPlayer() const
Definition Unit.h:1312
double gravity
Definition MovementUtil.cpp:24

References ASSERT, baseMoveSpeed, SpellInfo::Effects, Unit::GetSpeed(), GetUnitCasterForEffectHandlers(), Movement::gravity, Unit::IsControlledByPlayer(), 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 Object.cpp:3371
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition Spell.h:225

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

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

◆ CallScriptAfterCastHandlers()

void Spell::CallScriptAfterCastHandlers ( )
protected
8925{
8926 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8927 {
8928 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8929 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8930 for (; hookItr != hookItrEnd; ++hookItr)
8931 (*hookItr).Call(*scritr);
8932
8933 (*scritr)->_FinishScriptCall();
8934 }
8935}
@ 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
9037{
9038 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
9039 {
9040 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
9041 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
9042 for (; hookItr != hookItrEnd; ++hookItr)
9043 (*hookItr).Call(*scritr);
9044
9045 (*scritr)->_FinishScriptCall();
9046 }
9047}
@ 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
8899{
8900 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8901 {
8902 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8903 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8904 for (; hookItr != hookItrEnd; ++hookItr)
8905 (*hookItr).Call(*scritr);
8906
8907 (*scritr)->_FinishScriptCall();
8908 }
8909}
@ 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
9011{
9012 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
9013 {
9014 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
9015 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
9016 for (; hookItr != hookItrEnd; ++hookItr)
9017 (*hookItr).Call(*scritr, missInfo);
9018
9019 (*scritr)->_FinishScriptCall();
9020 }
9021}
@ 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
8938{
8940 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8941 {
8942 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8943 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8944 for (; hookItr != hookItrEnd; ++hookItr)
8945 {
8946 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8947 if (retVal == SPELL_CAST_OK)
8948 retVal = tempResult;
8949 }
8950
8951 (*scritr)->_FinishScriptCall();
8952 }
8953 return retVal;
8954}
@ 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
9078{
9079 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
9080 {
9081 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
9082 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
9083 for (; hookItr != hookItrEnd; ++hookItr)
9084 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
9085 hookItr->Call(*scritr, target);
9086
9087 (*scritr)->_FinishScriptCall();
9088 }
9089}
@ 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
8963{
8964 // execute script effect handler hooks and check if effects was prevented
8965 bool preventDefault = false;
8966 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8967 {
8968 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
8969 SpellScriptHookType hookType;
8970 switch (mode)
8971 {
8973 effItr = (*scritr)->OnEffectLaunch.begin();
8974 effEndItr = (*scritr)->OnEffectLaunch.end();
8976 break;
8978 effItr = (*scritr)->OnEffectLaunchTarget.begin();
8979 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
8981 break;
8983 effItr = (*scritr)->OnEffectHit.begin();
8984 effEndItr = (*scritr)->OnEffectHit.end();
8986 break;
8988 effItr = (*scritr)->OnEffectHitTarget.begin();
8989 effEndItr = (*scritr)->OnEffectHitTarget.end();
8991 break;
8992 default:
8993 ABORT();
8994 return false;
8995 }
8996 (*scritr)->_PrepareScriptCall(hookType);
8997 for (; effItr != effEndItr; ++effItr)
8998 // effect execution can be prevented
8999 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
9000 (*effItr).Call(*scritr, effIndex);
9001
9002 if (!preventDefault)
9003 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
9004
9005 (*scritr)->_FinishScriptCall();
9006 }
9007 return preventDefault;
9008}
#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
9050{
9051 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
9052 {
9053 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
9054 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
9055 for (; hookItr != hookItrEnd; ++hookItr)
9056 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
9057 hookItr->Call(*scritr, targets);
9058
9059 (*scritr)->_FinishScriptCall();
9060 }
9061}
@ 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
9064{
9065 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
9066 {
9067 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
9068 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
9069 for (; hookItr != hookItrEnd; ++hookItr)
9070 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
9071 hookItr->Call(*scritr, target);
9072
9073 (*scritr)->_FinishScriptCall();
9074 }
9075}
@ 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
8912{
8913 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8914 {
8915 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8916 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8917 for (; hookItr != hookItrEnd; ++hookItr)
8918 (*hookItr).Call(*scritr);
8919
8920 (*scritr)->_FinishScriptCall();
8921 }
8922}
@ 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
9024{
9025 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
9026 {
9027 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
9028 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
9029 for (; hookItr != hookItrEnd; ++hookItr)
9030 (*hookItr).Call(*scritr);
9031
9032 (*scritr)->_FinishScriptCall();
9033 }
9034}
@ 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)
7283{
7284 ObjectGuid targetguid = target->GetGUID();
7285
7286 for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
7287 {
7288 if (!spellEffectInfo.IsAura())
7289 continue;
7290
7291 AuraType const& auraType = spellEffectInfo.ApplyAuraName;
7292 Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(auraType);
7293 for (Unit::AuraEffectList::const_iterator auraIt = auras.begin(); auraIt != auras.end(); ++auraIt)
7294 {
7295 if (GetSpellInfo()->Id == (*auraIt)->GetSpellInfo()->Id)
7296 return false;
7297
7298 switch (sSpellMgr->CheckSpellGroupStackRules(GetSpellInfo(), (*auraIt)->GetSpellInfo()))
7299 {
7301 return false;
7303 if (GetCaster() == (*auraIt)->GetCaster())
7304 return false;
7305 break;
7306 case SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT: // this one has further checks, but i don't think they're necessary for autocast logic
7308 if (abs(spellEffectInfo.BasePoints) <= abs((*auraIt)->GetAmount()))
7309 return false;
7310 break;
7312 default:
7313 break;
7314 }
7315 }
7316 }
7317
7318 SpellCastResult result = CheckPetCast(target);
7319
7320 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7321 {
7323 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7324 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7325 if (ihit->targetGUID == targetguid)
7326 return true;
7327 }
7328 return false; //target invalid
7329}
@ 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
WorldObject * GetCaster() const
Definition Spell.h:590
SpellCastResult CheckPetCast(Unit *target)
Definition Spell.cpp:7085

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)
3810{
3811 Unit* unitCaster = m_caster->ToUnit();
3813 return;
3814
3815 uint32 oldState = m_spellState;
3817
3818 m_autoRepeat = false;
3819 switch (oldState)
3820 {
3824
3825 if (unitCaster && unitCaster->IsPlayer())
3826 {
3827 if (unitCaster->ToPlayer()->NeedSendSpectatorData())
3828 ArenaSpectator::SendCommand_Spell(unitCaster->FindMap(), unitCaster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3829 }
3830 [[fallthrough]];
3833 break;
3835 if (!bySelf)
3836 {
3837 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3838 if ((*ihit).missCondition == SPELL_MISS_NONE)
3839 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? unitCaster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3840 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3841
3842 if (unitCaster && unitCaster->IsPlayer() && m_spellInfo->IsCooldownStartedOnEvent())
3843 unitCaster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
3844
3847 }
3848
3849 if (unitCaster && unitCaster->IsPlayer() && unitCaster->ToPlayer()->NeedSendSpectatorData())
3850 ArenaSpectator::SendCommand_Spell(unitCaster->FindMap(), unitCaster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3851
3852 // spell is canceled-take mods and clear list
3853 if (Player* player = m_caster->GetSpellModOwner())
3854 player->RemoveSpellMods(this);
3855
3856 m_appliedMods.clear();
3857 break;
3858 default:
3859 break;
3860 }
3861
3863 if (m_selfContainer && *m_selfContainer == this)
3864 *m_selfContainer = nullptr;
3865
3866 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3868 {
3869 if (unitCaster)
3870 unitCaster->RemoveDynObject(m_spellInfo->Id);
3871 }
3872
3873 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3874 {
3875 if (unitCaster)
3876 {
3877 if (GameObject* gameObject = unitCaster->GetGameObject(m_spellInfo->Id))
3878 {
3879 unitCaster->RemoveGameObject(gameObject, true);
3880 if (gameObject->GetGoType() == GAMEOBJECT_TYPE_SUMMONING_RITUAL && unitCaster->IsPlayer())
3881 unitCaster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
3882 }
3883 }
3884 }
3885
3886 //set state back so finish will be processed
3887 m_spellState = oldState;
3888
3889 sScriptMgr->OnSpellCastCancel(this, unitCaster, m_spellInfo, bySelf);
3890
3891 finish(false);
3892}
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
Definition SharedDefines.h:1582
@ 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
Definition GameObject.h:120
bool NeedSendSpectatorData() const
Definition Player.cpp:15845
void SendChannelUpdate(uint32 time)
Definition Spell.cpp:5342
void CancelGlobalCooldown()
Definition Spell.cpp:9277
void SetReferencedFromCurrent(bool yes)
Definition Spell.h:576
UsedSpellMods m_appliedMods
Definition Spell.h:560
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:6348
GameObject * GetGameObject(uint32 spellId) const
Definition Unit.cpp:6320
bool RemoveDynObject(uint32 spellId)
Definition Unit.cpp:6292
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(), GAMEOBJECT_TYPE_SUMMONING_RITUAL, Unit::GetGameObject(), Object::GetGUID(), WorldObject::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, Object::ToPlayer(), and Object::ToUnit().

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

◆ CancelGlobalCooldown()

void Spell::CancelGlobalCooldown ( )
protected
9278{
9279 Unit* unitCaster = m_caster->ToUnit();
9280 if (!unitCaster)
9281 return;
9282
9284 return;
9285
9286 // Cancel global cooldown when interrupting current cast
9287 if (unitCaster->GetCurrentSpell(CURRENT_GENERIC_SPELL) != this)
9288 return;
9289
9290 // Only players or controlled units have global cooldown
9291 if (unitCaster->GetCharmInfo())
9293 else if (unitCaster->IsPlayer())
9295}
@ CURRENT_GENERIC_SPELL
Definition Unit.h:557
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition CharmInfo.cpp:424
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition Player.h:1832
uint32 StartRecoveryTime
Definition SpellInfo.h:375
CharmInfo * GetCharmInfo()
Definition Unit.h:1286
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:1581
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, Object::ToPlayer(), and Object::ToUnit().

Referenced by cancel().

◆ CanExecuteTriggersOnHit()

bool Spell::CanExecuteTriggersOnHit ( uint8  effMask,
SpellInfo const *  triggeredByAura = nullptr 
) const
protected
9115{
9116 // Relentless strikes, proc only from first effect
9117 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
9118 return effMask & (1 << EFFECT_0);
9119
9120 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
9121 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
9122 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
9123 {
9124 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
9125 return true;
9126 }
9127 return effMask;
9128}
@ 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
8729{
8730 Unit* unitCaster = m_caster->ToUnit();
8731 if (!lockId) // possible case for GO and maybe for items.
8732 return SPELL_CAST_OK;
8733
8734 // Get LockInfo
8735 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8736
8737 if (!lockInfo)
8739
8740 bool reqKey = false; // some locks not have reqs
8741
8742 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8743 {
8744 switch (lockInfo->Type[j])
8745 {
8746 // check key item (many fit cases can be)
8747 case LOCK_KEY_ITEM:
8748 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8749 return SPELL_CAST_OK;
8750 reqKey = true;
8751 break;
8752 // check key skill (only single first fit case can be)
8753 case LOCK_KEY_SKILL:
8754 {
8755 reqKey = true;
8756
8757 // wrong locktype, skip
8758 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8759 continue;
8760
8761 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8762
8763 if (skillId != SKILL_NONE)
8764 {
8765 reqSkillValue = lockInfo->Skill[j];
8766
8767 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8768 skillValue = m_CastItem || !unitCaster || !unitCaster->IsPlayer() ?
8769 0 : unitCaster->ToPlayer()->GetSkillValue(skillId);
8770
8771 // skill bonus provided by casting spell (mostly item spells)
8772 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8773 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8775 {
8776 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8777 }
8778
8779 if (skillValue < reqSkillValue)
8781 }
8782
8783 return SPELL_CAST_OK;
8784 }
8785 case LOCK_KEY_SPELL:
8786 {
8787 if (m_spellInfo->Id == lockInfo->Index[j])
8788 {
8789 return SPELL_CAST_OK;
8790 }
8791 reqKey = true;
8792 break;
8793 }
8794 }
8795 }
8796
8797 if (reqKey)
8799
8800 return SPELL_CAST_OK;
8801}
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
#define MAX_LOCK_CASE
Definition DBCStructure.h:1341
@ 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:5622
bool IsAbilityOfSkillType(uint32 skillType) const
Definition SpellInfo.cpp:1041
Definition DBCStructure.h:1344
uint32 Type[MAX_LOCK_CASE]
Definition DBCStructure.h:1346
uint32 Index[MAX_LOCK_CASE]
Definition DBCStructure.h:1347
uint32 Skill[MAX_LOCK_CASE]
Definition DBCStructure.h:1348

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(), Object::ToUnit(), and LockEntry::Type.

Referenced by CheckCast(), and EffectOpenLock().

◆ cast()

void Spell::cast ( bool  skipCheck = false)
3895{
3896 Player* modOwner = m_caster->GetSpellModOwner();
3897 Spell* lastMod = nullptr;
3898 if (modOwner)
3899 {
3900 lastMod = modOwner->m_spellModTakingSpell;
3901 if (lastMod)
3902 modOwner->SetSpellModTakingSpell(lastMod, false);
3903 }
3904
3905 _cast(skipCheck);
3906
3907 if (lastMod)
3908 modOwner->SetSpellModTakingSpell(lastMod, true);
3909}
Spell * m_spellModTakingSpell
Definition Player.h:2606
Definition Spell.h:298
void _cast(bool skipCheck)
Definition Spell.cpp:3911

References _cast(), WorldObject::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
5850{
5851 Unit* unitCaster = m_caster->ToUnit();
5852 // check death state
5855
5856 // Spectator check
5857 if (unitCaster && unitCaster->IsPlayer())
5858 if (((Player const*)unitCaster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5859 return SPELL_FAILED_NOT_HERE;
5860
5862
5863 sScriptMgr->OnSpellCheckCast(this, strict, res);
5864
5865 if (res != SPELL_CAST_OK)
5866 return res;
5867
5868 // check cooldowns to prevent cheating
5870 {
5871 if (unitCaster && unitCaster->IsPlayer())
5872 {
5873 //can cast triggered (by aura only?) spells while have this flag
5876
5878 {
5881 else
5883 }
5884
5885 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5888 }
5889 else if (!IsTriggered() && unitCaster && unitCaster->IsCreature() && unitCaster->ToCreature()->IsSpellProhibited(m_spellInfo->GetSchoolMask()))
5891 }
5892
5894 {
5897 }
5898
5899 // Check global cooldown
5902
5903 // only triggered spells can be processed an ended battleground
5904 if (!IsTriggered() && unitCaster && unitCaster->IsPlayer())
5905 if (Battleground* bg = unitCaster->ToPlayer()->GetBattleground())
5906 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5908
5909 if (unitCaster && unitCaster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5910 {
5912 !unitCaster->IsOutdoors())
5914
5916 unitCaster->IsOutdoors())
5918 }
5919
5920 // only check at first call, Stealth auras are already removed at second call
5921 // for now, ignore triggered spells
5922 if (strict && unitCaster && !HasTriggeredCastFlag(TRIGGERED_IGNORE_SHAPESHIFT))
5923 {
5924 bool checkForm = true;
5925 // Ignore form req aura
5927 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5928 {
5929 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5930 continue;
5931 checkForm = false;
5932 break;
5933 }
5934 if (checkForm)
5935 {
5936 // Cannot be used in this stance/form
5937 SpellCastResult shapeError = m_spellInfo->CheckShapeshift(unitCaster->GetShapeshiftForm());
5938 if (shapeError != SPELL_CAST_OK)
5939 return shapeError;
5940
5943 }
5944 }
5945
5946 bool reqCombat = true;
5947 if (unitCaster)
5948 {
5950 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5951 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5953
5955 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5956 {
5957 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5958 {
5959 m_needComboPoints = false;
5960 if ((*j)->GetMiscValue() == 1)
5961 {
5962 reqCombat = false;
5963 break;
5964 }
5965 }
5966 }
5967 }
5968
5969 // caster state requirements
5970 // not for triggered spells (needed by execute)
5972 {
5977
5978 // Note: spell 62473 requres CasterAuraSpell = triggering spell
5979 if (m_spellInfo->CasterAuraSpell && !unitCaster->HasAura(sSpellMgr->GetSpellIdForDifficulty(m_spellInfo->CasterAuraSpell, m_caster)))
5981 if (m_spellInfo->ExcludeCasterAuraSpell && unitCaster->HasAura(sSpellMgr->GetSpellIdForDifficulty(m_spellInfo->ExcludeCasterAuraSpell, m_caster)))
5983
5984 if (reqCombat && unitCaster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
5986 }
5987
5988 // Xinef: exploit protection
5990 {
5991 if (unitCaster && unitCaster->IsPlayer() && unitCaster->GetMap()->IsDungeon())
5992 if (InstanceScript* instanceScript = unitCaster->GetInstanceScript())
5993 if (instanceScript->IsEncounterInProgress())
5994 {
5995 if (Group* group = unitCaster->ToPlayer()->GetGroup())
5996 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
5997 if (Player* member = itr->GetSource())
5998 if (member->IsInMap(unitCaster))
5999 if (Unit* victim = member->GetVictim())
6000 if (victim->IsInCombat() && unitCaster->GetDistance(victim) < unitCaster->GetVisibilityRange())
6001 {
6002 unitCaster->EngageWithTarget(victim);
6003 break;
6004 }
6006 }
6007 }
6008
6009 // cancel autorepeat spells if cast start when moving
6010 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
6011 if (unitCaster && unitCaster->IsPlayer() && unitCaster->ToPlayer()->isMoving() && !IsTriggered())
6012 {
6013 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
6016 return SPELL_FAILED_MOVING;
6017 }
6018
6019 Vehicle* vehicle = unitCaster ? unitCaster->GetVehicle() : nullptr;
6021 {
6022 uint16 checkMask = 0;
6023 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
6024 {
6025 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
6027 {
6028 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
6029 if (shapeShiftEntry && (shapeShiftEntry->flags1 & SHAPESHIFT_FLAG_STANCE) == 0)
6030 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
6031 break;
6032 }
6033 }
6034
6037
6038 if (!checkMask)
6039 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
6040
6041 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
6042 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(unitCaster);
6044 && (vehicleSeat->m_flags & checkMask) != checkMask && unitCaster->IsPlayer())
6046 }
6047
6048 // check spell cast conditions from database
6049 {
6050 ConditionSourceInfo condInfo = ConditionSourceInfo(unitCaster);
6052 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
6053 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
6054 {
6055 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
6056 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
6057 {
6061 }
6062 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
6065 }
6066 }
6067
6068 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
6069 // those spells may have incorrect target entries or not filled at all (for example 15332)
6070 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
6071 // also, such casts shouldn't be sent to client
6072 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
6074 {
6075 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
6076 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
6078 {
6080 if (castResult != SPELL_CAST_OK)
6081 return castResult;
6082 }
6083 }
6084
6085 if (Unit* target = m_targets.GetUnitTarget())
6086 {
6087 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false);
6088 if (castResult != SPELL_CAST_OK)
6089 return castResult;
6090
6091 if (target != unitCaster)
6092 {
6093 // Must be behind the target
6094 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), unitCaster))
6096
6097 // Target must be facing you
6098 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), unitCaster))
6100
6101 if ((!unitCaster || !unitCaster->IsTotem() || !m_spellInfo->IsPositive()) && !m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) &&
6103 {
6104 bool castedByGameobject = false;
6105 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
6107 {
6108 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
6109 }
6110 else if (m_caster->GetEntry() == WORLD_TRIGGER)
6111 {
6112 if (TempSummon* tempSummon = unitCaster ? unitCaster->ToTempSummon() : nullptr)
6113 {
6114 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
6115 }
6116 }
6117
6118 if (castedByGameobject)
6119 {
6120 // If spell casted by gameobject then ignore M2 models
6121 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
6122 }
6123
6125 {
6127 }
6128 }
6129 }
6130 }
6131
6132 // Check for line of sight for spells with dest
6133 if (m_targets.HasDst())
6134 {
6135 float x, y, z;
6136 m_targets.GetDstPos()->GetPosition(x, y, z);
6137
6138 if ((!unitCaster || !unitCaster->IsTotem() || !m_spellInfo->IsPositive()) && !m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) &&
6140 {
6141 bool castedByGameobject = false;
6142 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
6144 {
6145 castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
6146 }
6147 else if (m_caster->GetEntry() == WORLD_TRIGGER)
6148 {
6149 if (TempSummon* tempSummon = unitCaster ? unitCaster->ToTempSummon() : nullptr)
6150 {
6151 castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
6152 }
6153 }
6154
6155 if (castedByGameobject)
6156 {
6157 // If spell casted by gameobject then ignore M2 models
6158 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
6159 }
6160
6162 {
6164 }
6165 }
6166 }
6167
6168 // check pet presence
6169 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
6170 {
6171 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
6172 {
6173 if (!unitCaster || (!unitCaster->GetGuardianPet() && !unitCaster->GetCharm()))
6174 {
6175 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
6177 else
6178 return SPELL_FAILED_NO_PET;
6179 }
6180 break;
6181 }
6182 }
6183 // Spell casted only on battleground
6184 if (m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_BATTLEGROUNDS) && unitCaster && unitCaster->IsPlayer())
6185 if (!unitCaster->ToPlayer()->InBattleground())
6187
6188 // do not allow spells to be cast in arenas
6189 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
6190 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
6193 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
6194 if (mapEntry->IsBattleArena())
6196
6197 // zone check
6198 if (!unitCaster || unitCaster->IsCreature() || !unitCaster->ToPlayer()->IsGameMaster())
6199 {
6200 uint32 zone, area;
6201 m_caster->GetZoneAndAreaId(zone, area);
6202
6204 m_caster->ToPlayer());
6205 if (locRes != SPELL_CAST_OK)
6206 return locRes;
6207 }
6208
6209 // not let players cast spells at mount (and let do it to creatures)
6210 if (unitCaster && unitCaster->IsMounted() && unitCaster->IsPlayer() && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE) &&
6212 {
6213 if (unitCaster->IsInFlight())
6215 else
6217 }
6218
6219 SpellCastResult castResult = SPELL_CAST_OK;
6220
6221 // always (except passive spells) check items (focus object can be required for any type casts)
6222 if (!m_spellInfo->IsPassive())
6223 {
6224 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
6225 castResult = CheckSpellFocus();
6226 if (castResult != SPELL_CAST_OK)
6227 return castResult;
6228
6229 castResult = CheckItems();
6230 if (castResult != SPELL_CAST_OK)
6231 return castResult;
6232 }
6233
6234 // Triggered spells also have range check
6236 castResult = CheckRange(strict);
6237 if (castResult != SPELL_CAST_OK)
6238 return castResult;
6239
6241 {
6242 castResult = CheckPower();
6243 if (castResult != SPELL_CAST_OK)
6244 return castResult;
6245 }
6246
6248 {
6249 return SPELL_CAST_OK;
6250 }
6251
6252 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6254 {
6256 if (castResult != SPELL_CAST_OK)
6257 return castResult;
6258
6259 // 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).
6260 if (unitCaster && m_spellInfo->Mechanic && m_spellInfo->IsSelfCast()
6262 {
6263 auto const& mechanicList = unitCaster->m_spellImmune[IMMUNITY_MECHANIC];
6264 if (mechanicList.count(m_spellInfo->Mechanic) > 0)
6266 }
6267 }
6268
6269 // script hook
6270 castResult = CallScriptCheckCastHandlers();
6271 if (castResult != SPELL_CAST_OK)
6272 return castResult;
6273
6274 bool hasDispellableAura = false;
6275 bool hasNonDispelEffect = false;
6276 uint32 dispelMask = 0;
6277 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6278 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6279 {
6281 {
6282 hasDispellableAura = true;
6283 break;
6284 }
6285
6286 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6287 }
6288 else if (m_spellInfo->Effects[i].IsEffect())
6289 {
6290 hasNonDispelEffect = true;
6291 break;
6292 }
6293
6294 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6295 {
6296 if (Unit* target = m_targets.GetUnitTarget())
6297 {
6298 // Xinef: do not allow to cast on hostile targets in sanctuary
6299 if (unitCaster && !unitCaster->IsFriendlyTo(target))
6300 {
6301 if (unitCaster->IsInSanctuary() || target->IsInSanctuary())
6302 {
6303 // Xinef: fix for duels
6304 Player* player = unitCaster->ToPlayer();
6305 if (!player || !player->duel || target != player->duel->Opponent)
6307 }
6308 }
6309
6310 DispelChargesList dispelList;
6311 target->GetDispellableAuraList(unitCaster, dispelMask, dispelList, m_spellInfo);
6312
6313 if (dispelList.empty())
6315 }
6316 }
6317
6318 uint8 approximateAuraEffectMask = 0;
6319 uint8 nonAuraEffectMask = 0;
6320 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6321 {
6322 // for effects of spells that have only one target
6323 switch (m_spellInfo->Effects[i].Effect)
6324 {
6326 {
6327 if (!unitCaster || !unitCaster->IsPlayer())
6329
6330 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6331 break;
6332
6333 Pet* pet = unitCaster->ToPlayer()->GetPet();
6334
6335 if (!pet)
6336 return SPELL_FAILED_NO_PET;
6337
6338 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6339
6340 if (!learn_spellproto)
6342
6343 if (m_spellInfo->SpellLevel > pet->GetLevel())
6344 return SPELL_FAILED_LOWLEVEL;
6345
6346 break;
6347 }
6349 {
6350 // check target only for unit target case
6352 {
6353 if (!unitCaster || !unitCaster->IsPlayer())
6355
6356 Pet* pet = unitTarget->ToPet();
6357 if (!pet || pet->GetOwner() != unitCaster)
6359
6360 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6361
6362 if (!learn_spellproto)
6364
6365 if (m_spellInfo->SpellLevel > pet->GetLevel())
6366 return SPELL_FAILED_LOWLEVEL;
6367 }
6368 break;
6369 }
6371 {
6372 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6373 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6374 if (unitCaster && unitCaster->HasAura(gp->SpellId))
6376 break;
6377 }
6379 {
6380 if (!unitCaster || !unitCaster->IsPlayer())
6382
6383 Item* foodItem = m_targets.GetItemTarget();
6384 if (!foodItem)
6386
6387 Pet* pet = unitCaster->ToPlayer()->GetPet();
6388
6389 if (!pet)
6390 return SPELL_FAILED_NO_PET;
6391
6392 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6394
6395 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6397
6398 if (unitCaster->IsInCombat() || pet->IsInCombat())
6400
6401 break;
6402 }
6405 {
6406 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6407 if (unitCaster && unitCaster->IsPlayer())
6408 if (Unit* target = m_targets.GetUnitTarget())
6409 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6411 break;
6412 }
6414 {
6415 if (unitCaster && unitCaster->HasUnitState(UNIT_STATE_CHARGING))
6416 {
6418 }
6419
6421 {
6422 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6423 if (strict && unitCaster && unitCaster->IsScriptOverriden(m_spellInfo, 6953))
6424 unitCaster->RemoveMovementImpairingAuras(true);
6425 }
6426 if (unitCaster && unitCaster->HasUnitState(UNIT_STATE_ROOT))
6427 {
6428 // Exception for Master's Call
6429 if (m_spellInfo->Id != 54216)
6430 {
6431 return SPELL_FAILED_ROOTED;
6432 }
6433 }
6434 if (unitCaster && unitCaster->IsPlayer())
6435 if (Unit* target = m_targets.GetUnitTarget())
6436 if (!target->IsAlive())
6438 // Xinef: Pass only explicit unit target spells
6439 // pussywizard:
6440 if (unitCaster && sDisableMgr->IsPathfindingEnabled(unitCaster->FindMap()) && m_spellInfo->NeedsExplicitUnitTarget())
6441 {
6442 Unit* target = m_targets.GetUnitTarget();
6443 if (!target)
6445
6446 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6447 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6449
6450 float objSize = target->GetCombatReach();
6451 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6452
6453 m_preGeneratedPath = std::make_unique<PathGenerator>(unitCaster);
6454 m_preGeneratedPath->SetPathLengthLimit(range);
6455
6456 float destX = target->GetPositionX();
6457 float destY = target->GetPositionY();
6458 float destZ = target->GetPositionZ();
6459 bool cutPath = true;
6460
6461 // first try with raycast, if it fails fall back to normal path
6462 bool result = m_preGeneratedPath->CalculatePath(destX, destY, destZ, false);
6463 bool pathFailed = !result || (m_preGeneratedPath->GetPathType() &
6465
6466 // Targets with an oversized combat reach can stand entirely over unwalkable space
6467 // (e.g. Kologarn) so pathing to their center fails or creates a falling shortcut into the void.
6468 // For these targets, fall back to pathing to the nearest walkable point on the melee ring facing the caster.
6469 if (target->GetCombatReach() > NOMINAL_MELEE_RANGE &&
6470 (pathFailed ||
6471 m_preGeneratedPath->IsInvalidDestinationZ(target) ||
6473 {
6474 float const targetZ = target->GetPositionZ();
6475 float const angle = target->GetAngle(m_caster);
6476 bool foundWalkable = false;
6477
6478 // Find the nearest point along the melee ring facing the caster that has walkable ground.
6479 // For targets standing over a void (e.g. Kologarn), the immediate contact ring (offset 0)
6480 // hangs over the chasm, while solid bridge ground begins slightly further out.
6481 for (float distOffset = 0.0f; distOffset <= NOMINAL_MELEE_RANGE; distOffset += 0.5f)
6482 {
6483 float testX, testY;
6484 target->GetNearPoint2D(m_caster, testX, testY, distOffset, angle);
6485 float groundZ = m_caster->GetMapHeight(testX, testY, targetZ);
6486 if (groundZ > INVALID_HEIGHT && std::abs(groundZ - targetZ) <= 5.0f)
6487 {
6488 destX = testX;
6489 destY = testY;
6490 destZ = groundZ;
6491 m_caster->UpdateAllowedPositionZ(destX, destY, destZ);
6492 foundWalkable = true;
6493 break;
6494 }
6495 }
6496
6497 if (!foundWalkable)
6498 return SPELL_FAILED_NOPATH;
6499
6500 cutPath = false;
6501
6502 result = m_preGeneratedPath->CalculatePath(destX, destY, destZ, false);
6503 pathFailed = !result || (m_preGeneratedPath->GetPathType() &
6505 }
6506
6507 if (pathFailed)
6508 return SPELL_FAILED_NOPATH;
6509 else if (cutPath && m_preGeneratedPath->IsInvalidDestinationZ(target))
6510 return SPELL_FAILED_NOPATH;
6511 else if (!cutPath && std::abs(m_preGeneratedPath->GetActualEndPosition().z - destZ) > 5.0f)
6512 return SPELL_FAILED_NOPATH;
6513
6514 if (cutPath)
6515 {
6516 m_preGeneratedPath->ShortenPathUntilDist(
6517 G3D::Vector3(destX, destY, destZ), objSize);
6518 }
6519 }
6520 if (Player* player = unitCaster ? unitCaster->ToPlayer() : nullptr)
6521 player->SetCanTeleport(true);
6522 break;
6523 }
6525 {
6526 if (!unitCaster || !unitCaster->IsPlayer() || !m_targets.GetUnitTarget() || !m_targets.GetUnitTarget()->IsCreature())
6528
6531
6532 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6533 if (!creature->IsCritter() && !creature->loot.isLooted())
6535
6536 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6537
6538 int32 skillValue = unitCaster->ToPlayer()->GetSkillValue(skill);
6539 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6540 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6541 if (ReqValue > skillValue)
6543
6544 break;
6545 }
6547 {
6548 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6549 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6550 break;
6551
6552 if (!unitCaster || !unitCaster->IsPlayer() // only players can open locks, gather etc.
6553 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6554 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6556
6557 Item* pTempItem = nullptr;
6559 {
6560 if (TradeData* pTrade = unitCaster->ToPlayer()->GetTradeData())
6561 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6562 }
6564 pTempItem = unitCaster->ToPlayer()->GetItemByGuid(m_targets.GetItemTargetGUID());
6565
6566 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6567 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6569 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6571
6572 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6573 if (GameObject* go = m_targets.GetGOTarget())
6574 {
6575 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6576 {
6578 }
6579 }
6580 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6582 {
6583 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6584 {
6585 if (!unitCaster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6587 }
6588 else if (unitCaster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6591 }
6592
6593 // get the lock entry
6594 uint32 lockId = 0;
6595 if (GameObject* go = m_targets.GetGOTarget())
6596 {
6597 lockId = go->GetGOInfo()->GetLockId();
6598 if (!lockId)
6600 }
6601 else if (Item* itm = m_targets.GetItemTarget())
6602 lockId = itm->GetTemplate()->LockID;
6603
6604 SkillType skillId = SKILL_NONE;
6605 int32 reqSkillValue = 0;
6606 int32 skillValue = 0;
6607
6608 // check lock compatibility
6609 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6610 if (res != SPELL_CAST_OK)
6611 return res;
6612
6613 // chance for fail at lockpicking attempt
6614 // second check prevent fail at rechecks
6615 // herbalism and mining cannot fail as of patch 3.1.0
6616 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6617 {
6618 // chance for failure in orange lockpick
6619 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6620 {
6622 }
6623 }
6624 break;
6625 }
6627 {
6628 Unit* unitCaster = m_caster->ToUnit();
6629 if (!unitCaster)
6630 {
6632 }
6633
6634 Creature* pet = unitCaster->GetGuardianPet();
6635 if (pet)
6636 {
6637 if (pet->IsAlive())
6638 {
6640 }
6641 }
6642 else if (Player* playerCaster = unitCaster->ToPlayer())
6643 {
6644 PetStable& petStable = playerCaster->GetOrInitPetStable();
6645 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6646 {
6647 return SPELL_FAILED_NO_PET;
6648 }
6649 }
6650
6651 break;
6652 }
6653 // This is generic summon effect
6655 {
6656 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6657 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6658 break;
6659 switch (SummonProperties->Category)
6660 {
6662 if (unitCaster && unitCaster->GetPetGUID())
6664 [[fallthrough]];
6666 if (unitCaster && unitCaster->GetCharmGUID())
6668 break;
6669 }
6670 break;
6671 }
6673 {
6675 {
6680 }
6681 break;
6682 }
6684 {
6685 Unit* unitCaster = m_caster->ToUnit();
6686 if (!unitCaster)
6688
6690 {
6691 if (unitCaster && unitCaster->GetPetGUID())
6693 if (unitCaster && unitCaster->GetCharmGUID())
6695 }
6696
6697 if (unitCaster && unitCaster->IsPlayer() && unitCaster->IsClass(CLASS_WARLOCK, CLASS_CONTEXT_PET) && strict)
6698 if (Pet* pet = unitCaster->ToPlayer()->GetPet())
6699 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6700
6701 Player* playerCaster = unitCaster ? unitCaster->ToPlayer() : nullptr;
6702 if (playerCaster && playerCaster->GetPetStable())
6703 {
6704 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6705 if (info.first)
6706 {
6707 if (info.first->Type == HUNTER_PET)
6708 {
6709 if (!info.first->Health)
6710 {
6711 playerCaster->SendTameFailure(PET_TAME_DEAD);
6713 }
6714
6715 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6716 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6717 {
6718 // if problem in exotic pet
6719 if (creatureInfo && creatureInfo->IsTameable(true))
6721 else
6723
6725 }
6726 }
6727 }
6728 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6729 {
6732 }
6733 }
6734 break;
6735 }
6737 {
6738 if (!unitCaster || !unitCaster->IsPlayer())
6740 if (!unitCaster || !unitCaster->GetTarget())
6742
6743 Player* target = ObjectAccessor::FindPlayer(unitCaster->ToPlayer()->GetTarget());
6744 if (!target || (!target->IsInSameRaidWith(unitCaster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6746
6747 // Xinef: Implement summon pending error
6748 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6750
6751 // check if our map is dungeon
6752 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6753 if (map->IsDungeon())
6754 {
6755 uint32 mapId = m_caster->GetMap()->GetId();
6756 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6757 /*if (map->IsRaid())
6758 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6759 if (targetBind->perm && targetBind != unitCaster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6760 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6761
6762 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6763 if (!instance)
6765 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6767 }
6768 break;
6769 }
6770 // RETURN HERE
6772 {
6773 if (!unitCaster || !unitCaster->IsPlayer())
6775
6776 Player* playerCaster = unitCaster->ToPlayer();
6777 //
6778 if (!(playerCaster->GetTarget()))
6780
6781 Player* target = ObjectAccessor::FindPlayer(unitCaster->ToPlayer()->GetTarget());
6782
6783 if (!target ||
6784 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6786
6787 // Xinef: Implement summon pending error
6788 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6790
6791 break;
6792 }
6793 case SPELL_EFFECT_LEAP:
6795 {
6796 //Do not allow to cast it before BG starts.
6797 if (unitCaster && unitCaster->IsPlayer())
6798 if (Battleground const* bg = unitCaster->ToPlayer()->GetBattleground())
6799 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6801 break;
6802 }
6804 {
6805 if (!m_targets.GetUnitTarget() || m_targets.GetUnitTarget() == unitCaster)
6807
6808 bool found = false;
6810 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6811 {
6812 if (itr->second->GetBase()->IsPassive())
6813 continue;
6814
6815 if (!itr->second->IsPositive())
6816 continue;
6817
6818 found = true;
6819 break;
6820 }
6821
6822 if (!found)
6824
6825 break;
6826 }
6828 {
6829 if (unitCaster && unitCaster->HasUnitState(UNIT_STATE_ROOT))
6830 {
6831 if (unitCaster && unitCaster->IsPlayer())
6832 return SPELL_FAILED_ROOTED;
6833 else
6835 }
6836 break;
6837 }
6838 // xinef: do not allow to use leaps while rooted
6839 case SPELL_EFFECT_JUMP:
6841 {
6842 if (unitCaster && unitCaster->HasUnitState(UNIT_STATE_ROOT))
6843 return SPELL_FAILED_ROOTED;
6844 break;
6845 }
6847 if (!sScriptMgr->CanSelectSpecTalent(this))
6849 // can't change during already started arena/battleground
6850 if (unitCaster && unitCaster->IsPlayer())
6851 if (Battleground const* bg = unitCaster->ToPlayer()->GetBattleground())
6852 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6854 break;
6855 default:
6856 break;
6857 }
6858
6859 if (m_spellInfo->Effects[i].IsAura())
6860 approximateAuraEffectMask |= 1 << i;
6861 else if (m_spellInfo->Effects[i].IsEffect())
6862 nonAuraEffectMask |= 1 << i;
6863 }
6864
6865 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6866 {
6867 switch (m_spellInfo->Effects[i].ApplyAuraName)
6868 {
6869 case SPELL_AURA_DUMMY:
6870 break;
6872 {
6873 if (!unitCaster || !unitCaster->IsPlayer())
6874 return SPELL_FAILED_NO_PET;
6875
6876 Pet* pet = unitCaster->ToPlayer()->GetPet();
6877 if (!pet)
6878 return SPELL_FAILED_NO_PET;
6879
6880 if (pet->GetCharmerGUID())
6881 return SPELL_FAILED_CHARMED;
6882 break;
6883 }
6887 {
6888 if (unitCaster && unitCaster->GetCharmerGUID())
6889 return SPELL_FAILED_CHARMED;
6890
6891 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6893 {
6894 if (unitCaster && unitCaster->GetPetGUID())
6896
6897 if (unitCaster && unitCaster->GetCharmGUID())
6899 }
6900 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6901 {
6902 if (unitCaster && unitCaster->GetCharmGUID())
6904 }
6905
6906 if (Unit* target = m_targets.GetUnitTarget())
6907 {
6908 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6910
6911 // Allow SPELL_AURA_MOD_POSSESS to work on mounted players,
6912 // but keep the old restriction for everything else.
6913 if (target->IsMounted())
6914 {
6915 if (!(target->IsPlayer() && m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS))
6917 }
6918
6919 if (target->GetCharmerGUID())
6920 return SPELL_FAILED_CHARMED;
6921
6922 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6924
6925 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6927
6928 int32 damage = CalculateSpellDamage(i, target);
6929 if (damage && int32(target->GetLevel()) > damage)
6931 }
6932
6933 break;
6934 }
6935 case SPELL_AURA_MOUNTED:
6936 {
6937 // Disallow casting flying mounts in water
6940
6941 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6942 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6943 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6944 if (it)
6945 allowMount = it->AllowMount;
6946 if (unitCaster && unitCaster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6948
6949 if (unitCaster && unitCaster->IsInDisallowedMountForm())
6951
6952 // xinef: dont allow to cast mounts in specific transforms
6953 if (unitCaster && unitCaster->getTransForm())
6954 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(unitCaster->getTransForm()))
6955 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6956 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6958
6959 break;
6960 }
6962 {
6963 if (!m_targets.GetUnitTarget())
6965
6966 // can be casted at non-friendly unit or own pet/charm
6967 if (unitCaster && unitCaster->IsFriendlyTo(m_targets.GetUnitTarget()))
6969
6970 break;
6971 }
6972 case SPELL_AURA_FLY:
6974 {
6975 // Xinef: added water check
6976 if (unitCaster && unitCaster->IsInWater())
6978
6979 // not allow cast fly spells if not have req. skills (all spells is self target)
6980 // allow always ghost flight spells
6982 {
6983 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
6984 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
6985 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
6986 return SPELL_FAILED_NOT_HERE;
6987 }
6988 break;
6989 }
6991 {
6992 if (m_spellInfo->Effects[i].IsTargetingArea())
6993 break;
6994
6995 if (!unitCaster || !unitCaster->IsPlayer() || m_CastItem)
6996 break;
6997
6998 if (!m_targets.GetUnitTarget())
7000
7003
7004 break;
7005 }
7006 case SPELL_AURA_HOVER:
7007 {
7009 {
7011 }
7012 break;
7013 }
7015 {
7016 if (unitCaster && unitCaster->HasAura(23397)) // Nefarian Class Call (Warrior): Berserk -- Nefertum: I don't really like this but I didn't find another way.
7017 {
7019 }
7020 break;
7021 }
7022 default:
7023 break;
7024 }
7025
7026 // check if target already has the same type, but more powerful aura
7027 if (!nonAuraEffectMask && (approximateAuraEffectMask & (1 << i)) && !m_spellInfo->IsTargetingArea())
7028 if (Unit* target = m_targets.GetUnitTarget())
7029 if (!target->IsHighestExclusiveAuraEffect(m_spellInfo, AuraType(m_spellInfo->Effects[i].ApplyAuraName),
7030 m_spellInfo->Effects[i].CalcValue(m_caster, &m_spellValue->EffectBasePoints[i]), approximateAuraEffectMask, false))
7032 }
7033
7034 // check trade slot case (last, for allow catch any another cast problems)
7036 {
7037 if (m_CastItem)
7039
7040 if (!unitCaster || !unitCaster->IsPlayer())
7042
7043 TradeData* my_trade = unitCaster->ToPlayer()->GetTradeData();
7044
7045 if (!my_trade)
7047
7049 if (slot != TRADE_SLOT_NONTRADED)
7051
7052 if (!IsTriggered())
7053 if (my_trade->GetSpell())
7055 }
7056
7057 // check if caster has at least 1 combo point on target for spells that require combo points
7059 {
7061 {
7062 if (!unitCaster || !unitCaster->GetComboPoints(m_targets.GetUnitTarget()))
7063 {
7065 }
7066 }
7067 else
7068 {
7069 if (!unitCaster || !unitCaster->GetComboPoints())
7070 {
7072 }
7073 }
7074 }
7075
7076 // xinef: check relic cooldown
7078 if (unitCaster && unitCaster->HasSpellCooldown(SPELL_RELIC_COOLDOWN) && !unitCaster->HasSpellItemCooldown(SPELL_RELIC_COOLDOWN, m_CastItem->GetEntry()))
7080
7081 // all ok
7082 return SPELL_CAST_OK;
7083}
#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
#define INVALID_HEIGHT
Definition GridTerrainData.h:27
@ INVTYPE_RELIC
Definition ItemTemplate.h:284
LineOfSightChecks
Definition Map.h:108
@ LINEOFSIGHT_ALL_CHECKS
Definition Map.h:115
#define NOMINAL_MELEE_RANGE
Definition ObjectDefines.h:47
@ PATHFIND_FARFROMPOLY_END
Definition PathGenerator.h:54
@ PATHFIND_NOT_USING_PATH
Definition PathGenerator.h:51
@ 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:69
@ AURA_INTERRUPT_FLAG_MOUNT
Definition SpellDefines.h:68
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore GCD.
Definition SpellDefines.h:143
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore shapeshift checks.
Definition SpellDefines.h:153
@ TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE
Will ignore caster aura states including combat requirements and death state.
Definition SpellDefines.h:154
@ TRIGGERED_IGNORE_SHAPESHIFT
Will not adjust facing to target (if any)
Definition SpellDefines.h:152
@ TRIGGERED_IGNORE_GCD
Not triggered.
Definition SpellDefines.h:142
@ TRIGGERED_IGNORE_EFFECTS
Periodic aura tick wont be reset on override.
Definition SpellDefines.h:161
@ TRIGGERED_IGNORE_CASTER_AURAS
Will ignore mounted/on vehicle restrictions.
Definition SpellDefines.h:155
@ 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
@ SPELL_ATTR0_CU_BYPASS_MECHANIC_IMMUNITY
Definition SpellInfo.h:209
#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:304
Loot loot
Definition Creature.h:231
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:207
bool IsSpellProhibited(SpellSchoolMask idSchoolMask) const
Definition Creature.cpp:2976
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:2447
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
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:2485
bool HaveInDiet(ItemTemplate const *item) const
Definition Pet.cpp:1447
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition Pet.cpp:1465
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:2547
bool IsInSameRaidWith(Player const *p) const
Definition Player.h:1914
bool CanTameExoticPets() const
Definition Player.h:2220
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition Player.cpp:13556
bool InBattleground() const
Definition Player.h:2299
PetStable * GetPetStable()
Definition Player.h:1226
Battleground * GetBattleground(bool create=false) const
Definition Player.cpp:12461
WorldSession * GetSession() const
Definition Player.h:2031
bool HasSpellCooldown(uint32 spell_id) const override
Definition Player.cpp:16726
uint32 GetLastPotionId()
Definition Player.h:1839
Group * GetGroup()
Definition Player.h:2517
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:6887
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:1125
std::unique_ptr< DuelInfo > duel
Definition Player.h:1906
Item * GetItemByGuid(ObjectGuid guid) const
Definition PlayerStorage.cpp:411
GameObject * GetGOTarget() const
Definition Spell.cpp:301
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
float GetMaxRange(bool positive=false, WorldObject *caster=nullptr, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2750
SpellCastResult CheckShapeshift(uint32 form) const
Definition SpellInfo.cpp:1468
uint32 Mechanic
Definition SpellInfo.h:347
uint32 GetDispelMask() const
Definition SpellInfo.cpp:1975
uint32 GetRecoveryTime() const
Definition SpellInfo.cpp:2824
bool IsSelfCast() const
Definition SpellInfo.cpp:1135
uint32 CasterAuraState
Definition SpellInfo.h:363
bool CanBeUsedInCombat() const
Definition SpellInfo.cpp:1277
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:1523
SpellSchoolMask GetSchoolMask() const
Definition SpellInfo.cpp:1921
int32 AreaGroupId
Definition SpellInfo.h:415
uint32 GetExplicitTargetMask() const
Definition SpellInfo.cpp:1989
SpellCastResult CheckExplicitTarget(WorldObject const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition SpellInfo.cpp:1870
bool NeedsExplicitUnitTarget() const
Definition SpellInfo.cpp:1078
uint32 ExcludeCasterAuraSpell
Definition SpellInfo.h:369
bool IsTargetingArea() const
Definition SpellInfo.cpp:1070
uint32 SpellFamilyName
Definition SpellInfo.h:411
uint32 AuraInterruptFlags
Definition SpellInfo.h:377
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition Spell.h:804
SpellCastResult CheckSpellFocus()
Definition Spell.cpp:8080
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition Spell.cpp:8728
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition Spell.h:491
SpellCastResult CheckPower()
Definition Spell.cpp:7428
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition Spell.cpp:7122
SpellCastResult CallScriptCheckCastHandlers()
Definition Spell.cpp:8937
SpellCastResult CheckItems(uint32 *param1=nullptr, uint32 *param2=nullptr)
Definition Spell.cpp:7477
SpellCastResult CheckRange(bool strict)
Definition Spell.cpp:7331
bool HasGlobalCooldown() const
Definition Spell.cpp:9213
Definition TemporarySummon.h:50
uint32 GetSpell() const
Definition TradeData.h:49
bool IsVehicle() const
Definition Unit.h:801
Vehicle * GetVehicle() const
Definition Unit.h:1932
SpellImmuneContainer m_spellImmune[MAX_SPELL_IMMUNITY]
Definition Unit.h:2094
Unit * GetOwner() const
Definition Unit.cpp:7487
Pet * ToPet()
Definition Unit.h:730
virtual bool HasSpellCooldown(uint32) const
Definition Unit.h:1340
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1963
ObjectGuid GetOwnerGUID() const override
Definition Unit.h:714
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition Unit.h:1341
bool IsInDisallowedMountForm() const
Definition Unit.cpp:16925
bool HasUnitFlag2(UnitFlags2 flags) const
Definition Unit.h:754
bool IsInSanctuary() const
Definition Unit.h:1049
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:5875
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:1844
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5764
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition Unit.h:688
bool IsInFlight() const
Definition Unit.h:1712
void SendTameFailure(uint8 result)
Definition Unit.cpp:15592
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition Unit.cpp:5648
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:775
virtual bool IsInWater() const
Definition Unit.cpp:4286
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition Unit.cpp:7434
bool isMoving() const
Definition Unit.h:1715
void EngageWithTarget(Unit *who)
Definition Unit.cpp:7306
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:1372
ObjectGuid GetCharmGUID() const
Definition Unit.h:722
VisibleAuraMap const * GetVisibleAuras()
Definition Unit.h:1544
bool IsMounted() const
Definition Unit.h:1892
Unit * GetVictim() const
Definition Unit.h:904
bool IsCritter() const
Definition Unit.h:834
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:7043
bool IsHighestExclusiveAuraEffect(SpellInfo const *spellInfo, AuraType auraType, int32 effectAmount, uint8 auraEffectMask, bool removeOtherAuraApplications=false)
Definition Unit.cpp:4335
uint8 GetComboPoints(Unit const *who=nullptr) const
Definition Unit.h:1020
ObjectGuid GetCharmerGUID() const
Definition Unit.h:720
uint32 getTransForm() const
Definition Unit.h:1974
virtual bool HasActivePowerType(Powers power)
Definition Unit.h:1138
void RemoveMovementImpairingAuras(bool withRoot)
Definition Unit.cpp:5268
bool IsTotem() const
Definition Unit.h:800
Guardian * GetGuardianPet() const
Definition Unit.cpp:7538
ObjectGuid GetTarget() const
Definition Unit.h:862
bool IsInCombat() const
Definition Unit.h:941
ObjectGuid GetPetGUID() const
Definition Unit.h:724
Definition Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition Vehicle.cpp:656
uint32 GetMapId() const
Definition Position.h:281
Map * GetMap() const
Definition Object.h:637
void UpdateAllowedPositionZ(float x, float y, float &z, float *groundZ=nullptr) const
Definition Object.cpp:1619
InstanceScript * GetInstanceScript() const
Definition Object.cpp:1247
float GetMapHeight(float x, float y, float z, bool vmap=true, float distanceToSearch=50.0f) const
Definition Object.cpp:3145
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:1412
bool IsOutdoors() const
Definition Object.cpp:3196
bool IsWithinLOS(float x, float y, float z, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS) const
Definition Object.cpp:1391
float GetVisibilityRange() const
Definition Object.cpp:1710
void GetNearPoint2D(WorldObject const *searcher, float &x, float &y, float distance, float absAngle, Position const *startPos=nullptr) const
Definition Object.cpp:2715
uint32 GetAreaId() const
Definition Object.cpp:3179
uint32 GetZoneId() const
Definition Object.cpp:3171
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:3187
uint32 GetRecruiterId() const
Definition WorldSession.h:675
uint32 GetAccountId() const
Definition WorldSession.h:502
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:1060
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:1361
bool IsDungeon() const
Definition DBCStructure.h:1387
float GetAngle(Position const *pos) const
Definition Position.cpp:85
void GetPosition(float &x, float &y) const
Definition Position.h:126
Definition DBCStructure.h:1853
uint32 flags1
Definition DBCStructure.h:1858
Definition DBCStructure.h:1945
uint32 Category
Definition DBCStructure.h:1947
Definition DBCStructure.h:2100
uint32 m_flags
Definition DBCStructure.h:2102

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(), Position::GetAngle(), 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(), WorldObject::GetMapHeight(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), WorldObject::GetNearPoint2D(), 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(), INVALID_HEIGHT, 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(), NOMINAL_MELEE_RANGE, PATHFIND_FARFROMPOLY_END, PATHFIND_INCOMPLETE, PATHFIND_NOPATH, PATHFIND_NOT_USING_PATH, 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_BYPASS_MECHANIC_IMMUNITY, 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, WorldObject::UpdateAllowedPositionZ(), 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
7123{
7124 Unit* unitCaster = m_caster->ToUnit();
7125 if (!unitCaster)
7126 return SPELL_CAST_OK;
7127 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
7129 return SPELL_CAST_OK;
7130
7131 uint8 school_immune = 0;
7132 uint64 mechanic_immune = 0;
7133 uint32 dispel_immune = 0;
7134
7135 // Check if the spell grants school or mechanic immunity.
7136 // We use bitmasks so the loop is done only once and not on every aura check below.
7138 {
7139 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
7140 {
7141 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
7142 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
7143 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
7144 mechanic_immune |= 1ULL << uint32(m_spellInfo->Effects[i].MiscValue);
7145 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
7146 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
7147 }
7148 // immune movement impairment and loss of control
7149 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
7150 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)
7152 }
7153
7155
7156 // Glyph of Pain Suppression
7157 // there is no other way to handle it
7158 if (m_spellInfo->Id == 33206 && !unitCaster->HasAura(63248))
7159 usableInStun = false;
7160
7161 // Check whether the cast should be prevented by any state you might have.
7162 SpellCastResult prevented_reason = SPELL_CAST_OK;
7163 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
7164 uint32 unitflag = unitCaster->GetUnitFlags(); // Get unit state
7165
7166 // Xinef: if spell is triggered check preventionType only
7167 if (!preventionOnly)
7168 {
7169 if (unitflag & UNIT_FLAG_STUNNED)
7170 {
7171 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
7172 if (usableInStun)
7173 {
7174 bool foundNotStun = false;
7175 uint64 mask = (1ULL << MECHANIC_STUN) | (1ULL << MECHANIC_FREEZE) | (1ULL << MECHANIC_HORROR);
7176 // Barkskin should skip sleep effects, sap and fears
7177 if (m_spellInfo->Id == 22812)
7178 mask |= 1ULL << MECHANIC_SAPPED | 1ULL << MECHANIC_HORROR | 1ULL << MECHANIC_SLEEP;
7179 // Hand of Freedom, can be used while sapped and while under fear-mechanic stuns (e.g. Intimidating Shout primary target)
7180 if (m_spellInfo->Id == 1044)
7181 mask |= (1ULL << MECHANIC_SAPPED) | (1ULL << MECHANIC_FEAR);
7182 Unit::AuraEffectList const& stunAuras = unitCaster->GetAuraEffectsByType(SPELL_AURA_MOD_STUN);
7183 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
7184 {
7185 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
7186 {
7187 foundNotStun = true;
7188 break;
7189 }
7190 }
7191 if (foundNotStun)
7192 prevented_reason = SPELL_FAILED_STUNNED;
7193 }
7194 else
7195 prevented_reason = SPELL_FAILED_STUNNED;
7196 }
7198 prevented_reason = SPELL_FAILED_CONFUSED;
7200 prevented_reason = SPELL_FAILED_FLEEING;
7201 }
7202
7203 // Xinef: if there is no prevented_reason, check prevention types
7204 if (prevented_reason == SPELL_CAST_OK)
7205 {
7207 prevented_reason = SPELL_FAILED_SILENCED;
7209 prevented_reason = SPELL_FAILED_PACIFIED;
7210 }
7211
7212 // Attr must make flag drop spell totally immune from all effects
7213 if (prevented_reason != SPELL_CAST_OK)
7214 {
7215 if (school_immune || mechanic_immune || dispel_immune)
7216 {
7217 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
7218 Unit::AuraApplicationMap const& auras = unitCaster->GetAppliedAuras();
7219 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
7220 {
7221 Aura const* aura = itr->second->GetBase();
7222 SpellInfo const* auraInfo = aura->GetSpellInfo();
7223 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
7224 continue;
7225 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
7226 continue;
7227 if (auraInfo->GetDispelMask() & dispel_immune)
7228 continue;
7229
7230 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
7231 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
7232 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
7233 {
7234 if (AuraEffect* part = aura->GetEffect(i))
7235 {
7236 switch (part->GetAuraType())
7237 {
7239 {
7240 uint64 mask = 1ULL << MECHANIC_STUN;
7241 // Barkskin should skip sleep effects, sap and fears
7242 if (m_spellInfo->Id == 22812)
7243 mask |= 1ULL << MECHANIC_SAPPED | 1ULL << MECHANIC_HORROR | 1ULL << MECHANIC_SLEEP;
7244 // Hand of Freedom, can be used while sapped and while under fear-mechanic stuns (e.g. Intimidating Shout primary target)
7245 if (m_spellInfo->Id == 1044)
7246 mask |= (1ULL << MECHANIC_SAPPED) | (1ULL << MECHANIC_FEAR);
7247
7248 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
7249 return SPELL_FAILED_STUNNED;
7250 break;
7251 }
7254 return SPELL_FAILED_CONFUSED;
7255 break;
7258 return SPELL_FAILED_FLEEING;
7259 break;
7264 return SPELL_FAILED_PACIFIED;
7266 return SPELL_FAILED_SILENCED;
7267 break;
7268 default:
7269 break;
7270 }
7271 }
7272 }
7273 }
7274 }
7275 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
7276 else
7277 return prevented_reason;
7278 }
7279 return SPELL_CAST_OK;
7280}
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:88
AuraEffect * GetEffect(uint8 effIndex) const
Definition SpellAuras.h:177
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:101
uint64 GetAllEffectsMechanicMask() const
Definition SpellInfo.cpp:1926
boost::container::flat_multimap< uint32, AuraApplication * > AuraApplicationMap
Definition Unit.h:674
AuraApplicationMap & GetAppliedAuras()
Definition Unit.h:1388

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, Object::ToUnit(), 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:443

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

Referenced by SelectEffectImplicitTargets(), and SelectImplicitDestDestTargets().

◆ CheckEffectExecuteData()

void Spell::CheckEffectExecuteData ( )
protected
8871{
8872 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8874}

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
8266{
8267 Unit* unitCaster = m_caster->ToUnit();
8268 switch (m_spellInfo->Effects[eff].ApplyAuraName)
8269 {
8274 if (target->IsCreature() && target->IsVehicle())
8275 return false;
8276 if (target->IsMounted() && m_spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_MOD_POSSESS)
8277 return false;
8278 if (target->GetCharmerGUID())
8279 return false;
8280 if (int32 damage = CalculateSpellDamage(eff, target))
8281 if ((int32)target->GetLevel() > damage)
8282 return false;
8283 break;
8284 default:
8285 break;
8286 }
8287
8288 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
8289 // 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
8290 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)))
8291 return true;
8292
8293 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
8296 {
8297 return true;
8298 }
8299
8301 //Check targets for LOS visibility (except spells without range limitations)
8302 switch (m_spellInfo->Effects[eff].Effect)
8303 {
8305 // player far away, maybe his corpse near?
8306 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
8307 {
8309 return false;
8310
8312 if (!corpse)
8313 return false;
8314
8315 if (target->GetGUID() != corpse->GetOwnerGUID())
8316 return false;
8317
8319 return false;
8320 }
8321 break;
8323 {
8325 {
8326 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
8327 return true;
8328
8329 return false;
8330 }
8331
8333 if (!corpse)
8334 return false;
8335
8336 if (target->GetGUID() != corpse->GetOwnerGUID())
8337 return false;
8338
8340 return false;
8341
8343 return false;
8344 }
8345 break;
8347 if (!unitCaster || !unitCaster->IsPlayer() || !target->IsPlayer())
8348 return false;
8349 if (unitCaster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != unitCaster->ToPlayer()->GetSession()->GetAccountId())
8350 return false;
8351 if (unitCaster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
8352 return false;
8353 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
8354 return false;
8355 break;
8356 default: // normal case
8357 {
8358 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8359 GameObject* gobCaster = nullptr;
8361 {
8363 }
8364 else if (m_caster->GetEntry() == WORLD_TRIGGER)
8365 {
8366 if (TempSummon* tempSummon = unitCaster ? unitCaster->ToTempSummon() : nullptr)
8367 {
8368 gobCaster = tempSummon->GetSummonerGameObject();
8369 }
8370 }
8371
8372 if (gobCaster)
8373 {
8374 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks())
8375 {
8376 return true;
8377 }
8378
8379 // If spell casted by gameobject then ignore M2 models
8380 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8381 }
8382
8383 if (target != m_caster)
8384 {
8385 if (m_targets.HasDst())
8386 {
8387 float x = m_targets.GetDstPos()->GetPositionX();
8388 float y = m_targets.GetDstPos()->GetPositionY();
8389 float z = m_targets.GetDstPos()->GetPositionZ();
8390
8391 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8392 {
8393 return false;
8394 }
8395 }
8397 {
8398 return false;
8399 }
8400 }
8401 break;
8402 }
8403 }
8404
8405 return true;
8406}
@ 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:205
Definition Corpse.h:49
ObjectGuid GetOwnerGUID() const override
Definition Corpse.h:69
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:880
ObjectGuid GetCorpseTargetGUID() const
Definition Spell.cpp:318
bool IsARecruiter() const
Definition WorldSession.h:676
#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(), Object::ToUnit(), 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.
7478{
7479 Unit* unitCaster = m_caster->ToUnit();
7480 if (!unitCaster)
7481 return SPELL_CAST_OK;
7482
7483 Player* player = unitCaster->ToPlayer();
7484 if (!player)
7485 {
7486 // Non-player case: Check if creature is disarmed
7488 {
7490 }
7491
7492 return SPELL_CAST_OK;
7493 }
7494
7495 if (!m_CastItem)
7496 {
7497 if (m_castItemGUID)
7499 }
7500 else
7501 {
7502 uint32 itemid = m_CastItem->GetEntry();
7503 if (!player->HasItemCount(itemid))
7505
7506 ItemTemplate const* proto = m_CastItem->GetTemplate();
7507 if (!proto)
7509
7510 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7511 if (proto->Spells[i].SpellCharges)
7512 if (m_CastItem->GetSpellCharges(i) == 0)
7514
7515 // consumable cast item checks
7517 {
7518 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7519 SpellCastResult failReason = SPELL_CAST_OK;
7520 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7521 {
7522 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7523 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7524 continue;
7525
7526 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7527 {
7529 {
7531 continue;
7532 }
7533 else
7534 {
7535 failReason = SPELL_CAST_OK;
7536 break;
7537 }
7538 }
7539
7540 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7541 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7542 {
7543 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7544 {
7546 continue;
7547 }
7548
7549 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7551 {
7553 continue;
7554 }
7555 else
7556 {
7557 failReason = SPELL_CAST_OK;
7558 break;
7559 }
7560 }
7561 }
7562 if (failReason != SPELL_CAST_OK)
7563 return failReason;
7564 }
7565 }
7566
7567 // check target item
7569 {
7570 if (!unitCaster->IsPlayer())
7572
7573 if (!m_targets.GetItemTarget())
7575
7578 }
7579 // if not item target then required item must be equipped
7580 else
7581 {
7582 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7583 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7584 if (unitCaster->IsPlayer() && !unitCaster->ToPlayer()->HasItemFitToSpellRequirements(m_spellInfo))
7586 }
7587
7588 // do not take reagents for these item casts
7590 {
7592 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7593 if (!checkReagents)
7594 if (Item* targetItem = m_targets.GetItemTarget())
7595 if (targetItem->GetOwnerGUID() != unitCaster->GetGUID())
7596 checkReagents = true;
7597
7598 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7599 if (checkReagents)
7600 {
7601 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7602 {
7603 if (m_spellInfo->Reagent[i] <= 0)
7604 continue;
7605
7606 uint32 itemid = m_spellInfo->Reagent[i];
7607 uint32 itemcount = m_spellInfo->ReagentCount[i];
7608
7609 // if CastItem is also spell reagent
7610 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7611 {
7612 ItemTemplate const* proto = m_CastItem->GetTemplate();
7613 if (!proto)
7615 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7616 {
7617 // CastItem will be used up and does not count as reagent
7618 int32 charges = m_CastItem->GetSpellCharges(s);
7619 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7620 {
7621 ++itemcount;
7622 break;
7623 }
7624 }
7625 }
7626 if (!player->HasItemCount(itemid, itemcount))
7627 return SPELL_FAILED_REAGENTS;
7628 }
7629 }
7630
7631 // check totem-item requirements (items presence in inventory)
7632 uint32 totems = 2;
7633 for (int i = 0; i < 2; ++i)
7634 {
7635 if (m_spellInfo->Totem[i] != 0)
7636 {
7637 if (player->HasItemCount(m_spellInfo->Totem[i]))
7638 {
7639 totems -= 1;
7640 continue;
7641 }
7642 }
7643 else
7644 totems -= 1;
7645 }
7646 if (totems != 0)
7647 return SPELL_FAILED_TOTEMS; //0x7C
7648
7649 // Check items for TotemCategory (items presence in inventory)
7651 for (int i = 0; i < 2; ++i)
7652 {
7653 if (m_spellInfo->TotemCategory[i] != 0)
7654 {
7656 {
7657 TotemCategory -= 1;
7658 continue;
7659 }
7660 }
7661 else
7662 TotemCategory -= 1;
7663 }
7664 if (TotemCategory != 0)
7665 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7666 }
7667
7668 // special checks for spell effects
7669 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7670 {
7671 switch (m_spellInfo->Effects[i].Effect)
7672 {
7675 {
7676 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7677 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7678 if (target->IsPlayer() && !IsTriggered())
7679 {
7680 // 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,
7681 // so we need to make sure there is at least one free space in the player's inventory
7683 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7684 {
7685 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7687 }
7688
7689 if (m_spellInfo->Effects[i].ItemType)
7690 {
7691 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7692 if (!itemTemplate)
7694
7695 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7696 ItemPosCountVec dest;
7697 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7698 if (msg != EQUIP_ERR_OK)
7699 {
7701 if (!itemTemplate->ItemLimitCategory)
7702 {
7703 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7705 }
7706 else
7707 {
7708 // Conjure Food/Water/Refreshment spells
7711 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7712 {
7713 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7715 }
7716 else
7717 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7718
7720 }
7721 }
7722 }
7723 }
7724 break;
7725 }
7727 {
7728 if (player->GetFreeInventorySpace() == 0)
7729 {
7730 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7732 }
7733 break;
7734 }
7736 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7738 {
7739 // cannot enchant vellum for other player
7740 if (m_targets.GetItemTarget()->GetOwner() != unitCaster)
7742 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7745 ItemPosCountVec dest;
7746 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7747 if (msg != EQUIP_ERR_OK)
7748 {
7749 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7751 }
7752 }
7753 [[fallthrough]];
7755 {
7756 Item* targetItem = m_targets.GetItemTarget();
7757 if (!targetItem)
7759
7760 // Apply item level restriction
7762 {
7763 uint32 requiredLevel = targetItem->GetTemplate()->RequiredLevel;
7764 if (!requiredLevel)
7765 requiredLevel = targetItem->GetTemplate()->ItemLevel;
7766
7767 if (requiredLevel < m_spellInfo->BaseLevel)
7768 return SPELL_FAILED_LOWLEVEL;
7769 }
7770
7771 if (m_CastItem && m_spellInfo->MaxLevel > 0 && targetItem->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7773
7774 bool isItemUsable = false;
7775 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7776 {
7777 ItemTemplate const* proto = targetItem->GetTemplate();
7778 if (proto->Spells[e].SpellId && (
7781 {
7782 isItemUsable = true;
7783 break;
7784 }
7785 }
7786
7787 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7788 // do not allow adding usable enchantments to items that have use effect already
7789 if (enchantEntry)
7790 {
7791 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7792 {
7793 switch (enchantEntry->type[s])
7794 {
7796 if (isItemUsable)
7798 break;
7800 {
7801 uint32 numSockets = 0;
7802 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7803 if (targetItem->GetTemplate()->Socket[socket].Color)
7804 ++numSockets;
7805
7806 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7808 break;
7809 }
7810 }
7811 }
7812 }
7813
7814 // Not allow enchant in trade slot for some enchant type
7815 if (targetItem->GetOwner() != unitCaster)
7816 {
7817 if (!enchantEntry)
7818 return SPELL_FAILED_ERROR;
7819 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7821 }
7822 break;
7823 }
7825 {
7826 Item* item = m_targets.GetItemTarget();
7827 if (!item)
7829 // Not allow enchant in trade slot for some enchant type
7830 if (item->GetOwner() != unitCaster)
7831 {
7832 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7833 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7834 if (!pEnchant)
7835 return SPELL_FAILED_ERROR;
7836 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7838 }
7839
7840 // Apply item level restriction
7842 {
7843 uint32 requiredLevel = item->GetTemplate()->RequiredLevel;
7844 if (!requiredLevel)
7845 requiredLevel = item->GetTemplate()->ItemLevel;
7846
7847 if (requiredLevel < m_spellInfo->BaseLevel)
7848 return SPELL_FAILED_LOWLEVEL;
7849 }
7850
7853
7854 break;
7855 }
7857 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7858 break;
7860 {
7861 if (!m_targets.GetItemTarget())
7863
7864 // prevent disenchanting in trade slot
7865 if (m_targets.GetItemTarget()->GetOwnerGUID() != unitCaster->GetGUID())
7867
7868 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7869 if (!itemProto)
7871
7872 uint32 item_quality = itemProto->Quality;
7873 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7874 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7875 if (item_disenchantskilllevel == uint32(-1))
7877 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7879 if (item_quality > 4 || item_quality < 2)
7881 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7883 if (!itemProto->DisenchantID)
7885 break;
7886 }
7888 {
7889 Item* item = m_targets.GetItemTarget();
7890 if (!item)
7892 //ensure item is a prospectable ore
7895 //prevent prospecting in trade slot
7896 if (item->GetOwnerGUID() != unitCaster->GetGUID())
7898 //Check for enough skill in jewelcrafting
7899 uint32 item_prospectingskilllevel = item->GetTemplate()->RequiredSkillRank;
7900 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7902 //make sure the player has the required ores in inventory
7903 if (item->GetCount() < 5)
7904 {
7905 if (param1 && param2)
7906 {
7907 *param1 = item->GetEntry();
7908 *param2 = 5;
7909 }
7911 }
7912
7915
7916 break;
7917 }
7919 {
7920 Item* item = m_targets.GetItemTarget();
7921 if (!item)
7923 //ensure item is a millable herb
7924 if (!(item->GetTemplate()->HasFlag(ITEM_FLAG_IS_MILLABLE)))
7926 //prevent milling in trade slot
7927 if (item->GetOwnerGUID() != unitCaster->GetGUID())
7929 //Check for enough skill in inscription
7930 uint32 item_millingskilllevel = item->GetTemplate()->RequiredSkillRank;
7931 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7933 //make sure the player has the required herbs in inventory
7934 if (item->GetCount() < 5)
7935 {
7936 if (param1 && param2)
7937 {
7938 *param1 = item->GetEntry();
7939 *param2 = 5;
7940 }
7942 }
7943
7946
7947 break;
7948 }
7951 {
7952 if (!unitCaster->IsPlayer())
7954
7956 break;
7957
7958 Item* pItem = unitCaster->ToPlayer()->GetWeaponForAttack(m_attackType);
7959 if (!pItem || pItem->IsBroken())
7961
7962 switch (pItem->GetTemplate()->SubClass)
7963 {
7965 {
7966 uint32 ammo = pItem->GetEntry();
7967 if (!unitCaster->ToPlayer()->HasItemCount(ammo))
7968 return SPELL_FAILED_NO_AMMO;
7969 };
7970 break;
7974 {
7975 uint32 ammo = unitCaster->ToPlayer()->GetUInt32Value(PLAYER_AMMO_ID);
7976 if (!ammo)
7977 {
7978 // Requires No Ammo
7979 if (unitCaster->HasAura(46699))
7980 break; // skip other checks
7981
7982 return SPELL_FAILED_NO_AMMO;
7983 }
7984
7985 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
7986 if (!ammoProto)
7987 return SPELL_FAILED_NO_AMMO;
7988
7989 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
7990 return SPELL_FAILED_NO_AMMO;
7991
7992 // check ammo ws. weapon compatibility
7993 switch (pItem->GetTemplate()->SubClass)
7994 {
7997 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
7998 return SPELL_FAILED_NO_AMMO;
7999 break;
8001 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
8002 return SPELL_FAILED_NO_AMMO;
8003 break;
8004 default:
8005 return SPELL_FAILED_NO_AMMO;
8006 }
8007
8008 if (!unitCaster->ToPlayer()->HasItemCount(ammo))
8009 {
8010 unitCaster->ToPlayer()->SetUInt32Value(PLAYER_AMMO_ID, 0);
8011 return SPELL_FAILED_NO_AMMO;
8012 }
8013 };
8014 break;
8016 break;
8017 default:
8018 break;
8019 }
8020 break;
8021 }
8023 {
8024 uint32 item_id = m_spellInfo->Effects[i].ItemType;
8025 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
8026
8027 if (!pProto)
8029
8030 if (Item* pitem = player->GetItemByEntry(item_id))
8031 {
8032 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
8033 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
8035 }
8036 break;
8037 }
8038 default:
8039 break;
8040 }
8041 }
8042
8043 // check weapon presence in slots for main/offhand weapons
8044 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
8045 {
8046 // main hand weapon required
8048 {
8049 Item* item = unitCaster->ToPlayer()->GetWeaponForAttack(BASE_ATTACK);
8050
8051 // skip spell if no weapon in slot or broken
8052 if (!item || item->IsBroken())
8054
8055 // skip spell if weapon not fit to triggered spell
8058 }
8059
8060 // offhand hand weapon required
8062 {
8063 Item* item = unitCaster->ToPlayer()->GetWeaponForAttack(OFF_ATTACK);
8064
8065 // skip spell if no weapon in slot or broken
8066 if (!item || item->IsBroken())
8068
8069 // skip spell if weapon not fit to triggered spell
8072 }
8073
8074 m_weaponItem = unitCaster->ToPlayer()->GetWeaponForAttack(m_attackType, true);
8075 }
8076
8077 return SPELL_CAST_OK;
8078}
@ 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:1675
#define MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS
Definition DBCStructure.h:1874
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:303
bool HasItemFitToSpellRequirements(SpellInfo const *spellInfo, Item const *ignoreItem=nullptr) const
Definition Player.cpp:12803
uint32 GetFreeInventorySpace() const
Definition PlayerStorage.cpp:470
Item * GetItemByEntry(uint32 entry) const
Definition PlayerStorage.cpp:3473
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:12878
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition PlayerStorage.cpp:492
void SendEquipError(InventoryResult msg, Item *pItem, Item *pItem2=nullptr, uint32 itemid=0)
Definition PlayerStorage.cpp:4131
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:1120
bool CanUseAttackType(WeaponAttackType attacktype) const
Definition Unit.h:998
uint32 GetMaxPower(Powers power) const
Definition Unit.h:1142
void SetUInt32Value(uint16 index, uint32 value)
Definition Unit.cpp:16980
uint32 GetPower(Powers power) const
Definition Unit.h:1141
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:827
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:1877
uint32 type[MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS]
Definition DBCStructure.h:1880
uint32 slot
Definition DBCStructure.h:1887
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, Object::ToUnit(), TRIGGERED_IGNORE_POWER_AND_REAGENT_COST, and SpellItemEnchantmentEntry::type.

Referenced by CheckCast().

◆ CheckPetCast()

SpellCastResult Spell::CheckPetCast ( Unit *  target)
7086{
7087 Unit* unitCaster = m_caster->ToUnit();
7088 if (unitCaster->HasUnitState(UNIT_STATE_CASTING) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
7090
7091 // dead owner (pets still alive when owners ressed?)
7092 if (Unit* owner = unitCaster->GetCharmerOrOwner())
7093 if (!owner->IsAlive() && unitCaster->GetEntry() != 30230) // Rise Ally
7095
7096 if (!target && m_targets.GetUnitTarget())
7097 target = m_targets.GetUnitTarget();
7098
7100 {
7101 if (!target)
7103 m_targets.SetUnitTarget(target);
7104 }
7105
7106 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
7108
7109 // cooldown
7110 if (Creature const* creatureCaster = unitCaster->ToCreature())
7111 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
7113
7114 // Check if spell is affected by GCD
7116 if (unitCaster->GetCharmInfo() && unitCaster->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(m_spellInfo))
7118
7119 return CheckCast(true);
7120}
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Definition CharmInfo.cpp:397
void SetUnitTarget(Unit *target)
Definition Spell.cpp:276
int32 CalcPowerCost(WorldObject const *caster, SpellSchoolMask schoolMask, Spell *spell=nullptr) const
Definition SpellInfo.cpp:2829
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(), Object::ToUnit(), TRIGGERED_IGNORE_CAST_IN_PROGRESS, and UNIT_STATE_CASTING.

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

◆ CheckPower()

SpellCastResult Spell::CheckPower ( )
7429{
7430 Unit* unitCaster = m_caster->ToUnit();
7431 if (!unitCaster)
7432 return SPELL_CAST_OK;
7433
7434 // item cast not used power
7435 if (m_CastItem)
7436 return SPELL_CAST_OK;
7437
7438 //While .cheat power is enabled dont check if we need power to cast the spell
7439 if (unitCaster->IsPlayer())
7440 {
7441 if (unitCaster->ToPlayer()->GetCommandStatus(CHEAT_POWER))
7442 {
7443 return SPELL_CAST_OK;
7444 }
7445 }
7446
7447 // health as power used - need check health amount
7449 {
7450 if (int32(unitCaster->GetHealth()) <= m_powerCost)
7452 return SPELL_CAST_OK;
7453 }
7454 // Check valid power type
7456 {
7457 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7458 return SPELL_FAILED_UNKNOWN;
7459 }
7460
7461 //check rune cost only if a spell has PowerType == POWER_RUNE
7463 {
7465 if (failReason != SPELL_CAST_OK)
7466 return failReason;
7467 }
7468
7469 // Check power amount
7471 if (int32(unitCaster->GetPower(PowerType)) < m_powerCost)
7472 return SPELL_FAILED_NO_POWER;
7473 else
7474 return SPELL_CAST_OK;
7475}
@ 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:5584
uint32 GetHealth() const
Definition Unit.h:1114

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, Object::ToPlayer(), and Object::ToUnit().

Referenced by CheckCast().

◆ CheckRange()

SpellCastResult Spell::CheckRange ( bool  strict)
7332{
7333 Unit* unitCaster = m_caster->ToUnit();
7334 // Don't check for instant cast spells
7335 if (!strict && m_casttime == 0)
7336 return SPELL_CAST_OK;
7337
7338 uint32 range_type = 0;
7339
7341 {
7342 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7343 // these are triggered by other spells - possibly we should omit range check in that case?
7344 if (m_spellInfo->RangeEntry->ID == 1)
7345 return SPELL_CAST_OK;
7346
7347 range_type = m_spellInfo->RangeEntry->Flags;
7348 }
7349
7350 Unit* target = m_targets.GetUnitTarget();
7351 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7352 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7353
7354 // xinef: hack for npc shooters
7355 if (min_range && unitCaster && unitCaster->IsCreature() && !unitCaster->ToCreature()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7356 range_type = SPELL_RANGE_RANGED;
7357
7358 if (Player* modOwner = m_caster->GetSpellModOwner())
7359 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7360
7361 // xinef: dont check max_range to strictly after cast
7362 if (range_type != SPELL_RANGE_MELEE && !strict)
7363 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7364
7365 if (target)
7366 {
7367 if (target != m_caster && unitCaster)
7368 {
7369 // A vehicle passenger can neither turn nor move, and their stored position and
7370 // orientation can be stale; never fail range or facing against the vehicle
7371 // carrying them (e.g. Yogg-Saron's Constrictor Tentacle grab).
7372 bool const targetIsVehicleBase = unitCaster->GetVehicleBase() == target;
7373
7374 // Xinef: Spells with 5yd range can hit target 9yd away?
7375 if (range_type == SPELL_RANGE_MELEE)
7376 {
7377 float real_max_range = max_range;
7378
7379 if (m_caster->GetLeewayBonusRange(target) > 0.0f)
7380 real_max_range -= MIN_MELEE_REACH; // less strict when leeway applies
7381 else
7382 real_max_range -= 2 * MIN_MELEE_REACH;
7383
7384 if (!targetIsVehicleBase && !unitCaster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7386 }
7387 else if (!targetIsVehicleBase && !unitCaster->IsWithinCombatRange(target, max_range))
7388 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7389
7390 if (!targetIsVehicleBase && unitCaster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !unitCaster->HasInArc(static_cast<float>(M_PI), target) && !unitCaster->IsWithinBoundaryRadius(target))
7392 }
7393 // Non-Unit casters (e.g. a GameObject trap) have no combat reach/facing of their own;
7394 // just check the target is within the spell's range of the caster's actual position.
7395 else if (target != m_caster && !unitCaster && !m_caster->IsWithinDist(target, max_range))
7397
7398 // Check min range - for ranged spells, min range is the spell's min range + melee range (no leeway)
7399 if (unitCaster && range_type == SPELL_RANGE_RANGED)
7400 {
7401 float minRangeCombined = min_range + unitCaster->GetMeleeRange(target);
7402 if (unitCaster->IsWithinRange(target, minRangeCombined))
7404 }
7405 else if (unitCaster && min_range > 0 && unitCaster->IsWithinCombatRange(target, min_range))
7407 }
7408
7409 if (GameObject* goTarget = m_targets.GetGOTarget())
7410 {
7411 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7412 {
7414 }
7415 }
7416
7417 if (m_targets.HasDst() && !m_targets.HasTraj())
7418 {
7421 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7423 }
7424
7425 return SPELL_CAST_OK;
7426}
#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:89
@ SPELL_FACING_FLAG_INFRONT
Definition SpellDefines.h:136
@ 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:828
bool IsWithinCombatRange(Unit const *obj, float dist2compare) const
Definition Unit.cpp:774
Unit * GetVehicleBase() const
Definition Unit.cpp:14626
bool IsWithinMeleeRange(Unit const *obj, float dist=0.f) const
Definition Unit.cpp:790
bool IsWithinRange(Unit const *obj, float dist) const
Definition Unit.cpp:813
float GetMeleeRange(Unit const *target) const
Definition Unit.cpp:807
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition Object.cpp:1354
float GetLeewayBonusRadius() const
Definition Object.cpp:1791
float GetLeewayBonusRange(Unit const *target) const
Definition Object.cpp:1777
float GetSpellMinRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Object.cpp:3981
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Object.cpp:3967
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1381
bool HasInArc(float arcangle, Position const *pos, float targetRadius=0.0f) const
Definition Position.cpp:148
uint32 Flags
Definition DBCStructure.h:1833
uint32 ID
Definition DBCStructure.h:1830

References SpellInfo::FacingCasterFlags, SpellRangeEntry::Flags, SpellCastTargets::GetDstPos(), SpellCastTargets::GetGOTarget(), WorldObject::GetLeewayBonusRadius(), WorldObject::GetLeewayBonusRange(), Unit::GetMeleeRange(), Unit::GetOwnerGUID(), WorldObject::GetSpellMaxRangeForTarget(), WorldObject::GetSpellMinRangeForTarget(), WorldObject::GetSpellModOwner(), SpellCastTargets::GetUnitTarget(), Unit::GetVehicleBase(), SpellCastTargets::HasDst(), Position::HasInArc(), SpellCastTargets::HasTraj(), SpellInfo::Id, SpellRangeEntry::ID, Object::IsCreature(), Object::IsPlayer(), ObjectGuid::IsPlayer(), Unit::IsWithinBoundaryRadius(), Unit::IsWithinCombatRange(), WorldObject::IsWithinDist(), 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, Object::ToCreature(), Object::ToPlayer(), and Object::ToUnit().

Referenced by CheckCast().

◆ CheckRuneCost()

SpellCastResult Spell::CheckRuneCost ( uint32  RuneCostID)
5585{
5586 Unit* unitCaster = m_caster->ToUnit();
5587 if (!unitCaster)
5588 return SPELL_CAST_OK;
5589
5590 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5591 return SPELL_CAST_OK;
5592
5593 if (!unitCaster->IsPlayer())
5594 return SPELL_CAST_OK;
5595
5596 Player* player = unitCaster->ToPlayer();
5597 //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)
5598 if (player->GetCommandStatus(CHEAT_POWER))
5599 {
5600 return SPELL_CAST_OK;
5601 }
5602
5604 return SPELL_CAST_OK;
5605
5606 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5607
5608 if (!src)
5609 return SPELL_CAST_OK;
5610
5611 if (src->NoRuneCost())
5612 return SPELL_CAST_OK;
5613
5614 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5615
5616 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5617 {
5618 runeCost[i] = src->RuneCost[i];
5619 if (Player* modOwner = unitCaster->GetSpellModOwner())
5620 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5621 }
5622
5623 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5624
5625 for (uint32 i = 0; i < MAX_RUNES; ++i)
5626 {
5627 RuneType rune = player->GetCurrentRune(i);
5628 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5629 runeCost[rune]--;
5630 }
5631
5632 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5633 if (runeCost[i] > 0)
5634 runeCost[RUNE_DEATH] += runeCost[i];
5635
5636 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5637 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5638
5639 return SPELL_CAST_OK;
5640}
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:98
@ CLASS_CONTEXT_ABILITY
Definition UnitDefines.h:241
uint32 GetRuneCooldown(uint8 index) const
Definition Player.h:2557
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition Player.cpp:1350
RuneType GetCurrentRune(uint8 index) const
Definition Player.h:2556
Player * GetSpellModOwner() const override
Definition Unit.cpp:12567
Definition DBCStructure.h:1841
uint32 RuneCost[3]
Definition DBCStructure.h:1843
bool NoRuneCost() const
Definition DBCStructure.h:1846

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, Object::ToPlayer(), and Object::ToUnit().

Referenced by CheckPower().

◆ CheckScriptEffectImplicitTargets()

bool Spell::CheckScriptEffectImplicitTargets ( uint32  effIndex,
uint32  effIndexToCheck 
)
protected
9092{
9093 // Skip if there are not any script
9094 if (!m_loadedScripts.size())
9095 return true;
9096
9097 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
9098 {
9099 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
9100 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
9101 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
9102 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
9103 return false;
9104
9105 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
9106 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
9107 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
9108 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
9109 return false;
9110 }
9111 return true;
9112}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
8081{
8082 // check spell focus object
8084 {
8086 Cell cell(p);
8087
8088 GameObject* ok = nullptr;
8091
8093 Map& map = *m_caster->GetMap();
8094 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
8095
8096 if (!ok)
8098
8099 focusObject = ok; // game object found in range
8100 }
8101 return SPELL_CAST_OK;
8102}
@ 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:404

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

◆ CleanupTargetList()

void Spell::CleanupTargetList ( )
2387{
2388 m_UniqueTargetInfo.clear();
2389 m_UniqueGOTargetInfo.clear();
2390 m_UniqueItemInfo.clear();
2391 m_delayMoment = 0;
2393}
uint64 m_delayTrajectory
Definition Spell.h:664

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 ( )
8105{
8106 Unit* unitCaster = m_caster->ToUnit();
8107 if (!unitCaster)// || !unitCaster->IsPlayer())
8108 return;
8109
8110 //if (m_spellState == SPELL_STATE_DELAYED)
8111 // return; // spell is active and can't be time-backed
8112
8113 if (isDelayableNoMore()) // Spells may only be delayed twice
8114 return;
8115
8117 return;
8118
8119 // spells not loosing casting time (slam, dynamites, bombs..)
8120 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
8121 // return;
8122
8123 //check pushback reduce
8124 int32 delaytime = 500; // spellcasting delay is normally 500ms
8125 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
8126 unitCaster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
8127 delayReduce += unitCaster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
8128 if (delayReduce >= 100)
8129 return;
8130
8131 AddPct(delaytime, -delayReduce);
8132
8133 if (m_timer + delaytime > m_casttime)
8134 {
8135 delaytime = m_casttime - m_timer;
8137 }
8138 else
8139 m_timer += delaytime;
8140
8141 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
8142
8143 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
8144 data << m_caster->GetPackGUID();
8145 data << uint32(delaytime);
8146
8147 m_caster->SendMessageToSet(&data, true);
8148}
#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:93
T AddPct(T &base, U pct)
Definition Util.h:58
PackedGuid const & GetPackGUID() const
Definition Object.h:122
void ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell *spell=nullptr, bool temporaryPet=false)
Definition Player.cpp:10013
bool isDelayableNoMore()
Definition Spell.h:652
int32 GetTotalAuraModifier(AuraType auratype) const
Definition Unit.cpp:6050
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:2171
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, Object::ToPlayer(), and Object::ToUnit().

◆ DelayedChannel()

void Spell::DelayedChannel ( )
8151{
8152 Unit* unitCaster = m_caster->ToUnit();
8153 if (!unitCaster || !unitCaster->IsPlayer() || getState() != SPELL_STATE_CASTING)
8154 return;
8155
8156 if (isDelayableNoMore()) // Spells may only be delayed twice
8157 return;
8158
8160 return;
8161
8162 //check pushback reduce
8163 // should be affected by modifiers, not take the dbc duration.
8164 int32 duration = ((m_channeledDuration > 0) ? m_channeledDuration : m_spellInfo->GetDuration());
8165
8166 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
8167 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
8168 unitCaster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
8169 delayReduce += unitCaster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
8170 if (delayReduce >= 100)
8171 return;
8172
8173 AddPct(delaytime, -delayReduce);
8174
8175 if (m_timer <= delaytime)
8176 {
8177 delaytime = m_timer;
8178 m_timer = 0;
8179 }
8180 else
8181 m_timer -= delaytime;
8182
8183 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
8184
8185 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8186 if ((*ihit).missCondition == SPELL_MISS_NONE)
8187 if (Unit* unit = (unitCaster->GetGUID() == ihit->targetGUID) ? unitCaster : ObjectAccessor::GetUnit(*unitCaster, ihit->targetGUID))
8188 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
8189
8190 // partially interrupt persistent area auras
8191 if (DynamicObject* dynObj = unitCaster->GetDynObject(m_spellInfo->Id))
8192 dynObj->Delay(delaytime);
8193
8195}
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:6279

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, Object::ToPlayer(), and Object::ToUnit().

◆ DoAllEffectOnLaunchTarget()

void Spell::DoAllEffectOnLaunchTarget ( TargetInfo &  targetInfo,
float *  multiplier 
)
protected
8661{
8662 Unit* unitCaster = m_caster->ToUnit();
8663 Unit* unit = nullptr;
8664 // In case spell hit target, do all effect on that target
8665 if (targetInfo.missCondition == SPELL_MISS_NONE)
8666 unit = m_caster->GetGUID() == targetInfo.targetGUID ? unitCaster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8667 // In case spell reflect from target, do all effect on caster (if hit)
8668 // gameobject casts bounce onto the original caster (e.g. a reflected trap spell freezes the trap owner)
8669 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8670 unit = unitCaster ? unitCaster : m_originalCaster;
8671 if (!unit)
8672 return;
8673
8674 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8675 {
8676 if (targetInfo.effectMask & (1 << i))
8677 {
8678 m_damage = 0;
8679 m_healing = 0;
8681
8682 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8683
8684 if (m_damage > 0)
8685 {
8686 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8687 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8688 {
8689 bool npcCaster = (unitCaster && !unitCaster->IsControlledByPlayer()) || GetSpellInfo()->HasAttribute(SPELL_ATTR7_TREAT_AS_NPC_AOE);
8691 if (unitCaster && unitCaster->IsPlayer())
8692 {
8693 uint32 targetAmount = m_UniqueTargetInfo.size();
8694 if (targetAmount > 10)
8695 m_damage = m_damage * 10 / targetAmount;
8696 }
8697 }
8698 }
8699
8700 if (m_applyMultiplierMask & (1 << i))
8701 {
8703 m_damageMultipliers[i] *= multiplier[i];
8704 }
8705 targetInfo.damage += m_damage;
8707 }
8708 }
8709
8710 // xinef: totem's inherit owner crit chance and dancing rune weapon
8711 Unit* caster = unitCaster;
8712 if (unitCaster && (unitCaster->IsTotem() || unitCaster->GetEntry() == 27893))
8713 {
8714 if (Unit* owner = unitCaster->GetOwner())
8715 caster = owner;
8716 }
8717 else if (m_originalCaster)
8718 caster = m_originalCaster;
8719
8720 if (caster)
8721 {
8722 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8723 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8724 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8725 }
8726}
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:8953
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:8863
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, bool npcCaster) const
Definition Unit.cpp:15941

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(), TargetInfo::targetGUID, and Object::ToUnit().

Referenced by HandleLaunchPhase().

◆ DoAllEffectOnTarget() [1/3]

void Spell::DoAllEffectOnTarget ( GOTargetInfo *  target)
protected
3420{
3421 Unit* unitCaster = m_caster->ToUnit();
3422 if (target->processed) // Check target
3423 return;
3424 target->processed = true; // Target checked in apply effects procedure
3425
3426 uint32 effectMask = target->effectMask;
3427 if (!effectMask)
3428 return;
3429
3430 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3431 if (!go)
3432 return;
3433
3436
3437 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3438 if (effectMask & (1 << effectNumber))
3439 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3440
3441 // xinef: inform ai about spellhit
3442 go->AI()->SpellHit(unitCaster, m_spellInfo);
3443
3445
3447}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition GameObjectAI.h:66
GameObjectAI * AI() const
Definition GameObject.h:308
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition Spell.cpp:9010
void CallScriptOnHitHandlers()
Definition Spell.cpp:9023
void CallScriptAfterHitHandlers()
Definition Spell.cpp:9036

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(), Spell::GOTargetInfo::targetGUID, and Object::ToUnit().

◆ DoAllEffectOnTarget() [2/3]

void Spell::DoAllEffectOnTarget ( ItemTargetInfo *  target)
protected
3450{
3451 uint32 effectMask = target->effectMask;
3452 if (!target->item || !effectMask)
3453 return;
3454
3457
3458 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3459 if (effectMask & (1 << effectNumber))
3460 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3461
3463
3465}

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
2628{
2629 Unit* unitCaster = m_caster->ToUnit();
2630 if (!target || target->processed)
2631 return;
2632
2633 target->processed = true; // Target checked in apply effects procedure
2634
2635 // Get mask of effects for target
2636 uint8 mask = target->effectMask;
2637
2638 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? unitCaster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2639 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2640 return;
2641
2642 if (!effectUnit || m_spellInfo->Id == 45927)
2643 {
2644 uint8 farMask = 0;
2645 // create far target mask
2646 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2647 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2648 if ((1 << i) & mask)
2649 farMask |= (1 << i);
2650
2651 if (!farMask)
2652 return;
2653 // find unit in world
2654 // Xinef: FindUnit Access without Map check!!! Intended
2655 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2656 if (!effectUnit)
2657 return;
2658
2659 // do far effects on the unit
2660 // can't use default call because of threading, do stuff as fast as possible
2661 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2662 if (farMask & (1 << i))
2663 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2664 return;
2665 }
2666
2667 if (effectUnit->IsAlive() != target->alive)
2668 return;
2669
2670 // Absorb delayed projectiles launched before Sanctuary (e.g. Vanish dodging a Frostbolt in flight)
2672 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime)
2673 return; // No missinfo in that case
2674
2675 // Absorb instant hostile spells on application within brief window after Sanctuary
2677 effectUnit->m_lastSanctuaryTime &&
2678 GameTime::GetGameTimeMS().count() <= (effectUnit->m_lastSanctuaryTime + 400))
2679 return; // No missinfo in that case
2680
2681 // Get original caster (if exist) and calculate damage/healing from him data
2682 // (can be nullptr for GameObject casts with no owner - unit-dependent handling is skipped then)
2684
2685 SpellMissInfo missInfo = target->missCondition;
2686
2687 // Need init unitTarget by default unit (can changed in code on reflect)
2688 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2689 unitTarget = effectUnit;
2690
2691 // Reset damage/healing counter
2692 m_damage = target->damage;
2693 m_healing = -target->damage;
2694
2695 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2696
2698 effectUnit->SetInCombatWith(m_originalCaster);
2699
2702
2703 //Spells with this flag cannot trigger if effect is casted on self
2705 bool reflectedSpell = missInfo == SPELL_MISS_REFLECT;
2706 Unit* reflectionSource = nullptr;
2707 Unit* spellHitTarget = nullptr;
2708
2709 if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
2710 spellHitTarget = unitTarget;
2711 else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
2712 {
2713 missInfo = target->reflectResult;
2714 if (missInfo == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
2715 {
2716 // gameobject casts bounce onto the original caster (e.g. a reflected trap spell freezes the trap owner)
2717 Unit* reflectDest = unitCaster ? unitCaster : m_originalCaster;
2718 if (reflectDest)
2719 {
2720 spellHitTarget = reflectDest;
2721 unitTarget = reflectDest;
2722 reflectionSource = effectUnit;
2723 if (reflectDest->IsCreature())
2724 reflectDest->ToCreature()->LowerPlayerDamageReq(target->damage);
2725 }
2726 }
2727 }
2728
2729 if (spellHitTarget)
2730 {
2731 if (reflectionSource)
2732 {
2733 m_reflectionTarget = reflectionSource;
2734 m_reflectionTargetGuid = reflectionSource->GetGUID();
2735 m_reflectionTargetPosition.Relocate(reflectionSource);
2736 }
2737 else
2738 {
2739 m_reflectionTarget = nullptr;
2742 }
2743
2744 SpellMissInfo missInfo2 = DoSpellHitOnUnit(spellHitTarget, mask, target->scaleAura);
2745
2746 m_reflectionTarget = nullptr;
2749 if (missInfo2 != SPELL_MISS_NONE)
2750 {
2751 if (missInfo2 != SPELL_MISS_MISS)
2752 m_caster->SendSpellMiss(spellHitTarget, m_spellInfo->Id, missInfo2);
2753 m_damage = 0;
2754 spellHitTarget = nullptr;
2755
2756 // Xinef: if missInfo2 is MISS_EVADE, override base missinfo data
2757 if (missInfo2 == SPELL_MISS_EVADE)
2758 missInfo = SPELL_MISS_EVADE;
2759 }
2760 }
2761
2762 // Do not take combo points on dodge and miss
2763 if (missInfo != SPELL_MISS_NONE && m_needComboPoints && m_targets.GetUnitTargetGUID() == target->targetGUID)
2764 {
2765 m_needComboPoints = false;
2766 // Restore spell mods for a miss/dodge/parry Cold Blood
2768 if (unitCaster && unitCaster->IsPlayer() && (missInfo == SPELL_MISS_MISS || missInfo == SPELL_MISS_DODGE || missInfo == SPELL_MISS_PARRY))
2769 unitCaster->ToPlayer()->RestoreSpellMods(this, 14177);
2770 }
2771
2772 // Fill base trigger info
2773 uint32 procAttacker = m_procAttacker;
2774 uint32 procVictim = m_procVictim;
2775
2776 // Trigger info was not filled in spell::preparedatafortriggersystem - we do it now
2777 if (canEffectTrigger && !procAttacker && !procVictim)
2778 {
2779 bool positive = true;
2780 if (m_damage > 0)
2781 positive = false;
2782 else if (!m_healing)
2783 {
2784 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2785 // If at least one effect negative spell is negative hit
2786 // Xinef: if missInfo is immune state check all effects to properly determine positiveness of spell
2787 if ((missInfo == SPELL_MISS_IMMUNE2 || (mask & (1 << i))) && !m_spellInfo->IsPositiveEffect(i))
2788 {
2789 positive = false;
2790 break;
2791 }
2792 }
2793 switch (m_spellInfo->DmgClass)
2794 {
2796 if (positive)
2797 {
2800 }
2801 else
2802 {
2805 }
2806 break;
2808 if (positive)
2809 {
2812 }
2813 else
2814 {
2817 }
2818 break;
2819 }
2820 }
2822
2823 // All calculated do it!
2824 // Skip unit-caster dependent damage/healing/proc handling if no unit caster is available (pure GameObject casts)
2825 if (caster)
2826 {
2827 // Do healing and triggers
2828 if (m_healing > 0)
2829 {
2830 bool crit = target->crit;
2831 uint32 addhealth = m_healing;
2832
2833 if (crit)
2834 addhealth = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, addhealth, nullptr);
2835
2836 HealInfo healInfo(caster, unitTarget, addhealth, m_spellInfo, m_spellInfo->GetSchoolMask());
2837
2838 // Heal amount before SpellHealingBonusTaken, used by Beacon of Light
2839 if (target->damageBeforeTakenMods != 0)
2840 {
2841 uint32 healBeforeTakenMods = uint32(-target->damageBeforeTakenMods);
2842 if (crit)
2843 healBeforeTakenMods = Unit::SpellCriticalHealingBonus(caster, m_spellInfo, healBeforeTakenMods, nullptr);
2844 healInfo.SetHealBeforeTakenMods(healBeforeTakenMods);
2845 }
2846 else
2847 healInfo.SetHealBeforeTakenMods(addhealth);
2848
2849 // Set hitMask based on crit
2850 if (crit)
2851 healInfo.AddHitMask(PROC_HIT_CRITICAL);
2852 else
2853 healInfo.AddHitMask(PROC_HIT_NORMAL);
2854
2855 // Xinef: override with forced crit, only visual result
2856 if (GetSpellValue()->ForcedCritResult)
2857 {
2858 crit = true;
2859 healInfo.AddHitMask(PROC_HIT_CRITICAL);
2860 }
2861
2862 int32 gain = caster->HealBySpell(healInfo, crit);
2863 float threat = float(gain) * 0.5f;
2864 if (caster->IsClass(CLASS_PALADIN))
2865 threat *= 0.5f;
2867 m_healing = gain;
2868
2869 // Xinef: if heal actually healed something, add no overheal flag
2870 if (m_healing)
2871 healInfo.AddHitMask(PROC_EX_NO_OVERHEAL);
2872
2873 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2874 if (canEffectTrigger)
2875 {
2876 uint32 hitMask = m_procEx | healInfo.GetHitMask();
2877 Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, hitMask, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2878 m_triggeredByAuraSpell.effectIndex, this, nullptr, &healInfo);
2879 }
2880 }
2881 // Do damage and triggers
2882 else if (m_damage > 0)
2883 {
2885
2886 // Fill base damage struct (unitTarget - is real spell target)
2888
2889 // Check damage immunity
2891 {
2892 m_damage = 0;
2893
2894 // no packet found in sniffs
2895 }
2896 else
2897 {
2898 // Add bonuses and fill damageInfo struct
2899 // Dancing Rune Weapon...
2900 if (unitCaster && unitCaster->GetEntry() == 27893)
2901 {
2902 if (Unit* owner = unitCaster->GetOwner())
2903 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2904 }
2905 else
2906 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2907
2908 // xinef: override miss info after absorb / block calculations
2909 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2910 {
2911 //if (damageInfo.absorb > 0)
2912 // missInfo = SPELL_MISS_ABSORB;
2913 if (damageInfo.blocked)
2914 missInfo = SPELL_MISS_BLOCK;
2915 }
2916
2917 // Xinef: override with forced crit, only visual result
2918 if (GetSpellValue()->ForcedCritResult)
2919 {
2920 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2921 }
2922
2923 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2924
2925 // xinef: health leech handling
2927 {
2928 uint8 effIndex = EFFECT_0;
2929 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2930 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2931 break;
2932
2933 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2934
2935 // get max possible damage, don't count overkill for heal
2936 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2937
2938 if (unitCaster && unitCaster->IsAlive())
2939 {
2940 healthGain = unitCaster->SpellHealingBonusDone(unitCaster, m_spellInfo, healthGain, HEAL, effIndex);
2941 healthGain = unitCaster->SpellHealingBonusTaken(unitCaster, m_spellInfo, healthGain, HEAL);
2942
2943 HealInfo healInfo(unitCaster, unitCaster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2944 unitCaster->HealBySpell(healInfo);
2945 }
2946 }
2947
2948 // Send log damage message to client
2949 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2950 // Xinef: send info to target about reflect
2951 if (reflectedSpell)
2952 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2953
2954 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2955
2956 caster->DealSpellDamage(&damageInfo, true, this);
2957
2958 // do procs after damage, eg healing effects
2959 // no need to check if target is alive, done in procdamageandspell
2960
2961 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2962 if (canEffectTrigger)
2963 {
2964 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE, m_attackType, missInfo);
2965 uint32 hitMask = m_procEx | dmgInfo.GetHitMask();
2966 Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, hitMask, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2967 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2968
2971 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, dmgInfo.GetHitMask());
2972 }
2973
2974 m_damage = damageInfo.damage;
2975 }
2976 }
2977 // Passive spell hits/misses or active spells only misses (only triggers)
2978 else
2979 {
2980 // Fill base damage struct (unitTarget - is real spell target)
2982 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2983 if (canEffectTrigger)
2984 {
2985 DamageInfo dmgInfo(damageInfo, NODAMAGE, m_attackType, missInfo);
2986 uint32 hitMask = m_procEx | dmgInfo.GetHitMask();
2987 Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, hitMask, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2988 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2989
2990 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2991 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2992 if ((dmgInfo.GetHitMask() & (PROC_HIT_NORMAL | PROC_HIT_CRITICAL)) && caster->IsPlayer() && m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT) == 0 &&
2994 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim | PROC_FLAG_TAKEN_DAMAGE, dmgInfo.GetHitMask());
2995 }
2996
2997 // Failed Pickpocket, reveal rogue
2999 {
3001 unitTarget->ToCreature()->EngageWithTarget(unitCaster);
3002 }
3003 }
3004 }
3005 else if (m_healing > 0 && unitTarget && unitTarget->IsAlive())
3006 {
3007 // pure gameobject cast without an owner: heal anyway, mirroring the damage case below
3009 }
3010 else if (m_damage > 0 && unitTarget && unitTarget->IsAlive())
3011 {
3012 // pure gameobject cast without an owner (e.g. world traps): deal the calculated
3013 // spell damage anyway, mitigated by the victim, without caster bonuses, crits or procs
3015 m_damage = 0;
3016 else
3017 {
3021
3023 Unit::CalcAbsorbResist(dmgInfo);
3024
3025 uint32 absorb = dmgInfo.GetAbsorb();
3026 uint32 resist = dmgInfo.GetResist();
3027 damage = dmgInfo.GetDamage();
3029
3030 // log the damage with the gameobject as the source
3032
3035 }
3036 }
3037
3038 if (unitCaster)
3039 {
3040 if (missInfo != SPELL_MISS_EVADE && !unitCaster->IsFriendlyTo(effectUnit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)))
3041 {
3044
3045 // Spells that don't initiate combat shouldn't affect stand state (e.g. Premeditation, Storm Giant/Felreaver Passive)
3046 if (m_spellInfo->HasInitialAggro() && !effectUnit->IsStandState())
3048 }
3049 }
3050
3051 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && unitCaster && unitCaster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
3053 {
3054 unitCaster->SetInCombatWith(effectUnit);
3055 }
3056
3057 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
3058 if (caster && m_spellInfo->HasAttribute(SPELL_ATTR7_CAN_CAUSE_INTERRUPT) && !effectUnit->IsPlayer())
3059 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
3060
3061 if (spellHitTarget)
3062 {
3063 //AI functions
3064 if (spellHitTarget->IsCreature())
3065 {
3066 if (spellHitTarget->ToCreature()->IsAIEnabled)
3067 spellHitTarget->ToCreature()->AI()->SpellHit(unitCaster, m_spellInfo);
3068 }
3069
3070 if (unitCaster && unitCaster->IsCreature() && unitCaster->ToCreature()->IsAIEnabled)
3071 unitCaster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
3072
3073 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
3074 DoTriggersOnSpellHit(spellHitTarget, mask);
3075
3076 // if target is fallged for pvp also flag caster if a player
3077 // xinef: do not flag spells with aura bind sight (no special attribute)
3078 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
3079 unitCaster && unitCaster->IsPlayer() && !m_spellInfo->HasAttribute(SPELL_ATTR0_CU_NO_PVP_FLAG))
3080 {
3081 unitCaster->ToPlayer()->UpdatePvP(true);
3082 }
3083
3085 }
3086}
@ 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
@ SPELL_SCHOOL_MASK_NORMAL
Definition SharedDefines.h:285
@ AURA_INTERRUPT_FLAG_TALK
Definition SpellDefines.h:61
@ 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:3926
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:10142
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition Player.cpp:7408
void UpdatePvP(bool state, bool _override=false)
Definition PlayerUpdates.cpp:1557
ObjectGuid GetUnitTargetGUID() const
Definition Spell.cpp:253
bool HasInitialAggro() const
Definition SpellInfo.cpp:1333
bool IsAuraEffectEqual(SpellInfo const *otherSpellInfo) const
Definition SpellInfo.cpp:1616
bool IsPositiveEffect(uint8 effIndex) const
Definition SpellInfo.cpp:1287
bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const *triggeredByAura=nullptr) const
Definition Spell.cpp:9114
SpellValue const * GetSpellValue()
Definition Spell.h:604
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition Spell.cpp:3088
Position m_reflectionTargetPosition
Definition Spell.h:683
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition Spell.cpp:3350
void ForwardThreatForAssistingMe(Unit *assistant, float baseAmount, SpellInfo const *spell=nullptr, bool ignoreModifiers=false)
== AFFECT OTHERS' THREAT LISTS ==
Definition ThreatManager.cpp:764
uint32 m_lastSanctuaryTime
Definition Unit.h:2095
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition Unit.cpp:1652
void SetInCombatWith(Unit *enemy, bool addSecondUnitSuppressed=false)
Definition Unit.h:945
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition Unit.cpp:6455
static uint32 CalcArmorReducedDamage(Unit const *attacker, Unit const *victim, const uint32 damage, SpellInfo const *spellInfo, uint8 attackerLevel=0, WeaponAttackType attackType=MAX_ATTACK)
Definition Unit.cpp:2229
bool CanProc()
Definition Unit.h:1562
bool IsPvP() const
Definition Unit.h:1050
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:9325
void AtTargetAttacked(Unit *target, bool canInitialAggro)
Definition Unit.cpp:11209
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition Unit.cpp:8140
bool IsStandState() const
Definition Unit.cpp:12716
static int32 DealHeal(Unit *healer, Unit *victim, uint32 addhealth)
Definition Unit.cpp:7844
int32 GetHealthGain(int32 dVal)
Definition Unit.cpp:10754
bool IsImmunedToDamage(SpellSchoolMask schoolMask) const
Definition Unit.cpp:9654
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition Unit.cpp:9200
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition Unit.cpp:6487
ThreatManager & GetThreatMgr()
Definition Unit.h:957
bool IsAIEnabled
Definition Unit.h:2102
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition Unit.h:977
virtual bool IsEngaged() const
Definition Unit.h:937
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition Unit.cpp:9445
void SetStandState(uint8 state)
Definition Unit.cpp:12731
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition Unit.cpp:5215
static void DealDamageMods(Unit const *victim, uint32 &damage, uint32 *absorb)
Definition Unit.cpp:980
void CalculateSpellDamageTaken(SpellNonMeleeDamage *damageInfo, int32 damage, SpellInfo const *spellInfo, WeaponAttackType attackType=BASE_ATTACK, bool crit=false)
Definition Unit.cpp:1505
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:990
static void CalcAbsorbResist(DamageInfo &dmgInfo, bool Splited=false, uint8 casterLevel=0)
Definition Unit.cpp:2340
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition Object.cpp:3830
void SendSpellNonMeleeDamageLog(Unit *target, SpellInfo const *spellInfo, uint32 damage, SpellSchoolMask schoolMask, uint32 absorb, uint32 resist)
Definition Object.cpp:3844
virtual uint8 getLevelForTarget(WorldObject const *) const
Definition Object.h:576
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::CalcAbsorbResist(), Unit::CalcArmorReducedDamage(), Unit::CalculateSpellDamageTaken(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), CanExecuteTriggersOnHit(), Unit::CanProc(), Player::CastItemCombatSpell(), Unit::CastSpell(), CLASS_PALADIN, ObjectGuid::Clear(), TargetInfo::crit, SpellNonMeleeDamage::damage, TargetInfo::damage, damage, TargetInfo::damageBeforeTakenMods, Unit::DealDamage(), Unit::DealDamageMods(), Unit::DealHeal(), Unit::DealSpellDamage(), SpellInfo::DmgClass, DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EFFECT_0, TriggeredByAuraSpellData::effectIndex, TargetInfo::effectMask, SpellInfo::Effects, Unit::EngageWithTarget(), ObjectAccessor::FindPlayer(), ThreatManager::ForwardThreatForAssistingMe(), DamageInfo::GetAbsorb(), DamageInfo::GetDamage(), Object::GetEntry(), GameTime::GetGameTimeMS(), Object::GetGUID(), Unit::GetHealthGain(), DamageInfo::GetHitMask(), HealInfo::GetHitMask(), WorldObject::getLevelForTarget(), Unit::GetOwner(), Unit::GetOwnerGUID(), DamageInfo::GetResist(), 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, WorldObject::SendSpellMiss(), Unit::SendSpellNonMeleeDamageLog(), WorldObject::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_SCHOOL_MASK_NORMAL, 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(), Object::ToUnit(), 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 
)
1753{
1754 Unit* unitCaster = m_caster->ToUnit();
1755 if (!unitTarget)
1756 return;
1757
1758 Player* player = unitTarget->ToPlayer();
1759 if (!player)
1760 {
1761 return;
1762 }
1763
1764 uint32 newitemid = itemId;
1765
1766 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1767 if (!pProto)
1768 {
1769 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1770 return;
1771 }
1772
1773 uint32 addNumber = damage;
1774
1775 // bg reward have some special in code work
1776 bool SelfCast = true;
1777 switch (m_spellInfo->Id)
1778 {
1783 case SPELL_WS_MARK_TIE:
1786 SelfCast = true;
1787 break;
1789 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1790 addNumber = 3;
1791 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1792 addNumber = 2;
1793 else
1794 addNumber = 1;
1795 SelfCast = true;
1796 break;
1797 }
1798
1799 if (addNumber < 1)
1800 addNumber = 1;
1801 if (addNumber > pProto->GetMaxStackSize())
1802 addNumber = pProto->GetMaxStackSize();
1803
1804 /* == gem perfection handling == */
1805
1806 // the chance of getting a perfect result
1807 float perfectCreateChance = 0.0f;
1808
1809 // the resulting perfect item if successful
1810 uint32 perfectItemType = itemId;
1811
1812 // get perfection capability and chance
1813 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1814 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1815 newitemid = perfectItemType; // the perfect item replaces the regular one
1816
1817 /* == gem perfection handling over == */
1818
1819 /* == profession specialization handling == */
1820
1821 // init items_count to 1, since 1 item will be created regardless of specialization
1822 int32 itemsCount = 1;
1823 float additionalCreateChance = 0.0f;
1824 int32 additionalMaxNum = 0;
1825 // get the chance and maximum number for creating extra items
1826 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1827 {
1828 // roll with this chance till we roll not to create or we create the max num
1829 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1830 ++itemsCount;
1831 }
1832
1833 // really will be created more items
1834 addNumber *= itemsCount;
1835
1836 /* == profession specialization handling over == */
1837
1838 // can the player store the new item?
1839 ItemPosCountVec dest;
1840 uint32 no_space = 0;
1841 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1842 if (msg != EQUIP_ERR_OK)
1843 {
1844 // convert to possible store amount
1846 addNumber -= no_space;
1847 else
1848 {
1849 // if not created by another reason from full inventory or unique items amount limitation
1850 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1851 return;
1852 }
1853 }
1854
1855 if (addNumber)
1856 {
1857 // create the new item and store it
1858 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1859
1860 // was it successful? return error if not
1861 if (!pItem)
1862 {
1863 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1864 return;
1865 }
1866
1867 // set the "Crafted by ..." property of the item
1868 if (unitCaster && unitCaster->IsPlayer() && pItem->GetTemplate()->HasSignature())
1869 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1870
1871 // send info to the client
1872 player->SendNewItem(pItem, addNumber, true, SelfCast);
1873
1874 sScriptMgr->OnPlayerCreateItem(player, pItem, addNumber);
1875
1876 // we succeeded in creating at least one item, so a levelup is possible
1877 if (SelfCast)
1879 }
1880}
@ 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:721
bool UpdateCraftSkill(uint32 spellid)
Definition PlayerUpdates.cpp:851
void SendNewItem(Item *item, uint32 count, bool received, bool created, bool broadcast=false, bool sendChatMessage=true)
Definition PlayerStorage.cpp:4855
Item * StoreNewItem(ItemPosCountVec const &pos, uint32 item, bool update, int32 randomPropertyId=0, bool refund=false)
Definition PlayerStorage.cpp:2635
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(), Object::ToUnit(), 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
3089{
3090 Unit* unitCaster = m_caster->ToUnit();
3091 if (!unit || !effectMask)
3092 return SPELL_MISS_EVADE;
3093
3094 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
3095 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(unitCaster, m_spellInfo)) || unit->IsImmunedToSpell(m_spellInfo, this)))
3096 {
3097 return SPELL_MISS_IMMUNE;
3098 }
3099
3100 // disable effects to which unit is immune
3101 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
3102 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3103 {
3104 if (effectMask & (1 << effectNumber))
3105 {
3106 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber, unitCaster))
3107 effectMask &= ~(1 << effectNumber);
3108 // Xinef: Buggs out polymorph
3109 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
3110 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
3111 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
3112 {
3113 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3114 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3115
3116 if (debuff_resist_chance > 0)
3117 if (irand(0,10000) <= (debuff_resist_chance * 100))
3118 {
3119 effectMask &= ~(1 << effectNumber);
3120 returnVal = SPELL_MISS_RESIST;
3121 }
3122 }*/
3123 }
3124 }
3125 if (!effectMask)
3126 return returnVal;
3127
3128 if (unit->IsPlayer())
3129 {
3133 }
3134
3135 if (unitCaster && unitCaster->IsPlayer())
3136 {
3139 }
3140
3141 if (m_caster != unit)
3142 {
3143 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3144 // Xinef: Also check evade state
3145 if (m_spellInfo->Speed > 0.0f)
3146 {
3147 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
3148 return SPELL_MISS_EVADE;
3149
3151 return SPELL_MISS_EVADE;
3152 }
3153
3154 if (m_caster->IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3155 {
3157 }
3158 else if (m_caster->IsFriendlyTo(unit))
3159 {
3160 // for delayed spells ignore negative spells (after duel end) for friendly targets
3162 if (!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
3163 return SPELL_MISS_EVADE;
3164
3165 // assisting case, healing and resurrection
3167 {
3168 if (unitCaster)
3169 {
3170 unitCaster->SetContestedPvP();
3172 unitCaster->ToPlayer()->UpdatePvP(true);
3173 }
3174 }
3175
3176 // xinef: triggered spells should not prolong combat
3178 {
3181 unit->GetThreatMgr().ForwardThreatForAssistingMe(m_originalCaster, 0.0f, nullptr, true);
3182 }
3183 }
3184 }
3185
3186 uint8 aura_effmask = 0;
3187 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3188 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3189 aura_effmask |= 1 << i;
3190
3191 Unit* originalCaster = GetOriginalCaster();
3192 if (!originalCaster)
3193 originalCaster = unitCaster;
3194
3195 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3196 // Xinef: Do not increase diminishing level for self cast
3198 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3199 if (((m_spellFlags & SPELL_FLAG_REFLECTED) && !(unit->HasReflectSpellsAura())) || (aura_effmask && m_diminishGroup && unit != m_caster && (!unitCaster || !unitCaster->IsCreature() || !unitCaster->ToCreature()->isWorldBoss())))
3200 {
3203
3204 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3205
3206 // Increase Diminishing on unit, current informations for actually casts will use values above
3207 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3209 {
3210 // Do not apply diminish return if caster is NPC
3211 if (unitCaster && unitCaster->IsCharmedOwnedByPlayerOrPlayer())
3212 {
3214 }
3215 }
3216 }
3217
3220
3221 if (aura_effmask)
3222 {
3223 // Select rank for aura with level requirements only in specific cases
3224 // 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
3225 SpellInfo const* aurSpellInfo = m_spellInfo;
3226 int32 basePoints[3];
3227 if (scaleAura)
3228 {
3230 ASSERT(aurSpellInfo);
3231 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3232 {
3233 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3234 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3235 {
3236 aurSpellInfo = m_spellInfo;
3237 break;
3238 }
3239 }
3240 }
3241
3242 if (m_originalCaster)
3243 {
3244 bool refresh = false;
3246 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3247 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, ObjectGuid::Empty, &refresh, refreshPeriodic);
3248
3249 // xinef: if aura was not refreshed, add proc ex
3250 if (!refresh)
3252
3253 if (m_spellAura)
3254 {
3255 // Set aura stack amount to desired value
3257 {
3258 if (!refresh)
3260 else
3262 }
3263
3264 // Now Reduce spell duration using data received at spell hit
3265 int32 duration = m_spellAura->GetMaxDuration();
3266 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3267
3268 // Xinef: if unit == caster - test versus original unit if available
3269 float diminishMod = 1.0f;
3270 if (unit == m_caster && m_targets.GetUnitTarget())
3272 else
3273 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3274
3275 // unit is immune to aura if it was diminished to 0 duration
3276 if (diminishMod == 0.0f)
3277 {
3280 return SPELL_MISS_IMMUNE;
3281 bool found = false;
3282 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3283 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3284 found = true;
3285 if (!found)
3286 return SPELL_MISS_IMMUNE;
3287 }
3288 else
3289 {
3290 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3291
3292 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3294 positive = aurApp->IsPositive();
3295
3296 duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3297
3298 // xinef: haste affects duration of those spells twice
3301
3302 if (m_spellValue->AuraDuration != 0)
3303 {
3304 if (m_spellAura->GetMaxDuration() != -1)
3305 {
3307 }
3308
3310 }
3311 else if (duration != m_spellAura->GetMaxDuration())
3312 {
3313 m_spellAura->SetMaxDuration(duration);
3314 m_spellAura->SetDuration(duration);
3315 }
3316
3317 // xinef: apply relic cooldown, imo best place to add this
3319 if (unitCaster)
3320 unitCaster->AddSpellCooldown(SPELL_RELIC_COOLDOWN, m_CastItem->GetEntry(), duration);
3321
3324 }
3325 }
3326 }
3327 }
3328
3329 int8 sanct_effect = -1;
3330
3331 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3332 {
3333 // handle sanctuary effects after aura apply!
3334 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3335 {
3336 sanct_effect = effectNumber;
3337 continue;
3338 }
3339
3340 if (effectMask & (1 << effectNumber))
3341 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3342 }
3343
3344 if (sanct_effect >= 0 && (effectMask & (1 << sanct_effect)))
3345 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3346
3347 return SPELL_MISS_NONE;
3348}
@ 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:51
@ TRIGGERED_NO_PERIODIC_RESET
Will ignore equipped item requirements.
Definition SpellDefines.h:160
@ 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:130
void SetStackAmount(uint8 num)
Definition SpellAuras.cpp:1030
AuraApplication const * GetApplicationOfTarget(ObjectGuid guid) const
Definition SpellAuras.h:185
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition SpellAuras.cpp:2856
void _RegisterForTargets()
Definition SpellAuras.h:122
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition SpellAuras.cpp:1056
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:903
void SetMaxDuration(int32 duration)
Definition SpellAuras.h:131
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:315
uint32 StackAmount
Definition SpellInfo.h:395
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition SpellInfo.cpp:2959
Unit * GetOriginalCaster() const
Definition Spell.h:591
Definition SpellAuras.h:290
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition Unit.cpp:5804
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition Unit.cpp:11349
void IncrDiminishing(DiminishingGroup group)
Definition Unit.cpp:11375
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition Unit.cpp:13265
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:748
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition Unit.cpp:11389
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition Unit.h:1342
ObjectGuid GetCharmerOrOwnerGUID() const override
Definition Unit.h:1300
bool HasReflectSpellsAura() const
Definition Unit.h:1819
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition Unit.h:1314
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition Unit.cpp:9848
CombatManager & GetCombatManager()
Definition Unit.h:959
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask) const
Definition Object.cpp:3395
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:4002
bool IsHostileTo(WorldObject const *target) const
Definition Object.cpp:3992
bool IsFriendlyTo(WorldObject const *target) const
Definition Object.cpp:3997
uint32 flags_extra
Definition CreatureData.h:241
int32 AuraDuration
Definition Spell.h:229
uint8 AuraStackAmount
Definition Spell.h:228

References 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(), WorldObject::IsFriendlyTo(), WorldObject::IsHostileTo(), Unit::IsImmunedToDamage(), Unit::IsImmunedToSpell(), Unit::IsImmunedToSpellEffect(), Unit::IsInCombat(), Creature::IsInEvadeMode(), Object::IsPlayer(), SpellInfo::IsPositive(), IsTriggered(), WorldObject::IsValidAttackTarget(), 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, WorldObject::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(), Object::ToUnit(), 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
3351{
3352 Unit* unitCaster = m_caster->ToUnit();
3353 // Apply additional spell effects to target
3355 if (m_preCastSpell)
3356 {
3357 // Avenging Wrath - also apply Immune Shield Marker
3358 if (m_preCastSpell == 61987)
3359 m_caster->CastSpell(unit, 61988, true);
3360
3361 // Fearie Fire (Feral) - damage
3362 if (m_preCastSpell == 60089)
3363 m_caster->CastSpell(unit, m_preCastSpell, true);
3364 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3365 // Blizz seems to just apply aura without bothering to cast
3366 if (unitCaster)
3367 unitCaster->AddAura(m_preCastSpell, unit);
3368 }
3369
3370 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3371 // this is executed after spell proc spells on target hit
3372 // spells are triggered for each hit spell target
3373 // info confirmed with retail sniffs of permafrost and shadow weaving
3374 if (!m_hitTriggerSpells.empty())
3375 {
3376 int _duration = 0;
3377 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3378 {
3379 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3380 {
3381 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3382 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3383
3384 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3385 // set duration of current aura to the triggered spell
3386 if (i->triggeredSpell->GetDuration() == -1)
3387 {
3388 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3389 {
3390 // get duration from aura-only once
3391 if (!_duration)
3392 {
3393 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3394 _duration = aur ? aur->GetDuration() : -1;
3395 }
3396 triggeredAur->SetDuration(std::max(triggeredAur->GetDuration(), _duration));
3397 }
3398 }
3399 }
3400 }
3401 }
3402
3403 // trigger linked auras remove/apply
3405 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3406 {
3407 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3408 if (*i < 0)
3409 {
3410 unit->RemoveAurasDueToSpell(-(*i));
3411 }
3412 else
3413 {
3414 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3415 }
3416 }
3417}
bool roll_chance_i(int chance)
Definition Random.h:63
@ SPELL_LINK_HIT
Definition SpellMgr.h:100
int32 GetDuration() const
Definition SpellAuras.h:134
HitTriggerSpellList m_hitTriggerSpells
Definition Spell.h:782
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5624
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:14747

References Unit::AddAura(), CanExecuteTriggersOnHit(), WorldObject::CastSpell(), 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, sSpellMgr, and Object::ToUnit().

Referenced by DoAllEffectOnTarget().

◆ EffectActivateObject()

void Spell::EffectActivateObject ( SpellEffIndex  effIndex)
4450{
4452 return;
4453
4454 if (!gameObjTarget)
4455 return;
4456
4457 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4458 switch (action)
4459 {
4465 break;
4466 case GameObjectActions::Disturb: // What's the difference with Open?
4468 if (Unit* unitCaster = m_caster->ToUnit())
4469 gameObjTarget->Use(unitCaster);
4470 break;
4472 if (Unit* unitCaster = m_caster->ToUnit())
4473 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4474 [[fallthrough]];
4478 break;
4482 break;
4485 break;
4489 break;
4493 break;
4495 if (Unit* unitCaster = m_caster->ToUnit())
4496 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4497 break;
4502 {
4503 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4504
4505 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4506
4507 uint32 artKitValue = 0;
4508 if (templateAddon)
4509 artKitValue = templateAddon->artKits[artKitIndex];
4510
4511 if (artKitValue == 0)
4512 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4513 else
4514 gameObjTarget->SetGoArtKit(artKitValue);
4515
4516 break;
4517 }
4519 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4520 break;
4521 default:
4522 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4523 break;
4524 }
4525}
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:1429
void SetGoArtKit(uint8 artkit)
Definition GameObject.cpp:1443
void SendCustomAnim(uint32 anim)
Definition GameObject.cpp:2164
void ResetDoorOrButton()
Definition GameObject.cpp:1419
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition GameObject.cpp:928
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition GameObject.cpp:907
void Use(Unit *user)
Definition GameObject.cpp:1479
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:836
void ApplyModFlag(uint16 index, uint32 flag, bool apply)
Definition Object.cpp:890
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)
6082{
6083 Unit* unitCaster = m_caster->ToUnit();
6084 if (!unitCaster)
6085 return;
6086
6088 return;
6089
6090 if (!unitCaster->IsPlayer())
6091 return;
6092
6093 Player* player = unitCaster->ToPlayer();
6094
6096 return;
6097
6098 // needed later
6099 m_runesState = unitCaster->ToPlayer()->GetRunesState();
6100
6101 uint32 count = damage;
6102 if (count == 0) count = 1;
6103 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
6104 {
6105 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
6106 {
6107 if (m_spellInfo->Id == 45529)
6108 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
6109 continue;
6110 player->SetRuneCooldown(j, 0);
6111 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
6112 --count;
6113 }
6114 }
6115
6116 // Blood Tap
6117 if (m_spellInfo->Id == 45529 && count > 0)
6118 {
6119 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
6120 {
6121 // Check if both runes are on cd as that is the only time when this needs to come into effect
6122 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)))
6123 {
6124 // Should always update the rune with the lowest cd
6125 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
6126 l++;
6127 player->SetRuneCooldown(l, 0);
6128 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
6129 --count;
6130 }
6131 else
6132 break;
6133 }
6134 }
6135
6136 // Empower rune weapon
6137 if (m_spellInfo->Id == 47568)
6138 {
6139 // Need to do this just once
6140 if (effIndex != 0)
6141 return;
6142
6143 for (uint32 i = 0; i < MAX_RUNES; ++i)
6144 {
6145 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
6146 {
6147 player->SetRuneCooldown(i, 0);
6148 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
6149 }
6150 }
6151 }
6152
6153 // is needed to push through to the client that the rune is active
6154 //player->ResyncRunes(MAX_RUNES);
6155 unitCaster->CastSpell(unitCaster, 47804, true);
6156}
@ RUNE_FROST
Definition Player.h:398
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition Player.h:2565
uint8 GetRunesState() const
Definition Player.h:2554
void SetGracePeriod(uint8 index, uint32 period)
Definition Player.h:2566
RuneType GetBaseRune(uint8 index) const
Definition Player.h:2555

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, Object::ToPlayer(), and Object::ToUnit().

◆ EffectActivateSpec()

void Spell::EffectActivateSpec ( SpellEffIndex  effIndex)
6484{
6486 return;
6487
6488 if (!unitTarget)
6489 return;
6490
6491 if (Player* player = unitTarget->ToPlayer())
6492 {
6493 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6494 }
6495}

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

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4274{
4276 {
4277 return;
4278 }
4279
4280 if (!unitTarget || damage <= 0)
4281 {
4282 return;
4283 }
4284
4286}
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)
4894{
4896 {
4897 return;
4898 }
4899
4900 if (!unitTarget || !unitTarget->IsAlive())
4901 {
4902 return;
4903 }
4904
4906
4908}
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition Spell.cpp:5267
void AddExtraAttacks(uint32 count)
Definition Unit.cpp:2957

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

◆ EffectAddFarsight()

void Spell::EffectAddFarsight ( SpellEffIndex  effIndex)
2878{
2879 Unit* unitCaster = m_caster->ToUnit();
2880 if (!unitCaster)
2881 return;
2882
2884 return;
2885
2886 if (!unitCaster->IsPlayer())
2887 return;
2888
2889 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2890 int32 duration = m_spellInfo->GetDuration();
2891 // Caster not in world, might be spell triggered from aura removal
2892 if (!unitCaster->IsInWorld())
2893 return;
2894
2895 // Remove old farsight if exist
2896 bool updateViewerVisibility = unitCaster->RemoveDynObject(m_spellInfo->Id);
2897
2898 DynamicObject* dynObj = new DynamicObject();
2900 {
2901 delete dynObj;
2902 return;
2903 }
2904
2905 dynObj->SetDuration(duration);
2906 dynObj->SetCasterViewpoint(updateViewerVisibility);
2907}
@ 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:2764

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(), SPELL_EFFECT_HANDLE_HIT, and Object::ToUnit().

◆ EffectAddHonor()

void Spell::EffectAddHonor ( SpellEffIndex  effIndex)
2956{
2958 return;
2959
2960 if (!unitTarget->IsPlayer())
2961 return;
2962
2963 // not scale value for item based reward (/10 value expected)
2964 if (m_CastItem)
2965 {
2966 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2967 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2969 return;
2970 }
2971
2972 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2973 if (damage <= 50)
2974 {
2976 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2977 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2978 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2979 }
2980 else
2981 {
2982 //maybe we have correct honor_gain in damage already
2983 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2984 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2986 }
2987}
std::string ToString() const
Definition ObjectGuid.cpp:48
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition Player.cpp:6269
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)
1399{
1401 return;
1402
1403 if (!m_spellAura || !unitTarget)
1404 return;
1407}
WorldObject * GetOwner() const
Definition SpellAuras.h:108
void _ApplyEffectForTargets(uint8 effIndex)
Definition SpellAuras.cpp:770

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)
4528{
4529 Unit* unitCaster = m_caster->ToUnit();
4530 if (!unitCaster)
4531 return;
4532
4534 return;
4535
4536 if (!unitCaster->IsPlayer() || m_glyphIndex >= MAX_GLYPH_SLOT_INDEX)
4537 return;
4538
4539 Player* player = unitCaster->ToPlayer();
4540
4541 // glyph sockets level requirement
4542 uint8 minLevel = 0;
4543 switch (m_glyphIndex)
4544 {
4545 case 0:
4546 case 1:
4547 minLevel = 15;
4548 break;
4549 case 2:
4550 minLevel = 50;
4551 break;
4552 case 3:
4553 minLevel = 30;
4554 break;
4555 case 4:
4556 minLevel = 70;
4557 break;
4558 case 5:
4559 minLevel = 80;
4560 break;
4561 }
4562 if (minLevel && unitCaster->GetLevel() < minLevel)
4563 {
4565 return;
4566 }
4567
4568 // apply new one
4569 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4570 {
4571 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4572 {
4573 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4574 {
4575 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4576 {
4578 return; // glyph slot mismatch
4579 }
4580 }
4581
4582 // remove old glyph aura
4583 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4584 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4585 {
4586 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4587
4588 // Removed any triggered auras
4589 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4590 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4591 {
4592 Aura* aura = iter->second;
4593 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4594 {
4595 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4596 {
4597 player->RemoveOwnedAura(iter);
4598 continue;
4599 }
4600 }
4601 ++iter;
4602 }
4603
4604 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4605 }
4606
4607 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4609 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4610 player->SendTalentsInfoData(false);
4611 }
4612 }
4613}
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:158
SpellInfo const * GetTriggeredByAuraSpellInfo() const
Definition SpellAuras.cpp:2870
void SendTalentsInfoData(bool pet)
Definition Player.cpp:14858
void SendLearnPacket(uint32 spellId, bool learn)
Definition Player.cpp:3137
uint32 GetGlyph(uint8 slot) const
Definition Player.h:1793
uint32 GetGlyphSlot(uint8 slot) const
Definition Player.h:1784
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition Player.h:1785
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4730
boost::container::flat_multimap< uint32, Aura * > AuraMap
Definition Unit.h:670
AuraMap & GetOwnedAuras()
Definition Unit.h:1378
bool PlayerLoading() const
Definition WorldSession.h:450
Definition DBCStructure.h:1068

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(), Object::ToUnit(), TRIGGERED_FULL_MASK, TRIGGERED_IGNORE_CASTER_AURASTATE, and TRIGGERED_IGNORE_SHAPESHIFT.

◆ EffectBind()

void Spell::EffectBind ( SpellEffIndex  effIndex)
6625{
6626 Unit* unitCaster = m_caster->ToUnit();
6627 if (!unitCaster)
6628 return;
6629
6631 return;
6632
6633 if (!unitTarget)
6634 return;
6635
6636 Player* player = unitTarget->ToPlayer();
6637 if (!player)
6638 {
6639 return;
6640 }
6641
6642 WorldLocation homeLoc;
6643 uint32 areaId = player->GetAreaId();
6644
6645 if (m_spellInfo->Effects[effIndex].MiscValue)
6646 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6647
6648 if (m_targets.HasDst())
6649 homeLoc.WorldRelocate(*destTarget);
6650 else
6651 {
6652 homeLoc = player->GetWorldLocation();
6653 }
6654
6655 player->SetHomebind(homeLoc, areaId);
6656
6657 // binding
6658 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6659 data << float(homeLoc.GetPositionX());
6660 data << float(homeLoc.GetPositionY());
6661 data << float(homeLoc.GetPositionZ());
6662 data << uint32(homeLoc.GetMapId());
6663 data << uint32(areaId);
6664 player->SendDirectMessage(&data);
6665
6666 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6667 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6668 // zone update
6669 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6670 data << unitCaster->GetGUID();
6671 data << uint32(areaId);
6672 player->SendDirectMessage(&data);
6673}
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5864
void SetHomebind(WorldLocation const &loc, uint32 areaId)
Definition PlayerStorage.cpp:5001
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(), Object::ToUnit(), unitTarget, and WorldLocation::WorldRelocate().

◆ EffectBlock()

void Spell::EffectBlock ( SpellEffIndex  effIndex)
4924{
4925 Unit* unitCaster = m_caster->ToUnit();
4926 if (!unitCaster)
4927 return;
4928
4930 return;
4931
4932 if (unitCaster->IsPlayer())
4933 unitCaster->ToPlayer()->SetCanBlock(true);
4934}
void SetCanBlock(bool value)
Definition Player.cpp:13463

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

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

6544{
6545 Unit* unitCaster = m_caster->ToUnit();
6546 if (!unitCaster)
6547 return;
6548
6550 return;
6551
6552 if (!unitCaster->IsPlayer())
6553 return;
6554
6555 Player* p_caster = unitCaster->ToPlayer();
6556 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6557 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6558
6559 for (; n_buttons; --n_buttons, ++button_id)
6560 {
6561 ActionButton const* ab = p_caster->GetActionButton(button_id);
6562 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6563 continue;
6564
6567 uint32 spell_id = ab->GetAction();
6568 if (!spell_id)
6569 continue;
6570
6571 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6572 if (!spellInfo)
6573 continue;
6574
6575 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6576 continue;
6577
6579 continue;
6580
6581 uint32 cost = spellInfo->CalcPowerCost(unitCaster, spellInfo->GetSchoolMask(), this);
6582 if (unitCaster->GetPower(POWER_MANA) < cost)
6583 continue;
6584
6586 unitCaster->CastSpell(unitCaster, spell_id, triggerFlags);
6587 }
6588}
@ 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:5823
bool HasSpell(uint32 spell) const override
Definition Player.cpp:4051
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(), Object::ToUnit(), TRIGGERED_CAST_DIRECTLY, TRIGGERED_IGNORE_CAST_IN_PROGRESS, and TRIGGERED_IGNORE_GCD.

◆ EffectCharge()

void Spell::EffectCharge ( SpellEffIndex  effIndex)
5159{
5160 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5161 if (!unitCaster)
5162 return;
5163
5165 {
5166 if (!unitTarget)
5167 return;
5168
5169 ObjectGuid targetGUID = ObjectGuid::Empty;
5170 Player* player = unitCaster->ToPlayer();
5171 if (player)
5172 {
5173 // charge changes fall time
5174 player->SetFallInformation(GameTime::GetGameTime().count(), unitCaster->GetPositionZ());
5175
5177 {
5178 targetGUID = unitTarget->GetGUID();
5179 }
5180 }
5181
5182 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
5183 // Spell is not using explicit target - no generated path
5184 if (!m_preGeneratedPath)
5185 {
5187 unitCaster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
5188 }
5189 else
5190 {
5191 unitCaster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
5192 }
5193
5194 if (player)
5195 {
5196 sScriptMgr->AnticheatSetUnderACKmount(player);
5197 }
5198 }
5199}
#define SPEED_CHARGE
Definition MotionMaster.h:136
@ 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:822
static ObjectGuid const Empty
Definition ObjectGuid.h:123
void SetFallInformation(uint32 time, float z)
Definition Player.h:2384
MotionMaster * GetMotionMaster()
Definition Unit.h:1761
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition Object.cpp:2947
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(), GetUnitCasterForEffectHandlers(), SpellInfo::HasAttribute(), SpellInfo::IsPositive(), 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()

void Spell::EffectChargeDest ( SpellEffIndex  effIndex)
5202{
5203 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5204 if (!unitCaster)
5205 return;
5206
5208 return;
5209
5210 if (m_targets.HasDst())
5211 {
5213
5214 if (!unitCaster->IsWithinLOS(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()))
5215 {
5216 float angle = unitCaster->GetRelativeAngle(pos.GetPositionX(), pos.GetPositionY());
5217 float dist = unitCaster->GetDistance(pos);
5218 pos = unitCaster->GetFirstCollisionPosition(dist, angle);
5219 }
5220
5221 unitCaster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ);
5222
5223 if (unitCaster->IsPlayer())
5224 {
5225 sScriptMgr->AnticheatSetUnderACKmount(unitCaster->ToPlayer());
5226 }
5227 }
5228}

References destTarget, effectHandleMode, WorldObject::GetDistance(), WorldObject::GetFirstCollisionPosition(), Unit::GetMotionMaster(), Position::GetPosition(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Position::GetRelativeAngle(), GetUnitCasterForEffectHandlers(), SpellCastTargets::HasDst(), Object::IsPlayer(), WorldObject::IsWithinLOS(), Position::m_positionX, Position::m_positionY, Position::m_positionZ, m_targets, MotionMaster::MoveCharge(), SPELL_EFFECT_HANDLE_LAUNCH, sScriptMgr, and Object::ToPlayer().

◆ EffectCreateItem()

void Spell::EffectCreateItem ( SpellEffIndex  effIndex)
1883{
1885 return;
1886
1887 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1888 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1889}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition Spell.cpp:5295
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition SpellEffects.cpp:1752

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);
1892{
1894 return;
1895
1896 if (!unitTarget)
1897 return;
1898
1899 Player* player = unitTarget->ToPlayer();
1900 if (!player)
1901 {
1902 return;
1903 }
1904
1905 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1906
1907 if (itemId)
1908 DoCreateItem(effIndex, itemId);
1909
1910 // special case: fake item replaced by generate using spell_loot_template
1912 {
1913 if (itemId)
1914 {
1915 if (!player->HasItemCount(itemId))
1916 return;
1917
1918 // remove reagent
1919 uint32 count = 1;
1920 player->DestroyItemCount(itemId, count, true);
1921
1922 // create some random items
1924 }
1925 else
1926 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1927 }
1929}
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:13826
void DestroyItemCount(uint32 item, uint32 count, bool update, bool unequip_check=false)
Definition PlayerStorage.cpp:3225
bool IsLootCrafting() const
Definition SpellInfo.cpp:961

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);
1932{
1934 return;
1935
1936 if (!unitTarget)
1937 return;
1938
1939 Player* player = unitTarget->ToPlayer();
1940 if (!player)
1941 {
1942 return;
1943 }
1944
1945 // create some random items
1948}

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)
6159{
6161 return;
6162
6164 return;
6165
6166 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
6167 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
6168 if (!pet)
6169 return;
6170
6171 // add to world
6172 pet->GetMap()->AddToMap(pet->ToCreature(), true);
6173
6174 // unitTarget has pet now
6175 unitTarget->SetMinion(pet, true);
6176
6177 pet->InitTalentForLevel();
6178
6179 if (unitTarget->IsPlayer())
6180 {
6183 }
6184}
@ CLASS_HUNTER
Definition SharedDefines.h:128
bool AddToMap(T *, bool checkTransport=false)
Definition Map.cpp:307
void InitTalentForLevel()
Definition Pet.cpp:2216
void SavePetToDB(PetSaveMode mode)
Definition Pet.cpp:502
void PetSpellInitialize()
Definition Player.cpp:9752
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:7572
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition Unit.cpp:13368

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)
5530{
5531 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5532 if (!unitCaster)
5533 return;
5534
5536 return;
5537
5538 int32 mana = 0;
5539 for (uint8 slot = SUMMON_SLOT_TOTEM_FIRE; slot < MAX_TOTEM_SLOT; ++slot)
5540 {
5541 if (!unitCaster->m_SummonSlot[slot])
5542 continue;
5543
5544 Creature* totem = unitCaster->GetMap()->GetCreature(unitCaster->m_SummonSlot[slot]);
5545 if (totem && totem->IsTotem())
5546 {
5547 uint32 spell_id = totem->GetUInt32Value(UNIT_CREATED_BY_SPELL);
5548 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
5549 if (spellInfo)
5550 {
5551 mana += spellInfo->ManaCost;
5552 mana += int32(CalculatePct(unitCaster->GetCreateMana(), spellInfo->ManaCostPercentage));
5553 }
5554 totem->ToTotem()->UnSummon();
5555 }
5556 }
5557 ApplyPct(mana, damage);
5558 if (mana)
5559 unitCaster->CastCustomSpell(unitCaster, 39104, &mana, nullptr, nullptr, true);
5560}
#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:2442
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:1429
uint32 GetCreateMana() const
Definition Unit.h:1154
ObjectGuid m_SummonSlot[MAX_SUMMON_SLOT]
Definition Unit.h:2083

References ApplyPct(), CalculatePct(), Unit::CastCustomSpell(), damage, effectHandleMode, Unit::GetCreateMana(), Map::GetCreature(), WorldObject::GetMap(), Object::GetUInt32Value(), GetUnitCasterForEffectHandlers(), Unit::IsTotem(), 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)
6187{
6189 return;
6190
6191 if (!unitTarget)
6192 return;
6193
6194 Player* player = unitTarget->ToPlayer();
6195 if (!player)
6196 {
6197 return;
6198 }
6199
6200 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
6201 if (sTaxiNodesStore.LookupEntry(nodeid))
6202 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
6203}
DBCStorage< TaxiNodesEntry > sTaxiNodesStore(TaxiNodesEntryfmt)
void SendDiscoverNewTaxiNode(uint32 nodeid)
Definition TaxiHandler.cpp:154

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)
4673{
4674 Unit* unitCaster = m_caster->ToUnit();
4675 if (!unitCaster)
4676 return;
4677
4679 return;
4680
4682 return;
4683
4684 if (Player* caster = unitCaster->ToPlayer())
4685 {
4686 caster->UpdateCraftSkill(m_spellInfo->Id);
4687 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4688 }
4689
4690 // item will be removed at disenchanting end
4691}
@ 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, Object::ToPlayer(), and Object::ToUnit().

◆ EffectDismissPet()

void Spell::EffectDismissPet ( SpellEffIndex  effIndex)
4767{
4769 return;
4770
4771 if (!unitTarget || !unitTarget->IsPet())
4772 return;
4773
4774 Pet* pet = unitTarget->ToPet();
4775
4776 ExecuteLogEffectUnsummonObject(effIndex, pet);
4778}
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:46
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition Pet.cpp:904
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition Spell.cpp:5313

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)
2718{
2719 Unit* unitCaster = m_caster->ToUnit();
2720 if (!unitCaster)
2721 return;
2722
2724 return;
2725
2726 if (!unitTarget)
2727 return;
2728
2729 // Create dispel mask by dispel type
2730 uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
2731 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2732
2733 DispelChargesList dispel_list;
2734 unitTarget->GetDispellableAuraList(unitCaster, dispelMask, dispel_list, m_spellInfo);
2735 if (dispel_list.empty())
2736 return;
2737
2738 // Ok if exist some buffs for dispel try dispel it
2739 uint32 failCount = 0;
2740 DispelChargesList success_list;
2741 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
2742 // dispel N = damage buffs (or while exist buffs for dispel)
2743 for (int32 count = 0; count < damage && !dispel_list.empty();)
2744 {
2745 // Random select buff for dispel
2746 DispelChargesList::iterator itr = dispel_list.begin();
2747 std::advance(itr, urand(0, dispel_list.size() - 1));
2748
2749 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(unitCaster));
2750 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2751 if (!chance)
2752 {
2753 dispel_list.erase(itr);
2754 continue;
2755 }
2756 else
2757 {
2758 if (roll_chance_i(chance))
2759 {
2760 bool alreadyListed = false;
2761 for (DispelChargesList::iterator successItr = success_list.begin(); successItr != success_list.end(); ++successItr)
2762 {
2763 if (successItr->first == itr->first)
2764 {
2765 ++successItr->second;
2766 alreadyListed = true;
2767 break;
2768 }
2769 }
2770 if (!alreadyListed)
2771 success_list.push_back(std::make_pair(itr->first, 1));
2772 --itr->second;
2773 if (itr->second <= 0)
2774 dispel_list.erase(itr);
2775 }
2776 else
2777 {
2778 if (!failCount)
2779 {
2780 // Failed to dispell
2781 dataFail << unitCaster->GetGUID(); // Caster GUID
2782 dataFail << unitTarget->GetGUID(); // Victim GUID
2783 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2784 }
2785 ++failCount;
2786 dataFail << uint32(itr->first->GetId()); // Spell Id
2787 }
2788 ++count;
2789 }
2790 }
2791
2792 if (failCount)
2793 unitCaster->SendMessageToSet(&dataFail, true);
2794
2795 // put in combat
2796 if (unitTarget->IsFriendlyTo(unitCaster))
2798
2799 if (success_list.empty())
2800 return;
2801
2802 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + success_list.size() * 5);
2803 // Send packet header
2804 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2805 dataSuccess << unitCaster->GetPackGUID(); // Caster GUID
2806 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2807 dataSuccess << uint8(0); // not used
2808 dataSuccess << uint32(success_list.size()); // count
2809 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
2810 {
2811 // Send dispelled spell info
2812 dataSuccess << uint32(itr->first->GetId()); // Spell Id
2813 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2814 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), unitCaster, itr->second);
2815 }
2816 unitCaster->SendMessageToSet(&dataSuccess, true);
2817
2818 // On success dispel
2819 // Devour Magic
2821 {
2822 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
2823 unitCaster->CastCustomSpell(unitCaster, 19658, &heal_amount, nullptr, nullptr, true);
2824 // Glyph of Felhunter
2825 if (Unit* owner = unitCaster->GetOwner())
2826 if (owner->GetAura(56249))
2827 owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
2828 }
2829}
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:884
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit *dispeller, uint8 chargesRemoved=1)
Definition Unit.cpp:4969
@ 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, Object::ToUnit(), unitTarget, and urand().

◆ EffectDispelMechanic()

void Spell::EffectDispelMechanic ( SpellEffIndex  effIndex)
5427{
5428 Unit* unitCaster = m_caster->ToUnit();
5429 if (!unitCaster)
5430 return;
5431
5433 return;
5434
5435 if (!unitTarget)
5436 return;
5437
5438 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5439
5440 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5441
5442 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5443 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5444 {
5445 Aura* aura = itr->second;
5447 continue;
5449 {
5450 if (aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1ULL << mechanic))
5451 {
5452 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5453
5454 // spell only removes 1 bleed effect do not continue
5455 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5456 {
5457 break;
5458 }
5459 }
5460 }
5461 }
5462
5463 for (; dispel_list.size(); dispel_list.pop())
5464 {
5465 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5466 }
5467
5468 // put in combat
5469 if (unitTarget->IsFriendlyTo(unitCaster))
5471}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition SpellAuraDefines.h:394
ObjectGuid GetCasterGUID() const
Definition SpellAuras.h:106
uint32 GetId() const
Definition SpellAuras.cpp:410
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition SpellAuras.cpp:1221
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4797

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, Object::ToUnit(), and unitTarget.

◆ EffectDistract()

void Spell::EffectDistract ( SpellEffIndex  effIndex)

@BUG Causes the player to stop moving.

2846{
2848 return;
2849
2850 // Check for possible target
2851 if (!unitTarget || unitTarget->IsEngaged())
2852 return;
2853
2854 // target must be OK to do this
2856 return;
2857
2860}
@ 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:960
void SetFacingTo(float ori)
Definition Unit.cpp:16068

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)
2832{
2834 return;
2835
2837}
virtual void SetCanDualWield(bool value)
Definition Unit.h:985

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

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4289{
4290 Unit* unitCaster = m_caster->ToUnit();
4291 if (!unitCaster)
4292 return;
4293
4295 return;
4296
4297 if (!unitTarget || !unitCaster->IsPlayer() || !unitTarget->IsPlayer())
4298 return;
4299
4300 Player* caster = unitCaster->ToPlayer();
4301 Player* target = unitTarget->ToPlayer();
4302
4303 // caster or target already have requested duel
4304 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4305 return;
4306
4307 // Players can only fight a duel in zones with this flag
4308 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4309 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4310 {
4311 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4312 return;
4313 }
4314
4315 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4316 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4317 {
4318 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4319 return;
4320 }
4321
4322 //CREATE DUEL FLAG OBJECT
4323 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4324 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4325
4326 Map* map = unitCaster->GetMap();
4327 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), unitCaster->GetOrientation());
4328 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4329 map, unitCaster->GetPhaseMask(),
4330 unitCaster->GetPositionX() + (unitTarget->GetPositionX() - unitCaster->GetPositionX()) / 2,
4331 unitCaster->GetPositionY() + (unitTarget->GetPositionY() - unitCaster->GetPositionY()) / 2,
4332 unitCaster->GetPositionZ(),
4333 unitCaster->GetOrientation(), rotation, 0, GO_STATE_READY))
4334 {
4335 delete pGameObj;
4336 return;
4337 }
4338
4339 pGameObj->SetUInt32Value(GAMEOBJECT_FACTION, unitCaster->GetFaction());
4340 pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, unitCaster->GetLevel() + 1);
4341 int32 duration = m_spellInfo->GetDuration();
4342 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4343 pGameObj->SetSpellId(m_spellInfo->Id);
4344
4345 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4346
4347 unitCaster->AddGameObject(pGameObj);
4348 map->AddToMap(pGameObj, true);
4349 //END
4350
4351 // Send request
4352 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4353 data << pGameObj->GetGUID();
4354 data << caster->GetGUID();
4355 caster->SendDirectMessage(&data);
4356 target->SendDirectMessage(&data);
4357
4358 // create duel-info
4359 bool isMounted = (GetSpellInfo()->Id == 62875);
4360 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4361 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4362
4363 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4364 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4365
4366 sScriptMgr->OnPlayerDuelRequest(target, caster);
4367}
@ 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:271
void SetRespawnTime(int32 respawn)
Definition GameObject.cpp:1288
void SetSpellId(uint32 id)
Definition GameObject.h:178
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:648
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:5307
Definition Transport.h:120
void AddGameObject(GameObject *gameObj)
Definition Unit.cpp:6330
uint32 GetFaction() const override
Definition Unit.h:852
uint32 GetPhaseMask() const
Definition Object.h:523
@ 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(), Object::ToUnit(), and unitTarget.

◆ EffectDummy()

void Spell::EffectDummy ( SpellEffIndex  effIndex)
692{
693 Unit* unitCaster = GetUnitCasterForEffectHandlers();
695 return;
696
698 return;
699
700 // selection by spell family
701 if (unitCaster)
702 {
704 {
706 {
707 switch (m_spellInfo->Id)
708 {
709 // Trial of the Champion, Trample
710 case 67866:
711 {
713 unitTarget->CastSpell(unitTarget, 67867, false);
714 return;
715 }
716 // Trial of the Champion, Hammer of the Righteous
717 case 66867:
718 {
719 if (!unitTarget)
720 return;
721 if (unitTarget->HasAura(66940))
722 unitCaster->CastSpell(unitTarget, 66903, true);
723 else
724 unitCaster->CastSpell(unitTarget, 66904, true);
725 return;
726 }
727 case 17731:
728 case 69294:
729 {
731 return;
732
736 trigger->CastSpell(trigger, 17731, false);
737
738 return;
739 }
740 // HoL, Arc Weld
741 case 59086:
742 {
743 if (unitCaster->IsPlayer() && unitCaster->ToPlayer()->isMoving())
744 unitCaster->CastSpell(unitCaster, 59097, true);
745
746 return;
747 }
748 }
749 break;
750 }
752 switch (m_spellInfo->Id)
753 {
754 case 31789: // Righteous Defense (step 1)
755 {
756 if (!unitTarget)
757 return;
758 // not empty (checked), copy
760
761 // remove invalid attackers
762 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
763 if (!(*aItr)->IsValidAttackTarget(unitCaster))
764 aItr = attackers.erase(aItr);
765 else
766 ++aItr;
767
768 // selected from list 3
769 uint32 maxTargets = std::min<uint32>(3, attackers.size());
770 for (uint32 i = 0; i < maxTargets; ++i)
771 {
772 Unit::AttackerSet::iterator aItr = attackers.begin();
773 std::advance(aItr, urand(0, attackers.size() - 1));
774 unitCaster->CastSpell((*aItr), 31790, true);
775 attackers.erase(aItr);
776 }
777
778 return;
779 }
780 }
781 break;
783 // Hunger for Blood
784 if (m_spellInfo->Id == 51662)
785 {
786 unitCaster->CastSpell(unitCaster, 63848, true);
787 return;
788 }
789 break;
790 }
791 }
792
793 // pet auras
794 if (unitCaster)
795 {
796 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
797 {
798 unitCaster->AddPetAura(petSpell);
799 return;
800 }
801 }
802
803 // normal DB scripted effect
804 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
806
807 if (gameObjTarget)
808 {
809 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
810 }
811 else if (unitTarget && unitTarget->IsCreature())
812 {
813 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
814 }
815 else if (itemTarget)
816 {
817 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
818 }
819}
ScriptMapMap sSpellScripts
Definition ObjectMgr.cpp:60
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:52
@ 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:210
time_t GetRespawnTime() const
Definition GameObject.h:185
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:13314
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:2453

References Unit::AddPetAura(), Unit::CastSpell(), effectHandleMode, gameObjTarget, Unit::getAttackers(), GameTime::GetGameTime(), GameObject::GetGoAnimProgress(), WorldObject::GetMap(), GameObject::GetRespawnTime(), Object::GetUInt32Value(), GetUnitCasterForEffectHandlers(), 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)
5563{
5565 return;
5566
5567 if (!unitTarget)
5568 return;
5569
5570 Player* player = unitTarget->ToPlayer();
5571 if (!player)
5572 {
5573 return;
5574 }
5575
5576 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5577
5578 // -1 means all player equipped items and -2 all items
5579 if (slot < 0)
5580 {
5581 player->DurabilityPointsLossAll(damage, (slot < -1));
5583 return;
5584 }
5585
5586 // invalid slot value
5587 if (slot >= INVENTORY_SLOT_BAG_END)
5588 return;
5589
5590 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5591 {
5592 player->DurabilityPointsLoss(item, damage);
5593 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5594 }
5595}
@ 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:4848
void DurabilityPointsLoss(Item *item, int32 points)
Definition Player.cpp:4874
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition Spell.cpp:5281

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)
5598{
5600 return;
5601
5602 if (!unitTarget)
5603 return;
5604
5605 Player* player = unitTarget->ToPlayer();
5606 if (!player)
5607 {
5608 return;
5609 }
5610
5611 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5612
5613 // FIXME: some spells effects have value -1/-2
5614 // Possibly its mean -1 all player equipped items and -2 all items
5615 if (slot < 0)
5616 {
5617 player->DurabilityLossAll(float(damage) / 100.0f, (slot < -1));
5618 return;
5619 }
5620
5621 // invalid slot value
5622 if (slot >= INVENTORY_SLOT_BAG_END)
5623 return;
5624
5625 if (damage <= 0)
5626 return;
5627
5628 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5629 player->DurabilityLoss(item, float(damage) / 100.0f);
5630}
void DurabilityLossAll(double percent, bool inventory)
Definition Player.cpp:4804
void DurabilityLoss(Item *item, double percent)
Definition Player.cpp:4830

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)
4616{
4617 Unit* unitCaster = m_caster->ToUnit();
4618 if (!unitCaster)
4619 return;
4620
4622 return;
4623
4624 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4625 if (!unitTarget)
4626 return;
4627
4628 Player* item_owner = unitTarget->ToPlayer();
4629 if (!item_owner)
4630 {
4631 return;
4632 }
4633
4635 if (!item)
4636 return;
4637
4638 // must be equipped
4639 if (!item->IsEquipped())
4640 return;
4641
4642 if (m_spellInfo->Effects[effIndex].MiscValue)
4643 {
4644 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4645 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4646 if (!duration)
4647 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4648 if (!duration)
4649 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4650
4651 // Xinef: Venomhide poison, no other spell uses this effect...
4652 if (m_spellInfo->Id == 14792)
4653 duration = 5 * MINUTE * IN_MILLISECONDS;
4654
4655 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4656 if (!pEnchant)
4657 return;
4658
4659 // Always go to temp enchantment slot
4661
4662 // Enchantment will not be applied if a different one already exists
4663 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4664 return;
4665
4666 // Apply the temporary enchantment
4667 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, unitCaster->GetGUID());
4668 item_owner->ApplyEnchantment(item, slot, true);
4669 }
4670}
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:4414
uint32 charges
Definition DBCStructure.h:1879

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(), Object::ToUnit(), and unitTarget.

◆ EffectEnchantItemPerm()

void Spell::EffectEnchantItemPerm ( SpellEffIndex  effIndex)
3006{
3007 Unit* unitCaster = m_caster->ToUnit();
3008 if (!unitCaster)
3009 return;
3010
3012 return;
3013
3014 if (!unitCaster->IsPlayer())
3015 return;
3016 if (!itemTarget)
3017 return;
3018
3019 Player* p_caster = unitCaster->ToPlayer();
3020
3021 // Handle vellums
3023 {
3024 // destroy one vellum from stack
3025 uint32 count = 1;
3026 p_caster->DestroyItemCount(itemTarget, count, true);
3027 unitTarget = p_caster;
3028 // and add a scroll
3029 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
3030 itemTarget = nullptr;
3031 m_targets.SetItemTarget(nullptr);
3032 }
3033 else
3034 {
3035 // do not increase skill if vellum used
3037 p_caster->UpdateCraftSkill(m_spellInfo->Id);
3038
3039 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3040 if (!enchant_id)
3041 return;
3042
3043 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3044 if (!pEnchant)
3045 return;
3046
3047 // item can be in trade slot and have owner diff. from caster
3048 Player* item_owner = itemTarget->GetOwner();
3049 if (!item_owner)
3050 return;
3051
3052 // remove old enchanting before applying new if equipped
3054
3055 itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0, unitCaster->GetGUID());
3056
3057 // add new enchanting if equipped
3059
3060 if (item_owner != p_caster && p_caster->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
3061 {
3062 LOG_GM(p_caster->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(perm): {} (SpellID: {} EncID: {}) on {}'s item: {} (Entry: {})",
3063 p_caster->GetName(), p_caster->GetSession()->GetAccountId(),
3064 m_spellInfo->SpellName[0], m_spellInfo->Id, enchant_id,
3065 item_owner->GetName(), itemTarget->GetTemplate()->Name1, itemTarget->GetEntry());
3066 }
3067
3068 item_owner->RemoveTradeableItem(itemTarget);
3070 }
3071}
@ 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:4249
void SetItemTarget(Item *item)
Definition Spell.cpp:365
std::array< char const *, 16 > SpellName
Definition SpellInfo.h:407
std::string const & GetName() const
Definition Object.h:535
bool HasPermission(uint32 permissionId)
Definition WorldSession.cpp:1691
@ 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(), Object::ToUnit(), unitTarget, and Player::UpdateCraftSkill().

◆ EffectEnchantItemPrismatic()

void Spell::EffectEnchantItemPrismatic ( SpellEffIndex  effIndex)
3074{
3075 Unit* unitCaster = m_caster->ToUnit();
3076 if (!unitCaster)
3077 return;
3078
3080 return;
3081
3082 if (!unitCaster->IsPlayer())
3083 return;
3084 if (!itemTarget)
3085 return;
3086
3087 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3088 if (!enchant_id)
3089 return;
3090
3091 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3092 if (!pEnchant)
3093 return;
3094
3095 // support only enchantings with add socket in this slot
3096 {
3097 bool add_socket = false;
3098 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
3099 {
3100 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
3101 {
3102 add_socket = true;
3103 break;
3104 }
3105 }
3106 if (!add_socket)
3107 {
3108 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.",
3110 return;
3111 }
3112 }
3113
3114 // item can be in trade slot and have owner diff. from caster
3115 Player* item_owner = itemTarget->GetOwner();
3116 if (!item_owner)
3117 return;
3118
3119 Player* p_caster = m_caster->ToPlayer();
3120 if (item_owner != p_caster && p_caster->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
3121 {
3122 LOG_GM(p_caster->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(prismatic): {} (SpellID: {} EncID: {}) on {}'s item: {} (Entry: {})",
3123 p_caster->GetName(), p_caster->GetSession()->GetAccountId(),
3124 m_spellInfo->SpellName[0], m_spellInfo->Id, enchant_id,
3125 item_owner->GetName(), itemTarget->GetTemplate()->Name1, itemTarget->GetEntry());
3126 }
3127
3128 // remove old enchanting before applying new if equipped
3130
3131 itemTarget->SetEnchantment(PRISMATIC_ENCHANTMENT_SLOT, enchant_id, 0, 0, unitCaster->GetGUID());
3132
3133 // add new enchanting if equipped
3135
3136 item_owner->RemoveTradeableItem(itemTarget);
3138}

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(), Object::ToUnit(), and SpellItemEnchantmentEntry::type.

◆ EffectEnchantItemTmp()

void Spell::EffectEnchantItemTmp ( SpellEffIndex  effIndex)
3141{
3142 Unit* unitCaster = m_caster->ToUnit();
3143 if (!unitCaster)
3144 return;
3145
3147 return;
3148
3149 if (!unitCaster->IsPlayer())
3150 return;
3151
3152 Player* p_caster = unitCaster->ToPlayer();
3153
3154 // Rockbiter Weapon apply to both weapon
3155 if (!itemTarget)
3156 return;
3158 {
3159 uint32 spell_id = 0;
3160
3161 // enchanting spell selected by calculated damage-per-sec stored in Effect[1] base value
3162 // Note: damage calculated (correctly) with rounding int32(float(v)) but
3163 // RW enchantments applied damage int32(float(v)+0.5), this create 0..1 difference sometime
3164 switch (damage)
3165 {
3166 // Rank 1
3167 case 2:
3168 spell_id = 36744;
3169 break; // 0% [ 7% == 2, 14% == 2, 20% == 2]
3170 // Rank 2
3171 case 4:
3172 spell_id = 36753;
3173 break; // 0% [ 7% == 4, 14% == 4]
3174 case 5:
3175 spell_id = 36751;
3176 break; // 20%
3177 // Rank 3
3178 case 6:
3179 spell_id = 36754;
3180 break; // 0% [ 7% == 6, 14% == 6]
3181 case 7:
3182 spell_id = 36755;
3183 break; // 20%
3184 // Rank 4
3185 case 9:
3186 spell_id = 36761;
3187 break; // 0% [ 7% == 6]
3188 case 10:
3189 spell_id = 36758;
3190 break; // 14%
3191 case 11:
3192 spell_id = 36760;
3193 break; // 20%
3194 default:
3195 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: Damage {} not handled in S'RW", damage);
3196 return;
3197 }
3198
3199 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
3200 if (!spellInfo)
3201 {
3202 LOG_ERROR("spells.effect", "Spell::EffectEnchantItemTmp: unknown spell id {}", spell_id);
3203 return;
3204 }
3205
3206 for (int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
3207 {
3208 if (Item* item = p_caster->GetWeaponForAttack(WeaponAttackType(j)))
3209 {
3210 if (item->IsFitToSpellRequirements(m_spellInfo))
3211 {
3212 Spell* spell = new Spell(unitCaster, spellInfo, TRIGGERED_FULL_MASK);
3213 SpellCastTargets targets;
3214 targets.SetItemTarget(item);
3215 spell->prepare(&targets);
3216 }
3217 }
3218 }
3219 return;
3220 }
3221 if (!itemTarget)
3222 return;
3223
3224 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3225
3226 if (!enchant_id)
3227 {
3228 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have 0 as enchanting id", m_spellInfo->Id, effIndex);
3229 return;
3230 }
3231
3232 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3233 if (!pEnchant)
3234 {
3235 LOG_ERROR("spells.effect", "Spell {} Effect {} (SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY) have not existed enchanting id {} ", m_spellInfo->Id, effIndex, enchant_id);
3236 return;
3237 }
3238
3239 // Enchantment duration
3240 uint32 duration = 3600; // Default 1 hour
3241
3242 // Exceptions
3243 if (m_spellInfo->SpellFamilyName == SPELLFAMILY_SHAMAN) // Shaman weapon enchants
3244 duration = 1800; // 30 mins
3245 else
3246 {
3247 switch (m_spellInfo->Id)
3248 {
3249 case 37360: // Consecrated Weapon
3250 duration = 300; // 5 mins
3251 break;
3252 case 8087: // Shiny Bauble
3253 case 8088: // Nightcrawlers
3254 case 8089: // Aquadynamic Fish Attractor
3255 case 8090: // Bright Baubles
3256 case 8532: // Aquadynamic Fish Lens
3257 case 9092: // Flesh Eating Worm
3258 case 43699: // Fishing Hat Lure
3259 case 45731: // Sharpened Fish Hook
3260 duration = 600; // 10 mins
3261 break;
3262 case 3594: // Shadow Oil
3263 case 3595: // Frost Oil
3264 case 6650: // Instant Toxin
3265 case 38615: // Bloodboil Poison
3266 // Explicitly listing Rockbiter Weapon because it isn't caught by spellfamily check
3267 case 36744: // Rockbiter Weapon Rank 1
3268 case 36753: // Rockbiter Weapon Rank 2
3269 case 36751: // Rockbiter Weapon Rank 2
3270 case 36754: // Rockbiter Weapon Rank 3
3271 case 36755: // Rockbiter Weapon Rank 3
3272 case 36761: // Rockbiter Weapon Rank 4
3273 case 36758: // Rockbiter Weapon Rank 4
3274 case 36760: // Rockbiter Weapon Rank 4
3275 duration = 1800; // 30 mins
3276 break;
3277 default:
3278 break;
3279 }
3280 }
3281
3282 // item can be in trade slot and have owner diff. from caster
3283 Player* item_owner = itemTarget->GetOwner();
3284 if (!item_owner)
3285 return;
3286
3287 // remove old enchanting before applying new if equipped
3289
3290 itemTarget->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, duration * 1000, pEnchant->charges, unitCaster->GetGUID());
3291
3292 // add new enchanting if equipped
3294
3295 if (item_owner != p_caster && p_caster->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
3296 {
3297 LOG_GM(p_caster->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(temp): {} (SpellID: {} EncID: {}) on {}'s item: {} (Entry: {})",
3298 p_caster->GetName(), p_caster->GetSession()->GetAccountId(),
3299 m_spellInfo->SpellName[0], m_spellInfo->Id, enchant_id,
3300 item_owner->GetName(), itemTarget->GetTemplate()->Name1, itemTarget->GetEntry());
3301 }
3302
3303 item_owner->RemoveTradeableItem(itemTarget);
3305}
@ 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:3556

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(), Object::ToUnit(), and TRIGGERED_FULL_MASK.

◆ EffectEnergize()

void Spell::EffectEnergize ( SpellEffIndex  effIndex)
1989{
1990 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1991 if (!unitCaster)
1992 return;
1993
1995 return;
1996
1997 if (!unitTarget)
1998 return;
1999 if (!unitTarget->IsAlive())
2000 return;
2001
2003 {
2004 unitCaster->SendSpellDamageImmune(unitTarget, GetSpellInfo()->Id);
2005 return;
2006 }
2007
2008 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
2009 return;
2010
2011 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
2012
2015 return;
2016
2017 if (unitTarget->GetMaxPower(power) == 0)
2018 return;
2019
2020 // Some level depends spells
2021 int level_multiplier = 0;
2022 int level_diff = 0;
2023 switch (m_spellInfo->Id)
2024 {
2025 case 9512: // Restore Energy
2026 level_diff = unitCaster->GetLevel() - 40;
2027 level_multiplier = 2;
2028 break;
2029 case 24571: // Blood Fury
2030 level_diff = unitCaster->GetLevel() - 60;
2031 level_multiplier = 10;
2032 break;
2033 case 24532: // Burst of Energy
2034 level_diff = unitCaster->GetLevel() - 60;
2035 level_multiplier = 4;
2036 break;
2037 case 31930: // Judgements of the Wise
2038 case 63375: // Improved Stormstrike
2039 case 68082: // Glyph of Seal of Command
2041 break;
2042 case 48542: // Revitalize
2044 break;
2045 case 71132: // Glyph of Shadow Word: Pain
2046 damage = int32(CalculatePct(unitTarget->GetCreateMana(), 1)); // set 1 as value, missing in dbc
2047 break;
2048 default:
2049 break;
2050 }
2051
2052 if (level_diff > 0)
2053 damage -= level_multiplier * level_diff;
2054
2055 if (damage < 0)
2056 return;
2057
2058 unitCaster->EnergizeBySpell(unitTarget, m_spellInfo->Id, damage, power);
2059
2060 // Mad Alchemist's Potion
2061 if (m_spellInfo->Id == 45051)
2062 {
2063 // find elixirs on target
2064 bool guardianFound = false;
2065 bool battleFound = false;
2067 for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
2068 {
2069 if (!guardianFound && sSpellMgr->IsSpellMemberOfSpellGroup(itr->second->GetBase()->GetId(), SPELL_GROUP_ELIXIR_GUARDIAN))
2070 guardianFound = true;
2071 if (!battleFound && sSpellMgr->IsSpellMemberOfSpellGroup(itr->second->GetBase()->GetId(), SPELL_GROUP_ELIXIR_BATTLE))
2072 battleFound = true;
2073 if (battleFound && guardianFound)
2074 break;
2075 }
2076
2077 // get all available elixirs by mask and spell level
2078 std::set<uint32> availableElixirs;
2079 if (!guardianFound)
2080 sSpellMgr->GetSetOfSpellsInSpellGroup(SPELL_GROUP_ELIXIR_GUARDIAN, availableElixirs);
2081 if (!battleFound)
2082 sSpellMgr->GetSetOfSpellsInSpellGroup(SPELL_GROUP_ELIXIR_BATTLE, availableElixirs);
2083 for (std::set<uint32>::iterator itr = availableElixirs.begin(); itr != availableElixirs.end();)
2084 {
2085 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(*itr);
2086 if (spellInfo->SpellLevel < m_spellInfo->SpellLevel || spellInfo->SpellLevel > unitTarget->GetLevel())
2087 availableElixirs.erase(itr++);
2088 else
2089 ++itr;
2090 }
2091
2092 if (!availableElixirs.empty())
2093 {
2094 // cast random elixir on target
2096 }
2097 }
2098}
@ 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:8167
void SendSpellDamageImmune(Unit *target, uint32 spellId)
Definition Unit.cpp:6654
bool IsImmunedToAuraPeriodicTick(Unit const *caster, SpellInfo const *spellInfo) const
Definition Unit.cpp:9737
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(), GetUnitCasterForEffectHandlers(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsAlive(), Unit::IsImmunedToAuraPeriodicTick(), Object::IsPlayer(), 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)
2101{
2102 Unit* unitCaster = GetUnitCasterForEffectHandlers();
2103 if (!unitCaster)
2104 return;
2105
2107 return;
2108
2109 if (!unitTarget)
2110 return;
2111 if (!unitTarget->IsAlive())
2112 return;
2113
2115 {
2116 unitCaster->SendSpellDamageImmune(unitTarget, GetSpellInfo()->Id);
2117 return;
2118 }
2119
2120 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
2121 return;
2122
2123 Powers power = Powers(m_spellInfo->Effects[effIndex].MiscValue);
2124
2126 return;
2127
2128 uint32 maxPower = unitTarget->GetMaxPower(power);
2129 if (maxPower == 0)
2130 return;
2131
2132 uint32 gain = CalculatePct(maxPower, damage);
2133 unitCaster->EnergizeBySpell(unitTarget, m_spellInfo->Id, gain, power);
2134}
@ UNIT_STATE_ISOLATED
Definition UnitDefines.h:186

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), Unit::GetMaxPower(), GetSpellInfo(), GetUnitCasterForEffectHandlers(), Unit::HasActivePowerType(), SpellInfo::HasAttribute(), Unit::HasUnitState(), SpellInfo::Id, Unit::IsAlive(), Object::IsPlayer(), 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)
304{
306 return;
307
308 if (!unitTarget || !unitTarget->IsAlive())
309 return;
310
311 if (unitTarget->IsPlayer())
313 else
314 {
315 Unit* unitCaster = GetUnitCasterForEffectHandlers();
317
318 uint32 absorb = dmgInfo.GetAbsorb();
319 uint32 resist = dmgInfo.GetResist();
320 uint32 envDamage = dmgInfo.GetDamage();
321
322 Unit::DealDamageMods(unitTarget, envDamage, &absorb);
323 damage = envDamage;
324
325 if (unitCaster)
326 unitCaster->SendSpellNonMeleeDamageLog(unitTarget, m_spellInfo, damage, m_spellInfo->GetSchoolMask(), absorb, resist, false, 0);
327 }
328}
@ 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(), GetUnitCasterForEffectHandlers(), Unit::IsAlive(), Object::IsPlayer(), 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
4730{
4731 Unit* unitCaster = m_caster->ToUnit();
4732 if (!unitCaster)
4733 return;
4734
4736 return;
4737
4738 Player* player = unitCaster->ToPlayer();
4739 if (!player)
4740 return;
4741
4742 Item* foodItem = itemTarget;
4743 if (!foodItem)
4744 return;
4745
4746 Pet* pet = player->GetPet();
4747 if (!pet)
4748 return;
4749
4750 if (!pet->IsAlive())
4751 return;
4752
4753 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4754 if (benefit <= 0)
4755 return;
4756
4757 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4758
4759 uint32 count = 1;
4760 player->DestroyItemCount(foodItem, count, true);
4762
4763 unitCaster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4764}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition Spell.cpp:5301

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, Object::ToPlayer(), and Object::ToUnit().

◆ EffectForceCast()

void Spell::EffectForceCast ( SpellEffIndex  effIndex)
1057{
1059 return;
1060
1061 if (!unitTarget)
1062 return;
1063
1064 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1065
1066 // normal case
1067 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1068
1069 if (!spellInfo)
1070 {
1071 LOG_ERROR("spells.effect", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1072 return;
1073 }
1074
1075 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
1076 {
1077 switch (m_spellInfo->Id)
1078 {
1079 case 52588: // Skeletal Gryphon Escape
1080 case 48598: // Ride Flamebringer Cue
1082 break;
1083 case 52463: // Hide In Mine Car
1084 case 52349: // Overtake
1085 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
1086 return;
1087 case 72378: // Blood Nova
1088 case 73058: // Blood Nova
1089 m_caster->CastSpell(unitTarget, damage, true); // additional spell cast
1090 break;
1091 }
1092 }
1093
1095 // set basepoints for trigger with value effect
1097 {
1098 // maybe need to set value only when basepoints == 0?
1099 args.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
1100 args.AddSpellMod(SPELLVALUE_BASE_POINT1, damage);
1101 args.AddSpellMod(SPELLVALUE_BASE_POINT2, damage);
1102 }
1103
1104 SpellCastTargets targets;
1105 // InitExplicitTargets turns a unit target the triggered spell cannot take into that spell's
1106 // destination, which would anchor the forced cast to the original caster instead of to the
1107 // forced one (e.g. Algalon's Cosmic Smash craters, Elder Brightleaf's Unstable Sun Beams).
1109 targets.SetUnitTarget(m_caster->ToUnit());
1110
1111 unitTarget->CastSpell(std::move(targets), spellInfo, args);
1112}
@ SPELL_EFFECT_FORCE_CAST
Definition SharedDefines.h:906
@ SPELL_EFFECT_FORCE_CAST_WITH_VALUE
Definition SharedDefines.h:907
@ SPELLVALUE_BASE_POINT1
Definition SpellDefines.h:122
@ SPELLVALUE_BASE_POINT2
Definition SpellDefines.h:123
@ SPELLVALUE_BASE_POINT0
Definition SpellDefines.h:121
@ TARGET_FLAG_UNIT_MASK
Definition SpellInfo.h:69
@ TARGET_FLAG_CORPSE_MASK
Definition SpellInfo.h:72
Definition SpellDefines.h:219

References CastSpellExtraArgs::AddSpellMod(), Unit::CastCustomSpell(), WorldObject::CastSpell(), Unit::CastSpell(), damage, effectHandleMode, SpellInfo::Effects, SpellInfo::GetExplicitTargetMask(), 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, TARGET_FLAG_CORPSE_MASK, TARGET_FLAG_UNIT_MASK, Object::ToUnit(), TRIGGERED_FULL_MASK, and unitTarget.

◆ EffectForceDeselect()

void Spell::EffectForceDeselect ( SpellEffIndex  effIndex)
5007{
5008 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5009 if (!unitCaster)
5010 return;
5011
5013 return;
5014
5015 // xinef: clear focus
5016 unitCaster->SendClearTarget();
5017
5019 data << unitCaster->GetGUID();
5020
5021 float dist = unitCaster->GetVisibilityRange() + VISIBILITY_COMPENSATION;
5022 Acore::MessageDistDelivererToHostile notifier(unitCaster, &data, dist);
5023 Cell::VisitObjects(unitCaster, notifier, dist);
5024
5025 // xinef: we should also force pets to remove us from current target
5026 Unit::AttackerSet attackerSet;
5027 for (Unit::AttackerSet::const_iterator itr = unitCaster->getAttackers().begin(); itr != unitCaster->getAttackers().end(); ++itr)
5028 if ((*itr)->IsCreature() && !(*itr)->CanHaveThreatList())
5029 attackerSet.insert(*itr);
5030
5031 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
5032 (*itr)->AttackStop();
5033
5034 // Xinef: Mirror images code Initialize Images
5035 if (m_spellInfo->Id == 58836)
5036 {
5037 std::vector<Unit*> images;
5038 for (Unit::ControlSet::const_iterator itr = unitCaster->m_Controlled.begin(); itr != unitCaster->m_Controlled.end(); ++itr)
5039 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
5040 images.push_back(*itr);
5041
5042 if (images.empty())
5043 return;
5044
5045 UnitList targets;
5046 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitCaster, unitCaster, unitCaster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
5047 Acore::UnitListSearcher<Acore::AnyUnfriendlyUnitInObjectRangeCheck> searcher(unitCaster, targets, u_check);
5048 Cell::VisitObjects(unitCaster, searcher, unitCaster->GetVisibilityRange());
5049 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
5050 {
5051 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
5052 continue;
5053
5054 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
5055 {
5056 if (spell->m_targets.GetUnitTargetGUID() == unitCaster->GetGUID())
5057 {
5058 SpellInfo const* si = spell->GetSpellInfo();
5059 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
5060 {
5061 Creature* c = (*iter)->ToCreature();
5062 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
5063 continue;
5064 }
5065
5066 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
5067 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
5068 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
5069 {
5070 // at least one effect truly targets an unit, interrupt the spell
5071 interrupt = true;
5072 break;
5073 }
5074
5075 if (interrupt)
5076 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
5077 }
5078 }
5079 }
5080 }
5081}
#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:3351
ControlSet m_Controlled
Definition Unit.h:2079
void SendClearTarget()
Definition Unit.cpp:15873
@ 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(), GetUnitCasterForEffectHandlers(), WorldObject::GetVisibilityRange(), SpellInfo::HasAttribute(), SpellInfo::Id, Creature::IsDungeonBoss(), Unit::IsPet(), Creature::isWorldBoss(), 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)
6239{
6241 return;
6242
6243 if (!gameObjTarget)
6244 return;
6245
6246 Unit* caster = m_originalCaster;
6247 if (!caster)
6248 return;
6249
6250 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
6252 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
6253 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
6255}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition GameObject.cpp:2319
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition Unit.cpp:6828
Definition DBCStructure.h:975
bool IsFriendlyTo(FactionTemplateEntry const &entry) const
Definition DBCStructure.h:987

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)
6258{
6260 return;
6261
6262 if (!gameObjTarget)
6263 return;
6264
6265 Unit* unitCaster = m_caster->ToUnit();
6266 if (!unitCaster)
6267 return;
6268
6269 gameObjTarget->ModifyHealth(damage, unitCaster);
6270}

References damage, effectHandleMode, gameObjTarget, m_caster, GameObject::ModifyHealth(), SPELL_EFFECT_HANDLE_HIT_TARGET, and Object::ToUnit().

◆ EffectGameObjectSetDestructionState()

void Spell::EffectGameObjectSetDestructionState ( SpellEffIndex  effIndex)
6273{
6275 return;
6276
6278 return;
6279
6282}
GameObjectDestructibleState
Definition SharedDefines.h:1630
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition GameObject.cpp:2382

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)
1561{
1562 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1564 return;
1565
1566 if (unitTarget && unitTarget->IsAlive() && damage >= 0)
1567 {
1568 // Try to get original caster
1569 Unit* caster = m_originalCasterGUID ? m_originalCaster : unitCaster;
1570
1571 // Skip if m_originalCaster not available
1572 if (!caster)
1573 return;
1574
1575 int32 addhealth = damage;
1576
1577 // Vessel of the Naaru (Vial of the Sunwell trinket)
1578 if (m_spellInfo->Id == 45064)
1579 {
1580 // Amount of heal - depends from stacked Holy Energy
1581 int damageAmount = 0;
1582 if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(45062, 0))
1583 {
1584 damageAmount += aurEff->GetAmount();
1585 unitCaster->RemoveAurasDueToSpell(45062);
1586 }
1587
1588 addhealth += damageAmount;
1589 }
1590 // Swiftmend - consumes Regrowth or Rejuvenation
1592 {
1594 // find most short by duration
1595 AuraEffect* forcedTargetAura = nullptr;
1596 AuraEffect* targetAura = nullptr;
1597 for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
1598 {
1599 if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID
1600 && (*i)->GetSpellInfo()->SpellFamilyFlags[0] & 0x50)
1601 {
1602 if (unitCaster->GetGUID() == (*i)->GetCasterGUID())
1603 {
1604 if (!forcedTargetAura || (*i)->GetBase()->GetDuration() < forcedTargetAura->GetBase()->GetDuration())
1605 forcedTargetAura = *i;
1606 }
1607 else if (!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
1608 targetAura = *i;
1609 }
1610 }
1611
1612 if (forcedTargetAura)
1613 targetAura = forcedTargetAura;
1614
1615 if (!targetAura)
1616 {
1617 LOG_ERROR("spells.effect", "Target({}) has aurastate AURA_STATE_SWIFTMEND but no matching aura.", unitTarget->GetGUID().ToString());
1618 return;
1619 }
1620
1621 int32 tickheal = targetAura->GetAmount();
1622 if (Unit* auraCaster = targetAura->GetCaster())
1623 {
1624 // MOD_HEALING_DONE_PERCENT is applied per-tick, not baked into GetAmount.
1625 tickheal = int32(float(tickheal) * auraCaster->GetTotalAuraMultiplier(SPELL_AURA_MOD_HEALING_DONE_PERCENT));
1626 tickheal = unitTarget->SpellHealingBonusTaken(auraCaster, targetAura->GetSpellInfo(), tickheal, DOT);
1627 }
1628
1629 //int32 tickheal = targetAura->GetSpellInfo()->EffectBasePoints[idx] + 1;
1630 //It is said that talent bonus should not be included
1631
1632 int32 tickcount = 0;
1633 // Rejuvenation
1634 if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x10)
1635 tickcount = 4;
1636 // Regrowth
1637 else // if (targetAura->GetSpellInfo()->SpellFamilyFlags[0] & 0x40)
1638 tickcount = 6;
1639
1640 addhealth += tickheal * tickcount;
1641
1642 // Swiftmend spell mods (e.g. Druid T8 Restoration 2P Bonus)
1643 if (Player* modOwner = caster->GetSpellModOwner())
1644 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DAMAGE, addhealth);
1645
1646 // Glyph of Swiftmend
1647 if (!caster->HasAura(54824))
1648 unitTarget->RemoveAura(targetAura->GetId(), targetAura->GetCasterGUID());
1649
1650 //addhealth += tickheal * tickcount;
1651 //addhealth = caster->SpellHealingBonus(m_spellInfo, addhealth, HEAL, unitTarget);
1652 }
1653 // Death Pact - return pct of max health to caster
1655 {
1656 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, int32(caster->CountPctFromMaxHealth(damage)), HEAL, effIndex);
1657 m_damageBeforeTakenMods -= addhealth;
1658 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1659 }
1660 else if (m_spellInfo->Id != 33778) // not lifebloom
1661 {
1662 addhealth = caster->SpellHealingBonusDone(unitTarget, m_spellInfo, addhealth, HEAL, effIndex);
1663 m_damageBeforeTakenMods -= addhealth;
1664 addhealth = unitTarget->SpellHealingBonusTaken(caster, m_spellInfo, addhealth, HEAL);
1665 }
1666
1667 // Implemented this way as there is no other way to do it currently (that I know :P)...
1668 if (caster->ToPlayer() && caster->HasAura(23401)) // Nefarian Corrupted Healing (priest)
1669 {
1671 {
1672 m_damage = 0;
1673 caster->CastSpell(unitTarget, 23402, false); // Nefarian Corrupted Healing Periodic Damage effect.
1674 return;
1675 }
1676 }
1677
1678 m_damage -= addhealth;
1679 }
1680}
@ 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
@ SPELLMOD_DAMAGE
Definition SpellDefines.h:84
@ 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:5537
uint32 CountPctFromMaxHealth(int32 pct) const
Definition Unit.h:1127

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(), Unit::GetSpellModOwner(), GetUnitCasterForEffectHandlers(), SpellInfo::HasAura(), Unit::HasAura(), Unit::HasAuraState(), HEAL, SpellInfo::Id, Unit::IsAlive(), LOG_ERROR, 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(), SPELLMOD_DAMAGE, SpellInfo::TargetAuraState, Object::ToPlayer(), ObjectGuid::ToString(), and unitTarget.

◆ EffectHealMaxHealth()

void Spell::EffectHealMaxHealth ( SpellEffIndex  effIndex)
3903{
3904 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3905 if (!unitCaster)
3906 return;
3907
3909 return;
3910
3911 if (!unitTarget || !unitTarget->IsAlive())
3912 return;
3913
3915 {
3916 unitCaster->SendSpellDamageImmune(unitTarget, GetSpellInfo()->Id);
3917 return;
3918 }
3919
3920 int32 addhealth = 0;
3921
3922 // damage == 0 - heal for caster max health
3923 if (damage == 0)
3924 addhealth = unitCaster->GetMaxHealth();
3925 else
3926 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3927
3928 m_healing += addhealth;
3929}
uint32 GetMaxHealth() const
Definition Unit.h:1115

References damage, effectHandleMode, Unit::GetHealth(), Unit::GetMaxHealth(), GetSpellInfo(), GetUnitCasterForEffectHandlers(), Unit::IsAlive(), Unit::IsImmunedToAuraPeriodicTick(), 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)
1720{
1721 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1723 return;
1724
1725 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1726 return;
1727
1728 if (unitCaster)
1729 {
1732 }
1733
1734 LOG_DEBUG("spells.aura", "HealthLeech :{}", damage);
1735
1736 // xinef: handled in spell.cpp
1737 //float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1738
1739 m_damage += damage;
1740 // get max possible damage, don't count overkill for heal
1741 //uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1742
1743 //if (unitCaster->IsAlive())
1744 //{
1745 // healthGain = unitCaster->SpellHealingBonusDone(unitCaster, m_spellInfo, healthGain, HEAL);
1746 // healthGain = unitCaster->SpellHealingBonusTaken(unitCaster, m_spellInfo, healthGain, HEAL);
1747
1748 // unitCaster->HealBySpell(unitCaster, m_spellInfo, uint32(healthGain));
1749 //}
1750}
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition Unit.cpp:8681
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:8507

References damage, effectHandleMode, GetUnitCasterForEffectHandlers(), Unit::IsAlive(), LOG_DEBUG, m_damage, m_spellInfo, SPELL_DIRECT_DAMAGE, SPELL_EFFECT_HANDLE_HIT_TARGET, Unit::SpellDamageBonusDone(), Unit::SpellDamageBonusTaken(), and unitTarget.

◆ EffectInebriate()

void Spell::EffectInebriate ( SpellEffIndex  effIndex)
4694{
4696 return;
4697
4698 if (!unitTarget)
4699 return;
4700
4701 Player* player = unitTarget->ToPlayer();
4702 if (!player)
4703 {
4704 return;
4705 }
4706
4707 uint8 currentDrunk = player->GetDrunkValue();
4708 int32 drunkMod = damage;
4709
4710 if (drunkMod == 0)
4711 return;
4712
4713 // drunkMod may contain values ​​that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
4714 // In addition, we would not want currentDrunk to become more than 100.
4715 // So before adding the values, let's check that everything is fine.
4716 if (drunkMod > 0 && drunkMod > static_cast<int32>(100 - currentDrunk))
4717 currentDrunk = 100;
4718 else if (drunkMod < 0 && drunkMod < static_cast<int32>(0 - currentDrunk))
4719 currentDrunk = 0;
4720 else
4721 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
4722
4723 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4724
4725 if (currentDrunk == 100 && roll_chance_i(25))
4726 player->CastSpell(player, 67468, false); // Drunken Vomit
4727}
uint8 GetDrunkValue() const
Definition Player.h:2202
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)
280{
282 return;
283
284 if (!unitTarget || !unitTarget->IsAlive() || unitTarget->HasAura(27827)) // Spirit of redemption doesn't make you death, but can cause infinite loops
285 return;
286
287 if (unitTarget->IsPlayer())
289 return;
290
291 if (m_caster == unitTarget) // prevent interrupt message
292 finish();
293
294 WorldPacket data(SMSG_SPELLINSTAKILLLOG, 8 + 8 + 4);
295 data << m_caster->GetGUID();
296 data << unitTarget->GetGUID();
297 data << uint32(m_spellInfo->Id);
298 m_caster->SendMessageToSet(&data, true);
299
301}
@ CHEAT_GOD
Definition Player.h:997
@ SMSG_SPELLINSTAKILLLOG
Definition Opcodes.h:845

References CHEAT_GOD, Unit::DealDamage(), effectHandleMode, finish(), Player::GetCommandStatus(), Object::GetGUID(), Unit::GetHealth(), GetUnitCasterForEffectHandlers(), 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
3932{
3934 return;
3935
3936 if (!unitTarget || !unitTarget->IsAlive())
3937 return;
3938
3940 // also exist case: apply cooldown to interrupted cast only and to all spells
3941 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3943 {
3945 {
3946 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3947 // check if we can interrupt spell
3948 if ((spell->getState() == SPELL_STATE_CASTING
3949 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3953 {
3954 if (m_originalCaster)
3955 {
3957 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3958 }
3959 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3961 }
3962 }
3963 }
3964}
@ CHANNEL_INTERRUPT_FLAG_INTERRUPT
Definition SpellDefines.h:45
@ SPELL_INTERRUPT_FLAG_INTERRUPT
Definition SpellDefines.h:37
#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:5274
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:3975
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition Unit.h:1589
int32 CalcSpellDuration(SpellInfo const *spellProto) const
Definition Object.cpp:3376

References WorldObject::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, WorldObject::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)
1134{
1135 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1136 if (!unitCaster)
1137 return;
1138
1140 return;
1141
1142 if (unitCaster->IsInFlight())
1143 return;
1144
1145 if (!unitTarget)
1146 return;
1147
1148 float speedXY, speedZ;
1149 CalculateJumpSpeeds(effIndex, unitCaster->GetExactDist2d(unitTarget), speedXY, speedZ);
1150 unitCaster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1151
1152 if (unitCaster->IsPlayer())
1153 {
1154 sScriptMgr->AnticheatSetUnderACKmount(unitCaster->ToPlayer());
1155 }
1156}
void MoveJump(Position const &pos, float speedXY, float speedZ, uint32 id=0)
Definition MotionMaster.h:257
void CalculateJumpSpeeds(uint8 i, float dist, float &speedxy, float &speedz)
Definition SpellEffects.cpp:1225
float GetExactDist2d(const float x, const float y) const
Definition Position.h:170

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

◆ EffectJumpDest()

void Spell::EffectJumpDest ( SpellEffIndex  effIndex)
1159{
1160 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1161 if (!unitCaster)
1162 return;
1163
1165 return;
1166
1167 if (unitCaster->IsInFlight())
1168 return;
1169
1170 if (!m_targets.HasDst() || unitCaster->GetVehicle())
1171 return;
1172
1173 // Init dest coordinates
1174 float x, y, z;
1175 destTarget->GetPosition(x, y, z);
1176 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1177 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1178 return;
1179
1180 float speedXY, speedZ;
1181 float dist = unitCaster->GetExactDist2d(x, y);
1182 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1183
1184 // Override, calculations are incorrect
1185 if (m_spellInfo->Id == 49376) // feral charge
1186 {
1187 speedXY = pow(speedZ * 10, 8);
1188 unitCaster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ, 0, ObjectAccessor::GetUnit(*unitCaster, unitCaster->GetGuidValue(UNIT_FIELD_TARGET)));
1189
1190 if (Player* player = unitCaster->ToPlayer())
1191 {
1192 player->SetCanTeleport(true);
1193 }
1194
1195 if (unitCaster->IsPlayer())
1196 {
1197 sScriptMgr->AnticheatSetUnderACKmount(unitCaster->ToPlayer());
1198 }
1199
1200 return;
1201 }
1202
1203 if (m_spellInfo->Id == 57604) // death grip
1204 {
1205 speedZ = 3.0f;
1206 speedXY = 50.0f;
1207 }
1208
1209 // crash fix?
1210 if (speedXY < 1.0f)
1211 speedXY = 1.0f;
1212
1213 if (Player* player = unitCaster->ToPlayer())
1214 {
1215 player->SetCanTeleport(true);
1216 }
1217 unitCaster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1218
1219 if (unitCaster->IsPlayer())
1220 {
1221 sScriptMgr->AnticheatSetUnderACKmount(unitCaster->ToPlayer());
1222 }
1223}
@ UNIT_FIELD_TARGET
Definition UpdateFields.h:92
ObjectGuid GetGuidValue(uint16 index) const
Definition Object.cpp:335
bool IsValidMapCoord(float c)
Definition GridDefines.h:210

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

◆ EffectKillCredit()

void Spell::EffectKillCredit ( SpellEffIndex  effIndex)
6019{
6021 return;
6022
6023 if (!unitTarget)
6024 return;
6025
6027 if (!player)
6028 {
6029 return;
6030 }
6031
6032 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
6033 if (!creatureEntry)
6034 {
6035 if (m_spellInfo->Id == 42793) // Burn Body
6036 creatureEntry = 24008; // Fallen Combatant
6037 }
6038
6039 if (creatureEntry)
6040 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
6041}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition Player.cpp:13046

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)
6005{
6007 return;
6008
6009 if (!unitTarget)
6010 return;
6011
6013 {
6014 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
6015 }
6016}

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

◆ EffectKnockBack()

void Spell::EffectKnockBack ( SpellEffIndex  effIndex)
5231{
5233 return;
5234
5235 if (!unitTarget)
5236 return;
5237
5238 // Xinef: allow entry specific spells to skip those checks
5239 if (m_spellInfo->Effects[effIndex].TargetA.GetCheckType() != TARGET_CHECK_ENTRY && m_spellInfo->Effects[effIndex].TargetB.GetCheckType() != TARGET_CHECK_ENTRY)
5240 {
5242 return;
5243
5244 if (unitTarget->GetVehicle())
5245 return;
5246
5247 if (Creature* creatureTarget = unitTarget->ToCreature())
5248 if (creatureTarget->isWorldBoss() || creatureTarget->IsDungeonBoss() || creatureTarget->IsImmuneToKnockback() || unitTarget->ToCreature()->GetCreatureType() == CREATURE_TYPE_GIANT)
5249 return;
5250 }
5251
5252 // Spells with SPELL_EFFECT_KNOCK_BACK(like Thunderstorm) can't knoback target if target has ROOT
5254 return;
5255
5256 // Instantly interrupt non melee spells being casted
5259
5260 float ratio = 0.1f;
5261 float speedxy = float(m_spellInfo->Effects[effIndex].MiscValue) * ratio;
5262 float speedz = float(damage) * ratio;
5263 if (speedxy <= 0.1f && speedz <= 0.1f)
5264 return;
5265
5266 float x, y;
5267 Unit* reflectionSource = m_reflectionTarget;
5268
5269 if (!reflectionSource && !m_reflectionTargetGuid.IsEmpty())
5270 {
5272 reflectionSource = resolvedSource;
5273 }
5274
5275 if (reflectionSource)
5276 {
5277 reflectionSource->GetPosition(x, y);
5278 }
5279 else if (!m_reflectionTargetGuid.IsEmpty())
5280 {
5283 }
5284 else if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_KNOCK_BACK_DEST)
5285 {
5286 if (m_targets.HasDst())
5287 destTarget->GetPosition(x, y);
5288 else
5289 return;
5290 }
5291 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_KNOCK_BACK)
5292 {
5293 m_caster->GetPosition(x, y);
5294 }
5295
5296 unitTarget->KnockbackFrom(x, y, speedxy, speedz);
5297
5298 if (unitTarget->IsPlayer())
5299 {
5300 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5301 }
5302}
@ 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:4047
uint32 GetCreatureType() const
Definition Unit.cpp:11529
void KnockbackFrom(float x, float y, float speedXY, float speedZ)
Definition Unit.cpp:14995

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)
4937{
4939 return;
4940
4941 if (!unitTarget || unitTarget->IsInFlight())
4942 return;
4943
4944 if (!m_targets.HasDst())
4945 return;
4946
4947 Position dstpos = destTarget->GetPosition();
4949}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition Unit.cpp:15572

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)
5305{
5306 Unit* unitCaster = m_caster->ToUnit();
5307 if (!unitCaster)
5308 return;
5309
5311 return;
5312
5313 if (!unitTarget)
5314 return;
5315
5316 float speedxy = m_spellInfo->Effects[effIndex].MiscValue / 10.0f;
5317 float speedz = damage / 10.0f;
5318 //1891: Disengage
5320
5321 if (unitCaster->IsPlayer())
5322 {
5323 sScriptMgr->AnticheatSetUnderACKmount(unitCaster->ToPlayer());
5324 }
5325
5326 // xinef: changes fall time
5327 if (unitCaster->IsPlayer())
5328 unitCaster->ToPlayer()->SetFallInformation(GameTime::GetGameTime().count(), unitCaster->GetPositionZ());
5329}
@ SPELLFAMILY_HUNTER
Definition SharedDefines.h:3793
void JumpTo(float speedXY, float speedZ, bool forward=true)
Definition Unit.cpp:15104

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(), Object::ToUnit(), and unitTarget.

◆ EffectLearnPetSpell()

void Spell::EffectLearnPetSpell ( SpellEffIndex  effIndex)
3483{
3485 return;
3486
3487 if (!unitTarget)
3488 return;
3489
3490 if (unitTarget->ToPlayer())
3491 {
3492 EffectLearnSpell(effIndex);
3493 return;
3494 }
3495 Pet* pet = unitTarget->ToPet();
3496 if (!pet)
3497 return;
3498
3499 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3500 if (!learn_spellproto)
3501 return;
3502
3503 pet->learnSpell(learn_spellproto->Id);
3505 pet->GetOwner()->PetSpellInitialize();
3506}
bool learnSpell(uint32 spell_id)
Definition Pet.cpp:1903
void EffectLearnSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:2688

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)
2940{
2942 return;
2943
2944 if (!unitTarget->IsPlayer())
2945 return;
2946
2947 if (damage < 0)
2948 return;
2949
2950 uint32 skillid = m_spellInfo->Effects[effIndex].MiscValue;
2951 uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid);
2952 unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->Effects[effIndex].CalcValue(), skillval ? skillval : 1, damage * 75);
2953}
uint16 GetPureSkillValue(uint32 skill) const
Definition Player.cpp:5687
void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal)
Definition Player.cpp:5496

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)
2689{
2690 Unit* unitCaster = m_caster->ToUnit();
2691 if (!unitCaster)
2692 return;
2693
2695 return;
2696
2697 if (!unitTarget)
2698 return;
2699
2700 if (!unitTarget->IsPlayer())
2701 {
2702 if (unitTarget->ToPet())
2703 EffectLearnPetSpell(effIndex);
2704 return;
2705 }
2706
2707 Player* player = unitTarget->ToPlayer();
2708
2709 uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell;
2710 player->learnSpell(spellToLearn);
2711
2712 LOG_DEBUG("spells.aura", "Spell: Player {} has learned spell {} from Npc {}",
2713 player->GetGUID().ToString(), spellToLearn, unitCaster->GetGUID().ToString());
2714}
void learnSpell(uint32 spellId, bool temporary=false, bool learnFromSkill=false)
Definition Player.cpp:3419
void EffectLearnPetSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:3482

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(), Object::ToUnit(), and unitTarget.

Referenced by EffectLearnPetSpell().

◆ EffectMilling()

void Spell::EffectMilling ( SpellEffIndex  effIndex)
5816{
5817 Unit* unitCaster = m_caster->ToUnit();
5818 if (!unitCaster)
5819 return;
5820
5822 return;
5823
5824 if (!unitCaster->IsPlayer())
5825 return;
5826
5827 Player* p_caster = unitCaster->ToPlayer();
5829 return;
5830
5831 if (itemTarget->GetCount() < 5)
5832 return;
5833
5834 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5835 {
5836 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5837 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5838 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5839 }
5840
5841 unitCaster->ToPlayer()->SendLoot(itemTarget->GetGUID(), LOOT_MILLING);
5842}
@ LOOT_MILLING
Definition LootMgr.h:87
@ CONFIG_SKILL_MILLING
Definition WorldConfig.h:49
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition Player.cpp:7985
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition PlayerUpdates.cpp:789

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(), Object::ToUnit(), and Player::UpdateGatherSkill().

◆ EffectModifyThreatPercent()

void Spell::EffectModifyThreatPercent ( SpellEffIndex  effIndex)
5633{
5634 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5635 if (!unitCaster)
5636 return;
5637
5639 return;
5640
5641 if (!unitTarget)
5642 return;
5643
5645}
void ModifyThreatByPercent(Unit *target, int32 percent)
Definition ThreatManager.h:150

References damage, effectHandleMode, Unit::GetThreatMgr(), GetUnitCasterForEffectHandlers(), 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
2202{
2203 Unit* unitCaster = m_caster->ToUnit();
2204 if (!unitCaster)
2205 return;
2206
2208 return;
2209
2210 if (!unitCaster->IsPlayer())
2211 {
2212 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2213 return;
2214 }
2215
2216 Player* player = unitCaster->ToPlayer();
2217
2218 uint32 lockId = 0;
2219 ObjectGuid guid;
2220
2221 // Get lockId
2222 if (gameObjTarget)
2223 {
2224 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2225 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2226 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2227 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2228 {
2229 //CanUseBattlegroundObject() already called in CheckCast()
2230 // in battleground check
2231 if (Battleground* bg = player->GetBattleground())
2232 {
2233 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2234 return;
2235 }
2236 }
2237 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2238 {
2239 //CanUseBattlegroundObject() already called in CheckCast()
2240 // in battleground check
2241 if (Battleground* bg = player->GetBattleground())
2242 {
2243 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2244 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2245 return;
2246 }
2247 }
2248 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2249 {
2252 {
2254 }
2255 return;
2256 }
2258 // handle outdoor pvp object opening, return true if go was registered for handling
2259 // these objects must have been spawned by outdoorpvp!
2260 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2261 return;
2262 lockId = goInfo->GetLockId();
2263 guid = gameObjTarget->GetGUID();
2264 }
2265 else if (itemTarget)
2266 {
2267 lockId = itemTarget->GetTemplate()->LockID;
2268 guid = itemTarget->GetGUID();
2269 }
2270 else
2271 {
2272 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2273 return;
2274 }
2275
2276 SkillType skillId = SKILL_NONE;
2277 int32 reqSkillValue = 0;
2278 int32 skillValue;
2279
2280 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2281 if (res != SPELL_CAST_OK)
2282 {
2283 SendCastResult(res);
2284 return;
2285 }
2286
2287 if (gameObjTarget)
2288 SendLoot(guid, LOOT_SKINNING);
2289 else if (itemTarget)
2290 {
2292 if (Player* itemOwner = itemTarget->GetOwner())
2293 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2294 }
2295
2296 // not allow use skill grow at item base open
2297 if (!m_CastItem && skillId != SKILL_NONE)
2298 {
2299 // update skill if really known
2300 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2301 {
2302 if (gameObjTarget)
2303 {
2304 // Allow one skill-up until respawned
2305 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2306 {
2308 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2309 }
2310
2311 }
2312 else if (itemTarget)
2313 {
2314 // Do one skill-up
2315 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2316 }
2317 }
2318 }
2320}
@ 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:1223
LootState getLootState() const
Definition GameObject.h:225
void SetLootState(LootState s, Unit *unit=nullptr)
Definition GameObject.cpp:2484
bool IsInSkillupList(ObjectGuid const &playerGuid) const
Definition GameObject.cpp:3117
void AddToSkillupList(ObjectGuid const &playerGuid)
Definition GameObject.cpp:3111
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition Item.cpp:715
Definition Object.h:111
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition Spell.cpp:5289
void SendLoot(ObjectGuid guid, LootType loottype)
Definition SpellEffects.cpp:2136
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(), Object::ToUnit(), GameObjectTemplate::type, and Player::UpdateGatherSkill().

◆ EffectParry()

void Spell::EffectParry ( SpellEffIndex  effIndex)
4911{
4912 Unit* unitCaster = m_caster->ToUnit();
4913 if (!unitCaster)
4914 return;
4915
4917 return;
4918
4919 if (unitCaster->IsPlayer())
4920 unitCaster->ToPlayer()->SetCanParry(true);
4921}
void SetCanParry(bool value)
Definition Player.cpp:13454

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

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1951{
1952 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1953 if (!unitCaster)
1954 return;
1955
1957 return;
1958
1959 if (!m_spellAura)
1960 {
1961 Unit* caster = unitCaster->GetEntry() == WORLD_TRIGGER ? m_originalCaster : unitCaster;
1962 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1963
1964 // Caster not in world, might be spell triggered from aura removal
1965 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1966 return;
1967 DynamicObject* dynObj = new DynamicObject();
1969 {
1970 delete dynObj;
1971 return;
1972 }
1973
1975 {
1976 m_spellAura = aura;
1979 }
1980 else
1981 return;
1982 }
1983
1986}
#define MAX_EFFECT_MASK
Definition DBCStructure.h:1674
@ DYNAMIC_OBJECT_AREA_SPELL
Definition DynamicObject.h:30
DynamicObject * GetDynobjOwner() const
Definition SpellAuras.h:110
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(), GetUnitCasterForEffectHandlers(), SpellInfo::Id, Object::IsInWorld(), 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)
2863{
2864 Unit* unitCaster = m_caster->ToUnit();
2865 if (!unitCaster)
2866 return;
2867
2869 return;
2870
2871 if (!unitCaster->IsPlayer())
2872 return;
2873
2875}
@ LOOT_PICKPOCKETING
Definition LootMgr.h:81

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

◆ EffectPlayMusic()

void Spell::EffectPlayMusic ( SpellEffIndex  effIndex)
6445{
6447 return;
6448
6449 if (!unitTarget)
6450 return;
6451
6452 Player* player = unitTarget->ToPlayer();
6453 if (!player)
6454 {
6455 return;
6456 }
6457
6458 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6459
6460 if (!sSoundEntriesStore.LookupEntry(soundid))
6461 {
6462 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6463 return;
6464 }
6465
6467}
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)
6498{
6500 return;
6501
6502 if (!unitTarget)
6503 return;
6504
6505 Player* player = unitTarget->ToPlayer();
6506 if (!player)
6507 {
6508 return;
6509 }
6510
6511 switch (m_spellInfo->Id)
6512 {
6513 case 58730: // Restricted Flight Area
6514 case 58600: // Restricted Flight Area
6516 break;
6517 default:
6518 break;
6519 }
6520
6521 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6522
6523 if (!sSoundEntriesStore.LookupEntry(soundId))
6524 {
6525 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6526 return;
6527 }
6528
6529 player->PlayDirectSound(soundId, player);
6530}
@ 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:3016

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)
1518{
1519 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1521 return;
1522
1523 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1524 return;
1525
1526 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1527
1529 return;
1530
1531 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1532 if (unitCaster && m_spellInfo->Id == 8129)
1533 {
1534 int32 maxDamage = int32(CalculatePct(unitCaster->GetMaxPower(PowerType), damage * 2));
1536 damage = std::min(damage, maxDamage);
1537
1538 // Remove fear
1540 }
1541
1542 int32 power = damage;
1543 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1544 if (PowerType == POWER_MANA)
1545 power -= unitTarget->GetSpellCritDamageReduction(power);
1546
1547 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -power));
1548
1549 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1550 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1551
1552 // add log data before multiplication (need power amount, not damage)
1553 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, 0.0f);
1554
1555 newDamage = int32(newDamage * dmgMultiplier);
1556
1557 m_damage += newDamage;
1558}
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
Definition Spell.cpp:5258
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:10780
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition Unit.h:1281

References CalculatePct(), damage, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectTakeTargetPower(), Unit::GetMaxPower(), Unit::GetSpellCritDamageReduction(), GetUnitCasterForEffectHandlers(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), 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)
1435{
1436 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1438 return;
1439
1440 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1441 return;
1442
1443 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1444
1446 return;
1447
1448 // add spell damage bonus
1449 if (unitCaster)
1450 {
1453 }
1454
1455 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1456 int32 power = damage;
1457 if (PowerType == POWER_MANA)
1458 power -= unitTarget->GetSpellCritDamageReduction(power);
1459
1460 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1461
1462 float gainMultiplier = 0.0f;
1463
1464 // Don`t restore from self drain
1465 if (unitCaster && unitCaster != unitTarget)
1466 {
1467 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1468
1469 int32 gain = int32(newDamage * gainMultiplier);
1470
1471 unitCaster->EnergizeBySpell(unitCaster, m_spellInfo->Id, gain, PowerType);
1472 }
1473 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1474}

References damage, effectHandleMode, SpellInfo::Effects, Unit::EnergizeBySpell(), ExecuteLogEffectTakeTargetPower(), Unit::GetSpellCritDamageReduction(), GetUnitCasterForEffectHandlers(), Unit::HasActivePowerType(), SpellInfo::Id, Unit::IsAlive(), 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)
2436{
2437 Unit* unitCaster = m_caster->ToUnit();
2438 if (!unitCaster)
2439 return;
2440
2442 return;
2443
2444 if (!unitCaster->IsPlayer())
2445 return;
2446 Player* p_target = unitCaster->ToPlayer();
2447
2449 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2450 {
2451 p_target->AddWeaponProficiency(subClassMask);
2453 }
2454 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2455 {
2456 p_target->AddArmorProficiency(subClassMask);
2458 }
2459}
uint32 GetArmorProficiency() const
Definition Player.h:1385
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition Player.cpp:10276
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, Object::ToPlayer(), and Object::ToUnit().

◆ EffectProspecting()

void Spell::EffectProspecting ( SpellEffIndex  effIndex)
5787{
5788 Unit* unitCaster = m_caster->ToUnit();
5789 if (!unitCaster)
5790 return;
5791
5793 return;
5794
5795 if (!unitCaster->IsPlayer())
5796 return;
5797
5798 Player* p_caster = unitCaster->ToPlayer();
5800 return;
5801
5802 if (itemTarget->GetCount() < 5)
5803 return;
5804
5805 if (sWorld->getBoolConfig(CONFIG_SKILL_PROSPECTING))
5806 {
5807 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_JEWELCRAFTING);
5808 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5809 p_caster->UpdateGatherSkill(SKILL_JEWELCRAFTING, SkillValue, reqSkillValue);
5810 }
5811
5813}
@ LOOT_PROSPECTING
Definition LootMgr.h:86
@ CONFIG_SKILL_PROSPECTING
Definition WorldConfig.h:48

References CONFIG_SKILL_PROSPECTING, effectHandleMode, Item::GetCount(), Object::GetGUID(), Player::GetPureSkillValue(), Item::GetTemplate(), ItemTemplate::HasFlag(), Object::IsPlayer(), ITEM_FLAG_IS_PROSPECTABLE, itemTarget, LOOT_PROSPECTING, m_caster, ItemTemplate::RequiredSkillRank, Player::SendLoot(), SKILL_JEWELCRAFTING, SPELL_EFFECT_HANDLE_HIT_TARGET, sWorld, Object::ToPlayer(), Object::ToUnit(), and Player::UpdateGatherSkill().

◆ EffectPull()

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

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5394{
5396 return;
5397
5398 if (!unitTarget)
5399 return;
5400
5401 Position pos;
5402 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5403 {
5404 if (m_targets.HasDst())
5405 pos.Relocate(*destTarget);
5406 else
5407 return;
5408 }
5409 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5410 {
5411 // Xinef: Increase Z position a little bit, should protect from falling through textures
5413 }
5414
5415 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5416 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5417
5418 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5419
5420 if (unitTarget->IsPlayer())
5421 {
5422 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5423 }
5424}
@ 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)
5332{
5334 return;
5335
5336 if (!unitTarget)
5337 return;
5338
5339 Player* player = unitTarget->ToPlayer();
5340 if (!player)
5341 {
5342 return;
5343 }
5344
5345 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5346
5347 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5348
5349 if (!quest)
5350 return;
5351
5352 // Player has never done this quest
5353 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5354 return;
5355
5356 // remove all quest entries for 'entry' from quest log
5357 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5358 {
5359 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5360 if (logQuest == quest_id)
5361 {
5362 player->SetQuestSlot(slot, 0);
5363
5364 // we ignore unequippable quest items in this case, it's still be equipped
5365 player->TakeQuestSourceItem(logQuest, false);
5366
5367 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5368 {
5369 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5370 player->UpdatePvPState();
5371 }
5372 }
5373 }
5374
5375 player->RemoveRewardedQuest(quest_id);
5376 player->RemoveActiveQuest(quest_id, false);
5377}
@ 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:2566
void UpdatePvPState()
Definition PlayerUpdates.cpp:1464
uint32 GetQuestSlotQuestId(uint16 slot) const
Definition Player.h:1510
void SetQuestSlot(uint16 slot, uint32 quest_id, uint32 timer=0)
Definition Player.h:1514
PvPInfo pvpInfo
Definition Player.h:1875
bool TakeQuestSourceItem(uint32 questId, bool msg)
Definition PlayerQuest.cpp:1436
void RemoveActiveQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1569
QuestStatus GetQuestStatus(uint32 quest_id) const
Definition PlayerQuest.cpp:1504
void RemoveRewardedQuest(uint32 questId, bool update=true)
Definition PlayerQuest.cpp:1587
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)
4978{
4980 return;
4981
4982 if (!unitTarget)
4983 return;
4984
4985 Player* player = unitTarget->ToPlayer();
4986 if (!player)
4987 {
4988 return;
4989 }
4990
4991 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4992 if (questId)
4993 {
4994 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
4995 if (!quest)
4996 return;
4997
4998 uint16 logSlot = player->FindQuestSlot(questId);
4999 if (logSlot < MAX_QUEST_LOG_SIZE)
5000 player->AreaExploredOrEventHappens(questId);
5001 else if (player->CanTakeQuest(quest, false)) // Check if the quest has already been turned in.
5002 player->SetRewardedQuest(questId); // If not, set status to rewarded without broadcasting it to client.
5003 }
5004}
uint16 FindQuestSlot(uint32 quest_id) const
Definition PlayerQuest.cpp:1856
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:1865

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)
6044{
6046 return;
6047
6048 if (!unitTarget)
6049 return;
6050
6051 if (Player* player = unitTarget->ToPlayer())
6052 {
6053 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
6054 }
6055}

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

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
6058{
6060 return;
6061
6062 if (!unitTarget)
6063 return;
6064
6065 Player* player = unitTarget->ToPlayer();
6066 if (!player)
6067 return;
6068
6069 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
6070 {
6071 if (!player->CanTakeQuest(quest, false))
6072 return;
6073
6074 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
6075 player->AddQuestAndCheckCompletion(quest, player);
6076
6077 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
6078 }
6079}
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:2286

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)
6591{
6592 Unit* unitCaster = m_caster->ToUnit();
6593 if (!unitCaster)
6594 return;
6595
6597 return;
6598
6599 if (!unitTarget || !unitTarget->IsPlayer())
6600 return;
6601
6602 Player* player = unitCaster->ToPlayer();
6603
6604 if (!player)
6605 return;
6606
6607 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6608
6609 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6610 if (!pProto)
6611 {
6612 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6613 return;
6614 }
6615
6616 if (Item* pItem = player->GetItemByEntry(item_id))
6617 {
6618 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6619 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6620 pItem->SetState(ITEM_CHANGED, player);
6621 }
6622}

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(), Object::ToUnit(), and unitTarget.

◆ EffectRedirectThreat()

void Spell::EffectRedirectThreat ( SpellEffIndex  effIndex)
6226{
6227 Unit* unitCaster = GetUnitCasterForEffectHandlers();
6228 if (!unitCaster)
6229 return;
6230
6232 return;
6233
6234 if (unitTarget)
6236}
void RegisterRedirectThreat(uint32 spellId, ObjectGuid const &victim, uint32 pct)
== REDIRECT SYSTEM ==
Definition ThreatManager.cpp:835

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

◆ EffectRemoveAura()

void Spell::EffectRemoveAura ( SpellEffIndex  effIndex)
6533{
6535 return;
6536
6537 if (!unitTarget)
6538 return;
6539 // there may be need of specifying casterguid of removed auras
6540 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6541}

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

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6433{
6435 return;
6436
6437 if (!unitTarget || !unitTarget->IsCreature() ||
6439 return;
6440
6442}
@ 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:902
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)
4952{
4954 return;
4955
4956 if (!unitTarget)
4957 return;
4958
4959 Player* player = unitTarget->ToPlayer();
4960 if (!player)
4961 {
4962 return;
4963 }
4964
4965 float repChange = static_cast<float>(damage);
4966
4967 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4968
4969 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4970 if (!factionEntry)
4971 return;
4972
4973 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4974 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4975}
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:6040
ReputationMgr & GetReputationMgr()
Definition Player.h:2156
bool ModifyReputation(FactionEntry const *factionEntry, float standing, bool noSpillOver=false, Optional< ReputationRank > repMaxCap={})
Definition ReputationMgr.h:117
Definition DBCStructure.h:943

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)
4858{
4859 Unit* unitCaster = m_caster->ToUnit();
4860 if (!unitCaster)
4861 return;
4862
4864 return;
4865
4866 if (!unitTarget)
4867 return;
4868
4869 if (!unitTarget)
4870 return;
4871
4872 Player* target = unitTarget->ToPlayer();
4873 if (!target)
4874 {
4875 return;
4876 }
4877
4878 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4879 return;
4880
4881 if (target->isResurrectRequested()) // already have one active request
4882 return;
4883
4884 uint32 health = target->CountPctFromMaxHealth(damage);
4886
4887 ExecuteLogEffectResurrect(effIndex, target);
4888
4889 target->setResurrectRequestData(unitCaster->GetGUID(), unitCaster->GetMapId(), unitCaster->GetPositionX(), unitCaster->GetPositionY(), unitCaster->GetPositionZ(), health, mana);
4890 SendResurrectRequest(target);
4891}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition Player.h:1844
bool isResurrectRequested() const
Definition Player.h:1856
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition Spell.cpp:5319
void SendResurrectRequest(Player *target)
Definition Spell.cpp:5389

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(), Object::ToUnit(), and unitTarget.

◆ EffectResurrectNew()

void Spell::EffectResurrectNew ( SpellEffIndex  effIndex)
250{
251 Unit* unitCaster = m_caster->ToUnit();
252 if (!unitCaster)
253 return;
254
256 return;
257
258 if (!unitTarget || unitTarget->IsAlive())
259 return;
260
261 if (!unitTarget->IsPlayer())
262 return;
263
264 if (!unitTarget->IsInWorld())
265 return;
266
267 Player* target = unitTarget->ToPlayer();
268
269 if (target->isResurrectRequested()) // already have one active request
270 return;
271
272 uint32 health = damage;
273 uint32 mana = m_spellInfo->Effects[effIndex].MiscValue;
274 ExecuteLogEffectResurrect(effIndex, target);
275 target->setResurrectRequestData(unitCaster->GetGUID(), unitCaster->GetMapId(), unitCaster->GetPositionX(), unitCaster->GetPositionY(), unitCaster->GetPositionZ(), health, mana);
276 SendResurrectRequest(target);
277}

References damage, effectHandleMode, SpellInfo::Effects, ExecuteLogEffectResurrect(), Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::IsAlive(), Object::IsInWorld(), Object::IsPlayer(), Player::isResurrectRequested(), m_caster, m_spellInfo, SendResurrectRequest(), Player::setResurrectRequestData(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), Object::ToUnit(), and unitTarget.

◆ EffectResurrectPet()

void Spell::EffectResurrectPet ( SpellEffIndex  effIndex)
Todo:
: Better to fail Hunter's "Revive Pet" at cast instead of here when casting ends
5474{
5475 Unit* unitCaster = m_caster->ToUnit();
5476 if (!unitCaster)
5477 return;
5478
5480 return;
5481
5482 if (damage < 0)
5483 return;
5484
5485 Player* player = unitCaster->ToPlayer();
5486 if (!player)
5487 {
5488 return;
5489 }
5490
5491 Pet* pet = player->GetPet();
5492 if (!pet)
5493 {
5494 // Position passed to SummonPet is irrelevant with current implementation,
5495 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5496 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0ms, damage);
5497 return;
5498 }
5499
5501 if (pet->IsAlive())
5502 {
5503 return;
5504 }
5505
5506 // Reposition the pet's corpse before reviving so as not to grab aggro
5507 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5508 float x, y, z; // Will be used later to reposition the pet if we have one
5509 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5510 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5511 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5515 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5517 pet->SetDisplayId(pet->GetNativeDisplayId());
5518
5519 // xinef: restore movement
5520 if (auto ci = pet->GetCharmInfo())
5521 {
5522 ci->SetIsAtStay(false);
5523 ci->SetIsFollowing(false);
5524 }
5525
5527}
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:2413
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0ms, uint32 healthPct=0)
Definition Player.cpp:9172
void ReplaceAllDynamicFlags(uint32 flag) override
Definition Unit.h:770
void SetHealth(uint32 val)
Definition Unit.cpp:11950
uint32 GetNativeDisplayId() const
Definition Unit.h:1982
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:2825

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(), Object::ToUnit(), UNIT_DYNFLAG_NONE, UNIT_FLAG_SKINNABLE, UNIT_STATE_ALL_STATE, and UNIT_STATE_POSSESSED.

◆ EffectSanctuary()

void Spell::EffectSanctuary ( SpellEffIndex  effIndex)
4214{
4216 return;
4217
4218 if (!unitTarget)
4219 return;
4220
4222
4224 {
4225 // stop all pve combat for players outside dungeons, suppress pvp combat
4226 unitTarget->CombatStop(false, false);
4227 }
4228 else
4229 {
4230 // in dungeons (or for nonplayers), reset this unit on all enemies' threat lists
4231 for (auto const& pair : unitTarget->GetThreatMgr().GetThreatenedByMeList())
4232 pair.second->ScaleThreat(0.0f);
4233 }
4234
4235 UnitList targets;
4236 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, unitTarget->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
4239 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
4240 {
4241 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
4242 continue;
4243
4245 {
4246 if ((*iter)->GetCurrentSpell(i) && (*iter)->GetCurrentSpell(i)->m_targets.GetUnitTargetGUID() == unitTarget->GetGUID())
4247 {
4248 SpellInfo const* si = (*iter)->GetCurrentSpell(i)->GetSpellInfo();
4249 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
4250 {
4251 Creature* c = (*iter)->ToCreature();
4252 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
4253 continue;
4254 }
4255 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
4256 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4257 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
4258 {
4259 // at least one effect truly targets an unit, interrupt the spell
4260 interrupt = true;
4261 break;
4262 }
4263 if (interrupt)
4264 (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
4265 }
4266 }
4267 }
4268
4269 // Xinef: Set last sanctuary time
4271}
#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:7273

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

References AddPct(), Unit::ApplyEffectModifiers(), ApplyPct(), AURA_STATE_CONFLAGRATE, BASE_ATTACK, WorldObject::CalcSpellDuration(), CalculatePct(), WorldObject::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(), GetUnitCasterForEffectHandlers(), SpellInfo::HasAttribute(), Unit::HasAura(), Unit::HasAuraState(), SpellInfo::Id, IN_MILLISECONDS, irand(), Unit::IsAlive(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), 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)
4018{
4019 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4021 return;
4022
4024
4025 if (unitCaster)
4026 {
4028 {
4030 {
4031 switch (m_spellInfo->Id)
4032 {
4033 // Shadow Flame (All script effects, not just end ones to prevent player from dodging the last triggered spell)
4034 case 22539:
4035 case 22972:
4036 case 22975:
4037 case 22976:
4038 case 22977:
4039 case 22978:
4040 case 22979:
4041 case 22980:
4042 case 22981:
4043 case 22982:
4044 case 22983:
4045 case 22984:
4046 case 22985:
4047 {
4048 if (!unitTarget || !unitTarget->IsAlive())
4049 return;
4050
4051 // Onyxia Scale Cloak
4052 if (unitTarget->HasAura(22683))
4053 return;
4054
4055 // Shadow Flame
4056 unitCaster->CastSpell(unitTarget, 22682, true);
4057 return;
4058 }
4059 // Plant Warmaul Ogre Banner
4060 case 32307:
4061 if (Player* caster = unitCaster->ToPlayer())
4062 {
4063 caster->RewardPlayerAndGroupAtEvent(18388, unitTarget);
4064 if (Creature* target = unitTarget->ToCreature())
4065 {
4066 target->setDeathState(DeathState::Corpse);
4067 target->RemoveCorpse();
4068 }
4069 }
4070 break;
4071 // SOTA defender teleport
4072 case 54640:
4073 {
4074 if (Player* player = unitTarget->ToPlayer())
4075 if (player->GetBattleground() && player->GetBattleground()->GetBgTypeID(true) == BATTLEGROUND_SA)
4076 {
4077 if (GameObject* dportal = player->FindNearestGameObject(192819, 10.0f))
4078 {
4079 BattlegroundSA* bg = ((BattlegroundSA*)player->GetBattleground());
4080 bg->DefendersPortalTeleport(dportal, player);
4081 }
4082 }
4083 return;
4084 }
4085 /*// Mug Transformation
4086 case 41931:
4087 {
4088 if (!unitCaster->IsPlayer())
4089 return;
4090
4091 uint8 bag = 19;
4092 uint8 slot = 0;
4093 Item* item = nullptr;
4094
4095 while (bag) // 256 = 0 due to var type
4096 {
4097 item = unitCaster->ToPlayer()->GetItemByPos(bag, slot);
4098 if (item && item->GetEntry() == 38587)
4099 break;
4100
4101 ++slot;
4102 if (slot == 39)
4103 {
4104 slot = 0;
4105 ++bag;
4106 }
4107 }
4108 if (bag)
4109 {
4110 if (unitCaster->ToPlayer()->GetItemByPos(bag, slot)->GetCount() == 1) unitCaster->ToPlayer()->RemoveItem(bag, slot, true);
4111 else unitCaster->ToPlayer()->GetItemByPos(bag, slot)->SetCount(unitCaster->ToPlayer()->GetItemByPos(bag, slot)->GetCount()-1);
4112 // Spell 42518 (Braufest - Gratisprobe des Braufest herstellen)
4113 unitCaster->CastSpell(unitCaster, 42518, true);
4114 return;
4115 }
4116 break;
4117 }*/
4118 case 52173: // Coyote Spirit Despawn
4119 case 60243: // Blood Parrot Despawn
4122 return;
4123 case 57347: // Retrieving (Wintergrasp RP-GG pickup spell)
4124 {
4125 if (!unitTarget || !unitTarget->IsCreature() || !unitCaster->IsPlayer())
4126 return;
4127
4129
4130 return;
4131 }
4132 case 57349: // Drop RP-GG (Wintergrasp RP-GG at death drop spell)
4133 {
4134 if (!unitCaster->IsPlayer())
4135 return;
4136
4137 // Delete item from inventory at death
4138 unitCaster->ToPlayer()->DestroyItemCount(damage, 5, true);
4139
4140 return;
4141 }
4142 case 58418: // Portal to Orgrimmar
4143 case 58420: // Portal to Stormwind
4144 {
4145 if (!unitTarget || !unitTarget->IsPlayer() || effIndex != 0)
4146 return;
4147
4148 uint32 spellID = m_spellInfo->Effects[EFFECT_0].CalcValue();
4149 uint32 questID = m_spellInfo->Effects[EFFECT_1].CalcValue();
4150
4152 unitTarget->CastSpell(unitTarget, spellID, true);
4153
4154 return;
4155 }
4156 case 61263: // for item Intravenous Healing Potion (44698)
4157 {
4158 if (!unitTarget)
4159 return;
4160
4161 unitCaster->CastSpell(unitCaster, 61267, true);
4162 unitCaster->CastSpell(unitCaster, 61268, true);
4163 return;
4164 }
4165 }
4166 break;
4167 }
4168 case SPELLFAMILY_ROGUE:
4169 {
4170 switch (m_spellInfo->Id)
4171 {
4172 // Master of Subtlety
4173 case 31666:
4174 {
4175 if (!unitTarget)
4176 return;
4177
4178 Aura* mos = unitTarget->GetAura(31665);
4179 if (mos)
4180 {
4181 mos->SetMaxDuration(6000);
4182 mos->SetDuration(6000, true);
4183 }
4184
4185 break;
4186 }
4187 // Overkill
4188 case 58428:
4189 {
4190 if (!unitTarget)
4191 return;
4192
4193 Aura* overkill = unitTarget->GetAura(58427);
4194 if (overkill)
4195 {
4196 overkill->SetMaxDuration(20000);
4197 overkill->SetDuration(20000, true);
4198 }
4199
4200 break;
4201 }
4202 }
4203 break;
4204 }
4205 }
4206 }
4207
4208 // normal DB scripted effect
4209 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectScriptEffect({})", m_spellInfo->Id, effIndex);
4211}
@ 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:2216
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:2567

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(), GetUnitCasterForEffectHandlers(), 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)
5084{
5085 Unit* unitCaster = m_caster->ToUnit();
5086 if (!unitCaster)
5087 return;
5088
5090 return;
5091
5092 if (!m_caster || unitCaster->IsAlive())
5093 return;
5094 if (!unitCaster->IsPlayer())
5095 return;
5096 if (!unitCaster->IsInWorld())
5097 return;
5098
5099 uint32 health = 0;
5100 uint32 mana = 0;
5101
5102 // flat case
5103 if (damage < 0)
5104 {
5105 health = uint32(-damage);
5106 mana = m_spellInfo->Effects[effIndex].MiscValue;
5107 }
5108 // percent case
5109 else
5110 {
5111 health = unitCaster->CountPctFromMaxHealth(damage);
5112 if (unitCaster->GetMaxPower(POWER_MANA) > 0)
5113 mana = CalculatePct(unitCaster->GetMaxPower(POWER_MANA), damage);
5114 }
5115
5116 Player* player = unitCaster->ToPlayer();
5117 player->ResurrectPlayer(0.0f);
5118
5119 player->SetHealth(health);
5120 player->SetPower(POWER_MANA, mana);
5121 player->SetPower(POWER_RAGE, 0);
5122 player->SetPower(POWER_ENERGY, player->GetMaxPower(POWER_ENERGY));
5123
5124 player->SpawnCorpseBones();
5125}
@ POWER_RAGE
Definition SharedDefines.h:258
void SpawnCorpseBones(bool triggerSave=true)
Definition Player.cpp:4774
void ResurrectPlayer(float restore_percent, bool applySickness=false)
Definition Player.cpp:4556
void SetPower(Powers power, uint32 val, bool withPowerUpdate=true, bool fromRegenerate=false)
Definition Unit.cpp:12038

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, Object::ToPlayer(), and Object::ToUnit().

◆ EffectSendEvent()

void Spell::EffectSendEvent ( SpellEffIndex  effIndex)
Todo:
: there should be a possibility to pass dest target to event script
1477{
1478 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1481 return;
1482
1483 WorldObject* target = nullptr;
1484
1485 // call events for object target if present
1487 {
1488 if (unitTarget)
1489 target = unitTarget;
1490 else if (gameObjTarget)
1491 target = gameObjTarget;
1492 }
1493 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1494 {
1495 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1496 // this check was requested by scripters, but it has some downsides:
1497 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1498 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1499 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
1500 return;
1501 // some spells have no target entries in dbc and they use focus target
1502 if (focusObject)
1503 target = focusObject;
1505 }
1506
1507 LOG_DEBUG("spells.aura", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
1508
1509 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1510 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1511 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1512 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1513
1514 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
1515}
ScriptMapMap sEventScripts
Definition ObjectMgr.cpp:61
@ TARGET_FLAG_GAMEOBJECT_MASK
Definition SpellInfo.h:71
ZoneScript * GetZoneScript() const
Definition Object.h:643
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)
5380{
5382 return;
5383
5384 if (!unitTarget)
5385 return;
5386
5387 if (Player* player = unitTarget->ToPlayer())
5388 {
5389 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5390 }
5391}

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

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5845{
5847 return;
5848
5849 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5850}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
5128{
5129 Unit* unitCaster = m_caster->ToUnit();
5130 if (!unitCaster)
5131 return;
5132
5134 return;
5135
5136 if (!unitTarget->IsCreature())
5137 return;
5138 if (!unitCaster->IsPlayer())
5139 return;
5140
5141 Creature* creature = unitTarget->ToCreature();
5142 int32 targetLevel = creature->GetLevel();
5143
5144 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
5145
5148 unitCaster->ToPlayer()->SendLoot(creature->GetGUID(), LOOT_SKINNING);
5149
5150 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
5151
5152 int32 skillValue = unitCaster->ToPlayer()->GetPureSkillValue(skill);
5153
5154 // Double chances for elites
5155 unitCaster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
5156}
@ UNIT_DYNFLAG_LOOTABLE
Definition SharedDefines.h:3354
bool isElite() const
Definition Creature.h:115
virtual void SetDynamicFlag(uint32 flag)
Definition Object.h:131

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(), Object::ToUnit(), UNIT_DYNFLAG_LOOTABLE, UNIT_FLAG_SKINNABLE, unitTarget, and Player::UpdateGatherSkill().

◆ EffectSkinPlayerCorpse()

void Spell::EffectSkinPlayerCorpse ( SpellEffIndex  effIndex)
5876{
5877 Unit* unitCaster = m_caster->ToUnit();
5878 if (!unitCaster)
5879 return;
5880
5882 return;
5883
5884 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5885 if ((!unitCaster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5886 return;
5887
5888 unitTarget->ToPlayer()->RemovedInsignia(unitCaster->ToPlayer());
5889
5890 // We have a corpse object as the target.
5891 // This target was deleted in RemovedInsignia() -> ConvertCorpseToBones().
5893}
void RemovedInsignia(Player *looterPlr)
Definition Player.cpp:7946
void RemoveObjectTarget()
Definition Spell.cpp:358

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

◆ EffectSpecCount()

void Spell::EffectSpecCount ( SpellEffIndex  effIndex)
6470{
6472 return;
6473
6474 if (!unitTarget)
6475 return;
6476
6477 if (Player* player = unitTarget->ToPlayer())
6478 {
6479 player->UpdateSpecCount(damage);
6480 }
6481}

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

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5857{
5859 return;
5860
5861 /*
5862 if (!unitTarget->IsPlayer())
5863 return;
5864 if (!unitTarget->IsInWorld())
5865 return;
5866
5867 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5868 //unitTarget->ToPlayer()->setResurrect(unitCaster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5869 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5870 unitTarget->ToPlayer()->SpawnCorpseBones();
5871 */
5872}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5896{
5897 Unit* unitCaster = m_caster->ToUnit();
5898 if (!unitCaster)
5899 return;
5900
5902 return;
5903
5904 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5905
5906 if (!unitTarget || unitTarget == unitCaster) // can't steal from self
5907 return;
5908
5909 DispelChargesList steal_list;
5910
5911 // Create dispel mask by dispel type
5912 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5913 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5914 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5915 {
5916 Aura* aura = itr->second;
5918 if (!aurApp)
5919 continue;
5920
5921 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5922 {
5923 // Need check for passive? this
5924 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5925 continue;
5926
5927 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5928 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5929 // Polymorph instead of 1 / (5 + 1) -> 16%.
5930 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5931 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5932 if (charges > 0)
5933 steal_list.push_back(std::make_pair(aura, charges));
5934 }
5935 }
5936
5937 if (steal_list.empty())
5938 return;
5939
5940 // Ok if exist some buffs for dispel try dispel it
5941 uint32 failCount = 0;
5942 DispelList success_list;
5943 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5944 // dispel N = damage buffs (or while exist buffs for dispel)
5945 for (int32 count = 0; count < damage && !steal_list.empty();)
5946 {
5947 // Random select buff for dispel
5948 DispelChargesList::iterator itr = steal_list.begin();
5949 std::advance(itr, urand(0, steal_list.size() - 1));
5950
5951 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(unitCaster));
5952 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5953 if (!chance)
5954 {
5955 steal_list.erase(itr);
5956 continue;
5957 }
5958 else
5959 {
5960 if (roll_chance_i(chance))
5961 {
5962 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5963 --itr->second;
5964 if (itr->second <= 0)
5965 steal_list.erase(itr);
5966 }
5967 else
5968 {
5969 if (!failCount)
5970 {
5971 // Failed to dispell
5972 dataFail << unitCaster->GetGUID(); // Caster GUID
5973 dataFail << unitTarget->GetGUID(); // Victim GUID
5974 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5975 }
5976 ++failCount;
5977 dataFail << uint32(itr->first->GetId()); // Spell Id
5978 }
5979 ++count;
5980 }
5981 }
5982
5983 if (failCount)
5984 unitCaster->SendMessageToSet(&dataFail, true);
5985
5986 if (success_list.empty())
5987 return;
5988
5989 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
5990 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
5991 dataSuccess << unitCaster->GetPackGUID(); // Caster GUID
5992 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
5993 dataSuccess << uint8(0); // not used
5994 dataSuccess << uint32(success_list.size()); // count
5995 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
5996 {
5997 dataSuccess << uint32(itr->first); // Spell Id
5998 dataSuccess << uint8(0); // 0 - steals !=0 transfers
5999 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, unitCaster);
6000 }
6001 unitCaster->SendMessageToSet(&dataSuccess, true);
6002}
@ 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:2716
bool IsPositive() const
Definition SpellAuras.h:69
uint8 GetCharges() const
Definition SpellAuras.h:142
bool IsPassive() const
Definition SpellAuras.cpp:1121
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit *stealer)
Definition Unit.cpp:5033
@ 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, Object::ToUnit(), unitTarget, and urand().

◆ EffectStuck()

void Spell::EffectStuck ( SpellEffIndex  effIndex)
4370{
4371 Unit* unitCaster = m_caster->ToUnit();
4372 if (!unitCaster)
4373 return;
4374
4376 return;
4377
4378 if (!unitCaster->IsPlayer())
4379 return;
4380
4381 Player* target = unitCaster->ToPlayer();
4382 if (target->IsInFlight())
4383 return;
4384
4385 // xinef: if player is dead - teleport to graveyard
4386 if (!target->IsAlive())
4387 {
4388 if (target->HasPreventResurectionAura())
4389 return;
4390
4391 // xinef: player is in corpse
4392 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4393 target->BuildPlayerRepop();
4394 target->RepopAtGraveyard();
4395 return;
4396 }
4397
4398 // xinef: no hearthstone in bag or on cooldown
4399 Item* hearthStone = target->GetItemByEntry(6948);
4400 if (!hearthStone || target->HasSpellCooldown(8690))
4401 {
4402 float o = rand_norm() * 2 * M_PI;
4403 Position pos = *target;
4404 target->MovePositionToFirstCollision(pos, 5.0f, o);
4405 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4406 return;
4407 }
4408
4409 // xinef: we have hearthstone not on cooldown, just use it
4411}
@ PLAYER_FLAGS_GHOST
Definition Player.h:463
double rand_norm()
Definition Random.cpp:85
void RepopAtGraveyard()
Definition Player.cpp:5006
void BuildPlayerRepop()
Definition Player.cpp:4508
bool HasPreventResurectionAura() const
Definition Unit.h:1810
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition Object.cpp:2984

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(), Object::ToUnit(), TRIGGERED_FULL_MASK, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

◆ EffectSummonChangeItem()

void Spell::EffectSummonChangeItem ( SpellEffIndex  effIndex)
2323{
2324 Unit* unitCaster = m_caster->ToUnit();
2325 if (!unitCaster)
2326 return;
2327
2329 return;
2330
2331 if (!unitCaster->IsPlayer())
2332 return;
2333
2334 Player* player = unitCaster->ToPlayer();
2335
2336 // applied only to using item
2337 if (!m_CastItem)
2338 return;
2339
2340 // ... only to item in own inventory/bank/equip_slot
2341 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2342 return;
2343
2344 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2345 if (!newitemid)
2346 return;
2347
2348 uint16 pos = m_CastItem->GetPos();
2349
2350 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2351 if (!pNewItem)
2352 return;
2353
2354 // Client-side enchantment durations update
2356
2360
2362 {
2364 player->DurabilityLoss(pNewItem, lossPercent);
2365 }
2366
2367 if (player->IsInventoryPos(pos))
2368 {
2369 ItemPosCountVec dest;
2370 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2371 if (msg == EQUIP_ERR_OK)
2372 {
2373 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2374
2375 // prevent crash at access and unexpected charges counting with item update queue corrupt
2377 m_targets.SetItemTarget(nullptr);
2378
2379 m_CastItem = nullptr;
2381
2382 player->StoreItem(dest, pNewItem, true);
2383 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2384 return;
2385 }
2386 }
2387 else if (player->IsBankPos(pos))
2388 {
2389 ItemPosCountVec dest;
2390 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2391 if (msg == EQUIP_ERR_OK)
2392 {
2393 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2394
2395 // prevent crash at access and unexpected charges counting with item update queue corrupt
2397 m_targets.SetItemTarget(nullptr);
2398
2399 m_CastItem = nullptr;
2401
2402 player->BankItem(dest, pNewItem, true);
2403 return;
2404 }
2405 }
2406 else if (player->IsEquipmentPos(pos))
2407 {
2408 uint16 dest;
2409
2410 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2411
2412 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2413
2414 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2415 {
2417
2418 // prevent crash at access and unexpected charges counting with item update queue corrupt
2420 m_targets.SetItemTarget(nullptr);
2421
2422 m_CastItem = nullptr;
2424
2425 player->EquipItem(dest, pNewItem, true);
2426 player->AutoUnequipOffhandIfNeed();
2427 return;
2428 }
2429 }
2430
2431 // fail
2432 delete pNewItem;
2433}
@ 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:4839
Item * StoreItem(ItemPosCountVec const &pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2690
void DestroyItem(uint8 bag, uint8 slot, bool update)
Definition PlayerStorage.cpp:3132
static bool IsInventoryPos(uint16 pos)
Definition Player.h:1282
void AutoUnequipOffhandIfNeed(bool force=false)
Definition Player.cpp:12748
Item * EquipItem(uint16 pos, Item *pItem, bool update)
Definition PlayerStorage.cpp:2837
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:1909
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(), Object::ToUnit(), and Player::UpdateEnchantmentDurations().

◆ EffectSummonCritter()

void Spell::EffectSummonCritter ( SpellEffIndex  effIndex)

◆ EffectSummonObject()

void Spell::EffectSummonObject ( SpellEffIndex  effIndex)
4781{
4782 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4783 if (!unitCaster)
4784 return;
4785
4787 return;
4788
4789 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4790
4791 uint8 slot = 0;
4792 switch (m_spellInfo->Effects[effIndex].Effect)
4793 {
4795 slot = 0;
4796 break;
4798 slot = 1;
4799 break;
4801 slot = 2;
4802 break;
4804 slot = 3;
4805 break;
4806 default:
4807 return;
4808 }
4809
4810 if (unitCaster)
4811 {
4812 ObjectGuid guid = unitCaster->m_ObjectSlot[slot];
4813 if (guid)
4814 {
4815 if (GameObject* gameObject = unitCaster->GetMap()->GetGameObject(guid))
4816 {
4817 // Recast case - null spell id to make auras not be removed on object remove from world
4818 if (m_spellInfo->Id == gameObject->GetSpellId())
4819 gameObject->SetSpellId(0);
4820 unitCaster->RemoveGameObject(gameObject, true);
4821 }
4822 unitCaster->m_ObjectSlot[slot].Clear();
4823 }
4824 }
4825
4826 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4827
4828 float x, y, z;
4829 // If dest location if present
4830 if (m_targets.HasDst())
4831 destTarget->GetPosition(x, y, z);
4832 // Summon in random point all other units if location present
4833 else
4834 unitCaster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
4835
4836 Map* map = unitCaster->GetMap();
4837 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), unitCaster->GetOrientation());
4838 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, unitCaster->GetPhaseMask(), x, y, z, unitCaster->GetOrientation(), rotation, 0, GO_STATE_READY))
4839 {
4840 delete pGameObj;
4841 return;
4842 }
4843
4844 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, unitCaster->GetLevel());
4845 int32 duration = m_spellInfo->GetDuration();
4846 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4847 pGameObj->SetSpellId(m_spellInfo->Id);
4848 unitCaster->AddGameObject(pGameObj);
4849
4850 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4851
4852 map->AddToMap(pGameObj, true);
4853
4854 unitCaster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4855}
#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:2084

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(), GetUnitCasterForEffectHandlers(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, 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)
3967{
3969 return;
3970
3971 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
3972
3973 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
3974
3975 WorldObject* target = focusObject;
3976 if (!target)
3977 target = m_caster;
3978
3979 float x, y, z;
3980 if (m_targets.HasDst())
3981 destTarget->GetPosition(x, y, z);
3982 else
3984
3985 Map* map = target->GetMap();
3986
3987 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), target->GetOrientation());
3988 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), rotation, 100, GO_STATE_READY))
3989 {
3990 delete pGameObj;
3991 return;
3992 }
3993
3994 int32 duration = m_spellInfo->GetDuration();
3995
3996 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
3997 pGameObj->SetSpellId(m_spellInfo->Id);
3998
3999 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4000
4001 // Wild object not have owner and check clickable by players
4002 map->AddToMap(pGameObj, true);
4003
4004 if (pGameObj->GetGoType() == GAMEOBJECT_TYPE_FLAGDROP)
4005 if (Player* player = m_caster->ToPlayer())
4006 if (Battleground* bg = player->GetBattleground())
4007 bg->SetDroppedFlagGUID(pGameObj->GetGUID(), player->GetTeamId() == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE);
4008
4009 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
4010 {
4011 linkedTrap->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS :0);
4012 linkedTrap->SetSpellId(m_spellInfo->Id);
4013 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
4014 }
4015}
@ GAMEOBJECT_TYPE_FLAGDROP
Definition SharedDefines.h:1590
@ TEAM_ALLIANCE
Definition SharedDefines.h:748
@ TEAM_HORDE
Definition SharedDefines.h:749
GameObject * GetLinkedTrap()
Definition GameObject.cpp:2777
GameobjectTypes GetGoType() const
Definition GameObject.h:204

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)
3368{
3369 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3371 return;
3372
3373 if (!m_originalCaster)
3374 return;
3375
3376 uint32 petentry = m_spellInfo->Effects[effIndex].MiscValue;
3377 int32 duration = m_spellInfo->GetDuration();
3378
3379 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
3380 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
3381
3382 Player* owner = m_originalCaster->ToPlayer();
3383 if (!owner && m_originalCaster->ToCreature()->IsTotem())
3385
3386 if (!owner)
3387 {
3388 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(67);
3389 if (properties)
3390 {
3391 // Xinef: unsummon old guardian
3392 if (Guardian* oldPet = m_originalCaster->GetGuardianPet())
3393 oldPet->UnSummon();
3394 SummonGuardian(effIndex, petentry, properties, 1, false);
3395 }
3396 return;
3397 }
3398
3399 Pet* OldSummon = owner->GetPet();
3400
3401 // if pet requested type already exist
3402 if (OldSummon)
3403 {
3404 if (petentry == 0 || OldSummon->GetEntry() == petentry)
3405 {
3406 // pet in corpse state can't be summoned
3407 if (OldSummon->isDead())
3408 return;
3409
3410 ASSERT(OldSummon->GetMap() == owner->GetMap());
3411
3412 //OldSummon->GetMap()->Remove(OldSummon->ToCreature(), false);
3413
3414 float px, py, pz;
3415 owner->GetClosePoint(px, py, pz, OldSummon->GetObjectSize());
3416
3417 OldSummon->NearTeleportTo(px, py, pz, OldSummon->GetOrientation());
3418 OldSummon->UpdateObjectVisibility();
3419
3420 OldSummon->SetHealth(OldSummon->GetMaxHealth());
3421 OldSummon->SetPower(OldSummon->getPowerType(), OldSummon->GetMaxPower(OldSummon->getPowerType()));
3422 // notify player
3423 for (CreatureSpellCooldowns::const_iterator itr = OldSummon->m_CreatureSpellCooldowns.begin(); itr != OldSummon->m_CreatureSpellCooldowns.end(); ++itr)
3424 owner->SendClearCooldown(itr->first, OldSummon);
3425
3426 // actually clear cooldowns
3427 OldSummon->m_CreatureSpellCooldowns.clear();
3428 Unit::AuraApplicationMap& myAuras = OldSummon->GetAppliedAuras();
3429 for (Unit::AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
3430 {
3431 Aura const* aura = i->second->GetBase();
3432 if (!aura->IsPassive() && !OldSummon->IsPetAura(aura) && aura->CanBeSentToClient())
3433 OldSummon->RemoveAura(i);
3434 else
3435 ++i;
3436 }
3437 return;
3438 }
3439
3440 if (owner->IsPlayer())
3441 owner->ToPlayer()->RemovePet(OldSummon, PET_SAVE_NOT_IN_SLOT, false);
3442 else
3443 return;
3444 }
3445
3446 float x, y, z;
3447 owner->GetClosePoint(x, y, z, owner->GetObjectSize());
3448 Pet* pet = owner->SummonPet(petentry, x, y, z, owner->GetOrientation(), SUMMON_PET);
3449 if (!pet)
3450 return;
3451
3452 if (unitCaster->IsCreature())
3453 {
3454 if (unitCaster->ToCreature()->IsTotem())
3456 else
3458 }
3459
3461
3462 // Reset cooldowns
3464 {
3465 pet->m_CreatureSpellCooldowns.clear();
3466 owner->PetSpellInitialize();
3467 }
3468
3469 // Set health to max if new pet is summoned
3470 // in this function old pet is saved with current health eg. 20% and new one is loaded from db with same amount
3471 // pet should have full health
3472 pet->SetHealth(pet->GetMaxHealth());
3473
3474 // generate new name for summon pet
3475 std::string new_name = sObjectMgr->GeneratePetName(petentry);
3476 if (!new_name.empty())
3477 pet->SetName(new_name);
3478
3479 // ExecuteLogEffectSummonObject(effectInfo->EffectIndex, pet);
3480}
@ SPELLMOD_DURATION
Definition SpellDefines.h:85
@ REACT_DEFENSIVE
Definition Unit.h:568
@ REACT_AGGRESSIVE
Definition Unit.h:569
bool CanBeSentToClient() const
Definition SpellAuras.cpp:1176
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:15088
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties, uint32 numSummons, bool personalSpawn)
Definition SpellEffects.cpp:6284
bool IsPetAura(Aura const *aura)
Definition Unit.cpp:13353
void UpdateObjectVisibility(bool forced=true, bool fromUpdate=false) override
Definition Unit.cpp:14982
Powers getPowerType() const
Definition Unit.h:1137
bool isDead() const
Definition Unit.h:1798
void SetName(std::string const &newname)
Definition Object.h:536
float GetObjectSize() const
Definition Object.cpp:2897

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(), GetUnitCasterForEffectHandlers(), SpellInfo::Id, Player::IsClass(), Object::IsCreature(), Unit::isDead(), Aura::IsPassive(), Unit::IsPetAura(), Object::IsPlayer(), Unit::IsTotem(), 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)
4414{
4415 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4416 if (!unitCaster)
4417 return;
4418
4419 // workaround - this effect should not use target map
4421 return;
4422
4423 if (!unitTarget)
4424 return;
4425
4426 Player* player = unitTarget->ToPlayer();
4427 if (!player)
4428 {
4429 return;
4430 }
4431
4432 // Evil Twin (ignore player summon, but hide this for summoner)
4433 // Xinef: Unit Target may be on other map!!!, Need workaround
4434 if (unitTarget->HasAura(23445))
4435 return;
4436
4437 float x, y, z;
4438 unitCaster->GetPosition(x, y, z);
4439
4440 player->SetSummonPoint(unitCaster->GetMapId(), x, y, z);
4441
4442 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4443 data << unitCaster->GetGUID(); // summoner guid
4444 data << uint32(unitCaster->GetZoneId()); // summoner zone
4445 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4446 player->SendDirectMessage(&data);
4447}
#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:16711
@ SMSG_SUMMON_REQUEST
Definition Opcodes.h:713

References effectHandleMode, Object::GetGUID(), WorldLocation::GetMapId(), Position::GetPosition(), GetUnitCasterForEffectHandlers(), WorldObject::GetZoneId(), Unit::HasAura(), IN_MILLISECONDS, 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)
6676{
6677 Unit* unitCaster = m_caster->ToUnit();
6678 if (!unitCaster)
6679 return;
6680
6682 return;
6683
6684 if (!unitCaster->IsPlayer())
6685 return;
6686
6687 if (!unitTarget)
6688 return;
6689
6690 Player* player = unitTarget->ToPlayer();
6691 if (!player)
6692 {
6693 return;
6694 }
6695
6696 float x, y, z;
6697 unitCaster->GetPosition(x, y, z);
6698 unitTarget->ToPlayer()->SetSummonPoint(unitCaster->GetMapId(), x, y, z);
6699 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6700 data << unitCaster->GetGUID();
6701 data << uint32(unitCaster->GetZoneId());
6702 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6703 player->SendDirectMessage(&data);
6704}

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(), Object::ToUnit(), and unitTarget.

◆ EffectSummonType()

void Spell::EffectSummonType ( SpellEffIndex  effIndex)
2462{
2464 return;
2465
2466 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2467
2468 if (m_spellValue->MiscVal[effIndex])
2469 entry = m_spellValue->MiscVal[effIndex];
2470
2471 if (!entry)
2472 return;
2473
2474 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2475 if (!properties)
2476 {
2477 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2478 return;
2479 }
2480
2481 if (!m_originalCaster)
2482 return;
2483
2484 Unit* unitCaster = m_originalCaster;
2485
2486 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2487 int32 duration = m_spellInfo->GetDuration();
2488 if (Player* modOwner = unitCaster->GetSpellModOwner())
2489 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2490
2491 TempSummon* summon = nullptr;
2492
2493 // determine how many units should be summoned
2494 uint32 numSummons;
2495
2496 // some spells need to summon many units, for those spells number of summons is stored in effect value
2497 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2498 // and in spell attributes, possibly we need to add a table for those)
2499 // so here's a list of MiscValueB values, which is currently most generic check
2500 switch (properties->Id)
2501 {
2502 case 64:
2503 case 61:
2504 case 1101:
2505 case 66:
2506 case 648:
2507 case 2301:
2508 case 1061:
2509 case 1261:
2510 case 629:
2511 case 181:
2512 case 715:
2513 case 1562:
2514 case 833:
2515 case 1161:
2516 case 713: // xinef, bloodworms
2517 numSummons = (damage > 0) ? damage : 1;
2518 break;
2519 default:
2520 numSummons = 1;
2521 break;
2522 }
2523
2524 switch (properties->Category)
2525 {
2529 if (properties->Flags & 512)
2530 {
2531 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2532 break;
2533 }
2534 switch (properties->Type)
2535 {
2536 case SUMMON_TYPE_PET:
2539 case SUMMON_TYPE_MINION:
2540 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2541 break;
2542 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2545 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, personalSpawn);
2546 break;
2548 case SUMMON_TYPE_TOTEM:
2549 {
2550 // protection code
2551 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, personalSpawn);
2552 if (!summon || !summon->IsTotem())
2553 return;
2554
2555 // Mana Tide Totem
2556 if (m_spellInfo->Id == 16190)
2558
2559 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2560 {
2561 summon->SetMaxHealth(damage);
2562 summon->SetHealth(damage);
2563 }
2564 break;
2565 }
2567 // For companions, recalculate the position to ensure they spawn at the intended π/4 angle.
2568 destTarget->Relocate(unitCaster->GetNearPosition(
2571 ));
2572 [[fallthrough]];
2573 case SUMMON_TYPE_JEEVES:
2574 {
2575 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, personalSpawn);
2576 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2577 return;
2578
2579 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2581
2582 summon->SetImmuneToAll(true);
2584
2585 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2586 //summon->AI()->EnterEvadeMode();
2587 if (properties->Type != SUMMON_TYPE_JEEVES)
2588 {
2589 summon->SetFacingToObject(unitCaster);
2590 summon->GetMotionMaster()->Clear(false);
2592 }
2593 break;
2594 }
2595 default:
2596 {
2597 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2598
2599 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2600
2601 WorldObject* summoner = unitCaster;
2602 if (Unit* unitSummoner = summoner->ToUnit())
2603 if (unitSummoner->IsPet())
2604 if (Unit* owner = unitSummoner->GetOwner())
2605 summoner = owner;
2606
2607 for (uint32 count = 0; count < numSummons; ++count)
2608 {
2609 Position pos;
2610 if (count == 0)
2611 pos = *destTarget;
2612 else
2613 // randomize position for multiple summons
2614 pos = m_caster->GetRandomPoint(*destTarget, radius);
2615
2616 summon = summoner->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2617 if (!summon)
2618 continue;
2619
2620 summon->SetTempSummonType(summonType);
2621
2622 if (properties->Category == SUMMON_CATEGORY_ALLY)
2623 {
2624 summon->SetOwnerGUID(summoner->GetGUID());
2625 summon->SetFaction(summoner->GetFaction());
2626 }
2627
2628 ExecuteLogEffectSummonObject(effIndex, summon);
2629 }
2630 return;
2631 }
2632 }//switch
2633 break;
2635 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2636 if (m_originalCaster)
2638 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2639 break;
2641 summon = m_caster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, personalSpawn);
2642 break;
2644 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2645 // to cast a ride vehicle spell on the summoned unit.
2646 //float x, y, z;
2647 //m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2648 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2649 if (std::fabs(m_caster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2651
2652 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, m_caster->ToUnit(), m_spellInfo->Id, 0, personalSpawn);
2653 if (!summon || !summon->IsVehicle())
2654 return;
2655
2656 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2658 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2659 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2660 {
2661 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2662 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2663 spellId = spellInfo->Id;
2664 }
2665
2666 // xinef: if we have small value, it indicates seat position
2667 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2668 unitCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2669 else
2670 unitCaster->CastSpell(summon, spellId, true);
2671
2672 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2673 //uint32 faction = properties->Faction;
2674 //if (!faction)
2675 uint32 faction = unitCaster->GetFaction();
2676
2677 summon->SetFaction(faction);
2678 break;
2679 }
2680
2681 if (summon)
2682 {
2683 summon->SetCreatorGUID(unitCaster->GetGUID());
2684 ExecuteLogEffectSummonObject(effIndex, summon);
2685 }
2686}
@ SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER
Definition DBCEnums.h:428
#define MAX_VEHICLE_SEATS
Definition DBCStructure.h:2060
@ MOTION_SLOT_ACTIVE
Definition MotionMaster.h:65
TempSummonType
Definition Object.h:49
@ TEMPSUMMON_DEAD_DESPAWN
Definition Object.h:56
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:1512
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:2246
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:194
void SetTempSummonType(TempSummonType type)
Definition TemporarySummon.cpp:287
void SetFacingToObject(WorldObject *object, Milliseconds timed=0ms)
Definition Unit.cpp:16078
void SetFaction(uint32 faction)
Definition Unit.cpp:6850
void SetOwnerGUID(ObjectGuid owner)
Definition Unit.cpp:7460
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:742
void SetMaxHealth(uint32 val)
Definition Unit.cpp:12000
void SetCreatorGUID(ObjectGuid creator)
Definition Unit.h:717
void ReplaceAllNpcFlags(NPCFlags flags)
Definition Unit.h:767
void RemoveAllMinionsByEntry(uint32 entry)
Definition Unit.cpp:7750
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition Unit.h:930
Position GetNearPosition(float dist, float angle)
Definition Object.cpp:2854
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:1322
virtual uint32 GetFaction() const
Definition Object.h:769
void GetRandomPoint(Position const &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const
Definition Object.cpp:1567
uint32 npcflag
Definition CreatureData.h:200
uint32 MiscVal[MAX_SPELL_EFFECTS]
Definition Spell.h:231
uint32 Flags
Definition DBCStructure.h:1951
uint32 Type
Definition DBCStructure.h:1949
uint32 Id
Definition DBCStructure.h:1946

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(), WorldObject::GetFaction(), 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::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, Object::ToUnit(), SummonPropertiesEntry::Type, UNIT_MASK_MINION, and VEHICLE_SPELL_RIDE_HARDCODED.

◆ EffectTameCreature()

void Spell::EffectTameCreature ( SpellEffIndex  effIndex)
3308{
3309 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3310 if (!unitCaster)
3311 return;
3312
3314 return;
3315
3316 if (unitCaster->GetPetGUID())
3317 return;
3318
3319 if (!unitTarget)
3320 return;
3321
3322 if (!unitTarget->IsCreature())
3323 return;
3324
3325 Creature* creatureTarget = unitTarget->ToCreature();
3326
3327 if (creatureTarget->IsPet())
3328 return;
3329
3330 if (!unitCaster->IsClass(CLASS_HUNTER, CLASS_CONTEXT_PET))
3331 return;
3332
3333 // cast finish successfully
3334 //SendChannelUpdate(0);
3335 finish();
3336
3337 Pet* pet = unitCaster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3338 if (!pet) // in very specific state like near world end/etc.
3339 return;
3340
3341 // "kill" original creature
3342 creatureTarget->DespawnOrUnsummon();
3343
3344 uint8 level = (creatureTarget->GetLevel() < (unitCaster->GetLevel() - 5)) ? (unitCaster->GetLevel() - 5) : creatureTarget->GetLevel();
3345
3346 // prepare visual effect for levelup
3347 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3348
3349 // add to world
3350 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3351
3352 // visual effect for levelup
3353 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3354
3355 // caster have pet now
3356 unitCaster->SetMinion(pet, true);
3357
3358 pet->InitTalentForLevel();
3359
3360 if (unitCaster->IsPlayer())
3361 {
3363 unitCaster->ToPlayer()->PetSpellInitialize();
3364 }
3365}
@ 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(), GetUnitCasterForEffectHandlers(), SpellInfo::Id, Pet::InitTalentForLevel(), Unit::IsClass(), Object::IsCreature(), Unit::IsPet(), Object::IsPlayer(), 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)
3509{
3510 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3511 if (!unitCaster)
3512 return;
3513
3515 return;
3516
3517 if (!unitTarget)
3518 return;
3519
3520 // xinef: Hand of Reckoning, cast before checking canhavethreatlist. fixes damage against pets
3521 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != unitCaster)
3522 unitCaster->CastSpell(unitTarget, 67485, true);
3523
3525 {
3527 return;
3528 }
3529
3531 if (mgr.GetCurrentVictim() == unitCaster)
3532 {
3534 return;
3535 }
3536
3537 if (!mgr.IsThreatListEmpty())
3538 mgr.MatchUnitThreatToHighestThreat(unitCaster);
3539}
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:506
bool CanHaveThreatList(bool skipAliveCheck=false) const
Definition Unit.cpp:11179

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

◆ EffectTeleportUnits()

void Spell::EffectTeleportUnits ( SpellEffIndex  effIndex)
1255{
1256 Unit* unitCaster = m_caster->ToUnit();
1258 return;
1259
1260 if (!unitTarget || unitTarget->IsInFlight())
1261 return;
1262
1263 if (unitTarget->IsPlayer())
1264 {
1265 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
1266 }
1267
1268 // Pre effects
1269 switch (m_spellInfo->Id)
1270 {
1271 case 70746: // Teleport Into Sunwell (for Battered Hilt)
1272 if (Player* target = unitTarget->ToPlayer())
1273 {
1274 uint32 mapid = destTarget->GetMapId();
1275 float x, y, z, orientation;
1276 destTarget->GetPosition(x, y, z, orientation);
1277 target->TeleportTo(mapid, x, y, z, orientation, TELE_TO_GM_MODE); // skip PlayerCannotEnter check
1278 }
1279 return;
1280 }
1281
1282 // If not exist data for dest location - return
1283 if (!m_targets.HasDst())
1284 {
1285 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - does not have destination for spell ID {}\n", m_spellInfo->Id);
1286 return;
1287 }
1288
1289 // Init dest coordinates
1290 uint32 mapid = destTarget->GetMapId();
1291 if (mapid == MAPID_INVALID)
1292 mapid = unitTarget->GetMapId();
1293 float x, y, z, orientation;
1294 destTarget->GetPosition(x, y, z, orientation);
1295 if (!orientation && m_targets.GetUnitTarget())
1296 orientation = m_targets.GetUnitTarget()->GetOrientation();
1297 LOG_DEBUG("spells.aura", "Spell::EffectTeleportUnits - teleport unit to {} {} {} {} {}\n", mapid, x, y, z, orientation);
1298
1299 if (mapid == unitTarget->GetMapId())
1300 {
1301 if (unitTarget->GetVehicleKit()) // we are vehicle!
1302 unitTarget->GetVehicleKit()->TeleportVehicle(x, y, z, orientation);
1303 else
1304 {
1306 unitTarget->NearTeleportTo(x, y, z, orientation, unitTarget == m_caster, false, withPet, true);
1307 if (unitTarget->IsPlayer()) // pussywizard: for units it's done inside NearTeleportTo
1309 }
1310 }
1311 else if (unitTarget->IsPlayer())
1312 unitTarget->ToPlayer()->TeleportTo(mapid, x, y, z, orientation, unitTarget == m_caster ? TELE_TO_SPELL : 0);
1313 else
1314 {
1315 LOG_ERROR("spells.effect", "Spell::EffectTeleportUnits - spellId {} attempted to teleport creature to a different map.", m_spellInfo->Id);
1316 return;
1317 }
1318
1319 // post effects for TARGET_DEST_DB
1320 // (engineering teleporter malfunctions and similar self-casts - unit casters only)
1321 if (!unitCaster)
1322 return;
1323
1324 switch (m_spellInfo->Id)
1325 {
1326 // Dimensional Ripper - Everlook
1327 case 23442:
1328 {
1329 int32 r = irand(0, 119);
1330 if (r >= 70) // 7/12 success
1331 {
1332 if (r < 100) // 4/12 evil twin
1333 unitCaster->CastSpell(unitCaster, 23445, true);
1334 else // 1/12 fire
1335 unitCaster->CastSpell(unitCaster, 23449, true);
1336 }
1337 return;
1338 }
1339 // Ultrasafe Transporter: Toshley's Station
1340 case 36941:
1341 {
1342 if (roll_chance_i(50)) // 50% success
1343 {
1344 int32 rand_eff = urand(1, 7);
1345 switch (rand_eff)
1346 {
1347 case 1:
1348 // soul split - evil
1349 unitCaster->CastSpell(unitCaster, 36900, true);
1350 break;
1351 case 2:
1352 // soul split - good
1353 unitCaster->CastSpell(unitCaster, 36901, true);
1354 break;
1355 case 3:
1356 // Increase the size
1357 unitCaster->CastSpell(unitCaster, 36895, true);
1358 break;
1359 case 4:
1360 // Decrease the size
1361 unitCaster->CastSpell(unitCaster, 36893, true);
1362 break;
1363 case 5:
1364 // Transform
1365 {
1366 if (unitCaster->ToPlayer()->GetTeamId() == TEAM_ALLIANCE)
1367 unitCaster->CastSpell(unitCaster, 36897, true);
1368 else
1369 unitCaster->CastSpell(unitCaster, 36899, true);
1370 break;
1371 }
1372 case 6:
1373 // chicken
1374 unitCaster->CastSpell(unitCaster, 36940, true);
1375 break;
1376 case 7:
1377 // evil twin
1378 unitCaster->CastSpell(unitCaster, 23445, true);
1379 break;
1380 }
1381 }
1382 return;
1383 }
1384 }
1385}
@ 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:2139
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0, Unit *target=nullptr, bool newInstance=false)
Definition Player.cpp:1401
Vehicle * GetVehicleKit() const
Definition Unit.h:1931
void TeleportVehicle(float x, float y, float z, float ang)
Definition Vehicle.cpp:600

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(), Object::ToUnit(), unitTarget, Unit::UpdateObjectVisibility(), and urand().

◆ EffectTeleUnitsFaceCaster()

◆ EffectThreat()

void Spell::EffectThreat ( SpellEffIndex  effIndex)
3883{
3884 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3885 if (!unitCaster)
3886 return;
3887
3889 return;
3890
3891 if (!unitTarget || !unitTarget->IsAlive() || !unitCaster->IsAlive())
3892 return;
3893
3894 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3895 if (!unitTarget->CanHaveThreatList() || unitCaster->IsFriendlyTo(unitTarget))
3896 return;
3897
3898 // SPELL_EFFECT_THREAT adds flat threat that should not be modified by threat reduction
3899 unitTarget->GetThreatMgr().AddThreat(unitCaster, float(damage), m_spellInfo, true);
3900}
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(), GetUnitCasterForEffectHandlers(), Unit::IsAlive(), Unit::IsFriendlyTo(), m_spellInfo, SPELL_EFFECT_HANDLE_HIT_TARGET, and unitTarget.

◆ EffectTitanGrip()

void Spell::EffectTitanGrip ( SpellEffIndex  effIndex)
6206{
6207 Unit* unitCaster = m_caster->ToUnit();
6208 if (!unitCaster)
6209 return;
6210
6212 return;
6213
6214 if (unitCaster->IsPlayer())
6215 {
6216 if (Aura* aur = unitCaster->GetAura(49152))
6217 aur->RecalculateAmountOfEffects();
6218 else
6219 unitCaster->CastSpell(unitTarget, 49152, true); // damage reduction
6220
6221 unitCaster->ToPlayer()->SetCanTitanGrip(true);
6222 }
6223}
void SetCanTitanGrip(bool value)
Definition Player.cpp:13472

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

◆ EffectTradeSkill()

void Spell::EffectTradeSkill ( SpellEffIndex  effIndex)
2990{
2991 Unit* unitCaster = m_caster->ToUnit();
2992 if (!unitCaster)
2993 return;
2994
2996 return;
2997
2998 if (!unitCaster->IsPlayer())
2999 return;
3000 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
3001 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
3002 // unitCaster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
3003}

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

◆ EffectTransmitted()

void Spell::EffectTransmitted ( SpellEffIndex  effIndex)
5648{
5649 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5650 if (!unitCaster)
5651 return;
5652
5654 return;
5655
5656 uint32 name_id = m_spellInfo->Effects[effIndex].MiscValue;
5657
5658 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
5659
5660 if (!goinfo)
5661 {
5662 LOG_ERROR("sql.sql", "Gameobject (Entry: {}) not exist and not created at spell (ID: {}) cast", name_id, m_spellInfo->Id);
5663 return;
5664 }
5665
5666 float fx, fy, fz;
5667
5668 if (m_targets.HasDst())
5669 destTarget->GetPosition(fx, fy, fz);
5670 //FIXME: this can be better check for most objects but still hack
5671 else if (m_spellInfo->Effects[effIndex].HasRadius() && m_spellInfo->Speed == 0)
5672 {
5673 float dis = m_spellInfo->Effects[effIndex].CalcRadius(m_originalCaster);
5674 unitCaster->GetClosePoint(fx, fy, fz, DEFAULT_WORLD_OBJECT_SIZE, dis);
5675 }
5676 else
5677 {
5678 //GO is always friendly to it's creator, get range for friends
5679 float min_dis = m_spellInfo->GetMinRange(true);
5680 float max_dis = m_spellInfo->GetMaxRange(true);
5681 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
5682
5683 unitCaster->GetClosePoint(fx, fy, fz, DEFAULT_WORLD_OBJECT_SIZE, dis);
5684 }
5685
5686 // Seaforium charge
5687 if (m_spellInfo->Id == 52410 || m_spellInfo->Id == 66268 || m_spellInfo->Id == 66674) // SotA / IoC / IoC Huge
5688 {
5689 fx = unitCaster->GetPositionX();
5690 fy = unitCaster->GetPositionY();
5691 fz = unitCaster->GetPositionZ();
5692 }
5693
5694 Map* cMap = unitCaster->GetMap();
5695
5696 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(name_id) ? new StaticTransport() : new GameObject();
5697
5698 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), unitCaster->GetOrientation());
5699 if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, unitCaster->GetPhaseMask(), fx, fy, fz, unitCaster->GetOrientation(), rotation, 100, GO_STATE_READY))
5700 {
5701 delete pGameObj;
5702 return;
5703 }
5704
5705 int32 duration = m_spellInfo->GetDuration();
5706
5707 switch (goinfo->type)
5708 {
5710 {
5711 if (unitCaster->IsPlayer())
5713
5714 unitCaster->SetGuidValue(UNIT_FIELD_CHANNEL_OBJECT, pGameObj->GetGUID());
5715 unitCaster->AddGameObject(pGameObj); // will removed at spell cancel
5716
5717 // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo))
5718 // start time == fish-FISHING_BOBBER_READY_TIME (0..GetDuration(m_spellInfo)-FISHING_BOBBER_READY_TIME)
5719 int32 lastSec = 0;
5720 switch (urand(0, 2))
5721 {
5722 case 0:
5723 lastSec = 3;
5724 break;
5725 case 1:
5726 lastSec = 7;
5727 break;
5728 case 2:
5729 lastSec = 13;
5730 break;
5731 }
5732
5733 // Duration of the fishing bobber can't be higher than the Fishing channeling duration
5734 duration = std::min(duration, duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS);
5735
5736 break;
5737 }
5739 {
5740 if (unitCaster->IsPlayer())
5741 {
5742 pGameObj->AddUniqueUse(unitCaster->ToPlayer());
5743 unitCaster->AddGameObject(pGameObj); // will be removed at spell cancel
5744 }
5745 break;
5746 }
5747 case GAMEOBJECT_TYPE_DUEL_ARBITER: // 52991
5748 unitCaster->AddGameObject(pGameObj);
5749 break;
5752 default:
5753 break;
5754 }
5755
5756 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5757
5758 pGameObj->SetOwnerGUID(unitCaster->GetGUID());
5759
5760 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, unitCaster->GetLevel());
5761 pGameObj->SetSpellId(m_spellInfo->Id);
5762
5763 ExecuteLogEffectSummonObject(effIndex, pGameObj);
5764
5765 LOG_DEBUG("spells.effect", "AddObject at SpellEfects.cpp EffectTransmitted");
5766 //unitCaster->AddGameObject(pGameObj);
5767 //m_ObjToDel.push_back(pGameObj);
5768
5769 cMap->AddToMap(pGameObj, true);
5770
5771 if (GameObject* linkedTrap = pGameObj->GetLinkedTrap())
5772 {
5773 linkedTrap->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
5774 linkedTrap->SetSpellId(m_spellInfo->Id);
5775 linkedTrap->SetOwnerGUID(unitCaster->GetGUID());
5776
5777 ExecuteLogEffectSummonObject(effIndex, linkedTrap);
5778 }
5779
5780 if (Player* player = unitCaster->ToPlayer())
5781 {
5782 player->SetCanTeleport(true);
5783 }
5784}
#define FISHING_BOBBER_READY_TIME
Definition GameObject.h:117
@ GAMEOBJECT_TYPE_DUEL_ARBITER
Definition SharedDefines.h:1580
@ 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:922
float GetMinRange(bool positive=false) const
Definition SpellInfo.cpp:2741
void RemoveGameObjectsByType(GameobjectTypes type, bool del)
Definition Unit.cpp:6414

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(), GetUnitCasterForEffectHandlers(), GO_STATE_READY, SpellCastTargets::HasDst(), SpellInfo::Id, IN_MILLISECONDS, Object::IsPlayer(), LOG_DEBUG, LOG_ERROR, 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)
998{
1001 return;
1002
1003 Unit* unitCaster = GetUnitCasterForEffectHandlers();
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 if (!spellInfo)
1010 {
1011 LOG_DEBUG("spells.aura", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
1012 return;
1013 }
1014
1015 SpellCastTargets targets;
1017 {
1018 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
1019 return;
1020 targets.SetUnitTarget(unitTarget);
1021 }
1022 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1023 {
1024 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
1025 return;
1026
1028 targets.SetDst(m_targets);
1029
1030 if (Unit* unit = m_caster->ToUnit())
1031 targets.SetUnitTarget(unit);
1032 else if (GameObject* go = m_caster->ToGameObject())
1033 targets.SetGOTarget(go);
1034 }
1035
1037 // set basepoints for trigger with value effect
1039 {
1040 // maybe need to set value only when basepoints == 0?
1041 args.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
1042 args.AddSpellMod(SPELLVALUE_BASE_POINT1, damage);
1043 args.AddSpellMod(SPELLVALUE_BASE_POINT2, damage);
1044 }
1045
1046 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
1047 if (unitCaster && unitCaster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
1048 {
1049 unitCaster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
1050 }
1051
1052 // original caster guid only for GO cast
1053 m_caster->CastSpell(std::move(targets), spellInfo->Id, args);
1054}
@ SPELL_EFFECT_TRIGGER_MISSILE_SPELL_WITH_VALUE
Definition SharedDefines.h:914
@ TARGET_FLAG_DEST_LOCATION
Definition SpellInfo.h:53
GameObject * ToGameObject()
Definition Object.h:220
void SetGOTarget(GameObject *target)
Definition Spell.cpp:308
bool NeedsToBeTriggeredByCaster(SpellInfo const *triggeringSpell, uint8 effIndex=MAX_SPELL_EFFECTS) const
Definition SpellInfo.cpp:1083
uint32 CategoryRecoveryTime
Definition SpellInfo.h:373

References CastSpellExtraArgs::AddSpellMod(), WorldObject::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, effectHandleMode, SpellInfo::Effects, SpellInfo::GetCategory(), SpellInfo::GetExplicitTargetMask(), GetUnitCasterForEffectHandlers(), SpellInfo::Id, Object::IsPlayer(), LOG_DEBUG, m_caster, m_originalCasterGUID, m_spellInfo, m_targets, SpellInfo::NeedsToBeTriggeredByCaster(), Player::RemoveSpellCooldown(), SpellCastTargets::SetDst(), SpellCastTargets::SetGOTarget(), 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::ToGameObject(), Object::ToPlayer(), Object::ToUnit(), and unitTarget.

◆ EffectTriggerRitualOfSummoning()

void Spell::EffectTriggerRitualOfSummoning ( SpellEffIndex  effIndex)
1115{
1117 return;
1118
1119 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1120 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1121
1122 if (!spellInfo)
1123 {
1124 LOG_ERROR("spells.effect", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1125 return;
1126 }
1127
1128 finish();
1129
1130 m_caster->CastSpell(nullptr, spellInfo->Id, true);
1131}

References WorldObject::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
822{
825 return;
826
827 Unit* unitCaster = GetUnitCasterForEffectHandlers();
828 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
829
831 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
833 {
834 // special cases
835 switch (triggered_spell_id)
836 {
837 // Mirror Image
838 case 58832:
839 {
840 if (!unitCaster)
841 break;
842
843 // Glyph of Mirror Image
844 if (unitCaster->HasAura(63093))
845 unitCaster->CastSpell(unitCaster, 65047, true); // Mirror Image
846
847 break;
848 }
849 // Demonic Empowerment -- succubus
850 case 54437:
851 {
855
856 // Cast Lesser Invisibility
857 unitTarget->CastSpell(unitTarget, 7870, true);
858 return;
859 }
860 // just skip
861 case 23770: // Sayge's Dark Fortune of *
862 // not exist, common cooldown can be implemented in scripts if need.
863 return;
864 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
865 case 29284:
866 {
867 if (!unitCaster)
868 return;
869
870 // Brittle Armor
871 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575);
872 if (!spell)
873 return;
874
875 for (uint32 j = 0; j < spell->StackAmount; ++j)
876 unitCaster->CastSpell(unitTarget, spell->Id, true);
877 return;
878 }
879 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
880 case 29286:
881 {
882 if (!unitCaster)
883 return;
884
885 // Mercurial Shield
886 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464);
887 if (!spell)
888 return;
889
890 for (uint32 j = 0; j < spell->StackAmount; ++j)
891 unitCaster->CastSpell(unitTarget, spell->Id, true);
892 return;
893 }
894 // Cloak of Shadows
895 case 35729:
896 {
897 if (!unitCaster)
898 return;
899
902 for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
903 {
904 // remove all harmful spells on you...
905 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
906
907 // Pounce Bleed shouldn't be removed by Cloak of Shadows.
908 if (spell->GetAllEffectsMechanicMask() & (1ULL << MECHANIC_BLEED))
909 return;
910
911 bool dmgClassNone = false;
913 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
914 {
915 if ((iter->second->GetEffectMask() & (1 << i)) &&
916 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE &&
917 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
918 spell->Effects[i].ApplyAuraName != SPELL_AURA_DUMMY)
919 {
920 dmgClassNone = false;
921 break;
922 }
923 dmgClassNone = true;
924 }
925
926 if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC || (spell->GetDispelMask() & dispelMask) || dmgClassNone) &&
927 // ignore positive and passive auras
928 !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive() &&
929 // Xinef: Ignore NPC spells having INVULNERABILITY attribute
931 {
932 unitCaster->RemoveAura(iter);
933 }
934 else
935 ++iter;
936 }
937 return;
938 }
939 }
940 }
941
942 // normal case
943 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
944 if (!spellInfo)
945 {
946 LOG_DEBUG("spells.aura", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
947 return;
948 }
949
950 SpellCastTargets targets;
952 {
953 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
954 return;
955 targets.SetUnitTarget(unitTarget);
956 }
957 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
958 {
959 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
960 return;
961
963 targets.SetDst(m_targets);
964
965 if (Unit* target = m_targets.GetUnitTarget())
966 targets.SetUnitTarget(target);
967 else
968 {
969 if (Unit* unit = m_caster->ToUnit())
970 targets.SetUnitTarget(unit);
971 else if (GameObject* go = m_caster->ToGameObject())
972 targets.SetGOTarget(go);
973 }
974 }
975
978 // set basepoints for trigger with value effect
980 {
981 // maybe need to set value only when basepoints == 0?
982 args.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
983 args.AddSpellMod(SPELLVALUE_BASE_POINT1, damage);
984 args.AddSpellMod(SPELLVALUE_BASE_POINT2, damage);
985 }
986
987 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
988 if (unitCaster && unitCaster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
989 {
990 unitCaster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
991 }
992
993 // original caster guid only for GO cast
994 m_caster->CastSpell(std::move(targets), spellInfo->Id, args);
995}
@ 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 CastSpellExtraArgs::AddSpellMod(), WorldObject::CastSpell(), Unit::CastSpell(), SpellInfo::CategoryRecoveryTime, damage, DISPEL_ALL, SpellInfo::DmgClass, EFFECT_0, effectHandleMode, SpellInfo::Effects, SpellInfo::GetAllEffectsMechanicMask(), Unit::GetAppliedAuras(), SpellInfo::GetCategory(), SpellInfo::GetDispelMask(), SpellInfo::GetExplicitTargetMask(), GetUnitCasterForEffectHandlers(), 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::SetGOTarget(), CastSpellExtraArgs::SetTriggerFlags(), 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::ToGameObject(), Object::ToPlayer(), Object::ToUnit(), TRIGGERED_FULL_MASK, TRIGGERED_NO_PERIODIC_RESET, and unitTarget.

◆ EffectUnlearnSpecialization()

void Spell::EffectUnlearnSpecialization ( SpellEffIndex  effIndex)
1410{
1411 Unit* unitCaster = m_caster->ToUnit();
1412 if (!unitCaster)
1413 return;
1414
1416 return;
1417
1418 if (!unitTarget)
1419 return;
1420
1421 Player* player = unitTarget->ToPlayer();
1422 if (!player)
1423 {
1424 return;
1425 }
1426
1427 uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
1428
1429 player->removeSpell(spellToUnlearn, SPEC_MASK_ALL, false);
1430 LOG_DEBUG("spells.aura", "Spell: Player {} has unlearned spell {} from Npc: {}",
1431 player->GetGUID().ToString(), spellToUnlearn, unitCaster->GetGUID().ToString());
1432}
#define SPEC_MASK_ALL
Definition Player.h:178
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary)
Definition Player.cpp:3504

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(), Object::ToUnit(), and unitTarget.

◆ EffectUntrainTalents()

void Spell::EffectUntrainTalents ( SpellEffIndex  effIndex)
2910{
2911 Unit* unitCaster = m_caster->ToUnit();
2912 if (!unitCaster)
2913 return;
2914
2916 return;
2917
2918 if (!unitTarget || unitCaster->IsPlayer())
2919 return;
2920
2921 if (ObjectGuid guid = unitCaster->GetGUID()) // the trainer is the caster
2923}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition Player.cpp:9121

References effectHandleMode, Object::GetGUID(), Object::IsPlayer(), m_caster, Player::SendTalentWipeConfirm(), SPELL_EFFECT_HANDLE_HIT_TARGET, Object::ToPlayer(), Object::ToUnit(), 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)
3542{
3543 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3544 if (!unitCaster)
3545 return;
3546
3548 return;
3549
3550 if (!unitTarget || !unitTarget->IsAlive())
3551 return;
3552
3553 // multiple weapon dmg effect workaround
3554 // execute only the last weapon damage
3555 // and handle all effects at once
3556 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
3557 {
3558 switch (m_spellInfo->Effects[j].Effect)
3559 {
3564 return; // we must calculate only at last weapon effect
3565 break;
3566 }
3567 }
3568
3569 // some spell specific modifiers
3570 float totalDamagePercentMod = 100.0f; // applied to final bonus+weapon damage
3571 int32 spell_bonus = 0; // bonus specific for spell
3572 bool normalized = false;
3573
3575 {
3577 {
3578 switch (m_spellInfo->Id)
3579 {
3580 // Trial of the Champion, Black Knight, Obliterate
3581 case 67725:
3582 case 67883:
3583 {
3584 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(unitCaster->GetGUID(), 1) * 30.0f);
3585 break;
3586 }
3587 }
3588 break;
3589 }
3591 {
3592 // Devastate (player ones)
3593 if (m_spellInfo->SpellFamilyFlags[1] & 0x40)
3594 {
3595 unitCaster->CastSpell(unitTarget, 58567, true);
3596
3597 if (Aura* aur = unitTarget->GetAura(58567))
3598 {
3599 // 58388 - Glyph of Devastate dummy aura.
3600 if (unitCaster->HasAura(58388))
3601 aur->ModStackAmount(1);
3602
3603 spell_bonus += (aur->GetStackAmount() - 1) * CalculateSpellDamage(2, unitTarget);
3604 }
3605 }
3606 break;
3607 }
3608 case SPELLFAMILY_ROGUE:
3609 {
3610 // Fan of Knives, Hemorrhage, Ghostly Strike
3611 if ((m_spellInfo->SpellFamilyFlags[1] & 0x40000)
3612 || (m_spellInfo->SpellFamilyFlags[0] & 0x6000000))
3613 {
3614 // Hemorrhage
3615 if (m_spellInfo->SpellFamilyFlags[0] & 0x2000000)
3616 {
3618 }
3619 // 50% more damage with daggers
3620 if (unitCaster->IsPlayer())
3621 if (Item* item = unitCaster->ToPlayer()->GetWeaponForAttack(m_attackType, true))
3622 if (item->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER)
3623 AddPct(totalDamagePercentMod, 50.0f);
3624 }
3625 // Mutilate (for each hand)
3626 else if (m_spellInfo->SpellFamilyFlags[1] & 0x6)
3627 {
3628 bool found = false;
3629 // fast check
3631 found = true;
3632 // full aura scan
3633 else
3634 {
3636 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
3637 {
3638 if (itr->second->GetBase()->GetSpellInfo()->Dispel == DISPEL_POISON)
3639 {
3640 found = true;
3641 break;
3642 }
3643 }
3644 }
3645
3646 if (found)
3647 AddPct(totalDamagePercentMod, 20.0f); // 120% if poisoned
3648 }
3649 break;
3650 }
3652 {
3653 switch (m_spellInfo->Id)
3654 {
3655 case 20467: // Seal of Command Unleashed
3656 spell_bonus += int32(0.08f * unitCaster->GetTotalAttackPowerValue(BASE_ATTACK));
3657 spell_bonus += int32(0.13f * unitCaster->SpellBaseDamageBonusDone(m_spellInfo->GetSchoolMask()));
3658 break;
3659 case 53385: // Divine Storm deals normalized damage
3660 normalized = true;
3661 break;
3662 default:
3663 break;
3664 }
3665 break;
3666 }
3667 case SPELLFAMILY_SHAMAN:
3668 {
3669 // Skyshatter Harness item set bonus
3670 // Stormstrike
3671 if (AuraEffect* aurEff = unitCaster->IsScriptOverriden(m_spellInfo, 5634))
3672 unitCaster->CastSpell(unitCaster, 38430, true, nullptr, aurEff);
3673 // Lava lash damage increased by Flametongue weapon
3675 AddPct(totalDamagePercentMod, 25.0f);
3676 break;
3677 }
3678 case SPELLFAMILY_DRUID:
3679 {
3680 // Mangle (Cat): CP
3681 if (m_spellInfo->SpellFamilyFlags[1] & 0x400)
3682 {
3684 }
3685 // Shred, Maul - Rend and Tear
3687 {
3688 if (AuraEffect const* rendAndTear = unitCaster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
3689 AddPct(totalDamagePercentMod, rendAndTear->GetAmount());
3690 }
3691 break;
3692 }
3693 case SPELLFAMILY_HUNTER:
3694 {
3695 // Kill Shot
3696 if (m_spellInfo->SpellFamilyFlags[1] & 0x800000)
3697 {
3698 spell_bonus += int32(unitCaster->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.4f);
3699 }
3700 break;
3701 }
3703 {
3704 // Plague Strike
3705 if (m_spellInfo->SpellFamilyFlags[0] & 0x1)
3706 {
3707 // Glyph of Plague Strike
3708 if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(58657, EFFECT_0))
3709 AddPct(totalDamagePercentMod, aurEff->GetAmount());
3710 break;
3711 }
3712 // Blood Strike
3713 if (m_spellInfo->SpellFamilyFlags[0] & 0x400000)
3714 {
3715 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3716 //Death Knight T8 Melee 4P Bonus
3717 if (AuraEffect* aurEff = unitCaster->GetAuraEffectDummy(64736))
3718 AddPct(disease_amt, aurEff->GetAmount());
3719
3720 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(unitCaster->GetGUID()) / 2.0f);
3721
3722 // Glyph of Blood Strike
3723 if (unitCaster->GetAuraEffect(59332, EFFECT_0))
3725 AddPct(totalDamagePercentMod, 20.0f);
3726 break;
3727 }
3728 // Death Strike
3729 if (m_spellInfo->SpellFamilyFlags[0] & 0x10)
3730 {
3731 // Glyph of Death Strike
3732 if (AuraEffect const* aurEff = unitCaster->GetAuraEffect(59336, EFFECT_0))
3733 if (uint32 runic = std::min<uint32>(unitCaster->GetPower(POWER_RUNIC_POWER), aurEff->GetSpellInfo()->Effects[EFFECT_1].CalcValue()))
3734 AddPct(totalDamagePercentMod, runic);
3735 break;
3736 }
3737 // Obliterate (12.5% more damage per disease)
3738 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000)
3739 {
3740 bool consumeDiseases = true;
3741 // Annihilation
3742 if (AuraEffect const* aurEff = unitCaster->GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 2710, EFFECT_0))
3743 // Do not consume diseases if roll sucesses
3744 if (roll_chance_i(aurEff->GetAmount()))
3745 consumeDiseases = false;
3746
3747 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3748 //Death Knight T8 Melee 4P Bonus
3749 if (AuraEffect* aurEff = unitCaster->GetAuraEffectDummy(64736))
3750 AddPct(disease_amt, aurEff->GetAmount());
3751
3752 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(unitCaster->GetGUID(), consumeDiseases) / 2.0f);
3753 break;
3754 }
3755 // Blood-Caked Strike - Blood-Caked Blade
3756 if (m_spellInfo->SpellIconID == 1736)
3757 {
3758 AddPct(totalDamagePercentMod, unitTarget->GetDiseasesByCaster(unitCaster->GetGUID()) * 50.0f);
3759 break;
3760 }
3761 // Heart Strike
3762 if (m_spellInfo->SpellFamilyFlags[0] & 0x1000000)
3763 {
3764 float disease_amt = m_spellInfo->Effects[EFFECT_2].CalcValue();
3765 //Death Knight T8 Melee 4P Bonus
3766 if (AuraEffect* aurEff = unitCaster->GetAuraEffectDummy(64736))
3767 AddPct(disease_amt, aurEff->GetAmount());
3768
3769 AddPct(totalDamagePercentMod, disease_amt * unitTarget->GetDiseasesByCaster(unitCaster->GetGUID()));
3770 break;
3771 }
3772 // Rune Strike
3773 if (m_spellInfo->SpellFamilyFlags[1] & 0x20000000)
3774 {
3775 spell_bonus += int32(0.15f * unitCaster->GetTotalAttackPowerValue(BASE_ATTACK));
3776 }
3777
3778 break;
3779 }
3780 }
3781
3782 float weaponDamagePercentMod = 100.0f;
3783 int32 fixed_bonus = 0;
3784
3785 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3786 {
3787 switch (m_spellInfo->Effects[j].Effect)
3788 {
3791 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3792 break;
3794 fixed_bonus += CalculateSpellDamage(j, unitTarget);
3795 normalized = true;
3796 break;
3798 ApplyPct(weaponDamagePercentMod, CalculateSpellDamage(j, unitTarget));
3799 break;
3800 default:
3801 break; // not weapon damage effect, just skip
3802 }
3803 }
3804
3805 bool const isPhysical = (m_spellSchoolMask & SPELL_SCHOOL_MASK_NORMAL);
3806 if (isPhysical && (fixed_bonus || spell_bonus))
3807 {
3808 UnitMods unitMod;
3809 switch (m_attackType)
3810 {
3811 default:
3812 case BASE_ATTACK:
3813 unitMod = UNIT_MOD_DAMAGE_MAINHAND;
3814 break;
3815 case OFF_ATTACK:
3816 unitMod = UNIT_MOD_DAMAGE_OFFHAND;
3817 break;
3818 case RANGED_ATTACK:
3819 unitMod = UNIT_MOD_DAMAGE_RANGED;
3820 break;
3821 }
3822 float weapon_total_pct = unitCaster->GetPctModifierValue(unitMod, TOTAL_PCT);
3823 fixed_bonus = int32(fixed_bonus * weapon_total_pct);
3824 spell_bonus = int32(spell_bonus * weapon_total_pct);
3825 }
3826
3827 int32 weaponDamage = 0;
3828 // Dancing Rune Weapon
3829 if (unitCaster->GetEntry() == 27893)
3830 {
3831 if (Unit* owner = unitCaster->GetOwner())
3832 weaponDamage = owner->CalculateDamage(m_attackType, normalized, isPhysical);
3833 }
3834 else
3835 {
3836 weaponDamage = unitCaster->CalculateDamage(m_attackType, normalized, isPhysical);
3837 }
3838
3839 // Sequence is important
3840 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3841 {
3842 // We assume that a spell have at most one fixed_bonus
3843 // and at most one weaponDamagePercentMod
3844 switch (m_spellInfo->Effects[j].Effect)
3845 {
3849 weaponDamage += fixed_bonus;
3850 break;
3852 ApplyPct(weaponDamage, weaponDamagePercentMod);
3853 default:
3854 break; // not weapon damage effect, just skip
3855 }
3856 }
3857
3858 weaponDamage += spell_bonus;
3859 ApplyPct(weaponDamage, totalDamagePercentMod);
3860
3861 // prevent negative damage
3862 uint32 eff_damage(std::max(weaponDamage, 0));
3863
3864 // Add melee damage bonuses (also check for negative)
3865 eff_damage = unitCaster->MeleeDamageBonusDone(unitTarget, eff_damage, m_attackType, m_spellInfo, m_spellSchoolMask);
3866 eff_damage = unitTarget->MeleeDamageBonusTaken(unitCaster, eff_damage, m_attackType, m_spellInfo, m_spellSchoolMask);
3867
3868 // Meteor like spells (divided damage to targets)
3870 {
3871 uint32 count = 0;
3872 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3873 if (ihit->effectMask & (1 << effIndex))
3874 ++count;
3875
3876 eff_damage /= count; // divide to all targets
3877 }
3878
3879 m_damage += eff_damage;
3880}
@ 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:11629
uint32 MeleeDamageBonusTaken(Unit *attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition Unit.cpp:10115
uint32 GetDiseasesByCaster(ObjectGuid casterGUID, uint8 mode=0)
Definition Unit.cpp:5887
bool HasDecreaseSpeedAura() const
Definition Unit.h:1829
AuraEffect * GetAuraEffectDummy(uint32 spellid) const
Definition Unit.cpp:5593
uint32 CalculateDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, uint8 itemDamagesMask=0)
Definition Unit.cpp:3174
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask)
Definition Unit.cpp:8818
uint32 MeleeDamageBonusDone(Unit *pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const *spellProto=nullptr, SpellSchoolMask damageSchoolMask=SPELL_SCHOOL_MASK_NORMAL)
Definition Unit.cpp:9925

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(), GetUnitCasterForEffectHandlers(), 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_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 
)
5296{
5297 InitEffectExecuteData(effIndex);
5298 *m_effectExecuteData[effIndex] << uint32(entry);
5299}
void InitEffectExecuteData(uint8 effIndex)
Definition Spell.cpp:8853

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5302{
5303 InitEffectExecuteData(effIndex);
5304 *m_effectExecuteData[effIndex] << uint32(entry);
5305}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit *  victim,
int32  itemId,
int32  slot 
)
5282{
5283 InitEffectExecuteData(effIndex);
5284 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5285 *m_effectExecuteData[effIndex] << int32(itemId);
5286 *m_effectExecuteData[effIndex] << int32(slot);
5287}

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

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit *  victim,
uint32  attCount 
)
5268{
5269 InitEffectExecuteData(effIndex);
5270 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5271 *m_effectExecuteData[effIndex] << uint32(attCount);
5272}

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

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit *  victim,
uint32  spellId 
)
5275{
5276 InitEffectExecuteData(effIndex);
5277 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5278 *m_effectExecuteData[effIndex] << uint32(spellId);
5279}

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

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object *  obj 
)
5290{
5291 InitEffectExecuteData(effIndex);
5292 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5293}

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

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit *  target 
)
5320{
5321 InitEffectExecuteData(effIndex);
5322 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5323}

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 
)
5259{
5260 InitEffectExecuteData(effIndex);
5261 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5262 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5263 *m_effectExecuteData[effIndex] << uint32(PowerType);
5264 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5265}

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 
)
5314{
5315 InitEffectExecuteData(effIndex);
5316 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5317}

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

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4613{
4615 return;
4616
4617 // the state must be set even for non-unit casters, otherwise the SpellEvent
4618 // never finishes and re-executes the spell every update tick
4620
4621 // FindMap() check: pending spell events are destroyed after the caster has left the map,
4622 // where resolving a unit-summoned caster's owner through ObjectAccessor would assert
4623 if (Player* modOwner = m_caster->FindMap() ? m_caster->GetSpellModOwner() : nullptr)
4624 modOwner->SetSpellModTakingSpell(this, false);
4625
4626 Unit* unitCaster = m_caster->ToUnit();
4627 if (!unitCaster)
4628 return;
4629
4630 if (m_spellInfo->IsChanneled())
4631 unitCaster->UpdateInterruptMask();
4632
4633 if (unitCaster->HasUnitState(UNIT_STATE_CASTING) && !unitCaster->IsNonMeleeSpellCast(false, false, true))
4635
4636 // Unsummon summon as possessed creatures on spell cancel
4637 if (m_spellInfo->IsChanneled() && unitCaster->IsPlayer())
4638 {
4639 if (Unit* charm = unitCaster->GetCharm())
4640 if (charm->IsCreature()
4641 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4642 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4643 ((Puppet*)charm)->UnSummon();
4644 }
4645
4646 if (Creature* creatureCaster = unitCaster->ToCreature())
4647 creatureCaster->ReleaseFocus(this);
4648
4649 if (ok)
4650 {
4652 unitCaster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
4653 }
4654 else
4655 {
4656 if (unitCaster->IsPlayer())
4657 {
4658 // Xinef: Restore spell mods in case of fail cast
4659 unitCaster->ToPlayer()->RestoreSpellMods(this);
4660
4661 // Xinef: Reset cooldown event in case of fail cast
4663 unitCaster->ToPlayer()->SendCooldownEvent(m_spellInfo, 0, 0, false);
4664 }
4665
4666 return;
4667 }
4668
4669 // pussywizard:
4672
4673 if (unitCaster->IsCreature() && unitCaster->ToCreature()->IsSummon())
4674 {
4675 // Unsummon statue
4676 uint32 spell = unitCaster->GetUInt32Value(UNIT_CREATED_BY_SPELL);
4677 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4678 if (spellInfo && spellInfo->SpellIconID == 2056)
4679 {
4680 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", unitCaster->GetGUID().ToString(), m_spellInfo->Id);
4682 return;
4683 }
4684 }
4685
4686 // potions disabled by client, send event "not in combat" if need
4687 if (unitCaster->IsPlayer() && !m_triggeredByAuraSpell)
4688 unitCaster->ToPlayer()->UpdatePotionCooldown(this);
4689
4690 // Take mods after trigger spell (needed for 14177 to affect 48664)
4691 // mods are taken only on succesfull cast and independantly from targets of the spell
4692 if (Player* player = unitCaster->GetSpellModOwner())
4693 player->RemoveSpellMods(this);
4694
4695 // xinef: clear reactive auras states after spell cast
4698
4699 // Stop Attack for some spells
4701 unitCaster->AttackStop();
4702}
@ 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:2946
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition PlayerUpdates.cpp:1584
Definition TemporarySummon.h:125
virtual void setDeathState(DeathState s, bool despawn=false)
Definition Unit.cpp:11120
void UpdateInterruptMask()
Definition Unit.cpp:892
void ModifyAuraState(AuraStateType flag, bool apply)
Definition Unit.cpp:7384
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition Unit.cpp:7240

References Unit::AttackStop(), AURA_STATE_DEFENSE, AURA_STATE_HUNTER_PARRY, SpellInfo::CasterAuraState, Unit::ClearUnitState(), ENCOUNTER_CREDIT_CAST_SPELL, WorldObject::FindMap(), Unit::GetCharm(), Object::GetGUID(), WorldObject::GetSpellModOwner(), 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(), Object::ToUnit(), 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
8849{
8851}
void SendLogExecute()
Definition Spell.cpp:5224

References SendLogExecute().

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

◆ GetCaster()

◆ 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
9329{
9330 std::stringstream sstr;
9331 sstr << std::boolalpha
9332 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
9333 << " State: " << getState();
9334 return sstr.str();
9335}

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
8198{
8200}
ObjectGuid m_originalTargetGUID
Definition Spell.h:632

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

Referenced by _handle_finish_phase().

◆ GetPowerCost()

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

References m_powerCost.

◆ GetSearcherTypeMask()

uint32 Spell::GetSearcherTypeMask ( SpellTargetObjectTypes  objType,
ConditionList *  condList 
)
2138{
2139 // this function selects which containers need to be searched for spell target
2141
2142 // filter searchers based on searched object type
2143 switch (objType)
2144 {
2151 break;
2155 break;
2156 default:
2157 break;
2158 }
2160 retMask &= ~GRID_MAP_TYPE_MASK_CORPSE;
2164 retMask &= GRID_MAP_TYPE_MASK_PLAYER;
2166 retMask &= ~GRID_MAP_TYPE_MASK_PLAYER;
2167
2168 if (condList)
2169 retMask &= sConditionMgr->GetSearcherTypeMaskForConditionList(*condList);
2170 return retMask;
2171}
@ 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
615{ return m_spellSchoolMask; }

References m_spellSchoolMask.

Referenced by Unit::IsImmunedToSpell().

◆ GetSpellValue()

SpellValue const * Spell::GetSpellValue ( )
inline
604{ 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
613{ return _triggeredCastFlags; }

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ GetUnitCasterForEffectHandlers()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4290{
4291 if (!UpdatePointers())
4292 {
4293 // finish the spell if UpdatePointers() returned false, something wrong happened there
4294 finish(false);
4295 return 0;
4296 }
4297
4298 Player* modOwner = m_caster->GetSpellModOwner();
4299 if (modOwner)
4300 modOwner->SetSpellModTakingSpell(this, true);
4301
4302 uint64 next_time = m_delayTrajectory;
4303
4305
4306 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4307 {
4309 m_immediateHandled = true;
4311 next_time = 0;
4312 }
4313
4314 bool single_missile = (m_targets.HasDst());
4315
4316 // 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)
4317 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4318 {
4319 if (ihit->processed == false)
4320 {
4321 if (single_missile || ihit->timeDelay <= t_offset)
4322 {
4323 ihit->timeDelay = t_offset;
4324 DoAllEffectOnTarget(&(*ihit));
4325 }
4326 else if (next_time == 0 || ihit->timeDelay < next_time)
4327 next_time = ihit->timeDelay;
4328 }
4329 }
4330
4331 // now recheck gameobject targeting correctness
4332 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4333 {
4334 if (ighit->processed == false)
4335 {
4336 if (single_missile || ighit->timeDelay <= t_offset)
4337 DoAllEffectOnTarget(&(*ighit));
4338 else if (next_time == 0 || ighit->timeDelay < next_time)
4339 next_time = ighit->timeDelay;
4340 }
4341 }
4342
4344
4345 if (modOwner)
4346 modOwner->SetSpellModTakingSpell(this, false);
4347
4348 // All targets passed - need finish phase
4349 if (next_time == 0)
4350 {
4351 // spell is finished, perform some last features of the spell here
4353
4354 finish(true); // successfully finish spell cast
4355
4356 // return zero, spell is finished now
4357 return 0;
4358 }
4359 else
4360 {
4361 // spell is unfinished, return next execution time
4362 return next_time;
4363 }
4364}
void _handle_finish_phase()
Definition Spell.cpp:4394
void PrepareTargetProcessing()
Definition Spell.cpp:8843
void _handle_immediate_phase()
Definition Spell.cpp:4366
void FinishTargetProcessing()
Definition Spell.cpp:8848

References _handle_finish_phase(), _handle_immediate_phase(), DoAllEffectOnTarget(), finish(), FinishTargetProcessing(), WorldObject::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 ( )
4219{
4220 Unit* unitCaster = m_caster->ToUnit();
4221 // start channeling if applicable
4222 if (m_spellInfo->IsChanneled())
4223 {
4224 int32 duration = m_spellInfo->GetDuration();
4226 duration = -1;
4227
4228 if (duration > 0)
4229 {
4230 // First mod_duration then haste - see Missile Barrage
4231 // Apply duration mod
4232 if (Player* modOwner = m_caster->GetSpellModOwner())
4233 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4234
4235 // Apply haste mods
4237 duration = int32(duration * unitCaster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4238
4240 if (unitCaster)
4242 m_channeledDuration = duration;
4243 SendChannelStart(duration);
4244 }
4245 else if (duration == -1)
4246 {
4248 if (unitCaster)
4250 SendChannelStart(duration);
4251 }
4252 }
4253
4255
4256 // process immediate effects (items, ground, etc.) also initialize some variables
4258
4259 // Sync persistent area aura duration with hasted channel duration
4262 {
4265 }
4266
4267 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4268 DoAllEffectOnTarget(&(*ihit));
4269
4270 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4271 DoAllEffectOnTarget(&(*ihit));
4272
4274
4275 // spell is finished, perform some last features of the spell here
4277
4278 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4279 TakeCastItem();
4280
4281 // handle ammo consumption for Hunter's volley spell
4283 TakeAmmo();
4284
4286 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4287}
@ DYNOBJ_AURA_TYPE
Definition SpellAuraDefines.h:386
AuraObjectType GetType() const
Definition SpellAuras.cpp:425
void SendChannelStart(uint32 duration)
Definition Spell.cpp:5361
void TakeAmmo()
Definition Spell.cpp:5550
void AddInterruptMask(uint32 mask)
Definition Unit.h:1609

References _handle_finish_phase(), _handle_immediate_phase(), Unit::AddInterruptMask(), SpellInfo::ChannelInterruptFlags, DoAllEffectOnTarget(), DYNOBJ_AURA_TYPE, finish(), FinishTargetProcessing(), SpellInfo::GetDuration(), Object::GetFloatValue(), WorldObject::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(), Object::ToUnit(), 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 
)
5824{
5826 return;
5827
5828 effectHandleMode = mode;
5829 unitTarget = pUnitTarget;
5830 itemTarget = pItemTarget;
5831 gameObjTarget = pGOTarget;
5833
5834 uint8 eff = m_spellInfo->Effects[i].Effect;
5835
5836 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5837
5838 // we do not need DamageMultiplier here.
5839 damage = CalculateSpellDamage(i, nullptr);
5840
5841 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5842
5843 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5844 {
5845 (this->*SpellEffects[eff])((SpellEffIndex)i);
5846 }
5847}
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:8962
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
8583{
8584 Unit* unitCaster = m_caster->ToUnit();
8585 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8586 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8587 {
8588 // don't do anything for empty effect
8589 if (!m_spellInfo->Effects[i].IsEffect())
8590 continue;
8591
8592 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8593 }
8594
8595 float multiplier[MAX_SPELL_EFFECTS];
8596 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8597 if (m_applyMultiplierMask & (1 << i))
8598 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8599
8601 if (unitCaster)
8602 {
8604 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8605 {
8606 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8607 usesAmmo = false;
8608 }
8609 }
8610
8612
8613 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8614 {
8615 TargetInfo& target = *ihit;
8616
8617 uint32 mask = target.effectMask;
8618 if (!mask)
8619 continue;
8620
8621 // do not consume ammo anymore for Hunter's volley spell
8623 usesAmmo = false;
8624
8625 if (usesAmmo)
8626 {
8627 bool ammoTaken = false;
8628 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8629 {
8630 if (!(mask & 1 << i))
8631 continue;
8632 switch (m_spellInfo->Effects[i].Effect)
8633 {
8639 ammoTaken = true;
8640 TakeAmmo();
8641 }
8642 if (ammoTaken)
8643 break;
8644 }
8645 }
8646
8648 {
8649 Unit* targetUnit = m_caster->GetGUID() == target.targetGUID ? unitCaster : ObjectAccessor::GetUnit(*m_caster, target.targetGUID);
8650 if (targetUnit && !m_originalCaster->IsFriendlyTo(targetUnit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)) && (m_spellInfo->HasInitialAggro() || targetUnit->IsEngaged()))
8651 m_originalCaster->SetInCombatWith(targetUnit, true);
8652 }
8653
8654 DoAllEffectOnLaunchTarget(target, multiplier);
8655 }
8656
8658}
@ 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:8660

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(), TargetInfo::targetGUID, and Object::ToUnit().

Referenced by _cast().

◆ HandleThreatSpells()

void Spell::HandleThreatSpells ( )
5769{
5770 if (m_UniqueTargetInfo.empty())
5771 return;
5772
5774 return;
5775
5777 if (!unitCaster)
5778 return;
5779
5780 float threat = 0.0f;
5781 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5782 {
5783 if (threatEntry->apPctMod != 0.0f)
5784 threat += threatEntry->apPctMod * unitCaster->GetTotalAttackPowerValue(BASE_ATTACK);
5785
5786 threat += threatEntry->flatMod;
5787 }
5789 threat += m_spellInfo->SpellLevel;
5790
5791 // past this point only multiplicative effects occur
5792 if (threat == 0.0f)
5793 return;
5794
5795 // 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
5796 threat /= m_UniqueTargetInfo.size();
5797
5798 for (auto& ihit : m_UniqueTargetInfo)
5799 {
5800 float threatToAdd = threat;
5801 if (ihit.missCondition != SPELL_MISS_NONE)
5802 threatToAdd = 0.0f;
5803
5804 Unit* target = ObjectAccessor::GetUnit(*unitCaster, ihit.targetGUID);
5805 if (!target)
5806 continue;
5807
5808 // positive spells distribute threat among all units that are in combat with target, like healing
5810 target->GetThreatMgr().ForwardThreatForAssistingMe(unitCaster, threatToAdd, m_spellInfo);
5811 // for negative spells threat gets distributed among affected targets
5812 // ignoreModifiers=true because flat SpellThreatEntry threat should not have modifiers applied twice
5813 else
5814 {
5815 if (!target->CanHaveThreatList())
5816 continue;
5817 target->GetThreatMgr().AddThreat(unitCaster, threatToAdd, m_spellInfo, true);
5818 }
5819 }
5820 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()));
5821}
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition SpellInfo.h:181
bool _IsPositiveSpell() const
Definition SpellInfo.cpp:3264
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, sSpellMgr, and Object::ToUnit().

Referenced by _handle_immediate_phase().

◆ HasGlobalCooldown()

bool Spell::HasGlobalCooldown ( ) const
protected
9214{
9215 Unit* unitCaster = m_caster->ToUnit();
9216 if (!unitCaster)
9217 return false;
9218
9219 // Only player or controlled units have global cooldown
9220 if (unitCaster->GetCharmInfo())
9222 else if (unitCaster->IsPlayer())
9224 else
9225 return false;
9226}

References Unit::GetCharmInfo(), Player::GetGlobalCooldownMgr(), CharmInfo::GetGlobalCooldownMgr(), GlobalCooldownMgr::HasGlobalCooldown(), Object::IsPlayer(), m_caster, m_spellInfo, Object::ToPlayer(), and Object::ToUnit().

Referenced by CheckCast().

◆ HasTriggeredCastFlag()

◆ HaveTargetsForEffect()

bool Spell::HaveTargetsForEffect ( uint8  effect) const
8445{
8446 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8447 if (itr->effectMask & (1 << effect))
8448 return true;
8449
8450 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8451 if (itr->effectMask & (1 << effect))
8452 return true;
8453
8454 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8455 if (itr->effectMask & (1 << effect))
8456 return true;
8457
8458 return false;
8459}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8854{
8855 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8856 if (!m_effectExecuteData[effIndex])
8857 {
8858 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8859 // first dword - target counter
8860 *m_effectExecuteData[effIndex] << uint32(1);
8861 }
8862 else
8863 {
8864 // increase target counter by one
8865 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8866 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8867 }
8868}

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)
767{
768 m_targets = targets;
769 m_originalTargetGUID = targets.GetObjectTargetGUID();
770 // this function tries to correct spell explicit targets for spell
771 // client doesn't send explicit targets correctly sometimes - we need to fix such spells serverside
772 // this also makes sure that we correctly send explicit targets to client (removes redundant data)
773 uint32 neededTargets = m_spellInfo->GetExplicitTargetMask();
774
775 if (WorldObject* target = m_targets.GetObjectTarget())
776 {
777 // check if object target is valid with needed target flags
778 // for unit case allow corpse target mask because player with not released corpse is a unit target
779 if ((target->ToUnit() && !(neededTargets & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)))
780 || (target->ToGameObject() && !(neededTargets & TARGET_FLAG_GAMEOBJECT_MASK))
781 || (target->ToCorpse() && !(neededTargets & TARGET_FLAG_CORPSE_MASK)))
783 }
784 else
785 {
786 // try to select correct unit target if not provided by client or by serverside cast
787 if (neededTargets & (TARGET_FLAG_UNIT_MASK))
788 {
789 Unit* unit = nullptr;
790 // try to use player selection as a target
791 if (Player* playerCaster = m_caster->ToPlayer())
792 {
793 // selection has to be found and to be valid target for the spell
794 if (Unit* selectedUnit = ObjectAccessor::GetUnit(*m_caster, playerCaster->GetTarget()))
796 unit = selectedUnit;
797 }
798 // try to use attacked unit as a target
799 else if (Unit* creatureCaster = m_caster->ToUnit(); creatureCaster && creatureCaster->IsCreature() && neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT))
800 unit = creatureCaster->GetVictim();
801
802 // didn't find anything - let's use self as target
803 if (!unit && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY))
804 unit = m_caster->ToUnit();
805
807 }
808 }
809
810 // check if spell needs dst target
811 if (neededTargets & TARGET_FLAG_DEST_LOCATION)
812 {
813 // and target isn't set
814 if (!m_targets.HasDst())
815 {
816 // try to use unit target if provided
817 if (WorldObject* target = targets.GetObjectTarget())
818 m_targets.SetDst(*target);
819 // or use self if not available
820 else
822 }
823 }
824 else
826
827 if (neededTargets & TARGET_FLAG_SOURCE_LOCATION)
828 {
829 if (!targets.HasSrc())
831 }
832 else
834}
@ 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_UNIT_PARTY
Definition SpellInfo.h:50
void RemoveDst()
Definition Spell.cpp:485
void RemoveSrc()
Definition Spell.cpp:428

References SpellInfo::CheckExplicitTarget(), SpellInfo::GetExplicitTargetMask(), SpellCastTargets::GetObjectTarget(), SpellCastTargets::GetObjectTargetGUID(), ObjectAccessor::GetUnit(), Unit::GetVictim(), SpellCastTargets::HasDst(), SpellCastTargets::HasSrc(), 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, Object::ToPlayer(), and Object::ToUnit().

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?
8419{
8422 {
8423 return false;
8424 }
8425
8427 {
8428 return false;
8429 }
8430
8431 return true;
8432}
@ 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
653 {
654 if (m_delayAtDamageCount >= 2)
655 return true;
656
658 return false;
659 }

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

References HasTriggeredCastFlag(), and TRIGGERED_DISALLOW_PROC_EVENTS.

Referenced by Unit::TriggerAurasProcOnEvent().

◆ IsTriggered()

◆ IsValidDeadOrAliveTarget()

bool Spell::IsValidDeadOrAliveTarget ( Unit const *  target) const
protected
8575{
8576 if (target->IsAlive())
8578
8580}
bool IsRequiringDeadTarget() const
Definition SpellInfo.cpp:1267
bool IsAllowingDeadTarget() const
Definition SpellInfo.cpp:1272

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

Referenced by UpdateChanneledTargetList().

◆ LoadScripts()

void Spell::LoadScripts ( )
8877{
8878 if (_scriptsLoaded)
8879 return;
8880 _scriptsLoaded = true;
8881 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8882 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8883 {
8884 if (!(*itr)->_Load(this))
8885 {
8886 std::list<SpellScript*>::iterator bitr = itr;
8887 ++itr;
8888 delete (*bitr);
8889 m_loadedScripts.erase(bitr);
8890 continue;
8891 }
8892 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8893 (*itr)->Register();
8894 ++itr;
8895 }
8896}

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 ( )
9298{
9299 Unit* unitCaster = m_caster->ToUnit();
9300 if (!unitCaster || !unitCaster->IsInWorld())
9301 return;
9302
9303 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
9304
9305 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
9306 // can succeed with a lockId of 0
9307 if (m_spellInfo->Id == 21651)
9308 {
9309 if (GameObject* go = m_targets.GetGOTarget())
9310 {
9311 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
9312 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
9313 {
9314 Spell* visual = new Spell(unitCaster, spellInfo, TRIGGERED_NONE);
9315 visual->prepare(&m_targets);
9316 }
9317 }
9318 }
9319}
@ LOCKTYPE_SLOW_OPEN
Definition SharedDefines.h:2612
@ TRIGGERED_NONE
Definition SpellDefines.h:141

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

Referenced by prepare().

◆ prepare()

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

m_castItemGUID &&

3557{
3558 Unit* unitCaster = m_caster->ToUnit();
3559 if (m_CastItem)
3560 {
3562 }
3563 else
3564 {
3566 }
3567
3568 InitExplicitTargets(*targets);
3569
3570 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3571 {
3572 finish(false);
3573 return SPELL_FAILED_UNKNOWN;
3574 }
3575
3576 // Fill aura scaling information
3577 if (sScriptMgr->CanScalingEverything(this) || (unitCaster && unitCaster->IsTotem()) || (unitCaster && unitCaster->IsControlledByPlayer() && !m_spellInfo->IsPassive() && m_spellInfo->SpellLevel && !m_spellInfo->IsChanneled() && !HasTriggeredCastFlag(TRIGGERED_IGNORE_AURA_SCALING)))
3578 {
3579 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3580 {
3581 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3584 {
3585 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3587 {
3588 m_auraScaleMask |= (1 << i);
3589 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3590 {
3591 m_auraScaleMask = 0;
3592 break;
3593 }
3594 }
3595 }
3596 }
3597 }
3598
3600
3601 if (triggeredByAura)
3602 {
3603 m_triggeredByAuraSpell.Init(triggeredByAura);
3604 }
3605
3606 // create and add update event for this spell
3607 _spellEvent = new SpellEvent(this);
3609
3610 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, unitCaster))
3611 {
3613 finish(false);
3615 }
3616
3617 //Prevent casting at cast another spell (ServerSide check)
3618 if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS) && unitCaster && unitCaster->IsNonMeleeSpellCast(false, true, true, m_spellInfo->Id == 75) && m_cast_count)
3619 {
3621 finish(false);
3623 }
3624
3625 LoadScripts();
3626
3627 OnSpellLaunch();
3628
3630
3631 // Set combo point requirement
3633 m_needComboPoints = false;
3634
3635 SpellCastResult result = CheckCast(true);
3636 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3637 {
3638 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3639 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3640 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3641 // a possible alternative sollution for those would be validating aura target on unit state change
3642 if (unitCaster && unitCaster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3643 {
3645 triggeredByAura->GetBase()->SetDuration(0);
3646 }
3647
3648 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3650 {
3651 SendCastResult(result);
3652
3653 finish(false);
3654 return result;
3655 }
3656 }
3657
3658 // Prepare data for triggers
3659 prepareDataForTriggerSystem(triggeredByAura);
3660
3661 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3663
3664 if (unitCaster && unitCaster->IsPlayer())
3665 if (unitCaster->ToPlayer()->GetCommandStatus(CHEAT_CASTTIME))
3666 m_casttime = 0;
3667
3668 // don't allow channeled spells / spells with cast time to be casted while moving
3669 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3670 if ((m_spellInfo->IsChanneled() || m_casttime) && unitCaster && unitCaster->IsPlayer() && unitCaster->isMoving() && m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT && !IsTriggered())
3671 {
3672 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3674 {
3676 finish(false);
3677 return SPELL_FAILED_MOVING;
3678 }
3679 }
3680
3681 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3682 if (m_CastItem)
3683 {
3684 bool selectTargets = false;
3685 bool nearbyDest = false;
3686
3687 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3688 {
3689 if (!m_spellInfo->Effects[i].IsEffect())
3690 continue;
3691
3692 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3693 {
3694 selectTargets = false;
3695 break;
3696 }
3697
3698 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3699 {
3700 nearbyDest = true;
3701 }
3702
3703 // xinef: by default set it to false, and to true if any valid target is found
3704 selectTargets = true;
3705 }
3706
3707 if (selectTargets)
3708 {
3710 _spellTargetsSelected = true;
3711 bool spellFailed = false;
3712
3713 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3714 {
3715 // no valid nearby target unit or game object found; check if nearby destination type
3716 if (nearbyDest)
3717 {
3718 if (!m_targets.HasDst())
3719 {
3720 // no valid target destination
3721 spellFailed = true;
3722 }
3723 }
3724 else
3725 {
3726 spellFailed = true;
3727 }
3728 }
3729
3730 if (spellFailed)
3731 {
3733 finish(false);
3735 }
3736 }
3737 }
3738
3739 // set timer base at cast time
3740 ReSetTimer();
3741
3742 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());
3743
3744 // prevent exploit that allows to cast spell while sitting
3747
3748 //Containers for channeled spells have to be set
3749 //TODO:Apply this to all casted spells if needed
3750 // Why check duration? 29350: channelled triggers channelled
3752 cast(true);
3753 else
3754 {
3755 // stealth must be removed at cast starting (at show channel bar)
3756 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3758 {
3759 // Farsight spells exception
3760 uint32 exceptSpellId = 0;
3762 {
3763 exceptSpellId = m_spellInfo->Id;
3764 }
3765
3766 unitCaster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CAST, exceptSpellId, m_spellInfo->Id == 75);
3768 }
3769
3770 if (unitCaster)
3771 unitCaster->SetCurrentCastedSpell(this);
3773
3774 // Call CreatureAI hook OnSpellStart for spells with cast time or channeled spells
3775 if (m_casttime > 0 || m_spellInfo->IsChanneled())
3776 if (Creature* caster = unitCaster ? unitCaster->ToCreature() : nullptr)
3777 if (caster->IsAIEnabled)
3778 caster->AI()->OnSpellStart(GetSpellInfo());
3779
3780 // set target for proper facing
3781 // channels that allow actions must not lock target and facing, the creature keeps fighting while channeling
3783 {
3784 if (unitCaster && unitCaster->IsCreature() && !unitCaster->ToCreature()->IsInEvadeMode() &&
3786 {
3787 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3788 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3789 unitCaster->ToCreature()->FocusTarget(this, m_targets.GetObjectTarget() != nullptr ? m_targets.GetObjectTarget() : unitCaster);
3790 }
3791 }
3792
3793 //item: first cast may destroy item and second cast causes crash
3794 // xinef: removed !m_spellInfo->StartRecoveryTime
3795 // second los check failed in events
3796 // xinef: removed itemguid check, currently there is no such item in database
3798 cast(true);
3799
3802 }
3803
3804 sScriptMgr->OnSpellPrepare(this, unitCaster, m_spellInfo);
3805
3806 return SPELL_CAST_OK;
3807}
@ 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:64
@ AURA_INTERRUPT_FLAG_CAST
Definition SpellDefines.h:53
@ TRIGGERED_IGNORE_AURA_SCALING
Will not take away cast item or update related achievement criteria.
Definition SpellDefines.h:146
@ TRIGGERED_IGNORE_AURA_INTERRUPT_FLAGS
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition SpellDefines.h:150
@ TRIGGERED_IGNORE_COMBO_POINTS
Will not check if a current cast is in progress.
Definition SpellDefines.h:148
@ SPELL_INTERRUPT_FLAG_MOVEMENT
Definition SpellDefines.h:34
@ 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:3622
Definition Spell.cpp:556
bool IsActionAllowedChannel() const
Definition SpellInfo.cpp:1306
int32 GetMaxDuration() const
Definition SpellInfo.cpp:2771
uint32 Attributes
Definition SpellInfo.h:348
bool IsBreakingStealth() const
Definition SpellInfo.cpp:1316
void LoadScripts()
Definition Spell.cpp:8876
void cast(bool skipCheck=false)
Definition Spell.cpp:3894
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition Spell.cpp:2301
void SendSpellStart()
Definition Spell.cpp:4865
void TriggerGlobalCooldown()
Definition Spell.cpp:9228
void OnSpellLaunch()
Definition Spell.cpp:9297
CurrentSpellTypes GetCurrentContainer() const
Definition Spell.cpp:8253
void ReSetTimer()
Definition Spell.h:565
void InitExplicitTargets(SpellCastTargets const &targets)
Definition Spell.cpp:766
void SetCurrentCastedSpell(Spell *pSpell)
Definition Unit.cpp:3868
bool IsSitState() const
Definition Unit.cpp:12707
void Init(AuraEffect const *aurEff)
Definition Spell.cpp:9321

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(), Object::ToUnit(), 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(), WorldObject::CastSpell(), Unit::CastSpell(), EffectEnchantItemTmp(), WorldSession::HandleAcceptTradeOpcode(), WorldSession::HandleCastSpellOpcode(), WorldSession::HandlePetActionHelper(), WorldSession::HandlePetCastSpellOpcode(), OnSpellLaunch(), and PetAI::UpdateAI().

◆ prepareDataForTriggerSystem()

void Spell::prepareDataForTriggerSystem ( AuraEffect const *  triggeredByAura)
protected
2302{
2303 Unit* unitCaster = m_caster->ToUnit();
2304 //==========================================================================================
2305 // Now fill data for trigger system, need know:
2306 // can spell trigger another or not (m_canTrigger)
2307 // Create base triggers flags for Attacker and Victim (m_procAttacker, m_procVictim and m_procEx)
2308 //==========================================================================================
2309
2311 // Get data for type of attack and fill base info for trigger
2312 switch (m_spellInfo->DmgClass)
2313 {
2316 if (m_attackType == OFF_ATTACK)
2318 else
2321 break;
2323 // Auto attack
2325 {
2328 }
2329 else // Ranged spell attack
2330 {
2333 }
2334 break;
2335 default:
2338 && m_spellInfo->HasAttribute(SPELL_ATTR2_AUTO_REPEAT)) // Wands auto attack
2339 {
2342 }
2343 // For other spells trigger procflags are set in Spell::DoAllEffectOnTarget
2344 // Because spell positivity is dependant on target
2345 }
2347
2348 // Hunter trap spells - activation proc for Lock and Load, Entrapment and Misdirection
2350 (m_spellInfo->SpellFamilyFlags[0] & 0x18 || // Freezing and Frost Trap, Freezing Arrow
2351 m_spellInfo->Id == 57879 || // Snake Trap - done this way to avoid double proc
2352 m_spellInfo->SpellFamilyFlags[2] & 0x00024000)) // Explosive and Immolation Trap
2353 {
2355
2356 // also fill up other flags (TargetInfo::DoDamageAndTriggers only fills up flag if both are not set)
2359 }
2360
2361 /* Effects which are result of aura proc from triggered spell cannot proc
2362 to prevent chain proc of these spells */
2363
2364 // Hellfire Effect - trigger as DOT
2366 {
2369 }
2370
2371 // Ranged autorepeat attack is set as triggered spell - ignore it
2373 {
2380 }
2381 // Totem casts require spellfamilymask defined in spell_proc to proc
2382 if (m_originalCaster && m_caster != m_originalCaster && unitCaster && unitCaster->IsCreature() && unitCaster->ToCreature()->IsTotem() && unitCaster->IsControlledByPlayer())
2384}
@ 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(), Object::ToUnit(), and TRIGGERED_DISALLOW_PROC_EVENTS.

Referenced by prepare().

◆ PrepareScriptHitHandlers()

void Spell::PrepareScriptHitHandlers ( )
protected
8957{
8958 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8959 (*scritr)->_InitHit();
8960}

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
9131{
9132 Unit* unitCaster = m_caster->ToUnit();
9133 if (!unitCaster)
9134 return;
9135
9138 {
9139 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
9140 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
9142 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
9143 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
9145 }
9146
9149 {
9151 {
9152 if (m_spellInfo->SpellFamilyFlags[1] & 0x40000000)
9153 {
9155 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
9156 {
9157 if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
9158 {
9159 m_preCastSpell = 26017;
9160 break;
9161 }
9162 else if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
9163 m_preCastSpell = 67;
9164 }
9165 }
9166 break;
9167 }
9168 case SPELLFAMILY_DRUID:
9169 {
9170 // Faerie Fire (Feral)
9171 if (m_spellInfo->Id == 16857 && (unitCaster->GetShapeshiftForm() == FORM_BEAR || unitCaster->GetShapeshiftForm() == FORM_DIREBEAR))
9172 m_preCastSpell = 60089;
9173
9174 break;
9175 }
9176 }
9177
9178 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
9179 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
9180 // and to correctly calculate proc chance when combopoints are present
9181 Unit::AuraEffectList const& targetTriggers = unitCaster->GetAuraEffectsByType(SPELL_AURA_ADD_TARGET_TRIGGER);
9182 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
9183 {
9184 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
9185 continue;
9186 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
9187 uint32 auraSpellIdx = (*i)->GetEffIndex();
9188 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
9189 {
9190 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
9191 // this possibly needs fixing
9192 int32 auraBaseAmount = (*i)->GetBaseAmount();
9193 // proc chance is stored in effect amount
9194 int32 chance = unitCaster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
9195 // build trigger and add to the list
9196 HitTriggerSpell spellTriggerInfo;
9197 spellTriggerInfo.triggeredSpell = spellInfo;
9198 spellTriggerInfo.triggeredByAura = auraSpellInfo;
9199 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
9200 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
9201 m_hitTriggerSpells.push_back(spellTriggerInfo);
9202 }
9203 }
9204}
@ 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 WorldObject::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, Object::ToUnit(), Spell::HitTriggerSpell::triggeredByAura, Spell::HitTriggerSpell::triggeredByEffIdx, and Spell::HitTriggerSpell::triggeredSpell.

Referenced by _cast().

◆ RecalculateDelayMomentForDst()

void Spell::RecalculateDelayMomentForDst ( )
971{
974}
void ModifyEventTime(BasicEvent *event, Milliseconds newTime)
Definition EventProcessor.cpp:145
uint64 CalculateDelayMomentForDst() const
Definition Spell.cpp:949
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,
WorldObject *  referer,
SpellTargetObjectTypes  objectType,
SpellTargetCheckTypes  selectionType,
ConditionList *  condList,
Acore::WorldObjectSpellAreaTargetSearchReason  searchReason = Acore::WorldObjectSpellAreaTargetSearchReason::Area,
SpellTargetReferenceTypes  referenceType = TARGET_REFERENCE_TYPE_CASTER 
)
2195{
2196 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2197 if (!containerTypeMask)
2198 return;
2199 Acore::WorldObjectSpellAreaTargetCheck check(range, position, m_caster, referer, m_spellInfo, selectionType, condList, searchReason, referenceType);
2200 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
2201 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellAreaTargetCheck> > (searcher, containerTypeMask, m_caster, position, range);
2202}
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionList *condList)
Definition Spell.cpp:2137
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 
)
2205{
2206 // max dist for jump target selection
2207 float jumpRadius = 0.0f;
2208 switch (m_spellInfo->DmgClass)
2209 {
2211 // 7.5y for multi shot
2212 jumpRadius = 7.5f;
2213 break;
2215 // 10y for swipe, cleave and similar
2216 jumpRadius = 10.0f;
2217 break;
2220 // 12.5y for chain heal spell since 3.2 patch
2221 if (isChainHeal)
2222 jumpRadius = 12.5f;
2223 // 10y as default for magic chain spells
2224 else
2225 jumpRadius = 10.0f;
2226 break;
2227 }
2228
2229 // per-spell override from spell_jump_distance table
2230 if (m_spellInfo->JumpDistance > 0.0f)
2231 jumpRadius = m_spellInfo->JumpDistance;
2232
2233 // chain lightning/heal spells and similar - allow to jump at larger distance and go out of los
2237
2238 // max dist which spell can reach
2239 float searchRadius = jumpRadius;
2240 if (isBouncingFar)
2241 searchRadius *= chainTargets;
2242
2244 std::list<WorldObject*> tempTargets;
2245 SearchAreaTargets(tempTargets, searchRadius, chainSource, m_caster, objectType, selectType, condList, Acore::WorldObjectSpellAreaTargetSearchReason::Chain);
2246 tempTargets.remove(target);
2247
2248 // remove targets which are always invalid for chain spells
2249 // for some spells allow only chain targets in front of caster (swipe for example)
2250 if (!isBouncingFar)
2251 tempTargets.remove_if([this](WorldObject* target) { return !m_caster->HasInArc(static_cast<float>(M_PI), target); });
2252
2253 while (chainTargets)
2254 {
2255 // try to get unit for next chain jump
2256 std::list<WorldObject*>::iterator foundItr = tempTargets.end();
2257 // get unit with highest hp deficit in dist
2258 if (isChainHeal)
2259 {
2260 uint32 maxHPDeficit = 0;
2261 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2262 {
2263 if (Unit* unit = (*itr)->ToUnit())
2264 {
2265 uint32 deficit = unit->GetMaxHealth() - unit->GetHealth();
2266 if (deficit > maxHPDeficit && chainSource->IsWithinDist(unit, jumpRadius) && chainSource->IsWithinLOSInMap(unit, VMAP::ModelIgnoreFlags::M2))
2267 {
2268 foundItr = itr;
2269 maxHPDeficit = deficit;
2270 }
2271 }
2272 }
2273 }
2274 // get closest object
2275 else
2276 {
2277 for (std::list<WorldObject*>::iterator itr = tempTargets.begin(); itr != tempTargets.end(); ++itr)
2278 {
2279 if (foundItr == tempTargets.end())
2280 {
2281 if ((!isBouncingFar || chainSource->IsWithinDist(*itr, jumpRadius)) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2282 foundItr = itr;
2283 }
2284 else if (chainSource->GetDistanceOrder(*itr, *foundItr) && chainSource->IsWithinLOSInMap(*itr, VMAP::ModelIgnoreFlags::M2))
2285 foundItr = itr;
2286 }
2287 }
2288 // not found any valid target - chain ends
2289 if (foundItr == tempTargets.end())
2290 break;
2291
2293 chainSource = *foundItr;
2294
2295 targets.push_back(*foundItr);
2296 tempTargets.erase(foundItr);
2297 --chainTargets;
2298 }
2299}
@ 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, WorldObject *referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionList *condList, Acore::WorldObjectSpellAreaTargetSearchReason searchReason=Acore::WorldObjectSpellAreaTargetSearchReason::Area, SpellTargetReferenceTypes referenceType=TARGET_REFERENCE_TYPE_CASTER)
Definition Spell.cpp:2194
bool GetDistanceOrder(WorldObject const *obj1, WorldObject const *obj2, bool is3D=true) const
Definition Object.cpp:1446

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 
)
2183{
2184 WorldObject* target = nullptr;
2185 uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList);
2186 if (!containerTypeMask)
2187 return nullptr;
2188 Acore::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList);
2190 SearchTargets<Acore::WorldObjectLastSearcher<Acore::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range);
2191 return target;
2192}
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,
WorldObject *  referer,
Position const *  pos,
float  radius 
)
2175{
2176 if (!containerMask)
2177 return;
2178
2179 Cell::VisitObjects(pos->GetPositionX(), pos->GetPositionY(), referer->GetMap(), searcher, radius);
2180}

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

◆ SelectEffectImplicitTargets()

void Spell::SelectEffectImplicitTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
uint32 &  processedEffectMask 
)
977{
978 if (!targetType.GetTarget())
979 return;
980
981 uint32 effectMask = 1 << effIndex;
982 // set the same target list for all effects
983 // some spells appear to need this, however this requires more research
984 switch (targetType.GetSelectionCategory())
985 {
989 {
990 // targets for effect already selected
991 if (effectMask & processedEffectMask)
992 {
993 return;
994 }
995
996 auto const& effects = GetSpellInfo()->Effects;
997
998 // choose which targets we can select at once
999 for (uint32 j = effIndex + 1; j < MAX_SPELL_EFFECTS; ++j)
1000 {
1001 if (effects[j].IsEffect() &&
1002 effects[effIndex].TargetA.GetTarget() == effects[j].TargetA.GetTarget() &&
1003 effects[effIndex].TargetB.GetTarget() == effects[j].TargetB.GetTarget() &&
1004 effects[effIndex].ImplicitTargetConditions == effects[j].ImplicitTargetConditions &&
1005 effects[effIndex].CalcRadius(m_caster) == effects[j].CalcRadius(m_caster) &&
1007 {
1008 effectMask |= 1 << j;
1009 }
1010 }
1011 processedEffectMask |= effectMask;
1012 break;
1013 }
1014 default:
1015 break;
1016 }
1017
1018 switch (targetType.GetSelectionCategory())
1019 {
1021 SelectImplicitChannelTargets(effIndex, targetType);
1022 break;
1024 SelectImplicitNearbyTargets(effIndex, targetType, effectMask);
1025 break;
1027 SelectImplicitConeTargets(effIndex, targetType, effectMask);
1028 break;
1030 SelectImplicitAreaTargets(effIndex, targetType, effectMask);
1031 break;
1033 // just in case there is no dest, explanation in SelectImplicitDestDestTargets
1034 CheckDst();
1035
1036 SelectImplicitTrajTargets(effIndex, targetType);
1037 break;
1039 switch (targetType.GetObjectType())
1040 {
1042 switch (targetType.GetReferenceType())
1043 {
1046 break;
1047 default:
1048 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_SRC");
1049 break;
1050 }
1051 break;
1053 switch (targetType.GetReferenceType())
1054 {
1056 SelectImplicitCasterDestTargets(effIndex, targetType);
1057 break;
1059 SelectImplicitTargetDestTargets(effIndex, targetType);
1060 break;
1062 SelectImplicitDestDestTargets(effIndex, targetType);
1063 break;
1064 default:
1065 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT_DEST");
1066 break;
1067 }
1068 break;
1069 default:
1070 switch (targetType.GetReferenceType())
1071 {
1073 SelectImplicitCasterObjectTargets(effIndex, targetType);
1074 break;
1076 SelectImplicitTargetObjectTargets(effIndex, targetType);
1077 break;
1078 default:
1079 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target reference type for TARGET_TYPE_OBJECT");
1080 break;
1081 }
1082 break;
1083 }
1084 break;
1086 LOG_DEBUG("spells.aura", "SPELL: target type {}, found in spellID {}, effect {} is not implemented yet!", m_spellInfo->Id, effIndex, targetType.GetTarget());
1087 break;
1088 default:
1089 ASSERT(false && "Spell::SelectEffectImplicitTargets: received not implemented select target category");
1090 break;
1091 }
1092}
@ 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:1818
void CheckDst()
Definition Spell.h:506
void SelectImplicitTrajTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1970
void SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1272
void SelectImplicitTargetDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1781
void SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1341
void SelectImplicitChannelTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1094
void SelectImplicitTargetObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1907
void SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1854
void SelectImplicitNearbyTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, uint32 effMask)
Definition Spell.cpp:1150
bool CheckScriptEffectImplicitTargets(uint32 effIndex, uint32 effIndexToCheck)
Definition Spell.cpp:9091
void SelectImplicitCasterDestTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:1431

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
2054{
2055 Unit* unitCaster = m_caster->ToUnit();
2056 // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER
2058 switch (m_spellInfo->Effects[effIndex].Effect)
2059 {
2062 if (unitCaster && unitCaster->IsPlayer() && unitCaster->ToPlayer()->GetTarget())
2063 {
2064 WorldObject* target = ObjectAccessor::FindPlayer(unitCaster->ToPlayer()->GetTarget());
2065
2067
2068 if (target && target->ToPlayer())
2069 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2070 }
2071 return;
2072 default:
2073 break;
2074 }
2075
2076 // select spell implicit targets based on effect type
2077 if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2078 return;
2079
2080 uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask();
2081
2082 if (!targetMask)
2083 return;
2084
2085 WorldObject* target = nullptr;
2086
2087 switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
2088 {
2089 // add explicit object target or self to the target map
2091 // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
2093 {
2095 target = unitTarget;
2096 else if (targetMask & TARGET_FLAG_CORPSE_MASK)
2097 {
2098 if (Corpse* corpseTarget = m_targets.GetCorpseTarget())
2099 {
2101 if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()))
2102 target = owner;
2103 }
2104 }
2105 else //if (targetMask & TARGET_FLAG_UNIT_MASK)
2106 target = m_caster;
2107 }
2108 if (targetMask & TARGET_FLAG_ITEM_MASK)
2109 {
2111 AddItemTarget(itemTarget, 1 << effIndex);
2112 return;
2113 }
2114 if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK)
2115 target = m_targets.GetGOTarget();
2116 break;
2117 // add self to the target map
2119 if (targetMask & TARGET_FLAG_UNIT_MASK)
2120 target = m_caster;
2121 break;
2122 default:
2123 break;
2124 }
2125
2127
2128 if (target)
2129 {
2130 if (target->ToUnit())
2131 AddUnitTarget(target->ToUnit(), 1 << effIndex, false);
2132 else if (target->ToGameObject())
2133 AddGOTarget(target->ToGameObject(), 1 << effIndex);
2134 }
2135}
@ EFFECT_IMPLICIT_TARGET_CASTER
Definition SpellInfo.h:145
@ EFFECT_IMPLICIT_TARGET_EXPLICIT
Definition SpellInfo.h:144
@ TARGET_FLAG_ITEM_MASK
Definition SpellInfo.h:73
Corpse * GetCorpseTarget() const
Definition Spell.cpp:331
Definition SpellInfo.h:238
void AddGOTarget(GameObject *target, uint32 effectMask)
Definition Spell.cpp:2531
void AddUnitTarget(Unit *target, uint32 effectMask, bool checkIfValid=true, bool implicit=true)
Definition Spell.cpp:2395
void AddItemTarget(Item *item, uint32 effectMask)
Definition Spell.cpp:2593
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:9063

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 ( )
837{
838 // here go all explicit target changes made to explicit targets after spell prepare phase is finished
839 if (Unit* target = m_targets.GetUnitTarget())
840 {
841 // check for explicit target redirection, for Grounding Totem for example
845 {
846 Unit* redirect;
847 switch (m_spellInfo->DmgClass)
848 {
851 break;
855 break;
856 default:
857 redirect = nullptr;
858 break;
859 }
860 if (redirect && (redirect != target))
861 {
862 m_targets.SetUnitTarget(redirect);
864 }
865 }
866 }
867}
Unit * GetMagicHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition Object.cpp:4041
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition Object.cpp:4050

References SpellInfo::DmgClass, SpellInfo::GetExplicitTargetMask(), WorldObject::GetMagicHitRedirectTarget(), WorldObject::GetMeleeHitRedirectTarget(), SpellCastTargets::GetUnitTarget(), SpellInfo::HasEffect(), WorldObject::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 
)
1342{
1343 WorldObject* referer = nullptr;
1344 switch (targetType.GetReferenceType())
1345 {
1349 referer = m_caster;
1350 break;
1352 referer = m_targets.GetUnitTarget();
1353 break;
1355 {
1356 // find last added target for this effect
1357 for (std::list<TargetInfo>::reverse_iterator ihit = m_UniqueTargetInfo.rbegin(); ihit != m_UniqueTargetInfo.rend(); ++ihit)
1358 {
1359 if (ihit->effectMask & (1 << effIndex))
1360 {
1361 referer = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1362 break;
1363 }
1364 }
1365 break;
1366 }
1367 default:
1368 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1369 return;
1370 }
1371 if (!referer)
1372 return;
1373
1374 Position const* center = nullptr;
1375 switch (targetType.GetReferenceType())
1376 {
1378 center = m_targets.GetSrcPos();
1379 break;
1381 center = m_targets.GetDstPos();
1382 break;
1386 center = referer;
1387 break;
1388 default:
1389 ASSERT(false && "Spell::SelectImplicitAreaTargets: received not implemented target reference type");
1390 return;
1391 }
1392
1393 // Xinef: the distance should be increased by caster size, it is neglected in latter calculations
1394 std::list<WorldObject*> targets;
1395 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1396 switch (targetType.GetTarget())
1397 {
1401 radius += m_caster->GetLeewayBonusRadius();
1402 break;
1403 default:
1404 break;
1405 }
1406
1407 SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions, Acore::WorldObjectSpellAreaTargetSearchReason::Area, targetType.GetReferenceType());
1408
1409 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1410
1411 if (!targets.empty())
1412 {
1413 // Other special target selection goes here
1414 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1415 {
1416 if (Unit const* unitCaster = m_caster->ToUnit())
1417 maxTargets += unitCaster->GetTotalAuraModifierByAffectMask(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, m_spellInfo);
1418 Acore::Containers::RandomResize(targets, maxTargets);
1419 }
1420
1421 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1422 {
1423 if (Unit* unitTarget = (*itr)->ToUnit())
1424 AddUnitTarget(unitTarget, effMask, false);
1425 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1426 AddGOTarget(gObjTarget, effMask);
1427 }
1428 }
1429}
@ 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:399
void CallScriptObjectAreaTargetSelectHandlers(std::list< WorldObject * > &targets, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:9049
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(), 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
1432{
1433 Unit* unitCaster = m_caster->ToUnit();
1435
1436 switch (targetType.GetTarget())
1437 {
1438 case TARGET_DEST_CASTER:
1440 break;
1441 case TARGET_DEST_HOME:
1442 if (Player* playerCaster = m_caster->ToPlayer())
1443 dest = SpellDestination(playerCaster->m_homebindX, playerCaster->m_homebindY, playerCaster->m_homebindZ, playerCaster->GetOrientation(), playerCaster->m_homebindMapId);
1444 break;
1445 case TARGET_DEST_DB:
1446 if (SpellTargetPosition const* st = sSpellMgr->GetSpellTargetPosition(m_spellInfo->Id, effIndex))
1447 {
1450 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1451 else if (st->target_mapId == m_caster->GetMapId())
1452 dest = SpellDestination(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1453 }
1454 else
1455 {
1456 LOG_DEBUG("spells.aura", "SPELL: unknown target coordinates for spell ID {}", m_spellInfo->Id);
1457 if (WorldObject* target = m_targets.GetObjectTarget())
1458 dest = SpellDestination(*target);
1459 }
1460 break;
1462 {
1463 float min_dis = m_spellInfo->GetMinRange(true);
1464 float max_dis = m_spellInfo->GetMaxRange(true);
1465 float dis = (float)rand_norm() * (max_dis - min_dis) + min_dis;
1466 float x, y, z, angle;
1467 angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1468 //unitCaster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle); this contains extra code that breaks fishing
1470
1471 float ground = m_caster->GetMapHeight(x, y, z, true);
1472 float liquidLevel = VMAP_INVALID_HEIGHT_VALUE;
1473 LiquidData const& liquidData = m_caster->GetMap()->GetLiquidData(m_caster->GetPhaseMask(), x, y, z, m_caster->GetCollisionHeight(), {});
1474 if (liquidData.Status)
1475 liquidLevel = liquidData.Level;
1476
1477 if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1478 {
1481 finish(false);
1482 return;
1483 }
1484
1485 if (ground + 0.75 > liquidLevel)
1486 {
1489 finish(false);
1490 return;
1491 }
1492
1493 if (!m_caster->IsWithinLOS(x, y, z))
1494 {
1497 finish(false);
1498 return;
1499 }
1500
1501 dest = SpellDestination(x, y, liquidLevel, m_caster->GetOrientation());
1502 break;
1503 }
1505 {
1506 if (!unitCaster)
1507 break;
1508
1509 float distance = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1510 Map* map = unitCaster->GetMap();
1511 uint32 phasemask = unitCaster->GetPhaseMask();
1512 float collisionHeight = unitCaster->GetCollisionHeight();
1513 float destz = 0.0f, startx = 0.0f, starty = 0.0f, startz = 0.0f, starto = 0.0f;
1514
1515 Position pos;
1516 Position lastpos;
1517 unitCaster->GetPosition(startx, starty, startz, starto);
1518 pos.Relocate(startx, starty, startz, starto);
1519 float destx = pos.GetPositionX() + distance * cos(pos.GetOrientation());
1520 float desty = pos.GetPositionY() + distance * sin(pos.GetOrientation());
1521
1522 // Added GROUND_HEIGHT_TOLERANCE to account for cases where, during a jump,
1523 // the Z position may be slightly below the vmap ground level.
1524 // Without this tolerance, a ray trace might incorrectly attempt to find ground
1525 // beneath the actual surface.
1526 //
1527 // Example:
1528 // actual vmap ground: -56.342392
1529 // Z position: -56.347195
1530 float searchGroundZPos = pos.GetPositionZ()+GROUND_HEIGHT_TOLERANCE;
1531 float ground = map->GetHeight(phasemask, pos.GetPositionX(), pos.GetPositionY(), searchGroundZPos);
1532
1533 bool isCasterInWater = unitCaster->IsInWater();
1534 if (!unitCaster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING) || (pos.GetPositionZ() - ground < distance))
1535 {
1536 float tstX = 0.0f, tstY = 0.0f, tstZ = 0.0f, prevX = 0.0f, prevY = 0.0f, prevZ = 0.0f;
1537 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;
1538 float maxtravelDistZ = 2.65f;
1539 float overdistance = 0.0f;
1540 float totalpath = 0.0f;
1541 float beforewaterz = 0.0f;
1542 bool inwater = false;
1543 bool wcol = false;
1544 const float step = 2.0f;
1545 const uint8 numChecks = std::ceil(std::fabs(distance / step));
1546 const float DELTA_X = (destx - pos.GetPositionX()) / numChecks;
1547 const float DELTA_Y = (desty - pos.GetPositionY()) / numChecks;
1548 int j = 1;
1549 for (; j < (numChecks + 1); j++)
1550 {
1551 prevX = pos.GetPositionX() + (float(j - 1) * DELTA_X);
1552 prevY = pos.GetPositionY() + (float(j - 1) * DELTA_Y);
1553 tstX = pos.GetPositionX() + (float(j) * DELTA_X);
1554 tstY = pos.GetPositionY() + (float(j) * DELTA_Y);
1555
1556 if (j < 2)
1557 {
1558 prevZ = pos.GetPositionZ();
1559 }
1560 else
1561 {
1562 prevZ = tstZ;
1563 }
1564
1565 tstZ = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true);
1566 ground = tstZ;
1567
1568 if (!isCasterInWater)
1569 {
1570 if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1571 {
1572 if (!(beforewaterz != 0.0f))
1573 {
1574 beforewaterz = prevZ;
1575 }
1576 tstZ = beforewaterz;
1577 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1578 //LOG_ERROR("spells", "(start was from land) step in water , number of cycle = {} , distance of step = {}, total path = {}, Z = {}", j, srange, totalpath, tstZ);
1579 }
1580 }
1581 else if (map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight))
1582 {
1583 prevZ = pos.GetPositionZ();
1584 tstZ = pos.GetPositionZ();
1585 srange = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX));
1586
1587 inwater = true;
1588 if (inwater && (fabs(tstZ - ground) < 2.0f))
1589 {
1590 wcol = true;
1591 //LOG_ERROR("spells", "step in water with collide and use standart check (for continue way after possible collide), number of cycle = {} ", j);
1592 }
1593
1594 // if (j < 2)
1595 // LOG_ERROR("spells", "(start in water) step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1596 // else
1597 // LOG_ERROR("spells", "step in water, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1598 }
1599
1600 bool IsInWater = map->IsInWater(phasemask, tstX, tstY, tstZ, collisionHeight);
1601 if ((!IsInWater && tstZ != beforewaterz) || wcol) // second safety check z for blink way if on the ground
1602 {
1603 if (inwater && !IsInWater)
1604 inwater = false;
1605
1606 // highest available point
1607 tstZ1 = map->GetHeight(phasemask, tstX, tstY, prevZ + maxtravelDistZ, true, 25.0f);
1608 // upper or floor
1609 tstZ2 = map->GetHeight(phasemask, tstX, tstY, prevZ, true, 25.0f);
1610 //lower than floor
1611 tstZ3 = map->GetHeight(phasemask, tstX, tstY, prevZ - maxtravelDistZ / 2, true, 25.0f);
1612
1613 //distance of rays, will select the shortest in 3D
1614 srange1 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ1 - prevZ) * (tstZ1 - prevZ));
1615 //LOG_ERROR("spells", "step = {}, distance of ray1 = {}", j, srange1);
1616 srange2 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ2 - prevZ) * (tstZ2 - prevZ));
1617 //LOG_ERROR("spells", "step = {}, distance of ray2 = {}", j, srange2);
1618 srange3 = sqrt((tstY - prevY) * (tstY - prevY) + (tstX - prevX) * (tstX - prevX) + (tstZ3 - prevZ) * (tstZ3 - prevZ));
1619 //LOG_ERROR("spells", "step = {}, distance of ray3 = {}", j, srange3);
1620
1621 if (srange1 < srange2)
1622 {
1623 tstZ = tstZ1;
1624 srange = srange1;
1625 }
1626 else if (srange3 < srange2)
1627 {
1628 tstZ = tstZ3;
1629 srange = srange3;
1630 }
1631 else
1632 {
1633 tstZ = tstZ2;
1634 srange = srange2;
1635 }
1636
1637 //LOG_ERROR("spells", "step on ground, number of cycle = {} , distance of step = {}, total path = {}", j, srange, totalpath);
1638 }
1639
1640 destx = tstX;
1641 desty = tstY;
1642 destz = tstZ;
1643
1644 totalpath += srange;
1645
1646 if (totalpath > distance)
1647 {
1648 overdistance = totalpath - distance;
1649 //LOG_ERROR("spells", "total path > than distance in 3D , need to move back a bit for save distance, total path = {}, overdistance = {}", totalpath, overdistance);
1650 }
1651
1652 bool col = unitCaster->GetMap()->GetMapCollisionData().GetStaticTree().GetObjectHitPos(prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1653 // check dynamic collision
1654 bool dcol = unitCaster->GetMap()->GetMapCollisionData().GetDynamicTree().GetObjectHitPos(phasemask, prevX, prevY, prevZ + 0.5f, tstX, tstY, tstZ + 0.5f, tstX, tstY, tstZ, -0.5f);
1655
1656 // collision occured
1657 if (col || dcol || (overdistance > 0.0f && !map->IsInWater(phasemask, tstX, tstY, ground, collisionHeight)) || (fabs(prevZ - tstZ) > maxtravelDistZ && (tstZ > prevZ)))
1658 {
1659 if ((overdistance > 0.0f) && (overdistance < 1.f))
1660 {
1661 destx = prevX + overdistance * cos(pos.GetOrientation());
1662 desty = prevY + overdistance * sin(pos.GetOrientation());
1663 //LOG_ERROR("spells", "(collision) collision occured 1");
1664 }
1665 else
1666 {
1667 // move back a bit
1668 destx = tstX - (0.6 * cos(pos.GetOrientation()));
1669 desty = tstY - (0.6 * sin(pos.GetOrientation()));
1670 //LOG_ERROR("spells", "(collision) collision occured 2");
1671 }
1672
1673 // highest available point
1674 destz1 = map->GetHeight(phasemask, destx, desty, prevZ + maxtravelDistZ, true, 25.0f);
1675 // upper or floor
1676 destz2 = map->GetHeight(phasemask, destx, desty, prevZ, true, 25.0f);
1677 //lower than floor
1678 destz3 = map->GetHeight(phasemask, destx, desty, prevZ - maxtravelDistZ / 2, true, 25.0f);
1679
1680 //distance of rays, will select the shortest in 3D
1681 srange1 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz1 - prevZ) * (destz1 - prevZ));
1682 srange2 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz2 - prevZ) * (destz2 - prevZ));
1683 srange3 = sqrt((desty - prevY) * (desty - prevY) + (destx - prevX) * (destx - prevX) + (destz3 - prevZ) * (destz3 - prevZ));
1684
1685 if (srange1 < srange2)
1686 destz = destz1;
1687 else if (srange3 < srange2)
1688 destz = destz3;
1689 else
1690 destz = destz2;
1691
1692 if (inwater && destz < prevZ && !wcol)
1693 destz = prevZ;
1694 //LOG_ERROR("spells", "(collision) destZ rewrited in prevZ");
1695
1696 // Don't make the player move backward from the xy adjustments by collisions.
1697 if ((DELTA_X > 0 && startx > destx) || (DELTA_X < 0 && startx < destx) ||
1698 (DELTA_Y > 0 && starty > desty) || (DELTA_Y < 0 && starty < desty))
1699 {
1700 destx = startx;
1701 desty = starty;
1702 destz = startz;
1703 }
1704
1705 break;
1706 }
1707 // we have correct destz now
1708 }
1709
1710 lastpos.Relocate(destx, desty, destz, pos.GetOrientation());
1711 dest = SpellDestination(lastpos);
1712 }
1713 else
1714 {
1715 float z = pos.GetPositionZ();
1716 bool col = unitCaster->GetMap()->GetMapCollisionData().GetStaticTree().GetObjectHitPos(pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1717 // check dynamic collision
1718 bool dcol = unitCaster->GetMap()->GetMapCollisionData().GetDynamicTree().GetObjectHitPos(phasemask, pos.GetPositionX(), pos.GetPositionY(), z, destx, desty, z, destx, desty, z, -0.5f);
1719
1720 // collision occured
1721 if (col || dcol)
1722 {
1723 // move back a bit
1724 destx = destx - (0.6 * cos(pos.GetOrientation()));
1725 desty = desty - (0.6 * sin(pos.GetOrientation()));
1726 }
1727
1728 lastpos.Relocate(destx, desty, z, pos.GetOrientation());
1729 dest = SpellDestination(lastpos);
1730 //float range = sqrt((desty - pos.GetPositionY())*(desty - pos.GetPositionY()) + (destx - pos.GetPositionX())*(destx - pos.GetPositionX()));
1731 //LOG_ERROR("spells", "Blink number 2, in falling but at a hight, distance of blink = {}", range);
1732 }
1733 break;
1734 }
1735 default:
1736 {
1737 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1738 float angle = targetType.CalcDirectionAngle();
1739 float objSize = m_caster->GetCombatReach();
1740
1741 switch (targetType.GetTarget())
1742 {
1744 dist = PET_FOLLOW_DIST;
1745 break;
1747 if (dist > objSize)
1748 dist = objSize + (dist - objSize) * float(rand_norm());
1749 break;
1754 {
1755 static float const DefaultTotemDistance = 3.0f;
1756 if (!m_spellInfo->Effects[effIndex].HasRadius())
1757 dist = DefaultTotemDistance;
1758 break;
1759 }
1760 default:
1761 break;
1762 }
1763
1764 if (dist < objSize)
1765 {
1766 dist = objSize;
1767 }
1768
1769 Position pos = dest._position;
1770 m_caster->MovePositionToFirstCollision(pos, dist, angle);
1771
1772 dest.Relocate(pos);
1773 break;
1774 }
1775 }
1776
1777 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1778 m_targets.SetDst(dest);
1779}
#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:1336
float GetHeight(float x, float y, float z, bool checkVMap=true, float maxSearchDist=DEFAULT_HEIGHT_SEARCH) const
Definition Map.cpp:1188
MapCollisionData & GetMapCollisionData()
Definition Map.h:573
bool IsInWater(uint32 phaseMask, float x, float y, float z, float collisionHeight) const
Definition Map.cpp:1615
void CallScriptDestinationTargetSelectHandlers(SpellDestination &target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:9077
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:16764
virtual float GetCollisionHeight() const
Definition Object.h:728
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:2752
virtual float GetCombatReach() const
Definition Object.h:513
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(), WorldObject::GetCollisionHeight(), Unit::GetCollisionHeight(), WorldObject::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(), Object::ToUnit(), and VMAP_INVALID_HEIGHT_VALUE.

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitCasterObjectTargets()

void Spell::SelectImplicitCasterObjectTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType 
)
1855{
1856 WorldObject* target = nullptr;
1857 bool checkIfValid = true;
1858
1859 switch (targetType.GetTarget())
1860 {
1861 case TARGET_UNIT_CASTER:
1862 target = m_caster;
1863 checkIfValid = false;
1864 break;
1865 case TARGET_UNIT_MASTER:
1866 target = m_caster->GetCharmerOrOwnerUnit();
1867 break;
1868 case TARGET_UNIT_PET:
1869 if (Unit* unitCaster = m_caster->ToUnit())
1870 {
1871 target = unitCaster->GetGuardianPet();
1872 if (!target)
1873 target = unitCaster->GetCharm();
1874 }
1875 break;
1877 if (Unit* unitCaster = m_caster->ToUnit())
1878 if (unitCaster->IsSummon())
1879 target = unitCaster->ToTempSummon()->GetSummonerUnit();
1880 break;
1882 if (Unit* unitCaster = m_caster->ToUnit())
1883 target = unitCaster->GetVehicleBase();
1884 break;
1893 if (Unit* unitCaster = m_caster->ToUnit())
1894 if (unitCaster->IsCreature() && unitCaster->ToCreature()->IsVehicle())
1895 target = unitCaster->GetVehicleKit()->GetPassenger(targetType.GetTarget() - TARGET_UNIT_PASSENGER_0);
1896 break;
1897 default:
1898 break;
1899 }
1900
1901 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1902
1903 if (target && target->ToUnit())
1904 AddUnitTarget(target->ToUnit(), 1 << effIndex, checkIfValid);
1905}
@ 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 * GetCharmerOrOwnerUnit() const
Definition Object.cpp:3314

References AddUnitTarget(), CallScriptObjectTargetSelectHandlers(), WorldObject::GetCharmerOrOwnerUnit(), SpellImplicitTargetInfo::GetTarget(), 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, and Object::ToUnit().

Referenced by SelectEffectImplicitTargets().

◆ SelectImplicitChainTargets()

void Spell::SelectImplicitChainTargets ( SpellEffIndex  effIndex,
SpellImplicitTargetInfo const &  targetType,
WorldObject *  target,
uint32  effMask 
)
1930{
1931 uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget;
1932 if (Player* modOwner = m_caster->GetSpellModOwner())
1933 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
1934
1935 if (maxTargets > 1)
1936 {
1937 // mark damage multipliers as used
1938 for (uint32 k = effIndex; k < MAX_SPELL_EFFECTS; ++k)
1939 if (effMask & (1 << k))
1940 m_damageMultipliers[k] = 1.0f;
1941 m_applyMultiplierMask |= effMask;
1942
1943 std::list<WorldObject*> targets;
1944 SearchChainTargets(targets, maxTargets - 1, target, targetType.GetObjectType(), targetType.GetCheckType(), targetType.GetSelectionCategory()
1945 , m_spellInfo->Effects[effIndex].ImplicitTargetConditions, targetType.GetTarget() == TARGET_UNIT_TARGET_CHAINHEAL_ALLY);
1946
1947 // Chain primary target is added earlier
1948 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1949
1950 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1951 if (Unit* unitTarget = (*itr)->ToUnit())
1952 AddUnitTarget(unitTarget, effMask, false);
1953 }
1954}
@ TARGET_UNIT_TARGET_CHAINHEAL_ALLY
Definition SharedDefines.h:1453
@ SPELLMOD_JUMP_TARGETS
Definition SpellDefines.h:101
void SearchChainTargets(std::list< WorldObject * > &targets, uint32 chainTargets, WorldObject *target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellTargetSelectionCategories selectCategory, ConditionList *condList, bool isChainHeal)
Definition Spell.cpp:2204

References AddUnitTarget(), CallScriptObjectAreaTargetSelectHandlers(), SpellInfo::Effects, SpellImplicitTargetInfo::GetCheckType(), SpellImplicitTargetInfo::GetObjectType(), SpellImplicitTargetInfo::GetSelectionCategory(), WorldObject::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 
)
1095{
1096 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1097 {
1098 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target reference type");
1099 return;
1100 }
1101
1102 switch (targetType.GetTarget())
1103 {
1105 {
1106 // Xinef: All channel selectors have needed data passed in m_targets structure
1108 if (target)
1109 {
1110 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1111 // unit target may be no longer avalible - teleported out of map for example
1112 if (target && target->ToUnit())
1113 AddUnitTarget(target->ToUnit(), 1 << effIndex);
1114 }
1115 else
1116 {
1117 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1118 }
1119 break;
1120 }
1125 {
1126 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1127 if (target)
1128 m_targets.SetDst(*target);
1129 }
1131 {
1132 if (channeledSpell->m_targets.GetUnitTarget())
1133 m_targets.SetDst(*channeledSpell->m_targets.GetUnitTarget());
1134 }
1135 else //if (!m_targets.HasDst())
1136 {
1137 LOG_DEBUG("spells.aura", "SPELL: cannot find channel spell destination for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1138 }
1139 break;
1141 if (GetOriginalCaster())
1143 break;
1144 default:
1145 ASSERT(false && "Spell::SelectImplicitChannelTargets: received not implemented target type");
1146 break;
1147 }
1148}
@ 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(WorldObject *caster) const
Definition Spell.cpp:501
SpellDestination const * GetDstChannel() const
Definition Spell.cpp:511
bool HasDstChannel() const
Definition Spell.cpp:506

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 
)
1273{
1274 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1275 {
1276 ASSERT(false && "Spell::SelectImplicitConeTargets: received not implemented target reference type");
1277 return;
1278 }
1279 std::list<WorldObject*> targets;
1280 SpellTargetObjectTypes objectType = targetType.GetObjectType();
1281 SpellTargetCheckTypes selectionType = targetType.GetCheckType();
1282 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1283 float coneAngle = G3D::toRadians(60.0f);
1284 if (SpellCone const* sc = sSpellMgr->GetSpellCone(m_spellInfo->Id))
1285 coneAngle = G3D::toRadians(static_cast<float>(sc->cone_degrees));
1286 else
1287 {
1288 switch (targetType.GetTarget())
1289 {
1291 coneAngle = G3D::toRadians(24.0f);
1292 break;
1294 coneAngle = G3D::toRadians(54.0f);
1295 break;
1297 coneAngle = G3D::toRadians(104.0f);
1298 break;
1299 default:
1300 break;
1301 }
1302 }
1303
1304 float radius = m_spellInfo->Effects[effIndex].CalcRadius(m_caster) * m_spellValue->RadiusMod;
1305
1306 radius += m_caster->GetLeewayBonusRadius();
1307
1308 if (uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList))
1309 {
1310 Acore::WorldObjectSpellConeTargetCheck check(coneAngle, radius, m_caster, m_spellInfo, selectionType, condList);
1311 Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> searcher(m_caster, targets, check, containerTypeMask);
1312 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellConeTargetCheck> >(searcher, containerTypeMask, m_caster, m_caster, radius);
1313
1314 CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
1315
1316 if (!targets.empty())
1317 {
1318 // Other special target selection goes here
1319 if (uint32 maxTargets = m_spellValue->MaxAffectedTargets)
1320 {
1321 if (Unit const* unitCaster = m_caster->ToUnit())
1322 maxTargets += unitCaster->GetTotalAuraModifierByAffectMask(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS, m_spellInfo);
1323 Acore::Containers::RandomResize(targets, maxTargets);
1324 }
1325
1326 for (std::list<WorldObject*>::iterator itr = targets.begin(); itr != targets.end(); ++itr)
1327 {
1328 if (Unit* unit = (*itr)->ToUnit())
1329 {
1330 AddUnitTarget(unit, effMask, false);
1331 }
1332 else if (GameObject* gObjTarget = (*itr)->ToGameObject())
1333 {
1334 AddGOTarget(gObjTarget, effMask);
1335 }
1336 }
1337 }
1338 }
1339}
@ 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(), 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 
)
1819{
1820 // set destination to caster if no dest provided
1821 // can only happen if previous destination target could not be set for some reason
1822 // (not found nearby target, or channel target for example
1823 // maybe we should abort the spell in such case?
1824 CheckDst();
1825
1827
1828 switch (targetType.GetTarget())
1829 {
1833 case TARGET_DEST_DEST:
1834 return;
1835 default:
1836 {
1837 float angle = targetType.CalcDirectionAngle();
1838 float dist = m_spellInfo->Effects[effIndex].CalcRadius(m_caster);
1839 if (targetType.GetTarget() == TARGET_DEST_DEST_RANDOM)
1840 dist *= float(rand_norm());
1841
1842 Position pos = dest._position;
1843 m_caster->MovePosition(pos, dist, angle);
1844
1845 dest.Relocate(pos);
1846 break;
1847 }
1848 }
1849
1850 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1851 m_targets.ModDst(dest);
1852}
@ 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:473
SpellDestination const * GetDst() const
Definition Spell.cpp:433
void MovePosition(Position &pos, float dist, float angle)
Definition Object.cpp:2902

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 
)
1151{
1152 if (targetType.GetReferenceType() != TARGET_REFERENCE_TYPE_CASTER)
1153 {
1154 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target reference type");
1155 return;
1156 }
1157
1158 float range = 0.0f;
1159 switch (targetType.GetCheckType())
1160 {
1161 case TARGET_CHECK_ENEMY:
1162 range = m_spellInfo->GetMaxRange(false, m_caster, this);
1163 break;
1164 case TARGET_CHECK_ALLY:
1165 case TARGET_CHECK_PARTY:
1166 case TARGET_CHECK_RAID:
1168 range = m_spellInfo->GetMaxRange(true, m_caster, this);
1169 break;
1170 case TARGET_CHECK_ENTRY:
1173 break;
1174 default:
1175 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented selection check type");
1176 break;
1177 }
1178
1179 ConditionList* condList = m_spellInfo->Effects[effIndex].ImplicitTargetConditions;
1180
1181 // handle emergency case - try to use other provided targets if no conditions provided
1182 if (targetType.GetCheckType() == TARGET_CHECK_ENTRY && (!condList || condList->empty()))
1183 {
1184 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);
1185 switch (targetType.GetObjectType())
1186 {
1189 {
1190 if (focusObject)
1191 AddGOTarget(focusObject, effMask);
1192 return;
1193 }
1194 break;
1197 {
1198 if (focusObject)
1199 {
1201 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1202 m_targets.SetDst(dest);
1203 }
1204 return;
1205 }
1206 break;
1207 default:
1208 break;
1209 }
1210 }
1211
1212 WorldObject* target = SearchNearbyTarget(range, targetType.GetObjectType(), targetType.GetCheckType(), condList);
1213 if (!target)
1214 {
1215 LOG_DEBUG("spells.aura", "Spell::SelectImplicitNearbyTargets: cannot find nearby target for spell ID {}, effect {}", m_spellInfo->Id, effIndex);
1216 return;
1217 }
1218
1219 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1220 if (!target)
1221 {
1222 //LOG_DEBUG("spells", "Spell::SelectImplicitNearbyTargets: OnObjectTargetSelect script hook for spell Id {} set nullptr target, effect {}", m_spellInfo->Id, effIndex);
1223 return;
1224 }
1225
1226 switch (targetType.GetObjectType())
1227 {
1229 {
1230 if (Unit* unit = target->ToUnit())
1231 {
1232 AddUnitTarget(unit, effMask, true, false);
1233 // xinef: important! if channeling spell have nearby entry, it has no unitTarget by default
1234 // and if channeled spell has target 77, it requires unitTarget, set it here!
1235 // xinef: if we have NO unit target
1236 if (!m_targets.GetUnitTarget())
1237 {
1239 }
1240 }
1241 else
1242 {
1243 //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);
1244 return;
1245 }
1246 break;
1247 }
1249 if (GameObject* gobjTarget = target->ToGameObject())
1250 AddGOTarget(gobjTarget, effMask);
1251 else
1252 {
1253 //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);
1254 return;
1255 }
1256 break;
1258 {
1259 SpellDestination dest(*target);
1260 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1261 m_targets.SetDst(dest);
1262 break;
1263 }
1264 default:
1265 ASSERT(false && "Spell::SelectImplicitNearbyTargets: received not implemented target object type");
1266 break;
1267 }
1268
1269 SelectImplicitChainTargets(effIndex, targetType, target, effMask);
1270}
@ 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:2182
void SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType, WorldObject *target, uint32 effMask)
Definition Spell.cpp:1929

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 
)
1782{
1784
1785 SpellDestination dest(*target);
1786
1787 switch (targetType.GetTarget())
1788 {
1791 break;
1792 default:
1793 {
1794 float angle = targetType.CalcDirectionAngle();
1795 float dist = m_spellInfo->Effects[effIndex].CalcRadius(nullptr);
1796 if (targetType.GetTarget() == TARGET_DEST_TARGET_RANDOM)
1797 {
1798 dist *= float(rand_norm());
1799 }
1800
1801 if (targetType.GetTarget() == TARGET_DEST_TARGET_BACK)
1802 {
1804 }
1805
1806 Position pos = dest._position;
1807 target->MovePositionToFirstCollision(pos, dist, angle);
1808
1809 dest.Relocate(pos);
1810 break;
1811 }
1812 }
1813
1814 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
1815 m_targets.SetDst(dest);
1816}
@ 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 
)
1908{
1909 ASSERT((m_targets.GetObjectTarget() || m_targets.GetItemTarget()) && "Spell::SelectImplicitTargetObjectTargets - no explicit object or item target available!");
1910
1912
1913 CallScriptObjectTargetSelectHandlers(target, effIndex, targetType);
1914
1915 if (target)
1916 {
1917 if (Unit* unit = target->ToUnit())
1918 AddUnitTarget(unit, 1 << effIndex, true, false);
1919 else if (GameObject* gobj = target->ToGameObject())
1920 AddGOTarget(gobj, 1 << effIndex);
1921
1922 SelectImplicitChainTargets(effIndex, targetType, target, 1 << effIndex);
1923 }
1924 // Script hook can remove object target and we would wrongly land here
1925 else if (Item* item = m_targets.GetItemTarget())
1926 AddItemTarget(item, 1 << effIndex);
1927}

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 
)
1971{
1972 if (!m_targets.HasTraj())
1973 return;
1974
1975 float dist2d = m_targets.GetDist2d();
1976 if (!dist2d)
1977 return;
1978
1979 Position srcPos = *m_targets.GetSrcPos();
1981 float srcToDestDelta = m_targets.GetDstPos()->m_positionZ - srcPos.m_positionZ;
1982
1983 std::list<WorldObject*> targets;
1984 Acore::WorldObjectSpellTrajTargetCheck check(dist2d, &srcPos, m_caster, m_spellInfo, targetType.GetCheckType(), m_spellInfo->Effects[effIndex].ImplicitTargetConditions);
1986 SearchTargets<Acore::WorldObjectListSearcher<Acore::WorldObjectSpellTrajTargetCheck> > (searcher, GRID_MAP_TYPE_MASK_ALL, m_caster, &srcPos, dist2d);
1987 if (targets.empty())
1988 return;
1989
1991
1992 float b = tangent(m_targets.GetElevation());
1993 float a = (srcToDestDelta - dist2d * b) / (dist2d * dist2d);
1994 if (a > -0.0001f)
1995 a = 0.f;
1996
1997 // We should check if triggered spell has greater range (which is true in many cases, and initial spell has too short max range)
1998 // limit max range to 300 yards, sometimes triggered spells can have 50000yds
1999 float bestDist = m_spellInfo->GetMaxRange(false);
2000 if (SpellInfo const* triggerSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell))
2001 bestDist = std::min(std::max(bestDist, triggerSpellInfo->GetMaxRange(false)), std::min(dist2d, 300.0f));
2002
2003 // GameObjects don't cast traj
2004 Unit* unitCaster = ASSERT_NOTNULL(m_caster->ToUnit());
2005 for (auto itr = targets.begin(); itr != targets.end(); ++itr)
2006 {
2007 if (m_spellInfo->CheckTarget(unitCaster, *itr, true) != SPELL_CAST_OK)
2008 continue;
2009
2010 if (Unit* unit = (*itr)->ToUnit())
2011 {
2012 if (unitCaster == *itr || unitCaster->IsOnVehicle(unit) || unit->GetVehicle())
2013 continue;
2014
2015 if (Creature* creatureTarget = unit->ToCreature())
2016 {
2017 if (!(creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPE_FLAG_COLLIDE_WITH_MISSILES))
2018 continue;
2019 }
2020 }
2021
2022 float const size = std::max((*itr)->GetCombatReach(), 1.0f);
2023 float const objDist2d = srcPos.GetExactDist2d(*itr);
2024 float const dz = (*itr)->GetPositionZ() - srcPos.m_positionZ;
2025
2026 float const horizontalDistToTraj = std::fabs(objDist2d * std::sin(srcPos.GetRelativeAngle(*itr)));
2027 float const sizeFactor = std::cos((horizontalDistToTraj / size) * (M_PI / 2.0f));
2028 float const distToHitPoint = std::max(objDist2d * std::cos(srcPos.GetRelativeAngle(*itr)) - size * sizeFactor, 0.0f);
2029 float const height = distToHitPoint * (a * distToHitPoint + b);
2030
2031 if (fabs(dz - height) > size + b / 2.0f + TRAJECTORY_MISSILE_SIZE)
2032 continue;
2033
2034 if (distToHitPoint < bestDist)
2035 {
2036 bestDist = distToHitPoint;
2037 break;
2038 }
2039 }
2040
2041 if (dist2d > bestDist)
2042 {
2043 float x = m_targets.GetSrcPos()->m_positionX + std::cos(unitCaster->GetOrientation()) * bestDist;
2044 float y = m_targets.GetSrcPos()->m_positionY + std::sin(unitCaster->GetOrientation()) * bestDist;
2045 float z = m_targets.GetSrcPos()->m_positionZ + bestDist * (a * bestDist + b);
2046
2047 SpellDestination dest(x, y, z, unitCaster->GetOrientation());
2048 CallScriptDestinationTargetSelectHandlers(dest, effIndex, targetType);
2049 m_targets.ModDst(dest);
2050 }
2051}
#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:1956
#define TRAJECTORY_MISSILE_SIZE
Definition Spell.h:51
Definition Object.h:860
float GetElevation() const
Definition Spell.h:180
bool IsOnVehicle(Unit const *vehicle) const
Definition Unit.h:1933
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 ( )
870{
871 // select targets for cast phase
873
874 uint32 processedAreaEffectsMask = 0;
875 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
876 {
877 // not call for empty effect.
878 // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
879 if (!m_spellInfo->Effects[i].IsEffect())
880 continue;
881
882 // set expected type of implicit targets to be sent to client
883 uint32 implicitTargetMask = GetTargetFlagMask(m_spellInfo->Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(m_spellInfo->Effects[i].TargetB.GetObjectType());
884 if (implicitTargetMask & TARGET_FLAG_UNIT)
886 if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM))
888
889 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetA, processedAreaEffectsMask);
890 SelectEffectImplicitTargets(SpellEffIndex(i), m_spellInfo->Effects[i].TargetB, processedAreaEffectsMask);
891
892 // Select targets of effect based on effect type
893 // those are used when no valid target could be added for spell effect based on spell target type
894 // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL)
895 // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON)
896 // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS)
898
899 if (m_targets.HasDst())
901
903 {
904 // maybe do this for all spells?
905 if (!focusObject && m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty() && m_UniqueItemInfo.empty() && !m_targets.HasDst())
906 {
908 finish(false);
909 return;
910 }
911
912 uint8 mask = (1 << i);
913 for (auto ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
914 {
915 if (ihit->effectMask & mask)
916 {
918 break;
919 }
920 }
921 }
922 else if (m_auraScaleMask)
923 {
924 bool checkLvl = !m_UniqueTargetInfo.empty();
925 m_UniqueTargetInfo.erase(std::remove_if(std::begin(m_UniqueTargetInfo), std::end(m_UniqueTargetInfo), [&](TargetInfo const& targetInfo) -> bool
926 {
927 // remove targets which did not pass min level check
928 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask)
929 {
930 if (!targetInfo.scaleAura && targetInfo.targetGUID != m_caster->GetGUID())
931 return true;
932 }
933
934 return false;
935 }), std::end(m_UniqueTargetInfo));
936
937 if (checkLvl && m_UniqueTargetInfo.empty())
938 {
940 finish(false);
941 }
942 }
943 }
944
945 if (uint64 dstDelay = CalculateDelayMomentForDst())
946 m_delayMoment = dstDelay;
947}
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:976
void SelectExplicitTargets()
Definition Spell.cpp:836
void AddDestTarget(SpellDestination const &dest, uint32 effIndex)
Definition Spell.cpp:2622
void SelectEffectTypeImplicitTargets(uint8 effIndex)
Definition Spell.cpp:2053

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
4810{
4811 if (result == SPELL_CAST_OK)
4812 return;
4813
4814 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4815 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4816
4817 caster->SendDirectMessage(&data);
4818}
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition Spell.cpp:4704
@ 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)
4821{
4822 Unit* unitCaster = m_caster->ToUnit();
4823 if (!unitCaster)
4824 return;
4825
4826 if (result == SPELL_CAST_OK)
4827 return;
4828
4829 if (!unitCaster->IsPlayer() || unitCaster->IsCharmed())
4830 return;
4831
4832 if (unitCaster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4833 return;
4834
4835 // 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
4837 result = SPELL_FAILED_DONT_REPORT;
4838
4840}
@ SPELL_FAILED_BM_OR_INVISGOD
Definition SharedDefines.h:1096
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Disallows proc events from triggered spell (default)
Definition SpellDefines.h:157
bool IsCharmed() const
Definition Unit.h:1315

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(), Object::ToUnit(), and TRIGGERED_DONT_REPORT_CAST_ERROR.

◆ SendChannelStart()

void Spell::SendChannelStart ( uint32  duration)
5362{
5363 Unit* unitCaster = m_caster->ToUnit();
5364 if (!unitCaster)
5365 return;
5366
5367 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5368 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5369 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5370 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5371
5372 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5373 data << m_caster->GetPackGUID();
5374 data << uint32(m_spellInfo->Id);
5375 data << uint32(duration);
5376
5377 m_caster->SendMessageToSet(&data, true);
5378
5379 if (unitCaster->IsPlayer() && unitCaster->ToPlayer()->NeedSendSpectatorData())
5380 ArenaSpectator::SendCommand_Spell(unitCaster->FindMap(), unitCaster->GetGUID(), "SPE", m_spellInfo->Id, -((int32)duration));
5381
5382 m_timer = duration;
5383 if (channelTarget)
5384 unitCaster->SetGuidValue(UNIT_FIELD_CHANNEL_OBJECT, channelTarget);
5385
5387}
@ 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(), Object::ToUnit(), UNIT_CHANNEL_SPELL, and UNIT_FIELD_CHANNEL_OBJECT.

Referenced by handle_immediate().

◆ SendChannelUpdate()

void Spell::SendChannelUpdate ( uint32  time)
5343{
5344 Unit* unitCaster = m_caster->ToUnit();
5345 if (!unitCaster)
5346 return;
5347
5348 if (time == 0)
5349 {
5351 unitCaster->SetUInt32Value(UNIT_CHANNEL_SPELL, 0);
5352 }
5353
5354 WorldPacket data(MSG_CHANNEL_UPDATE, 8 + 4);
5355 data << m_caster->GetPackGUID();
5356 data << uint32(time);
5357
5358 m_caster->SendMessageToSet(&data, true);
5359}
@ MSG_CHANNEL_UPDATE
Definition Opcodes.h:344

References ObjectGuid::Empty, Object::GetPackGUID(), m_caster, MSG_CHANNEL_UPDATE, WorldObject::SendMessageToSet(), Object::SetGuidValue(), Unit::SetUInt32Value(), Object::ToUnit(), UNIT_CHANNEL_SPELL, and UNIT_FIELD_CHANNEL_OBJECT.

Referenced by cancel(), DelayedChannel(), Unit::FinishSpell(), prepare(), SelectImplicitCasterDestTargets(), and update().

◆ SendInterrupted()

void Spell::SendInterrupted ( uint8  result)
5326{
5327 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5328 data << m_caster->GetPackGUID();
5329 data << uint8(m_cast_count);
5330 data << uint32(m_spellInfo->Id);
5331 data << uint8(result);
5332 m_caster->SendMessageToSet(&data, true);
5333
5334 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5335 data << m_caster->GetPackGUID();
5336 data << uint8(m_cast_count);
5337 data << uint32(m_spellInfo->Id);
5338 data << uint8(result);
5339 m_caster->SendMessageToSet(&data, true);
5340}
@ 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 ( )
5225{
5226 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5227
5228 data << m_caster->GetPackGUID();
5229
5230 data << uint32(m_spellInfo->Id);
5231
5232 uint8 effCount = 0;
5233 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5234 {
5235 if (m_effectExecuteData[i])
5236 ++effCount;
5237 }
5238
5239 if (!effCount)
5240 return;
5241
5242 data << uint32(effCount);
5243 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5244 {
5245 if (!m_effectExecuteData[i])
5246 continue;
5247
5248 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5249
5250 data.append(*m_effectExecuteData[i]);
5251
5252 delete m_effectExecuteData[i];
5253 m_effectExecuteData[i] = nullptr;
5254 }
5255 m_caster->SendMessageToSet(&data, true);
5256}
@ 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
2137{
2138 Unit* unitCaster = m_caster->ToUnit();
2139 if (!unitCaster)
2140 return;
2141
2142 Player* player = unitCaster->ToPlayer();
2143 if (!player)
2144 return;
2145
2146 if (gameObjTarget)
2147 {
2148 // Players shouldn't be able to loot gameobjects that are currently despawned
2149 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2150 {
2151 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2152 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2153 return;
2154 }
2155 // special case, already has GossipHello inside so return and avoid calling twice
2157 {
2158 gameObjTarget->Use(unitCaster);
2159 return;
2160 }
2161
2162 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2163 return;
2164
2165 if (gameObjTarget->AI()->GossipHello(player, false))
2166 return;
2167
2168 switch (gameObjTarget->GetGoType())
2169 {
2171 gameObjTarget->UseDoorOrButton(0, false, player);
2172 return;
2174 gameObjTarget->UseDoorOrButton(0, false, player);
2175
2176 // Xinef: properly link possible traps
2177 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2178 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2179 return;
2183 return;
2184
2186 // triggering linked GO
2188 gameObjTarget->TriggeringLinkedGameObject(trapEntry, unitCaster);
2189 return;
2190
2191 // Don't return, let loots been taken
2192 default:
2193 break;
2194 }
2195 }
2196
2197 // Send loot
2198 player->SendLoot(guid, loottype);
2199}
@ 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:191
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition GameObject.cpp:1385
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

References GameObject::AI(), GameObjectTemplate::button, GAMEOBJECT_TYPE_BUTTON, 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(), Object::ToUnit(), GameObject::TriggeringLinkedGameObject(), GameObject::Use(), and GameObject::UseDoorOrButton().

Referenced by EffectOpenLock().

◆ SendPetCastResult()

void Spell::SendPetCastResult ( SpellCastResult  result)
4843{
4844 Unit* unitCaster = m_caster->ToUnit();
4845 if (!unitCaster)
4846 return;
4847
4848 if (result == SPELL_CAST_OK)
4849 return;
4850
4851 Unit* owner = unitCaster->GetCharmerOrOwner();
4852 if (!owner)
4853 return;
4854
4855 Player* player = owner->ToPlayer();
4856 if (!player)
4857 return;
4858
4859 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4861
4862 player->SendDirectMessage(&data);
4863}
@ 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(), Object::ToUnit(), and WriteCastResultInfo().

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

◆ SendResurrectRequest()

void Spell::SendResurrectRequest ( Player *  target)
5390{
5391 Unit* unitCaster = m_caster->ToUnit();
5392 if (!unitCaster)
5393 return;
5394
5395 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5396 // for player resurrections the name is looked up by guid
5397 std::string const sentName(unitCaster->IsPlayer()
5398 ? ""
5399 : unitCaster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()));
5400
5401 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5402 data << unitCaster->GetGUID();
5403 data << uint32(sentName.size() + 1);
5404
5405 data << sentName;
5406 data << uint8(0); // null terminator
5407
5408 data << uint8(unitCaster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5409 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5411 data << uint32(0);
5412 target->SendDirectMessage(&data);
5413}
@ 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, SPELL_ATTR3_NO_RES_TIMER, and Object::ToUnit().

Referenced by EffectResurrect(), and EffectResurrectNew().

◆ SendSpellCooldown()

void Spell::SendSpellCooldown ( )
4476{
4477 Unit* unitCaster = m_caster->ToUnit();
4478 if (!unitCaster)
4479 return;
4480
4481 // xinef: properly add creature cooldowns
4482 if (!unitCaster->IsPlayer())
4483 {
4485 {
4486 // xinef: this should be added here
4487 //unitCaster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4488
4489 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4491 if (Player* player = unitCaster->GetCharmerOrOwnerPlayerOrPlayerItself())
4492 {
4493 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4494 data << unitCaster->GetGUID();
4496 data << uint32(m_spellInfo->Id);
4498 player->SendDirectMessage(&data);
4499 }
4500 }
4501 return;
4502 }
4503
4504 Player* _player = unitCaster->ToPlayer();
4505
4506 // mana/health/etc potions, disabled by client (until combat out as declarate)
4508 {
4509 // need in some way provided data for Spell::finish SendCooldownEvent
4510 _player->SetLastPotionId(m_CastItem->GetEntry());
4511 return;
4512 }
4513
4514 // have infinity cooldown but set at aura apply
4515 // do not set cooldown for triggered spells (needed by reincarnation)
4520 return;
4521
4523}
@ 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:1840
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition Player.cpp:11089
uint32 RecoveryTime
Definition SpellInfo.h:372
bool RequireCooldownInfo() const
Definition SpellInfo.cpp:1227
@ 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(), Object::ToUnit(), TRIGGERED_IGNORE_EFFECTS, and TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD.

Referenced by _cast().

◆ SendSpellGo()

void Spell::SendSpellGo ( )
4947{
4948 Unit* unitCaster = m_caster->ToUnit();
4949 // not send invisible spell casting
4950 if (!IsNeedSendToClient(true))
4951 return;
4952
4953 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4954
4955 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4956
4957 // triggered spells with spell visual != 0
4959 castFlags |= CAST_FLAG_PENDING;
4960
4962 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4963
4964 // should only be sent to self, but the current messaging doesn't make that possible
4965 if (unitCaster && (unitCaster->IsPlayer() || unitCaster->IsPet()))
4966 {
4967 switch (m_spellInfo->PowerType)
4968 {
4969 case POWER_HEALTH:
4970 break;
4971 case POWER_RUNE:
4972 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4973 break;
4974 default:
4975 if (m_powerCost != 0)
4976 {
4977 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4978 }
4979 break;
4980 }
4981 }
4982
4983 if (unitCaster && (unitCaster->IsPlayer())
4987 {
4988 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4989 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4990 }
4991
4993 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
4994
4995 if (m_targets.HasTraj())
4996 castFlags |= CAST_FLAG_ADJUST_MISSILE;
4997
4999 castFlags |= CAST_FLAG_NO_GCD;
5000
5001 PackedGuid realCasterGUID = m_caster->GetPackGUID();
5002 if (TempSummon const* tempSummon = unitCaster ? unitCaster->ToTempSummon() : nullptr)
5003 {
5004 if (tempSummon->GetEntry() == WORLD_TRIGGER)
5005 {
5006 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
5007 {
5008 realCasterGUID = casterGameobject->GetPackGUID();
5009 }
5010 }
5011 }
5012
5013 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
5014
5015 if (m_CastItem)
5016 data << m_CastItem->GetPackGUID();
5017 else
5018 data << realCasterGUID;
5019
5020 data << realCasterGUID;
5021 data << uint8(m_cast_count); // pending spell cast?
5022 data << uint32(m_spellInfo->Id); // spellId
5023 data << uint32(castFlags); // cast flags
5024 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
5025
5026 WriteSpellGoTargets(&data);
5027
5028 m_targets.Write(data);
5029
5030 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
5031 data << uint32(unitCaster ? unitCaster->GetPower((Powers)m_spellInfo->PowerType) : 0);
5032
5033 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
5034 {
5035 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
5036 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
5037 if (Player* player = unitCaster ? unitCaster->ToPlayer() : nullptr)
5038 {
5039 uint8 runeMaskInitial = m_runesState;
5040 uint8 runeMaskAfterCast = player->GetRunesState();
5041 data << uint8(runeMaskInitial); // runes state before
5042 data << uint8(runeMaskAfterCast); // runes state after
5043 for (uint8 i = 0; i < MAX_RUNES; ++i)
5044 {
5045 uint8 mask = (1 << i);
5046 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
5047 {
5048 // float casts ensure the division is performed on floats as we need float result
5049 float baseCd = float(player->GetRuneBaseCooldown(i, true));
5050 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
5051 }
5052 }
5053 }
5054 }
5055 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
5056 {
5057 data << m_targets.GetElevation();
5059 }
5060
5061 if (castFlags & CAST_FLAG_PROJECTILE)
5062 WriteAmmoToPacket(&data);
5063
5064 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
5065 {
5066 data << uint32(0);
5067 data << uint32(0);
5068 }
5069
5071 {
5072 data << uint8(0);
5073 }
5074
5075 m_caster->SendMessageToSet(&data, true);
5076}
@ 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:216
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:5164
void WriteAmmoToPacket(WorldPacket *data)
Definition Spell.cpp:5078
bool IsNeedSendToClient(bool go) const
Definition Spell.cpp:8434
@ SMSG_SPELL_GO
Definition Opcodes.h:336
int32 CastTime
Definition DBCStructure.h:1796

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(), Object::ToUnit(), WORLD_TRIGGER, SpellCastTargets::Write(), WriteAmmoToPacket(), and WriteSpellGoTargets().

Referenced by _cast().

◆ SendSpellStart()

void Spell::SendSpellStart ( )
4866{
4867 Unit* unitCaster = m_caster->ToUnit();
4868 if (!IsNeedSendToClient(false))
4869 return;
4870
4871 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4872
4873 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4874
4876 castFlags |= CAST_FLAG_PENDING;
4877
4879 castFlags |= CAST_FLAG_PROJECTILE;
4880
4881 if (unitCaster && (unitCaster->IsPlayer() || unitCaster->IsPet()))
4882 {
4883 switch (m_spellInfo->PowerType)
4884 {
4885 case POWER_HEALTH:
4886 break;
4887 case POWER_RUNE:
4888 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4889 break;
4890 default:
4891 if (m_powerCost != 0)
4892 {
4893 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4894 }
4895 break;
4896 }
4897 }
4898
4900 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4901
4902 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4903 if (TempSummon const* tempSummon = unitCaster ? unitCaster->ToTempSummon() : nullptr)
4904 {
4905 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4906 {
4907 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4908 {
4909 realCasterGUID = casterGameobject->GetPackGUID();
4910 }
4911 }
4912 }
4913
4914 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4915 if (m_CastItem)
4916 data << m_CastItem->GetPackGUID();
4917 else
4918 data << realCasterGUID;
4919
4920 data << realCasterGUID;
4921 data << uint8(m_cast_count); // pending spell cast?
4922 data << uint32(m_spellInfo->Id); // spellId
4923 data << uint32(castFlags); // cast flags
4924 data << int32(m_timer); // delay?
4925
4926 m_targets.Write(data);
4927
4928 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4929 data << uint32(unitCaster ? unitCaster->GetPower((Powers)m_spellInfo->PowerType) : 0);
4930
4931 if (castFlags & CAST_FLAG_PROJECTILE)
4932 WriteAmmoToPacket(&data);
4933
4934 if (castFlags & CAST_FLAG_UNKNOWN_23)
4935 {
4936 data << uint32(0);
4937 data << uint32(0);
4938 }
4939
4940 m_caster->SendMessageToSet(&data, true);
4941
4942 if (!m_spellInfo->IsChanneled() && unitCaster && unitCaster->IsPlayer() && unitCaster->ToPlayer()->NeedSendSpectatorData())
4943 ArenaSpectator::SendCommand_Spell(unitCaster->FindMap(), unitCaster->GetGUID(), "SPE", m_spellInfo->Id, m_timer);
4944}
@ 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(), Object::ToUnit(), 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 
)
8804{
8805 switch (mod)
8806 {
8808 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8809 break;
8811 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8812 break;
8814 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8815 break;
8817 m_spellValue->RadiusMod = (float)value / 10000;
8818 break;
8821 break;
8824 break;
8826 m_spellValue->AuraDuration = value;
8827 break;
8829 m_spellValue->ForcedCritResult = (bool)value;
8830 break;
8832 m_spellValue->MiscVal[0] = value;
8833 break;
8835 m_spellValue->MiscVal[1] = value;
8836 break;
8838 m_spellValue->MiscVal[2] = value;
8839 break;
8840 }
8841}
@ SPELLVALUE_AURA_STACK
Definition SpellDefines.h:126
@ SPELLVALUE_MISCVALUE1
Definition SpellDefines.h:130
@ SPELLVALUE_AURA_DURATION
Definition SpellDefines.h:127
@ SPELLVALUE_MISCVALUE2
Definition SpellDefines.h:131
@ SPELLVALUE_RADIUS_MOD
Definition SpellDefines.h:124
@ SPELLVALUE_MAX_TARGETS
Definition SpellDefines.h:125
@ SPELLVALUE_FORCED_CRIT_RESULT
Definition SpellDefines.h:128
@ SPELLVALUE_MISCVALUE0
Definition SpellDefines.h:129
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(), WorldObject::CastSpell(), 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
6285{
6286 Unit* unitCaster = GetUnitCasterForEffectHandlers();
6287 Unit* caster = m_originalCaster;
6288 if (!caster)
6289 return;
6290
6291 if (caster->IsTotem())
6292 caster = caster->ToTotem()->GetOwner();
6293 else if (caster->IsPet())
6294 if (Unit* owner = caster->GetOwner())
6295 caster = owner;
6296
6297 // in another case summon new
6298 uint8 summonLevel = caster->GetLevel();
6299
6300 // level of pet summoned using engineering item based at engineering skill level
6301 if (m_CastItem && caster->IsPlayer())
6302 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
6303 {
6304 // xinef: few special cases
6305 if (proto->RequiredSkill == SKILL_ENGINEERING)
6306 {
6307 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
6308 summonLevel = skill202 / 5;
6309 }
6310
6311 switch (m_spellInfo->Id)
6312 {
6313 // Target dummies use RequiredSkillRank/5, not player's current skill
6314 case 4071: // Target Dummy
6315 case 4072: // Advanced Target Dummy
6316 case 19805: // Masterwork Target Dummy
6317 summonLevel = proto->RequiredSkillRank / 5;
6318 break;
6319
6320 // Dragon's Call
6321 case 13049:
6322 summonLevel = 55;
6323 break;
6324
6325 // Cleansed Timberling Heart: Summon Timberling
6326 case 5666:
6327 summonLevel = 7;
6328 break;
6329
6330 // Glowing Cat Figurine: Summon Ghost Saber
6331 case 6084:
6332 // minLevel 19, maxLevel 20
6333 summonLevel = 20;
6334 break;
6335
6336 // Spiked Collar: Summon Felhunter
6337 case 8176:
6338 summonLevel = 30;
6339 break;
6340
6341 // Dog Whistle: Summon Tracking Hound
6342 case 9515:
6343 summonLevel = 30;
6344 break;
6345
6346 // Barov Peasant Caller: Death by Peasant
6347 case 18307:
6348 case 18308:
6349 summonLevel = 60;
6350 break;
6351
6352 // Thornling Seed: Plant Thornling
6353 case 22792:
6354 summonLevel = 60;
6355 break;
6356
6357 // Cannonball Runner: Summon Crimson Cannon
6358 case 6251:
6359 summonLevel = 61;
6360 break;
6361 }
6362 }
6363
6364 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6365
6366 float radius = 5.0f;
6367 int32 duration = m_spellInfo->GetDuration();
6368
6369 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6370 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6371
6372 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6373 Map* map = caster->GetMap();
6374 TempSummon* summon = nullptr;
6375
6376 uint32 currMinionsCount = unitCaster->m_Controlled.size();
6377 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6378
6379 for (uint32 count = 0; count < numGuardians; ++count)
6380 {
6381 Position pos;
6382
6383 // xinef: do not use precalculated position for effect summon pet in this function
6384 // it means it was cast by NPC and should have its position overridden unless the
6385 // target position is specified in the DB AND the effect has no or zero radius
6386 if ((totalNumGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6387 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6388 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6389 {
6390 pos = *destTarget;
6391 }
6392 else
6393 {
6394 // randomize position
6395 pos = unitCaster->GetRandomPoint(*destTarget, radius);
6396 }
6397
6398 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6399 if (!summon)
6400 return;
6401
6402 // xinef: set calculated level
6403 summon->SetLevel(summonLevel);
6404
6405 // if summonLevel changed, set stats for calculated level
6406 if (summonLevel != caster->GetLevel())
6407 {
6408 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6409 }
6410
6411 // xinef: if we have more than one guardian, change follow angle
6412 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6413 ((Minion*)summon)->SetFollowAngle(unitCaster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6414 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6415 // ((Minion*)summon)->SetFollowAngle(unitCaster->GetAngle(summon));
6416
6417 // xinef: move this here, some auras are added in initstatsforlevel!
6418 if (!summon->IsInCombat() && !summon->IsTrigger())
6419 {
6420 // summon->AI()->EnterEvadeMode();
6421 summon->GetMotionMaster()->Clear(false);
6423 }
6424
6425 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6426 summon->SetFaction(caster->GetFaction());
6427
6429 }
6430}
@ SKILL_ENGINEERING
Definition SharedDefines.h:3156
@ CONFIG_MAX_PLAYER_LEVEL
Definition WorldConfig.h:194
@ 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:11932
virtual float GetFollowAngle() const
Definition Unit.h:1901

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(), GetUnitCasterForEffectHandlers(), Unit::HasUnitTypeMask(), SpellInfo::Id, Unit::IsInCombat(), Unit::IsPet(), Object::IsPlayer(), Unit::IsTotem(), Creature::IsTrigger(), 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 ( )
5551{
5552 Unit* unitCaster = m_caster->ToUnit();
5553 if (!unitCaster)
5554 return;
5555
5557 {
5558 Item* pItem = unitCaster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK);
5559
5560 // wands don't have ammo
5561 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5562 return;
5563
5564 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5565 {
5566 if (pItem->GetMaxStackCount() == 1)
5567 {
5568 // decrease durability for non-stackable throw weapon
5570 }
5571 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5572 {
5573 // decrease items amount for stackable throw weapon
5574 uint32 count = 1;
5575 unitCaster->ToPlayer()->DestroyItemCount(pItem, count, true);
5576 }
5577 }
5578 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5579 if (uint32 ammo = unitCaster->ToPlayer()->GetUInt32Value(PLAYER_AMMO_ID))
5580 unitCaster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5581 }
5582}
@ 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:4904

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, Object::ToPlayer(), and Object::ToUnit().

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

◆ TakeCastItem()

void Spell::TakeCastItem ( )
5416{
5417 Unit* unitCaster = m_caster->ToUnit();
5418 if (!unitCaster)
5419 return;
5420
5421 if (!m_CastItem || !unitCaster->IsPlayer())
5422 return;
5423
5424 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5426 return;
5427
5428 ItemTemplate const* proto = m_CastItem->GetTemplate();
5429
5430 if (!proto)
5431 {
5432 // This code is to avoid a crash
5433 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5434 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5435 return;
5436 }
5437
5438 bool expendable = false;
5439 bool withoutCharges = false;
5440
5441 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5442 {
5443 if (proto->Spells[i].SpellId)
5444 {
5445 // item has limited charges
5446 if (proto->Spells[i].SpellCharges)
5447 {
5448 if (proto->Spells[i].SpellCharges < 0)
5449 expendable = true;
5450
5451 int32 charges = m_CastItem->GetSpellCharges(i);
5452
5453 // item has charges left
5454 if (charges)
5455 {
5456 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5457 if (proto->Stackable == 1)
5458 m_CastItem->SetSpellCharges(i, charges);
5459 m_CastItem->SetState(ITEM_CHANGED, unitCaster->ToPlayer());
5460 }
5461
5462 // all charges used
5463 withoutCharges = (charges == 0);
5464 }
5465 }
5466 }
5467
5468 if (expendable && withoutCharges)
5469 {
5470 uint32 count = 1;
5471 unitCaster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5472
5473 // prevent crash at access to deleted m_targets.GetItemTarget
5475 m_targets.SetItemTarget(nullptr);
5476
5477 m_CastItem = nullptr;
5479 }
5480}
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(), Object::ToUnit(), and TRIGGERED_IGNORE_CAST_ITEM.

Referenced by _cast(), and handle_immediate().

◆ TakePower()

void Spell::TakePower ( )
5483{
5484 Unit* unitCaster = m_caster->ToUnit();
5485 if (!unitCaster)
5486 return;
5487
5489 return;
5490
5491 //Don't take power if the spell is cast while .cheat power is enabled.
5492 if (unitCaster->IsPlayer())
5493 if (unitCaster->ToPlayer()->GetCommandStatus(CHEAT_POWER))
5494 return;
5495
5497 bool hit = true;
5498 if (unitCaster->IsPlayer())
5499 {
5501 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5502 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5503 if (ihit->targetGUID == targetGUID)
5504 {
5505 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5506 {
5507 hit = false;
5508 //lower spell cost on fail (by talent aura)
5509 if (Player* modOwner = unitCaster->ToPlayer()->GetSpellModOwner())
5510 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5511 }
5512 break;
5513 }
5514 }
5515
5516 if (PowerType == POWER_RUNE)
5517 {
5518 TakeRunePower(hit);
5519 return;
5520 }
5521
5522 if (!m_powerCost)
5523 return;
5524
5525 // health as power used
5526 if (PowerType == POWER_HEALTH)
5527 {
5528 unitCaster->ModifyHealth(-(int32)m_powerCost);
5529 return;
5530 }
5531
5532 if (PowerType >= MAX_POWERS)
5533 {
5534 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5535 return;
5536 }
5537
5538 if (hit)
5539 unitCaster->ModifyPower(PowerType, -m_powerCost);
5540 else
5541 unitCaster->ModifyPower(PowerType, -irand(0, m_powerCost / 4));
5542
5543 // Set the five second timer
5544 if (PowerType == POWER_MANA && m_powerCost > 0)
5545 {
5546 unitCaster->SetLastManaUse(GameTime::GetGameTimeMS().count());
5547 }
5548}
@ SPELL_MISS_ABSORB
Definition SharedDefines.h:1533
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition SpellDefines.h:114
void TakeRunePower(bool didHit)
Definition Spell.cpp:5642
int32 ModifyHealth(int32 val)
Definition Unit.cpp:10722
void SetLastManaUse(uint32 spellCastTime)
Definition Unit.h:1157

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(), Object::ToPlayer(), and Object::ToUnit().

Referenced by _cast().

◆ TakeReagents()

void Spell::TakeReagents ( )
5716{
5717 Unit* unitCaster = m_caster->ToUnit();
5718 if (!unitCaster)
5719 return;
5720
5721 if (!unitCaster->IsPlayer())
5722 return;
5723
5724 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5725
5726 // do not take reagents for these item casts
5727 if (castItemTemplate && castItemTemplate->HasFlag(ITEM_FLAG_NO_REAGENT_COST))
5728 return;
5729
5730 Player* p_caster = unitCaster->ToPlayer();
5731 if (p_caster->CanNoReagentCast(m_spellInfo))
5732 return;
5733
5734 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5735 {
5736 if (m_spellInfo->Reagent[x] <= 0)
5737 continue;
5738
5739 uint32 itemid = m_spellInfo->Reagent[x];
5740 uint32 itemcount = m_spellInfo->ReagentCount[x];
5741
5742 // if CastItem is also spell reagent
5743 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5744 {
5745 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5746 {
5747 // CastItem will be used up and does not count as reagent
5748 int32 charges = m_CastItem->GetSpellCharges(s);
5749 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5750 {
5751 ++itemcount;
5752 break;
5753 }
5754 }
5755
5756 m_CastItem = nullptr;
5758 }
5759
5760 // if GetItemTarget is also spell reagent
5761 if (m_targets.GetItemTargetEntry() == itemid)
5762 m_targets.SetItemTarget(nullptr);
5763
5764 p_caster->DestroyItemCount(itemid, itemcount, true);
5765 }
5766}
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, Object::ToPlayer(), and Object::ToUnit().

Referenced by _cast().

◆ TakeRunePower()

void Spell::TakeRunePower ( bool  didHit)
5643{
5644 Unit* unitCaster = m_caster->ToUnit();
5645 if (!unitCaster)
5646 return;
5647
5648 if (!unitCaster->IsPlayer() || !unitCaster->IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_ABILITY))
5649 return;
5650
5651 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5652 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5653 return;
5654
5655 Player* player = unitCaster->ToPlayer();
5656 m_runesState = player->GetRunesState(); // store previous state
5657
5658 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5659
5660 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5661 {
5662 runeCost[i] = runeCostData->RuneCost[i];
5663 if (Player* modOwner = unitCaster->GetSpellModOwner())
5664 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5665 }
5666
5667 runeCost[RUNE_DEATH] = 0; // calculated later
5668
5669 for (uint32 i = 0; i < MAX_RUNES; ++i)
5670 {
5671 RuneType rune = player->GetCurrentRune(i);
5672 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5673 {
5674 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5675 player->SetLastUsedRune(rune);
5676 runeCost[rune]--;
5677 }
5678 }
5679
5680 // Xinef: firstly consume death runes of base type
5681 // Xinef: in second loop consume all available
5682 for (uint8 loop = 0; loop < 2; ++loop)
5683 {
5684 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5685 if (runeCost[RUNE_DEATH] > 0)
5686 {
5687 for (uint8 i = 0; i < MAX_RUNES; ++i)
5688 {
5689 RuneType rune = player->GetCurrentRune(i);
5690 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5691 {
5692 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5693 player->SetLastUsedRune(rune);
5694 runeCost[rune]--;
5695 if (!loop)
5696 runeCost[player->GetBaseRune(i)]--;
5697
5698 // keep Death Rune type if missed
5699 if (didHit)
5700 player->RestoreBaseRune(i);
5701
5702 if (runeCost[RUNE_DEATH] == 0)
5703 break;
5704 }
5705 }
5706 }
5707 }
5708
5709 // you can gain some runic power when use runes
5710 if (didHit)
5711 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5712 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5713}
@ 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:407
void SetLastUsedRune(RuneType type)
Definition Player.h:2562
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition Player.cpp:13706
void RestoreBaseRune(uint8 index)
Definition Player.cpp:13735
bool NoRunicPowerGain() const
Definition DBCStructure.h:1847
uint32 runePowerGain
Definition DBCStructure.h:1844

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, Object::ToPlayer(), and Object::ToUnit().

Referenced by TakePower().

◆ TriggerGlobalCooldown()

void Spell::TriggerGlobalCooldown ( )
protected
9229{
9230 Unit* unitCaster = m_caster->ToUnit();
9231 if (!unitCaster)
9232 return;
9233
9235 if (!gcd)
9236 {
9237 // Xinef: fix for charmed pet spells with no cooldown info
9238 if (m_spellInfo->RecoveryTime == 0 && m_spellInfo->CategoryRecoveryTime == 0 && unitCaster->GetCharmInfo())
9239 gcd = MIN_GCD;
9240 else
9241 return;
9242 }
9243
9244 if (unitCaster->IsPlayer())
9245 if (unitCaster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN))
9246 return;
9247
9248 // Global cooldown can't leave range 1..1.5 secs
9249 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
9250 // but as tests show are not affected by any spell mods.
9252 {
9253 // gcd modifier auras are applied only to own spells and only players have such mods
9254 if (unitCaster->IsPlayer())
9255 unitCaster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_GLOBAL_COOLDOWN, gcd, this);
9256
9257 // Apply haste rating
9260 {
9261 gcd = int32(float(gcd) * unitCaster->GetFloatValue(UNIT_MOD_CAST_SPEED));
9262 }
9263
9264 if (gcd < MIN_GCD)
9265 gcd = MIN_GCD;
9266 else if (gcd > MAX_GCD)
9267 gcd = MAX_GCD;
9268 }
9269
9270 // Only players or controlled units have global cooldown
9271 if (unitCaster->GetCharmInfo())
9273 else if (unitCaster->IsPlayer())
9275}
@ SPELLMOD_GLOBAL_COOLDOWN
Definition SpellDefines.h:105
@ MIN_GCD
Definition Spell.cpp:9209
@ MAX_GCD
Definition Spell.cpp:9210
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(), Object::ToUnit(), and UNIT_MOD_CAST_SPEED.

Referenced by prepare().

◆ update()

void Spell::update ( uint32  difftime)
4526{
4527 Unit* unitCaster = m_caster->ToUnit();
4528 // update pointers based at it's GUIDs
4529 if (!UpdatePointers())
4530 {
4531 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4532 cancel();
4533 return;
4534 }
4535
4537 {
4538 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4539 cancel();
4540 return;
4541 }
4542
4543 // check if the player caster has moved before the spell finished
4544 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4545 if ((unitCaster && unitCaster->IsPlayer() && m_timer != 0) &&
4548 {
4549 // don't cancel for melee, autorepeat, triggered and instant spells
4551 cancel(true);
4552 }
4553
4554 switch (m_spellState)
4555 {
4557 {
4558 if (m_timer > 0)
4559 {
4560 if (difftime >= (uint32)m_timer)
4561 m_timer = 0;
4562 else
4563 m_timer -= difftime;
4564 }
4565
4566 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4567 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4568 cast(!m_casttime);
4569 break;
4570 }
4572 {
4573 if (m_timer)
4574 {
4575 if (m_timer > 0)
4576 {
4577 if (difftime >= (uint32)m_timer)
4578 m_timer = 0;
4579 else
4580 m_timer -= difftime;
4581 }
4582 }
4583
4584 if (m_timer == 0)
4585 {
4587
4588 finish();
4589
4590 // 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
4591 if (Creature* creatureCaster = unitCaster ? unitCaster->ToCreature() : nullptr)
4592 if (creatureCaster->IsAIEnabled)
4593 creatureCaster->AI()->OnChannelFinished(m_spellInfo);
4594 }
4595 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4596 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4597 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4598 // Xinef: so the aura can be removed in different updates for all units
4599 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4600 {
4601 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4603 finish();
4604 }
4605 break;
4606 }
4607 default:
4608 break;
4609 }
4610}
bool UpdateChanneledTargetList()
Definition Spell.cpp:3467

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(), Object::ToUnit(), UpdateChanneledTargetList(), and UpdatePointers().

Referenced by SpellEvent::Execute().

◆ UpdateChanneledTargetList()

bool Spell::UpdateChanneledTargetList ( )
protected
3468{
3469 Unit* unitCaster = m_caster->ToUnit();
3470 // Not need check return true
3472 return true;
3473
3474 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3475 uint8 channelAuraMask = 0;
3476 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3478 channelAuraMask |= 1 << i;
3479
3480 channelAuraMask &= channelTargetEffectMask;
3481
3482 float range = 0;
3483 if (channelAuraMask)
3484 {
3486 if (range == 0)
3487 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3488 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3489 {
3490 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3491 break;
3492 }
3493
3494 if (Player* modOwner = m_caster->GetSpellModOwner())
3495 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3496
3497 // xinef: add little tolerance level
3498 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3499 }
3500
3501 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3502 {
3503 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3504 {
3505 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? unitCaster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3506
3507 if (!unit)
3508 continue;
3509
3510 if (IsValidDeadOrAliveTarget(unit))
3511 {
3512 if (channelAuraMask & ihit->effectMask)
3513 {
3515 {
3516 if (m_caster != unit)
3517 {
3518 if (!m_caster->IsWithinDistInMap(unit, range))
3519 {
3520 ihit->effectMask &= ~aurApp->GetEffectMask();
3521 unit->RemoveAura(aurApp);
3522 continue;
3523 }
3524 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3525 else if (unitCaster && !unitCaster->IsPlayer() && m_spellInfo->HasAttribute(SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL))
3526 unitCaster->UpdateOrientation(unitCaster->GetAngle(unit));
3527 }
3528 }
3529 else // aura is dispelled
3530 continue;
3531 }
3532
3533 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3534 }
3535 }
3536 }
3537
3538 // Xinef: not all effects are covered, remove applications from all targets
3539 if (channelTargetEffectMask != 0)
3540 {
3541 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3542 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3543 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? unitCaster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3544 if (IsValidDeadOrAliveTarget(unit))
3546 {
3547 ihit->effectMask &= ~aurApp->GetEffectMask();
3548 unit->RemoveAura(aurApp);
3549 }
3550 }
3551
3552 // is all effects from m_needAliveTargetMask have alive targets
3553 return channelTargetEffectMask == 0;
3554}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition SharedDefines.h:421
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition Spell.cpp:8574
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition Unit.cpp:5605
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition Unit.cpp:15656
bool IsWithinDistInMap(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:1386

References EFFECT_0, EFFECT_2, SpellInfo::Effects, Position::GetAngle(), Unit::GetAuraApplication(), Object::GetGUID(), SpellInfo::GetMaxRange(), WorldObject::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, Object::ToUnit(), and Unit::UpdateOrientation().

Referenced by update().

◆ UpdatePointers()

bool Spell::UpdatePointers ( )
8203{
8204 Unit* unitCaster = m_caster->ToUnit();
8206 m_originalCaster = unitCaster;
8207 else
8208 {
8211 m_originalCaster = nullptr;
8212 }
8213
8214 if (m_castItemGUID && unitCaster && unitCaster->IsPlayer())
8215 {
8217 // cast item not found, somehow the item is no longer where we expected
8218 if (!m_CastItem)
8219 return false;
8220 }
8221 else
8222 m_CastItem = nullptr;
8223
8225
8226 // further actions done only for dest targets
8227 if (!m_targets.HasDst())
8228 return true;
8229
8230 // cache last transport
8231 WorldObject* transport = nullptr;
8232
8233 // update effect destinations (in case of moved transport dest target)
8234 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
8235 {
8236 SpellDestination& dest = m_destTargets[effIndex];
8237 if (!dest._transportGUID)
8238 continue;
8239
8240 if (!transport || transport->GetGUID() != dest._transportGUID)
8242
8243 if (transport)
8244 {
8245 dest._position.Relocate(transport);
8247 }
8248 }
8249
8250 return true;
8251}
void Update(WorldObject *caster)
Definition Spell.cpp:516
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(), Object::ToUnit(), and SpellCastTargets::Update().

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

◆ WriteAmmoToPacket()

void Spell::WriteAmmoToPacket ( WorldPacket *  data)
5079{
5080 Unit* unitCaster = m_caster->ToUnit();
5081 uint32 ammoInventoryType = 0;
5082 uint32 ammoDisplayID = 0;
5083
5084 if (unitCaster && unitCaster->IsPlayer())
5085 {
5086 Item* pItem = unitCaster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK);
5087 if (pItem)
5088 {
5089 ammoInventoryType = pItem->GetTemplate()->InventoryType;
5090 if (ammoInventoryType == INVTYPE_THROWN)
5091 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
5092 else
5093 {
5094 uint32 ammoID = unitCaster->ToPlayer()->GetUInt32Value(PLAYER_AMMO_ID);
5095 if (ammoID)
5096 {
5097 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
5098 if (pProto)
5099 {
5100 ammoDisplayID = pProto->DisplayInfoID;
5101 ammoInventoryType = pProto->InventoryType;
5102 }
5103 }
5104 else if (unitCaster->HasAura(46699)) // Requires No Ammo
5105 {
5106 ammoDisplayID = 5996; // normal arrow
5107 ammoInventoryType = INVTYPE_AMMO;
5108 }
5109 }
5110 }
5111 }
5112 else if (unitCaster)
5113 {
5114 uint32 nonRangedAmmoDisplayID = 0;
5115 uint32 nonRangedAmmoInventoryType = 0;
5116 for (uint8 i = 0; i < 3; ++i)
5117 {
5118 if (uint32 item_id = unitCaster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i))
5119 {
5120 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
5121 {
5122 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
5123 {
5124 switch (itemEntry->SubclassID)
5125 {
5127 ammoDisplayID = itemEntry->DisplayInfoID;
5128 ammoInventoryType = itemEntry->InventoryType;
5129 break;
5132 ammoDisplayID = 5996; // is this need fixing?
5133 ammoInventoryType = INVTYPE_AMMO;
5134 break;
5136 ammoDisplayID = 5998; // is this need fixing?
5137 ammoInventoryType = INVTYPE_AMMO;
5138 break;
5139 default:
5140 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
5141 nonRangedAmmoInventoryType = itemEntry->InventoryType;
5142 break;
5143 }
5144
5145 if (ammoDisplayID)
5146 break;
5147 }
5148 }
5149 }
5150 }
5151
5152 if (!ammoDisplayID && !ammoInventoryType)
5153 {
5154 ammoDisplayID = nonRangedAmmoDisplayID;
5155 ammoInventoryType = nonRangedAmmoInventoryType;
5156 }
5157 }
5158
5159 *data << uint32(ammoDisplayID);
5160 *data << uint32(ammoInventoryType);
5161}
DBCStorage< ItemEntry > sItemStore(Itemfmt)
@ INVTYPE_AMMO
Definition ItemTemplate.h:280
@ UNIT_VIRTUAL_ITEM_SLOT_ID
Definition UpdateFields.h:116
Definition DBCStructure.h:1179
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(), Object::ToUnit(), 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
4705{
4706 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4707 data << uint32(spellInfo->Id);
4708 data << uint8(result); // problem
4709 switch (result)
4710 {
4712 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4713 break;
4714 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4715 // hardcode areas limitation case
4716 switch (spellInfo->Id)
4717 {
4718 case 41617: // Cenarion Mana Salve
4719 case 41619: // Cenarion Healing Salve
4720 data << uint32(3905);
4721 break;
4722 case 41618: // Bottled Nethergon Energy
4723 case 41620: // Bottled Nethergon Vapor
4724 data << uint32(3842);
4725 break;
4726 case 45373: // Bloodberry Elixir
4727 data << uint32(4075);
4728 break;
4729 default: // default case (don't must be)
4730 data << uint32(0);
4731 break;
4732 }
4733 break;
4735 if (spellInfo->Totem[0])
4736 data << uint32(spellInfo->Totem[0]);
4737 if (spellInfo->Totem[1])
4738 data << uint32(spellInfo->Totem[1]);
4739 break;
4741 if (spellInfo->TotemCategory[0])
4742 data << uint32(spellInfo->TotemCategory[0]);
4743 if (spellInfo->TotemCategory[1])
4744 data << uint32(spellInfo->TotemCategory[1]);
4745 break;
4749 data << uint32(spellInfo->EquippedItemClass);
4750 data << uint32(spellInfo->EquippedItemSubClassMask);
4751 break;
4753 {
4754 uint32 item = 0;
4755 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4756 if (spellInfo->Effects[eff].ItemType)
4757 item = spellInfo->Effects[eff].ItemType;
4758 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4759 if (proto && proto->ItemLimitCategory)
4760 data << uint32(proto->ItemLimitCategory);
4761 break;
4762 }
4764 data << uint32(customError);
4765 break;
4767 {
4768 uint32 missingItem = 0;
4769 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4770 {
4771 if (spellInfo->Reagent[i] <= 0)
4772 continue;
4773
4774 uint32 itemid = spellInfo->Reagent[i];
4775 uint32 itemcount = spellInfo->ReagentCount[i];
4776
4777 if (!caster->HasItemCount(itemid, itemcount))
4778 {
4779 missingItem = itemid;
4780 break;
4781 }
4782 }
4783
4784 data << uint32(missingItem); // first missing item
4785 break;
4786 }
4788 data << uint32(spellInfo->Mechanic);
4789 break;
4791 data << uint32(spellInfo->EquippedItemSubClassMask);
4792 break;
4794 data << uint32(0); // Item entry
4795 data << uint32(0); // Count
4796 break;
4798 data << uint32(0); // SkillLine.dbc Id
4799 data << uint32(0); // Amount
4800 break;
4802 data << uint32(0); // Skill level
4803 break;
4804 default:
4805 break;
4806 }
4807}
@ 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.

5165{
5166 // This function also fill data for channeled spells:
5167 // m_needAliveTargetMask req for stop channelig if one target die
5168 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5169 {
5170 if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
5171 // possibly SPELL_MISS_IMMUNE2 for this??
5172 ihit->missCondition = SPELL_MISS_IMMUNE2;
5173 }
5174
5175 // Hit and miss target counts are both uint8, that limits us to 255 targets for each
5176 // sending more than 255 targets crashes the client (since count sent would be wrong)
5177 // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
5178 // target conditions but we still need to limit the number of targets sent and keeping
5179 // correct count for both hit and miss).
5180
5181 uint32 hit = 0;
5182 std::size_t hitPos = data->wpos();
5183 *data << (uint8)0; // placeholder
5184 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
5185 {
5186 if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
5187 {
5188 *data << ihit->targetGUID;
5189 // Xinef: No channeled spell checked, no anything
5190 //m_channelTargetEffectMask |=ihit->effectMask;
5191 ++hit;
5192 }
5193 }
5194
5195 for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
5196 {
5197 *data << ighit->targetGUID; // Always hits
5198 ++hit;
5199 }
5200
5201 uint32 miss = 0;
5202 std::size_t missPos = data->wpos();
5203 *data << (uint8)0; // placeholder
5204 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
5205 {
5206 if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
5207 {
5208 *data << ihit->targetGUID;
5209 *data << uint8(ihit->missCondition);
5210 if (ihit->missCondition == SPELL_MISS_REFLECT)
5211 *data << uint8(ihit->reflectResult);
5212 ++miss;
5213 }
5214 }
5215 // Reset m_needAliveTargetMask for non channeled spell
5216 // Xinef: Why do we reset something that is not set??????
5217 //if (!m_spellInfo->IsChanneled())
5218 // m_channelTargetEffectMask = 0;
5219
5220 data->put<uint8>(hitPos, (uint8)hit);
5221 data->put<uint8>(missPos, (uint8)miss);
5222}
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

WorldObject* const Spell::m_caster
protected

Referenced by _cast(), _handle_finish_phase(), AddGOTarget(), AddUnitTarget(), CalculateDelayMomentForDst(), CalculateSpellDamage(), cancel(), CancelGlobalCooldown(), CanOpenLock(), cast(), CheckCast(), CheckCasterAuras(), CheckDst(), CheckEffectTarget(), CheckItems(), CheckPetCast(), CheckPower(), CheckRange(), CheckRuneCost(), CheckSpellFocus(), CheckSrc(), Delayed(), DelayedChannel(), DoAllEffectOnLaunchTarget(), DoAllEffectOnTarget(), DoAllEffectOnTarget(), DoCreateItem(), DoSpellHitOnUnit(), DoTriggersOnSpellHit(), EffectActivateObject(), EffectActivateRune(), EffectAddFarsight(), EffectApplyGlyph(), EffectBind(), EffectBlock(), EffectCastButtons(), EffectDisEnchant(), EffectDispel(), EffectDispelMechanic(), EffectDuel(), EffectDummy(), EffectEnchantHeldItem(), EffectEnchantItemPerm(), EffectEnchantItemPrismatic(), EffectEnchantItemTmp(), EffectFeedPet(), EffectForceCast(), EffectGameObjectRepair(), EffectInstaKill(), EffectKnockBack(), EffectLeap(), EffectLeapBack(), EffectLearnSpell(), EffectMilling(), EffectOpenLock(), EffectParry(), EffectPickPocket(), EffectProficiency(), EffectProspecting(), EffectPullTowards(), EffectRechargeManaGem(), EffectResurrect(), EffectResurrectNew(), EffectResurrectPet(), EffectScriptEffect(), EffectSelfResurrect(), EffectSendEvent(), EffectSkinning(), EffectSkinPlayerCorpse(), EffectStealBeneficialBuff(), EffectStuck(), EffectSummonChangeItem(), EffectSummonObjectWild(), EffectSummonRaFFriend(), EffectSummonType(), EffectTeleportUnits(), EffectTeleUnitsFaceCaster(), EffectTitanGrip(), EffectTradeSkill(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), finish(), GetCaster(), GetOriginalTarget(), GetUnitCasterForEffectHandlers(), 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(), 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::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: