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 IsFromPreDeathAura () 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
 
GameObject * GetGameObjectCaster () const
 
std::optional< float > GetLOSCollisionHeight () 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
 
bool _fromPreDeathAura {false}
 
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:851
@ 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:224
@ BASE_ATTACK
Definition Unit.h:223
@ RANGED_ATTACK
Definition Unit.h:225
@ DIMINISHING_LEVEL_1
Definition Unit.h:277
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:682
bool m_referencedFromCurrentSpell
Definition Spell.h:673
bool m_canReflect
Definition Spell.h:649
uint32 m_procVictim
Definition Spell.h:708
Unit * m_originalCaster
Definition Spell.h:635
bool m_needComboPoints
Definition Spell.h:675
uint64 m_delayStart
Definition Spell.h:667
bool _scriptsLoaded
Definition Spell.h:759
TriggerCastFlags _triggeredCastFlags
Definition Spell.h:800
int32 damage
Definition Spell.h:684
SpellEffectHandleMode effectHandleMode
Definition Spell.h:685
int32 m_channeledDuration
Definition Spell.h:648
Aura * m_spellAura
Definition Spell.h:690
SpellDestination m_destTargets[MAX_SPELL_EFFECTS]
Definition Spell.h:734
uint8 m_delayAtDamageCount
Definition Spell.h:656
WeaponAttackType m_attackType
Definition Spell.h:645
bool m_immediateHandled
Definition Spell.h:670
uint32 m_spellState
Definition Spell.h:796
ObjectGuid m_originalCasterGUID
Definition Spell.h:633
WorldObject *const m_caster
Definition Spell.h:629
void CleanupTargetList()
Definition Spell.cpp:2386
int32 m_timer
Definition Spell.h:797
int32 m_casttime
Definition Spell.h:647
Item * itemTarget
Definition Spell.h:681
uint8 m_cast_count
Definition Spell.h:539
int32 m_damage
Definition Spell.h:700
bool m_executedCurrently
Definition Spell.h:674
DiminishingLevels m_diminishLevel
Definition Spell.h:693
float m_damageMultipliers[3]
Definition Spell.h:677
ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]
Definition Spell.h:815
uint8 m_auraScaleMask
Definition Spell.h:809
int32 m_damageBeforeTakenMods
Definition Spell.h:702
SpellCustomErrors m_customError
Definition Spell.h:543
uint8 m_spellFlags
Definition Spell.h:651
bool m_skipCheck
Definition Spell.h:808
int32 m_healing
Definition Spell.h:701
uint32 m_glyphIndex
Definition Spell.h:540
uint8 m_channelTargetEffectMask
Definition Spell.h:716
Item * m_weaponItem
Definition Spell.h:537
Unit * unitTarget
Definition Spell.h:680
SpellSchoolMask m_spellSchoolMask
Definition Spell.h:644
Unit * m_reflectionTarget
Definition Spell.h:686
SpellEvent * _spellEvent
Definition Spell.h:799
bool _spellTargetsSelected
Definition Spell.h:813
ObjectGuid m_reflectionTargetGuid
Definition Spell.h:687
uint32 m_preCastSpell
Definition Spell.h:541
WorldLocation * destTarget
Definition Spell.h:683
Spell ** m_selfContainer
Definition Spell.h:639
uint8 m_applyMultiplierMask
Definition Spell.h:676
DiminishingGroup m_diminishGroup
Definition Spell.h:694
uint32 m_procEx
Definition Spell.h:709
Item * m_CastItem
Definition Spell.h:536
SpellValue *const m_spellValue
Definition Spell.h:631
int32 m_powerCost
Definition Spell.h:646
uint32 m_procAttacker
Definition Spell.h:707
GameObject * focusObject
Definition Spell.h:697
SpellInfo const *const m_spellInfo
Definition Spell.h:535
uint8 m_runesState
Definition Spell.h:654
bool m_autoRepeat
Definition Spell.h:653
Unit * GetCharmerOrOwner() const
Definition Unit.h:1303
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:8908
std::list< SpellScript * > m_loadedScripts
Definition Spell.h:774
Map * FindMap() const
Definition Object.h:638
virtual Player * GetSpellModOwner() const
Definition Object.cpp:3358

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

3933{
3934 Unit* unitCaster = m_caster->ToUnit();
3935 // update pointers base at GUIDs to prevent access to non-existed already object
3936 if (!UpdatePointers())
3937 {
3938 // cancel the spell if UpdatePointers() returned false, something wrong happened there
3939 cancel();
3940 return;
3941 }
3942
3943 // cancel at lost explicit target during cast
3945 {
3946 cancel();
3947 return;
3948 }
3949
3950 // Xinef: implement attribute SPELL_ATTR1_DISMISS_PET_FIRST, on spell cast current pet is dismissed and charms are removed
3952 {
3953 if (unitCaster->IsPlayer() && !m_spellInfo->HasEffect(SPELL_EFFECT_SUMMON_PET))
3954 if (Pet* pet = unitCaster->ToPlayer()->GetPet())
3955 unitCaster->ToPlayer()->RemovePet(pet, PET_SAVE_AS_CURRENT);
3956
3957 if (Unit* charm = unitCaster->GetCharm())
3958 charm->RemoveAurasByType(SPELL_AURA_MOD_CHARM, unitCaster->GetGUID());
3959 }
3960
3961 if (Player* playerCaster = m_caster->ToPlayer())
3962 {
3963 // now that we've done the basic check, now run the scripts
3964 // should be done before the spell is actually executed
3965 sScriptMgr->OnPlayerSpellCast(playerCaster, this, skipCheck);
3966
3967 // As of 3.0.2 pets begin attacking their owner's target immediately
3968 // Let any pets know we've attacked something. Check DmgClass for harmful spells only
3969 // This prevents spells such as Hunter's Mark from triggering pet attack
3970 // xinef: take into account SPELL_ATTR3_SUPPRESS_TARGET_PROCS
3973 if (!playerCaster->m_Controlled.empty())
3974 for (Unit::ControlSet::iterator itr = playerCaster->m_Controlled.begin(); itr != playerCaster->m_Controlled.end(); ++itr)
3975 if (Unit* pet = *itr)
3976 if (pet->IsAlive() && pet->IsCreature())
3977 pet->ToCreature()->AI()->OwnerAttacked(m_targets.GetUnitTarget());
3978 }
3979
3981
3983 if (unitCaster && unitCaster->IsCreature() && m_targets.GetObjectTarget() && m_caster != m_targets.GetObjectTarget())
3984 unitCaster->SetInFront(m_targets.GetObjectTarget());
3985
3987
3988 Player* modOwner = m_caster->GetSpellModOwner();
3989 // skip check if done already (for instant cast spells for example)
3990 if (!skipCheck)
3991 {
3992 SpellCastResult castResult = CheckCast(false);
3993 if (castResult != SPELL_CAST_OK)
3994 {
3995 SendCastResult(castResult);
3996 SendInterrupted(0);
3997
3998 finish(false);
3999 SetExecutedCurrently(false);
4000 return;
4001 }
4002
4003 // additional check after cast bar completes (must not be in CheckCast)
4004 // if trade not complete then remember it in trade data
4006 {
4007 if (unitCaster && unitCaster->IsPlayer())
4008 {
4009 if (TradeData* my_trade = unitCaster->ToPlayer()->GetTradeData())
4010 {
4011 if (!my_trade->IsInAcceptProcess())
4012 {
4013 // Spell will be casted at completing the trade. Silently ignore at this place
4014 my_trade->SetSpell(m_spellInfo->Id, m_CastItem);
4016 SendInterrupted(0);
4017
4018 finish(false);
4019 SetExecutedCurrently(false);
4020 return;
4021 }
4022 }
4023 }
4024 }
4025 }
4026
4027 if (modOwner)
4028 modOwner->SetSpellModTakingSpell(this, true);
4029
4032
4033 if (modOwner)
4034 modOwner->SetSpellModTakingSpell(this, false);
4035
4036 // Spell may be finished after target map check
4038 {
4039 SendInterrupted(0);
4040 finish(false);
4041 SetExecutedCurrently(false);
4042 return;
4043 }
4044
4045 if (modOwner)
4046 modOwner->SetSpellModTakingSpell(this, true);
4047
4049
4051
4052 if (modOwner)
4053 modOwner->SetSpellModTakingSpell(this, false);
4054
4055 // traded items have trade slot instead of guid in m_itemTargetGUID
4056 // set to real guid to be sent later to the client
4058
4059 if (unitCaster && unitCaster->IsPlayer())
4060 {
4062 {
4065 }
4066
4068 }
4069
4071 {
4072 // Powers have to be taken before SendSpellGo
4073 TakePower();
4074 TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
4075 }
4076 else if (Item* targetItem = m_targets.GetItemTarget())
4077 {
4079 if (targetItem->GetOwnerGUID() != m_caster->GetGUID())
4080 TakeReagents();
4081 }
4082
4084
4085 // CAST SPELL
4086 if (modOwner)
4087 modOwner->SetSpellModTakingSpell(this, true);
4088
4090
4092
4093 // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
4094 SendSpellGo();
4095
4096 bool resetAttackTimers = unitCaster && IsAutoActionResetSpell() && !m_spellInfo->HasAttribute(SPELL_ATTR2_DO_NOT_RESET_COMBAT_TIMERS);
4097 if (resetAttackTimers)
4098 {
4100 for (Unit::AuraEffectList::const_iterator i = vIgnoreReset.begin(); i != vIgnoreReset.end(); ++i)
4101 {
4102 if ((*i)->IsAffectedOnSpell(m_spellInfo))
4103 {
4104 resetAttackTimers = false;
4105 break;
4106 }
4107 }
4108 }
4109
4110 // CAST -> HIT -> FINISH ordering: fire CAST before handle_immediate so an aura
4111 // applied during HIT (e.g. Arcane Potency from Clearcasting) isn't consumed by
4112 // the same cast. Triggered spells skip this so periodic ticks (Blizzard etc.)
4113 // don't burn cast-charge buffs.
4114 if (m_originalCaster && !IsTriggered())
4115 {
4116 uint32 procAttacker = m_procAttacker;
4117 if (!procAttacker)
4118 {
4119 bool IsPositive = m_spellInfo->IsPositive();
4121 {
4123 }
4124 else
4125 {
4127 }
4128 }
4129
4130 uint32 hitMask = PROC_HIT_NORMAL;
4131
4132 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4133 {
4134 if (ihit->missCondition != SPELL_MISS_NONE)
4135 continue;
4136
4137 if (!ihit->crit)
4138 continue;
4139
4140 hitMask |= PROC_HIT_CRITICAL;
4141 break;
4142 }
4143
4146 }
4147
4148 // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
4149 if ((m_spellInfo->Speed > 0.0f && !m_spellInfo->IsChanneled())/* xinef: we dont need this || m_spellInfo->Id == 14157*/)
4150 {
4151 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4152 // in case delayed spell remove item at cast delay start
4153 TakeCastItem();
4154
4155 // Okay, maps created, now prepare flags
4156 m_immediateHandled = false;
4158 SetDelayStart(0);
4159
4160 if (unitCaster && unitCaster->HasUnitState(UNIT_STATE_CASTING) && !unitCaster->IsNonMeleeSpellCast(false, false, true))
4162
4163 // remove all applied mods at this point
4164 // dont allow user to use them twice in case spell did not reach current target
4165 if (modOwner)
4166 modOwner->RemoveSpellMods(this);
4167
4168 // Xinef: why do we keep focus after spell is sent to air?
4169 // Xinef: Because of this, in the middle of some animation after setting targetguid to 0 etc
4170 // Xinef: we get focused to it out of nowhere...
4171 if (Creature* creatureCaster = unitCaster ? unitCaster->ToCreature() : nullptr)
4172 creatureCaster->ReleaseFocus(this);
4173 }
4174 else
4175 {
4176 // Immediate spell, no big deal
4178 }
4179
4180 if (resetAttackTimers)
4181 {
4182 if (m_casttime == 0 && m_spellInfo->CalcCastTime())
4183 {
4184 resetAttackTimers = false;
4185 }
4186
4187 if (resetAttackTimers)
4188 {
4189 unitCaster->resetAttackTimer(BASE_ATTACK);
4190
4191 if (unitCaster->HasOffhandWeaponForAttack())
4192 {
4193 unitCaster->resetAttackTimer(OFF_ATTACK);
4194 }
4195
4196 unitCaster->resetAttackTimer(RANGED_ATTACK);
4197 }
4198 }
4199
4201
4202 if (modOwner)
4203 modOwner->SetSpellModTakingSpell(this, false);
4204
4205 if (std::vector<int32> const* spell_triggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id))
4206 {
4207 for (int32 id : *spell_triggered)
4208 {
4209 if (id < 0)
4210 {
4211 if (unitCaster)
4212 unitCaster->RemoveAurasDueToSpell(-id);
4213 }
4214 else
4216 }
4217 }
4218
4219 // Interrupt Spell casting
4220 // handle this here, in other places SpellHitTarget can be set to nullptr, if there is an error in this function
4222 if (Unit* target = m_targets.GetUnitTarget())
4223 if (target->IsCreature())
4224 m_caster->CastSpell(target, 32747, true);
4225
4226 if (unitCaster && unitCaster->IsPlayer())
4227 if (unitCaster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN))
4228 unitCaster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
4229
4230 sScriptMgr->OnSpellCast(this, unitCaster, m_spellInfo, skipCheck);
4231
4232 SetExecutedCurrently(false);
4233
4234 // Call CreatureAI hook on successful cast
4235 if (Creature* caster = unitCaster ? unitCaster->ToCreature() : nullptr)
4236 if (caster->IsAIEnabled)
4237 caster->AI()->OnSpellCast(GetSpellInfo());
4238}
@ 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:769
@ 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:2232
void SetSpellModTakingSpell(Spell *spell, bool apply)
Definition Player.cpp:10286
void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost=0)
Definition Player.cpp:14324
void RemoveSpellMods(Spell *spell)
Definition Player.cpp:10224
Pet * GetPet() const
Definition Player.cpp:9171
bool GetCommandStatus(uint32 command) const
Definition Player.h:1202
void RemovePet(Pet *pet, PetSaveMode mode, bool returnreagent=false)
Definition Player.cpp:9321
TradeData * GetTradeData() const
Definition Player.h:1400
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition Player.cpp:3705
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:2792
float Speed
Definition SpellInfo.h:394
bool IsChanneled() const
Definition SpellInfo.cpp:1301
SpellInfo const * GetSpellInfo() const
Definition Spell.h:601
void CallScriptAfterCastHandlers()
Definition Spell.cpp:8962
void PrepareTriggersExecutedOnHit()
Definition Spell.cpp:9168
bool HasTriggeredCastFlag(TriggerCastFlags flag) const
Definition Spell.h:569
SpellCastTargets m_targets
Definition Spell.h:542
TriggeredByAuraSpellData m_triggeredByAuraSpell
Definition Spell.h:806
void handle_immediate()
Definition Spell.cpp:4240
void SendSpellGo()
Definition Spell.cpp:4969
void TakeReagents()
Definition Spell.cpp:5738
void SetExecutedCurrently(bool yes)
Definition Spell.h:579
bool IsFromPreDeathAura() const
Definition Spell.h:571
void SendInterrupted(uint8 result)
Definition Spell.cpp:5348
void PrepareScriptHitHandlers()
Definition Spell.cpp:8994
void CallScriptOnCastHandlers()
Definition Spell.cpp:8949
void cancel(bool bySelf=false)
Definition Spell.cpp:3830
void SendSpellCooldown()
Definition Spell.cpp:4498
void CallScriptBeforeCastHandlers()
Definition Spell.cpp:8936
void HandleLaunchPhase()
Definition Spell.cpp:8619
bool UpdatePointers()
Definition Spell.cpp:8249
void SetDelayStart(uint64 m_time)
Definition Spell.h:581
std::list< TargetInfo > m_UniqueTargetInfo
Definition Spell.h:715
void SelectSpellTargets()
Definition Spell.cpp:869
void TakePower()
Definition Spell.cpp:5505
static void SendCastResult(Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError=SPELL_CUSTOM_ERROR_NONE)
Definition Spell.cpp:4832
bool IsTriggered() const
Definition Spell.h:568
void TakeCastItem()
Definition Spell.cpp:5438
SpellCastResult CheckCast(bool strict, uint32 *param1=nullptr, uint32 *param2=nullptr)
Definition Spell.cpp:5874
bool IsAutoActionResetSpell() const
Definition Spell.cpp:8455
void finish(bool ok=true)
Definition Spell.cpp:4635
Definition TradeData.h:36
Definition Unit.h:670
bool HasOffhandWeaponForAttack() const
Definition Unit.h:1004
void ClearUnitState(uint32 f)
Definition Unit.h:743
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:1445
Unit * GetCharm() const
Definition Unit.cpp:7588
std::vector< AuraEffect * > AuraEffectList
Definition Unit.h:686
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false, bool isAutoshoot=false, bool skipInstant=true) const
Definition Unit.cpp:4049
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4969
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:6590
bool HasUnitState(const uint32 f) const
Definition Unit.h:742
void SetInFront(WorldObject const *target)
Definition Unit.cpp:16151
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:3278
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(), IsFromPreDeathAura(), 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 ( )
4417{
4418 // GameObject casts (e.g. hunter traps) have no unit caster but must still
4419 // reach the finish procs below through m_originalCaster (Entrapment, Lock and Load)
4420 if (Unit* unitCaster = m_caster->ToUnit())
4421 {
4422 // Take for real after all targets are processed
4424 {
4425 unitCaster->ClearComboPoints();
4426 }
4427
4428 // Real add combo points from effects
4430 {
4431 // remove Premed-like effects unless they were caused by ourselves
4432 // (this Aura removes the already-added CP when it expires from duration - now that we've added CP, this shouldn't happen anymore!)
4434 {
4435 unitCaster->RemoveAurasByType(SPELL_AURA_RETAIN_COMBO_POINTS);
4436 }
4437
4438 unitCaster->AddComboPoints(m_comboTarget, m_comboPointGain);
4439 }
4440
4442 {
4443 unitCaster->SetLastExtraAttackSpell(m_spellInfo->Id);
4444 }
4445
4447 if (unitCaster->GetCharmerOrOwnerPlayerOrPlayerItself())
4448 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4449 {
4450 // Xinef: Properly clear infinite cooldowns in some cases
4451 if (ihit->targetGUID == unitCaster->GetGUID() && ihit->missCondition != SPELL_MISS_NONE)
4452 if (unitCaster->IsPlayer() && m_spellInfo->IsCooldownStartedOnEvent())
4453 unitCaster->ToPlayer()->SendCooldownEvent(m_spellInfo);
4454 }
4455 }
4456
4457 // Handle procs on finish
4458 if (m_originalCaster)
4459 {
4460 uint32 procAttacker = m_procAttacker;
4461 if (!procAttacker)
4462 {
4463 bool IsPositive = m_spellInfo->IsPositive();
4465 {
4467 }
4468 else
4469 {
4471 }
4472 }
4473
4474 uint32 hitMask = PROC_HIT_NORMAL;
4475 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4476 {
4477 if (ihit->missCondition != SPELL_MISS_NONE)
4478 continue;
4479
4480 if (!ihit->crit)
4481 continue;
4482
4483 hitMask |= PROC_HIT_CRITICAL;
4484 break;
4485 }
4486
4487 // For trap activation, pass the original target (trap triggerer) so proc trigger spells
4488 // like Entrapment can find a valid target to cast on
4489 Unit* finishVictim = nullptr;
4490 if (procAttacker & PROC_FLAG_DONE_TRAP_ACTIVATION)
4491 finishVictim = GetOriginalTarget();
4492
4495 }
4496}
@ 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
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:8215
bool IsNextMeleeSwingSpell() const
Definition Spell.cpp:8445

References BASE_ATTACK, SpellInfo::DmgClass, TriggeredByAuraSpellData::effectIndex, GetOriginalTarget(), SpellInfo::HasAura(), SpellInfo::HasEffect(), SpellInfo::Id, IsAutoRepeat(), SpellInfo::IsCooldownStartedOnEvent(), IsNextMeleeSwingSpell(), 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(), SPELL_AURA_RETAIN_COMBO_POINTS, SPELL_DAMAGE_CLASS_MAGIC, SPELL_EFFECT_ADD_EXTRA_ATTACKS, SPELL_MISS_NONE, TriggeredByAuraSpellData::spellInfo, and Object::ToUnit().

Referenced by handle_delayed(), and handle_immediate().

◆ _handle_immediate_phase()

void Spell::_handle_immediate_phase ( )
4389{
4390 m_spellAura = nullptr;
4391 // initialize Diminishing Returns Data
4394
4395 // handle some immediate features of the spell here
4397
4399
4400 // handle effects with SPELL_EFFECT_HANDLE_HIT mode
4401 for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
4402 {
4403 // don't do anything for empty effect
4404 if (!m_spellInfo->Effects[j].IsEffect())
4405 continue;
4406
4407 // call effect handlers to handle destination hit
4408 HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT);
4409 }
4410
4411 // process items
4412 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
4413 DoAllEffectOnTarget(&(*ihit));
4414}
@ SPELL_EFFECT_HANDLE_HIT
Definition Spell.h:248
std::array< SpellEffectInfo, MAX_SPELL_EFFECTS > Effects
Definition SpellInfo.h:417
void HandleThreatSpells()
Definition Spell.cpp:5791
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, SpellEffectHandleMode mode)
Definition Spell.cpp:5848
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition Spell.h:732
void DoAllEffectOnTarget(TargetInfo *target)
Definition Spell.cpp:2624

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
2620{
2621 m_destTargets[effIndex] = dest;
2622}

References m_destTargets.

Referenced by SelectSpellTargets().

◆ AddGOTarget()

void Spell::AddGOTarget ( GameObject *  target,
uint32  effectMask 
)
protected
2529{
2530 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2531 {
2532 if (!m_spellInfo->Effects[effIndex].IsEffect())
2533 effectMask &= ~(1 << effIndex);
2534 else
2535 {
2536 switch (m_spellInfo->Effects[effIndex].Effect)
2537 {
2541 if (go->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
2542 effectMask &= ~(1 << effIndex);
2543 break;
2544 default:
2545 break;
2546 }
2547 }
2548 }
2549
2550 if (!effectMask)
2551 return;
2552
2553 ObjectGuid targetGUID = go->GetGUID();
2554
2555 // Lookup target in already in list
2556 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2557 {
2558 if (targetGUID == ihit->targetGUID) // Found in list
2559 {
2560 ihit->effectMask |= effectMask; // Add only effect mask
2561 return;
2562 }
2563 }
2564
2565 // This is new target calculate data for him
2566
2567 GOTargetInfo target;
2568 target.targetGUID = targetGUID;
2569 target.effectMask = effectMask;
2570 target.processed = false; // Effects not apply on target
2571
2572 // Spell have speed - need calculate incoming time
2573 if (m_spellInfo->Speed > 0.0f)
2574 {
2575 // calculate spell incoming interval
2576 float dist = m_caster->GetDistance(go->GetPositionX(), go->GetPositionY(), go->GetPositionZ());
2577 if (dist < 5.0f)
2578 dist = 5.0f;
2579 target.timeDelay = uint64(std::floor(dist / m_spellInfo->Speed * 1000.0f));
2580 if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
2581 m_delayMoment = target.timeDelay;
2582 }
2583 else
2584 target.timeDelay = 0LL;
2585
2586 // Add target to list
2587 m_UniqueGOTargetInfo.push_back(target);
2588}
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:668
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition Spell.h:725
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
2591{
2592 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2593 if (!m_spellInfo->Effects[effIndex].IsEffect())
2594 effectMask &= ~(1 << effIndex);
2595
2596 // no effects left
2597 if (!effectMask)
2598 return;
2599
2600 // Lookup target in already in list
2601 for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2602 {
2603 if (item == ihit->item) // Found in list
2604 {
2605 ihit->effectMask |= effectMask; // Add only effect mask
2606 return;
2607 }
2608 }
2609
2610 // This is new target add data
2611
2612 ItemTargetInfo target;
2613 target.item = item;
2614 target.effectMask = effectMask;
2615
2616 m_UniqueItemInfo.push_back(target);
2617}

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,
2410 if (res != SPELL_CAST_OK)
2411 return;
2412 }
2413
2414 // Check for effect immune skip if immuned
2415 for (uint32 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2416 if (target->IsImmunedToSpellEffect(m_spellInfo, effIndex, unitCaster))
2417 effectMask &= ~(1 << effIndex);
2418
2419 ObjectGuid targetGUID = target->GetGUID();
2420
2421 // Lookup target in already in list
2422 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2423 {
2424 if (targetGUID == ihit->targetGUID) // Found in list
2425 {
2426 ihit->effectMask |= effectMask; // Immune effects removed from mask
2427 ihit->scaleAura = false;
2428 if (m_auraScaleMask && ihit->effectMask == m_auraScaleMask && m_caster != target)
2429 {
2430 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2431 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2432 ihit->scaleAura = true;
2433 }
2434
2435 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, *ihit);
2436 return;
2437 }
2438 }
2439
2440 // This is new target calculate data for him
2441
2442 // Get spell hit result on target
2443 TargetInfo targetInfo;
2444 targetInfo.targetGUID = targetGUID; // Store target GUID
2445 targetInfo.effectMask = effectMask; // Store all effects not immune
2446 targetInfo.processed = false; // Effects not apply on target
2447 targetInfo.alive = target->IsAlive();
2448 targetInfo.damage = 0;
2449 targetInfo.damageBeforeTakenMods = 0;
2450 targetInfo.crit = false;
2451 targetInfo.scaleAura = false;
2452 if (m_auraScaleMask && targetInfo.effectMask == m_auraScaleMask && m_caster != target)
2453 {
2454 SpellInfo const* auraSpell = m_spellInfo->GetFirstRankSpell();
2455 if (uint32(target->GetLevel() + 10) >= auraSpell->SpellLevel)
2456 targetInfo.scaleAura = true;
2457 }
2458
2459 sScriptMgr->OnScaleAuraUnitAdd(this, target, effectMask, checkIfValid, implicit, m_auraScaleMask, targetInfo);
2460
2461 // Calculate hit result
2463 targetInfo.missCondition = caster->SpellHitResult(target, this, m_canReflect);
2464 if (m_skipCheck && targetInfo.missCondition != SPELL_MISS_IMMUNE)
2465 {
2466 targetInfo.missCondition = SPELL_MISS_NONE;
2467 }
2468
2469 // Spell have speed - need calculate incoming time
2470 // Incoming time is zero for self casts. At least I think so.
2471 if (m_spellInfo->Speed > 0.0f && m_caster != target)
2472 {
2473 // calculate spell incoming interval
2475 float dist = m_caster->GetDistance(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ());
2476
2477 if (dist < 5.0f)
2478 dist = 5.0f;
2479 targetInfo.timeDelay = (uint64) std::floor(dist / m_spellInfo->Speed * 1000.0f);
2480
2481 // Calculate minimum incoming time
2482 if (m_delayMoment == 0 || m_delayMoment > targetInfo.timeDelay)
2483 m_delayMoment = targetInfo.timeDelay;
2484 }
2485 else
2486 targetInfo.timeDelay = 0LL;
2487
2488 // If target reflect spell back to caster
2489 if (targetInfo.missCondition == SPELL_MISS_REFLECT)
2490 {
2491 // Calculate reflected spell result on caster
2492 targetInfo.reflectResult = unitCaster ? unitCaster->SpellHitResult(unitCaster, this, m_canReflect) : SPELL_MISS_NONE;
2493
2494 if (targetInfo.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
2495 targetInfo.reflectResult = SPELL_MISS_PARRY;
2496
2497 // Increase time interval for reflected spells by 1.5
2498 if (unitCaster)
2499 unitCaster->m_Events.AddEventAtOffset(new ReflectEvent(unitCaster, targetInfo.targetGUID, m_spellInfo), Milliseconds(targetInfo.timeDelay));
2500 targetInfo.timeDelay += targetInfo.timeDelay >> 1;
2501
2503
2504 // HACK: workaround check for succubus seduction case
2506 if (unitCaster && unitCaster->IsPet())
2507 {
2508 CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(unitCaster->GetEntry());
2509 switch (ci->family)
2510 {
2512 {
2513 if (m_spellInfo->SpellIconID != 694) // Soothing Kiss
2514 cancel();
2515 }
2516 break;
2517 return;
2518 }
2519 }
2520 }
2521 else
2522 targetInfo.reflectResult = SPELL_MISS_NONE;
2523
2524 // Add target to list
2525 m_UniqueTargetInfo.push_back(targetInfo);
2526}
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_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:874
Definition SpellInfo.h:340
uint32 SpellLevel
Definition SpellInfo.h:384
SpellInfo const * GetFirstRankSpell() const
Definition SpellInfo.cpp:2948
SpellCastResult CheckTarget(WorldObject const *caster, WorldObject const *target, bool implicit=true, Unit const *originalCaster=nullptr) const
Definition SpellInfo.cpp:1677
uint32 SpellIconID
Definition SpellInfo.h:404
bool CheckEffectTarget(Unit const *target, uint32 eff) const
Definition Spell.cpp:8312
bool IsPet() const
Definition Unit.h:803
bool IsAlive() const
Definition Unit.h:1812
uint8 GetLevel() const
Definition Unit.h:1117
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index, WorldObject const *caster=nullptr) const
Definition Unit.cpp:9899
EventProcessor m_Events
Definition Object.h:749
SpellMissInfo SpellHitResult(Unit *victim, SpellInfo const *spellInfo, bool canReflect=false)
Definition Object.cpp:3689
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_triggeredByAuraSpell, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, TargetInfo::missCondition, TargetInfo::processed, TargetInfo::reflectResult, TargetInfo::scaleAura, sObjectMgr, SpellInfo::Speed, SPELL_CAST_OK, SPELL_FLAG_REFLECTED, 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
1213{
1214 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1215 ASSERT(unitCaster);
1216 float runSpeed = unitCaster->IsControlledByPlayer() ? playerBaseMoveSpeed[MOVE_RUN] : baseMoveSpeed[MOVE_RUN];
1217 if (Creature* creature = unitCaster->ToCreature())
1218 runSpeed *= creature->GetCreatureTemplate()->speed_run;
1219
1220 float multiplier = m_spellInfo->Effects[i].ValueMultiplier;
1221 if (multiplier <= 0.0f)
1222 multiplier = 1.0f;
1223
1224 speedXY = std::min(runSpeed * 3.0f * multiplier, std::max(28.0f, unitCaster->GetSpeed(MOVE_RUN) * 4.0f));
1225
1226 float duration = dist / speedXY;
1227 float durationSqr = duration * duration;
1228 float minHeight = m_spellInfo->Effects[i].MiscValue ? m_spellInfo->Effects[i].MiscValue / 10.0f : 0.5f; // Lower bound is blizzlike
1229 float maxHeight = m_spellInfo->Effects[i].MiscValueB ? m_spellInfo->Effects[i].MiscValueB / 10.0f : 1000.0f; // Upper bound is unknown
1230 float height;
1231 if (durationSqr < minHeight * 8 / Movement::gravity)
1232 height = minHeight;
1233 else if (durationSqr > maxHeight * 8 / Movement::gravity)
1234 height = maxHeight;
1235 else
1236 height = Movement::gravity * durationSqr / 8;
1237
1238 speedZ = std::sqrt(2 * Movement::gravity * height);
1239}
#define ASSERT
Definition Errors.h:68
@ MOVE_RUN
Definition UnitDefines.h:357
std::array< float, MAX_MOVE_TYPE > playerBaseMoveSpeed
Definition Unit.cpp:95
std::array< float, MAX_MOVE_TYPE > baseMoveSpeed
Definition Unit.cpp:94
Unit * GetUnitCasterForEffectHandlers() const
Definition Spell.cpp:8498
float GetSpeed(UnitMoveType mtype) const
Definition Unit.cpp:11109
bool IsControlledByPlayer() const
Definition Unit.h:1324
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:3378
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
8963{
8964 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8965 {
8966 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_CAST);
8967 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->AfterCast.end(), hookItr = (*scritr)->AfterCast.begin();
8968 for (; hookItr != hookItrEnd; ++hookItr)
8969 (*hookItr).Call(*scritr);
8970
8971 (*scritr)->_FinishScriptCall();
8972 }
8973}
@ 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
9075{
9076 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
9077 {
9078 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_AFTER_HIT);
9079 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->AfterHit.end(), hookItr = (*scritr)->AfterHit.begin();
9080 for (; hookItr != hookItrEnd; ++hookItr)
9081 (*hookItr).Call(*scritr);
9082
9083 (*scritr)->_FinishScriptCall();
9084 }
9085}
@ 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
8937{
8938 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8939 {
8940 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_CAST);
8941 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->BeforeCast.end(), hookItr = (*scritr)->BeforeCast.begin();
8942 for (; hookItr != hookItrEnd; ++hookItr)
8943 (*hookItr).Call(*scritr);
8944
8945 (*scritr)->_FinishScriptCall();
8946 }
8947}
@ 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
9049{
9050 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
9051 {
9052 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_BEFORE_HIT);
9053 std::list<SpellScript::BeforeHitHandler>::iterator hookItrEnd = (*scritr)->BeforeHit.end(), hookItr = (*scritr)->BeforeHit.begin();
9054 for (; hookItr != hookItrEnd; ++hookItr)
9055 (*hookItr).Call(*scritr, missInfo);
9056
9057 (*scritr)->_FinishScriptCall();
9058 }
9059}
@ 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
8976{
8978 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8979 {
8980 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_CHECK_CAST);
8981 std::list<SpellScript::CheckCastHandler>::iterator hookItrEnd = (*scritr)->OnCheckCast.end(), hookItr = (*scritr)->OnCheckCast.begin();
8982 for (; hookItr != hookItrEnd; ++hookItr)
8983 {
8984 SpellCastResult tempResult = (*hookItr).Call(*scritr);
8985 if (retVal == SPELL_CAST_OK)
8986 retVal = tempResult;
8987 }
8988
8989 (*scritr)->_FinishScriptCall();
8990 }
8991 return retVal;
8992}
@ 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
9116{
9117 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
9118 {
9119 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_DESTINATION_TARGET_SELECT);
9120 std::list<SpellScript::DestinationTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnDestinationTargetSelect.end(), hookItr = (*scritr)->OnDestinationTargetSelect.begin();
9121 for (; hookItr != hookItrEnd; ++hookItr)
9122 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
9123 hookItr->Call(*scritr, target);
9124
9125 (*scritr)->_FinishScriptCall();
9126 }
9127}
@ 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
9001{
9002 // execute script effect handler hooks and check if effects was prevented
9003 bool preventDefault = false;
9004 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
9005 {
9006 std::list<SpellScript::EffectHandler>::iterator effItr, effEndItr;
9007 SpellScriptHookType hookType;
9008 switch (mode)
9009 {
9011 effItr = (*scritr)->OnEffectLaunch.begin();
9012 effEndItr = (*scritr)->OnEffectLaunch.end();
9014 break;
9016 effItr = (*scritr)->OnEffectLaunchTarget.begin();
9017 effEndItr = (*scritr)->OnEffectLaunchTarget.end();
9019 break;
9021 effItr = (*scritr)->OnEffectHit.begin();
9022 effEndItr = (*scritr)->OnEffectHit.end();
9024 break;
9026 effItr = (*scritr)->OnEffectHitTarget.begin();
9027 effEndItr = (*scritr)->OnEffectHitTarget.end();
9029 break;
9030 default:
9031 ABORT();
9032 return false;
9033 }
9034 (*scritr)->_PrepareScriptCall(hookType);
9035 for (; effItr != effEndItr; ++effItr)
9036 // effect execution can be prevented
9037 if (!(*scritr)->_IsEffectPrevented(effIndex) && (*effItr).IsEffectAffected(m_spellInfo, effIndex))
9038 (*effItr).Call(*scritr, effIndex);
9039
9040 if (!preventDefault)
9041 preventDefault = (*scritr)->_IsDefaultEffectPrevented(effIndex);
9042
9043 (*scritr)->_FinishScriptCall();
9044 }
9045 return preventDefault;
9046}
#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
9088{
9089 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
9090 {
9091 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_AREA_TARGET_SELECT);
9092 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectAreaTargetSelect.end(), hookItr = (*scritr)->OnObjectAreaTargetSelect.begin();
9093 for (; hookItr != hookItrEnd; ++hookItr)
9094 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
9095 hookItr->Call(*scritr, targets);
9096
9097 (*scritr)->_FinishScriptCall();
9098 }
9099}
@ 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
9102{
9103 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
9104 {
9105 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_OBJECT_TARGET_SELECT);
9106 std::list<SpellScript::ObjectTargetSelectHandler>::iterator hookItrEnd = (*scritr)->OnObjectTargetSelect.end(), hookItr = (*scritr)->OnObjectTargetSelect.begin();
9107 for (; hookItr != hookItrEnd; ++hookItr)
9108 if (hookItr->IsEffectAffected(m_spellInfo, effIndex) && targetType.GetTarget() == hookItr->GetTarget())
9109 hookItr->Call(*scritr, target);
9110
9111 (*scritr)->_FinishScriptCall();
9112 }
9113}
@ 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
8950{
8951 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8952 {
8953 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_ON_CAST);
8954 std::list<SpellScript::CastHandler>::iterator hookItrEnd = (*scritr)->OnCast.end(), hookItr = (*scritr)->OnCast.begin();
8955 for (; hookItr != hookItrEnd; ++hookItr)
8956 (*hookItr).Call(*scritr);
8957
8958 (*scritr)->_FinishScriptCall();
8959 }
8960}
@ 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
9062{
9063 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
9064 {
9065 (*scritr)->_PrepareScriptCall(SPELL_SCRIPT_HOOK_HIT);
9066 std::list<SpellScript::HitHandler>::iterator hookItrEnd = (*scritr)->OnHit.end(), hookItr = (*scritr)->OnHit.begin();
9067 for (; hookItr != hookItrEnd; ++hookItr)
9068 (*hookItr).Call(*scritr);
9069
9070 (*scritr)->_FinishScriptCall();
9071 }
9072}
@ 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)
7301{
7302 ObjectGuid targetguid = target->GetGUID();
7303
7304 for (SpellEffectInfo const& spellEffectInfo : m_spellInfo->GetEffects())
7305 {
7306 if (!spellEffectInfo.IsAura())
7307 continue;
7308
7309 AuraType const& auraType = spellEffectInfo.ApplyAuraName;
7310 Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(auraType);
7311 for (Unit::AuraEffectList::const_iterator auraIt = auras.begin(); auraIt != auras.end(); ++auraIt)
7312 {
7313 if (GetSpellInfo()->Id == (*auraIt)->GetSpellInfo()->Id)
7314 return false;
7315
7316 switch (sSpellMgr->CheckSpellGroupStackRules(GetSpellInfo(), (*auraIt)->GetSpellInfo()))
7317 {
7319 return false;
7321 if (GetCaster() == (*auraIt)->GetCaster())
7322 return false;
7323 break;
7324 case SPELL_GROUP_STACK_RULE_EXCLUSIVE_SAME_EFFECT: // this one has further checks, but i don't think they're necessary for autocast logic
7326 if (abs(spellEffectInfo.BasePoints) <= abs((*auraIt)->GetAmount()))
7327 return false;
7328 break;
7330 default:
7331 break;
7332 }
7333 }
7334 }
7335
7336 SpellCastResult result = CheckPetCast(target);
7337
7338 if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
7339 {
7341 //check if among target units, our WANTED target is as well (->only self cast spells return false)
7342 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
7343 if (ihit->targetGUID == targetguid)
7344 return true;
7345 }
7346 return false; //target invalid
7347}
@ 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:591
SpellCastResult CheckPetCast(Unit *target)
Definition Spell.cpp:7103

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)
3831{
3832 Unit* unitCaster = m_caster->ToUnit();
3834 return;
3835
3836 uint32 oldState = m_spellState;
3838
3839 m_autoRepeat = false;
3840 switch (oldState)
3841 {
3845
3846 if (unitCaster && unitCaster->IsPlayer())
3847 {
3848 if (unitCaster->ToPlayer()->NeedSendSpectatorData())
3849 ArenaSpectator::SendCommand_Spell(unitCaster->FindMap(), unitCaster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3850 }
3851 [[fallthrough]];
3854 break;
3856 if (!bySelf)
3857 {
3858 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3859 if ((*ihit).missCondition == SPELL_MISS_NONE)
3860 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? unitCaster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3861 unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
3862
3863 if (unitCaster && unitCaster->IsPlayer() && m_spellInfo->IsCooldownStartedOnEvent())
3864 unitCaster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
3865
3868 }
3869
3870 if (unitCaster && unitCaster->IsPlayer() && unitCaster->ToPlayer()->NeedSendSpectatorData())
3871 ArenaSpectator::SendCommand_Spell(unitCaster->FindMap(), unitCaster->GetGUID(), "SPE", m_spellInfo->Id, bySelf ? 99998 : 99999);
3872
3873 // spell is canceled-take mods and clear list
3874 if (Player* player = m_caster->GetSpellModOwner())
3875 player->RemoveSpellMods(this);
3876
3877 m_appliedMods.clear();
3878 break;
3879 default:
3880 break;
3881 }
3882
3884 if (m_selfContainer && *m_selfContainer == this)
3885 *m_selfContainer = nullptr;
3886
3887 // Do not remove current far sight object (already done in Spell::EffectAddFarsight) to prevent from reset viewpoint to player
3889 {
3890 if (unitCaster)
3891 unitCaster->RemoveDynObject(m_spellInfo->Id);
3892 }
3893
3894 if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet
3895 {
3896 if (unitCaster)
3897 {
3898 if (GameObject* gameObject = unitCaster->GetGameObject(m_spellInfo->Id))
3899 {
3900 unitCaster->RemoveGameObject(gameObject, true);
3901 if (gameObject->GetGoType() == GAMEOBJECT_TYPE_SUMMONING_RITUAL && unitCaster->IsPlayer())
3902 unitCaster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
3903 }
3904 }
3905 }
3906
3907 //set state back so finish will be processed
3908 m_spellState = oldState;
3909
3910 sScriptMgr->OnSpellCastCancel(this, unitCaster, m_spellInfo, bySelf);
3911
3912 finish(false);
3913}
@ 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:125
bool NeedSendSpectatorData() const
Definition Player.cpp:15903
void SendChannelUpdate(uint32 time)
Definition Spell.cpp:5365
void CancelGlobalCooldown()
Definition Spell.cpp:9315
void SetReferencedFromCurrent(bool yes)
Definition Spell.h:577
UsedSpellMods m_appliedMods
Definition Spell.h:560
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:6384
GameObject * GetGameObject(uint32 spellId) const
Definition Unit.cpp:6356
bool RemoveDynObject(uint32 spellId)
Definition Unit.cpp:6328
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
9316{
9317 Unit* unitCaster = m_caster->ToUnit();
9318 if (!unitCaster)
9319 return;
9320
9322 return;
9323
9324 // Cancel global cooldown when interrupting current cast
9325 if (unitCaster->GetCurrentSpell(CURRENT_GENERIC_SPELL) != this)
9326 return;
9327
9328 // Only players or controlled units have global cooldown
9329 if (unitCaster->GetCharmInfo())
9331 else if (unitCaster->IsPlayer())
9333}
@ CURRENT_GENERIC_SPELL
Definition Unit.h:564
void CancelGlobalCooldown(SpellInfo const *spellInfo)
Definition CharmInfo.cpp:424
GlobalCooldownMgr & GetGlobalCooldownMgr()
Definition Player.h:1833
uint32 StartRecoveryTime
Definition SpellInfo.h:375
CharmInfo * GetCharmInfo()
Definition Unit.h:1298
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:1593
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
9153{
9154 // Relentless strikes, proc only from first effect
9155 if (triggeredByAura && triggeredByAura->SpellIconID == 559)
9156 return effMask & (1 << EFFECT_0);
9157
9158 bool only_on_caster = (triggeredByAura && triggeredByAura->HasAttribute(SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET));
9159 // If triggeredByAura has SPELL_ATTR4_CLASS_TRIGGER_ONLY_ON_TARGET then it can only proc on a casted spell with TARGET_UNIT_CASTER
9160 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
9161 {
9162 if ((effMask & (1 << i)) && (!only_on_caster || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)))
9163 return true;
9164 }
9165 return effMask;
9166}
@ 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
8767{
8768 Unit* unitCaster = m_caster->ToUnit();
8769 if (!lockId) // possible case for GO and maybe for items.
8770 return SPELL_CAST_OK;
8771
8772 // Get LockInfo
8773 LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
8774
8775 if (!lockInfo)
8777
8778 bool reqKey = false; // some locks not have reqs
8779
8780 for (int j = 0; j < MAX_LOCK_CASE; ++j)
8781 {
8782 switch (lockInfo->Type[j])
8783 {
8784 // check key item (many fit cases can be)
8785 case LOCK_KEY_ITEM:
8786 if (lockInfo->Index[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->Index[j])
8787 return SPELL_CAST_OK;
8788 reqKey = true;
8789 break;
8790 // check key skill (only single first fit case can be)
8791 case LOCK_KEY_SKILL:
8792 {
8793 reqKey = true;
8794
8795 // wrong locktype, skip
8796 if (uint32(m_spellInfo->Effects[effIndex].MiscValue) != lockInfo->Index[j])
8797 continue;
8798
8799 skillId = SkillByLockType(LockType(lockInfo->Index[j]));
8800
8801 if (skillId != SKILL_NONE)
8802 {
8803 reqSkillValue = lockInfo->Skill[j];
8804
8805 // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
8806 skillValue = m_CastItem || !unitCaster || !unitCaster->IsPlayer() ?
8807 0 : unitCaster->ToPlayer()->GetSkillValue(skillId);
8808
8809 // skill bonus provided by casting spell (mostly item spells)
8810 // add the effect base points modifier from the spell casted (cheat lock / skeleton key etc.)
8811 if ((m_spellInfo->Effects[effIndex].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET || m_spellInfo->Effects[effIndex].TargetB.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET)
8813 {
8814 skillValue += m_spellInfo->Effects[effIndex].CalcValue();
8815 }
8816
8817 if (skillValue < reqSkillValue)
8819 }
8820
8821 return SPELL_CAST_OK;
8822 }
8823 case LOCK_KEY_SPELL:
8824 {
8825 if (m_spellInfo->Id == lockInfo->Index[j])
8826 {
8827 return SPELL_CAST_OK;
8828 }
8829 reqKey = true;
8830 break;
8831 }
8832 }
8833 }
8834
8835 if (reqKey)
8837
8838 return SPELL_CAST_OK;
8839}
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:5644
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)
3916{
3917 Player* modOwner = m_caster->GetSpellModOwner();
3918 Spell* lastMod = nullptr;
3919 if (modOwner)
3920 {
3921 lastMod = modOwner->m_spellModTakingSpell;
3922 if (lastMod)
3923 modOwner->SetSpellModTakingSpell(lastMod, false);
3924 }
3925
3926 _cast(skipCheck);
3927
3928 if (lastMod)
3929 modOwner->SetSpellModTakingSpell(lastMod, true);
3930}
Spell * m_spellModTakingSpell
Definition Player.h:2607
Definition Spell.h:298
void _cast(bool skipCheck)
Definition Spell.cpp:3932

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
5875{
5876 Unit* unitCaster = m_caster->ToUnit();
5877 // check death state
5880
5881 // Spectator check
5882 if (unitCaster && unitCaster->IsPlayer())
5883 if (((Player const*)unitCaster)->IsSpectator() && m_spellInfo->Id != SPECTATOR_SPELL_BINDSIGHT)
5884 return SPELL_FAILED_NOT_HERE;
5885
5887
5888 sScriptMgr->OnSpellCheckCast(this, strict, res);
5889
5890 if (res != SPELL_CAST_OK)
5891 return res;
5892
5893 // check cooldowns to prevent cheating
5895 {
5896 if (unitCaster && unitCaster->IsPlayer())
5897 {
5898 //can cast triggered (by aura only?) spells while have this flag
5901
5903 {
5906 else
5908 }
5909
5910 // check if we are using a potion in combat for the 2nd+ time. Cooldown is added only after caster gets out of combat
5913 }
5914 else if (!IsTriggered() && unitCaster && unitCaster->IsCreature() && unitCaster->ToCreature()->IsSpellProhibited(m_spellInfo->GetSchoolMask()))
5916 }
5917
5919 {
5922 }
5923
5924 // Check global cooldown
5927
5928 // only triggered spells can be processed an ended battleground
5929 if (!IsTriggered() && unitCaster && unitCaster->IsPlayer())
5930 if (Battleground* bg = unitCaster->ToPlayer()->GetBattleground())
5931 if (bg->GetStatus() == STATUS_WAIT_LEAVE)
5933
5934 if (unitCaster && unitCaster->IsPlayer() /*&& VMAP::VMapFactory::createOrGetVMapMgr()->isLineOfSightCalcEnabled()*/) // pussywizard: optimization (commented)
5935 {
5937 !unitCaster->IsOutdoors())
5939
5941 unitCaster->IsOutdoors())
5943 }
5944
5945 // only check at first call, Stealth auras are already removed at second call
5946 // for now, ignore triggered spells
5947 if (strict && unitCaster && !HasTriggeredCastFlag(TRIGGERED_IGNORE_SHAPESHIFT))
5948 {
5949 bool checkForm = true;
5950 // Ignore form req aura
5952 for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
5953 {
5954 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
5955 continue;
5956 checkForm = false;
5957 break;
5958 }
5959 if (checkForm)
5960 {
5961 // Cannot be used in this stance/form
5962 SpellCastResult shapeError = m_spellInfo->CheckShapeshift(unitCaster->GetShapeshiftForm());
5963 if (shapeError != SPELL_CAST_OK)
5964 return shapeError;
5965
5968 }
5969 }
5970
5971 bool reqCombat = true;
5972 if (unitCaster)
5973 {
5975 for (Unit::AuraEffectList::const_iterator blockItr = blockSpells.begin(); blockItr != blockSpells.end(); ++blockItr)
5976 if (uint32((*blockItr)->GetMiscValue()) == m_spellInfo->SpellFamilyName)
5978
5980 for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
5981 {
5982 if ((*j)->IsAffectedOnSpell(m_spellInfo))
5983 {
5984 m_needComboPoints = false;
5985 if ((*j)->GetMiscValue() == 1)
5986 {
5987 reqCombat = false;
5988 break;
5989 }
5990 }
5991 }
5992 }
5993
5994 // caster state requirements
5995 // not for triggered spells (needed by execute)
5997 {
6002
6003 // Note: spell 62473 requres CasterAuraSpell = triggering spell
6004 if (m_spellInfo->CasterAuraSpell && !unitCaster->HasAura(sSpellMgr->GetSpellIdForDifficulty(m_spellInfo->CasterAuraSpell, m_caster)))
6006 if (m_spellInfo->ExcludeCasterAuraSpell && unitCaster->HasAura(sSpellMgr->GetSpellIdForDifficulty(m_spellInfo->ExcludeCasterAuraSpell, m_caster)))
6008
6009 if (reqCombat && unitCaster->IsInCombat() && !m_spellInfo->CanBeUsedInCombat())
6011 }
6012
6013 // Xinef: exploit protection
6015 {
6016 if (unitCaster && unitCaster->IsPlayer() && unitCaster->GetMap()->IsDungeon())
6017 if (InstanceScript* instanceScript = unitCaster->GetInstanceScript())
6018 if (instanceScript->IsEncounterInProgress())
6019 {
6020 if (Group* group = unitCaster->ToPlayer()->GetGroup())
6021 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
6022 if (Player* member = itr->GetSource())
6023 if (member->IsInMap(unitCaster))
6024 if (Unit* victim = member->GetVictim())
6025 if (victim->IsInCombat() && unitCaster->GetDistance(victim) < unitCaster->GetVisibilityRange())
6026 {
6027 unitCaster->EngageWithTarget(victim);
6028 break;
6029 }
6031 }
6032 }
6033
6034 // cancel autorepeat spells if cast start when moving
6035 // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
6036 if (unitCaster && unitCaster->IsPlayer() && unitCaster->ToPlayer()->isMoving() && !IsTriggered())
6037 {
6038 // skip stuck spell to allow use it in falling case and apply spell limitations at movement
6041 return SPELL_FAILED_MOVING;
6042 }
6043
6044 Vehicle* vehicle = unitCaster ? unitCaster->GetVehicle() : nullptr;
6046 {
6047 uint16 checkMask = 0;
6048 for (uint8 effIndex = EFFECT_0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
6049 {
6050 SpellEffectInfo const* effInfo = &m_spellInfo->Effects[effIndex];
6052 {
6053 SpellShapeshiftFormEntry const* shapeShiftEntry = sSpellShapeshiftFormStore.LookupEntry(effInfo->MiscValue);
6054 if (shapeShiftEntry && (shapeShiftEntry->flags1 & SHAPESHIFT_FLAG_STANCE) == 0)
6055 checkMask |= VEHICLE_SEAT_FLAG_UNCONTROLLED;
6056 break;
6057 }
6058 }
6059
6062
6063 if (!checkMask)
6064 checkMask = VEHICLE_SEAT_FLAG_CAN_ATTACK;
6065
6066 // All creatures should be able to cast as passengers freely, restriction and attribute are only for players
6067 VehicleSeatEntry const* vehicleSeat = vehicle->GetSeatForPassenger(unitCaster);
6069 && (vehicleSeat->m_flags & checkMask) != checkMask && unitCaster->IsPlayer())
6071 }
6072
6073 // check spell cast conditions from database
6074 {
6075 ConditionSourceInfo condInfo = ConditionSourceInfo(unitCaster);
6077 ConditionList conditions = sConditionMgr->GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
6078 if (!conditions.empty() && !sConditionMgr->IsObjectMeetToConditions(condInfo, conditions))
6079 {
6080 // mLastFailedCondition can be nullptr if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
6081 if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
6082 {
6086 }
6087 if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
6090 }
6091 }
6092
6093 // Don't check explicit target for passive spells (workaround) (check should be skipped only for learn case)
6094 // those spells may have incorrect target entries or not filled at all (for example 15332)
6095 // such spells when learned are not targeting anyone using targeting system, they should apply directly to caster instead
6096 // also, such casts shouldn't be sent to client
6097 // Xinef: do not check explicit casts for self cast of triggered spells (eg. reflect case)
6099 {
6100 // Check explicit target for m_originalCaster - todo: get rid of such workarounds
6101 // Xinef: do not check explicit target for triggered spell casted on self with targetflag enemy
6103 {
6105 if (castResult != SPELL_CAST_OK)
6106 return castResult;
6107 }
6108 }
6109
6110 if (Unit* target = m_targets.GetUnitTarget())
6111 {
6112 SpellCastResult castResult = m_spellInfo->CheckTarget(m_caster, target, false,
6114 if (castResult != SPELL_CAST_OK)
6115 return castResult;
6116
6117 if (target != unitCaster)
6118 {
6119 // Must be behind the target
6120 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET) && target->HasInArc(static_cast<float>(M_PI), unitCaster))
6122
6123 // Target must be facing you
6124 if (m_spellInfo->HasAttribute(SPELL_ATTR0_CU_REQ_TARGET_FACING_CASTER) && !target->HasInArc(static_cast<float>(M_PI), unitCaster))
6126
6127 // A unit riding a player sits on their back (Gormok's Snobold Vassals), out of reach of their targeted harmful spells
6128 if (unitCaster && unitCaster->IsPlayer() && target->GetVehicleBase() == unitCaster && !m_spellInfo->IsPositive())
6130
6131 // Ignore LOS for gameobject casts: one has no collision height, so the ray would start on its floor
6132 // position, which the floor under a player standing on it can block. CheckEffectTarget still checks
6133 // LOS for gameobjects that do not ignore it.
6134 if (!m_caster->IsGameObject() && (!unitCaster || !unitCaster->IsTotem() || !m_spellInfo->IsPositive()) &&
6137 {
6138 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
6139 if (GetGameObjectCaster())
6140 {
6141 // If spell casted by gameobject then ignore M2 models
6142 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
6143 }
6144
6146 {
6148 }
6149 }
6150 }
6151 }
6152
6153 // Check for line of sight for spells with dest
6154 if (m_targets.HasDst())
6155 {
6156 float x, y, z;
6157 m_targets.GetDstPos()->GetPosition(x, y, z);
6158
6159 if ((!unitCaster || !unitCaster->IsTotem() || !m_spellInfo->IsPositive()) && !m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) &&
6161 {
6162 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
6163 if (GetGameObjectCaster())
6164 {
6165 // If spell casted by gameobject then ignore M2 models
6166 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
6167 }
6168
6169 // An owned GameObject is measured from its owner's height, as for a unit target
6170 bool inLineOfSight = false;
6171 if (std::optional<float> collisionHeight = GetLOSCollisionHeight())
6173 m_caster->GetPositionZ() + *collisionHeight, x, y, z + *collisionHeight, m_caster->GetPhaseMask(),
6175 else
6176 inLineOfSight = m_caster->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2,
6177 LineOfSightChecks(losChecks));
6178
6179 if (!inLineOfSight)
6180 {
6182 }
6183 }
6184 }
6185
6186 // check pet presence
6187 for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
6188 {
6189 if (m_spellInfo->Effects[j].TargetA.GetTarget() == TARGET_UNIT_PET)
6190 {
6191 if (!unitCaster || (!unitCaster->GetGuardianPet() && !unitCaster->GetCharm()))
6192 {
6193 if (m_triggeredByAuraSpell.spellInfo) // not report pet not existence for triggered spells
6195 else
6196 return SPELL_FAILED_NO_PET;
6197 }
6198 break;
6199 }
6200 }
6201 // Spell casted only on battleground
6202 if (m_spellInfo->HasAttribute(SPELL_ATTR3_ONLY_BATTLEGROUNDS) && unitCaster && unitCaster->IsPlayer())
6203 if (!unitCaster->ToPlayer()->InBattleground())
6205
6206 // do not allow spells to be cast in arenas
6207 // - with greater than 10 min CD without SPELL_ATTR4_IGNORE_DEFAULT_ARENA_RESTRICTIONS flag
6208 // - with SPELL_ATTR4_NOT_IN_ARENA_OR_RATED_BATTLEGROUND flag
6211 if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
6212 if (mapEntry->IsBattleArena())
6214
6215 // zone check
6216 if (!unitCaster || unitCaster->IsCreature() || !unitCaster->ToPlayer()->IsGameMaster())
6217 {
6218 uint32 zone, area;
6219 m_caster->GetZoneAndAreaId(zone, area);
6220
6222 m_caster->ToPlayer());
6223 if (locRes != SPELL_CAST_OK)
6224 return locRes;
6225 }
6226
6227 // not let players cast spells at mount (and let do it to creatures)
6228 if (unitCaster && unitCaster->IsMounted() && unitCaster->IsPlayer() && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE) &&
6230 {
6231 if (unitCaster->IsInFlight())
6233 else
6235 }
6236
6237 SpellCastResult castResult = SPELL_CAST_OK;
6238
6239 // always (except passive spells) check items (focus object can be required for any type casts)
6240 if (!m_spellInfo->IsPassive())
6241 {
6242 // spell focus needs to be checked not only for players! there are vehicle spells that require spell focus
6243 castResult = CheckSpellFocus();
6244 if (castResult != SPELL_CAST_OK)
6245 return castResult;
6246
6247 castResult = CheckItems();
6248 if (castResult != SPELL_CAST_OK)
6249 return castResult;
6250 }
6251
6252 // Triggered spells also have range check
6254 castResult = CheckRange(strict);
6255 if (castResult != SPELL_CAST_OK)
6256 return castResult;
6257
6259 {
6260 castResult = CheckPower();
6261 if (castResult != SPELL_CAST_OK)
6262 return castResult;
6263 }
6264
6266 {
6267 return SPELL_CAST_OK;
6268 }
6269
6270 // xinef: do not skip triggered spells if they posses prevention type (eg. Bladestorm vs Hand of Protection)
6272 {
6274 if (castResult != SPELL_CAST_OK)
6275 return castResult;
6276
6277 // 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).
6278 if (unitCaster && m_spellInfo->Mechanic && m_spellInfo->IsSelfCast()
6280 {
6281 auto const& mechanicList = unitCaster->m_spellImmune[IMMUNITY_MECHANIC];
6282 if (mechanicList.count(m_spellInfo->Mechanic) > 0)
6284 }
6285 }
6286
6287 // script hook
6288 castResult = CallScriptCheckCastHandlers();
6289 if (castResult != SPELL_CAST_OK)
6290 return castResult;
6291
6292 bool hasDispellableAura = false;
6293 bool hasNonDispelEffect = false;
6294 uint32 dispelMask = 0;
6295 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6296 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_DISPEL)
6297 {
6299 {
6300 hasDispellableAura = true;
6301 break;
6302 }
6303
6304 dispelMask |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
6305 }
6306 else if (m_spellInfo->Effects[i].IsEffect())
6307 {
6308 hasNonDispelEffect = true;
6309 break;
6310 }
6311
6312 if (!hasNonDispelEffect && !hasDispellableAura && dispelMask && !IsTriggered())
6313 {
6314 if (Unit* target = m_targets.GetUnitTarget())
6315 {
6316 // Xinef: do not allow to cast on hostile targets in sanctuary
6317 if (unitCaster && !unitCaster->IsFriendlyTo(target))
6318 {
6319 if (unitCaster->IsInSanctuary() || target->IsInSanctuary())
6320 {
6321 // Xinef: fix for duels
6322 Player* player = unitCaster->ToPlayer();
6323 if (!player || !player->duel || target != player->duel->Opponent)
6325 }
6326 }
6327
6328 DispelChargesList dispelList;
6329 target->GetDispellableAuraList(unitCaster, dispelMask, dispelList, m_spellInfo);
6330
6331 if (dispelList.empty())
6333 }
6334 }
6335
6336 uint8 approximateAuraEffectMask = 0;
6337 uint8 nonAuraEffectMask = 0;
6338 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6339 {
6340 // for effects of spells that have only one target
6341 switch (m_spellInfo->Effects[i].Effect)
6342 {
6344 {
6345 if (!unitCaster || !unitCaster->IsPlayer())
6347
6348 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_UNIT_PET)
6349 break;
6350
6351 Pet* pet = unitCaster->ToPlayer()->GetPet();
6352
6353 if (!pet)
6354 return SPELL_FAILED_NO_PET;
6355
6356 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6357
6358 if (!learn_spellproto)
6360
6361 if (m_spellInfo->SpellLevel > pet->GetLevel())
6362 return SPELL_FAILED_LOWLEVEL;
6363
6364 break;
6365 }
6367 {
6368 // check target only for unit target case
6370 {
6371 if (!unitCaster || !unitCaster->IsPlayer())
6373
6374 Pet* pet = unitTarget->ToPet();
6375 if (!pet || pet->GetOwner() != unitCaster)
6377
6378 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[i].TriggerSpell);
6379
6380 if (!learn_spellproto)
6382
6383 if (m_spellInfo->SpellLevel > pet->GetLevel())
6384 return SPELL_FAILED_LOWLEVEL;
6385 }
6386 break;
6387 }
6389 {
6390 uint32 glyphId = m_spellInfo->Effects[i].MiscValue;
6391 if (GlyphPropertiesEntry const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
6392 if (unitCaster && unitCaster->HasAura(gp->SpellId))
6394 break;
6395 }
6397 {
6398 if (!unitCaster || !unitCaster->IsPlayer())
6400
6401 Item* foodItem = m_targets.GetItemTarget();
6402 if (!foodItem)
6404
6405 Pet* pet = unitCaster->ToPlayer()->GetPet();
6406
6407 if (!pet)
6408 return SPELL_FAILED_NO_PET;
6409
6410 if (!pet->HaveInDiet(foodItem->GetTemplate()))
6412
6413 if (!pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel))
6415
6416 if (unitCaster->IsInCombat() || pet->IsInCombat())
6418
6419 break;
6420 }
6423 {
6424 // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
6425 if (unitCaster && unitCaster->IsPlayer())
6426 if (Unit* target = m_targets.GetUnitTarget())
6427 if (target != m_caster && !target->HasActivePowerType(Powers(m_spellInfo->Effects[i].MiscValue)))
6429 break;
6430 }
6432 {
6433 if (unitCaster && unitCaster->HasUnitState(UNIT_STATE_CHARGING))
6434 {
6436 }
6437
6439 {
6440 // Warbringer - can't be handled in proc system - should be done before checkcast root check and charge effect process
6441 if (strict && unitCaster && unitCaster->IsScriptOverriden(m_spellInfo, 6953))
6442 unitCaster->RemoveMovementImpairingAuras(true);
6443 }
6444 if (unitCaster && unitCaster->HasUnitState(UNIT_STATE_ROOT))
6445 {
6446 // Exception for Master's Call
6447 if (m_spellInfo->Id != 54216)
6448 {
6449 return SPELL_FAILED_ROOTED;
6450 }
6451 }
6452 if (unitCaster && unitCaster->IsPlayer())
6453 if (Unit* target = m_targets.GetUnitTarget())
6454 if (!target->IsAlive())
6456 // Xinef: Pass only explicit unit target spells
6457 // pussywizard:
6458 if (unitCaster && sDisableMgr->IsPathfindingEnabled(unitCaster->FindMap()) && m_spellInfo->NeedsExplicitUnitTarget())
6459 {
6460 Unit* target = m_targets.GetUnitTarget();
6461 if (!target)
6463
6464 // first we must check to see if the target is in LoS. A path can usually be built but LoS matters for charge spells
6465 if (!target->IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
6467
6468 float objSize = target->GetCombatReach();
6469 float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
6470
6471 m_preGeneratedPath = std::make_unique<PathGenerator>(unitCaster);
6472 m_preGeneratedPath->SetPathLengthLimit(range);
6473
6474 float destX = target->GetPositionX();
6475 float destY = target->GetPositionY();
6476 float destZ = target->GetPositionZ();
6477 bool cutPath = true;
6478
6479 // first try with raycast, if it fails fall back to normal path
6480 bool result = m_preGeneratedPath->CalculatePath(destX, destY, destZ, false);
6481 bool pathFailed = !result || (m_preGeneratedPath->GetPathType() &
6483
6484 // Targets with an oversized combat reach can stand entirely over unwalkable space
6485 // (e.g. Kologarn) so pathing to their center fails or creates a falling shortcut into the void.
6486 // For these targets, fall back to pathing to the nearest walkable point on the melee ring facing the caster.
6487 if (target->GetCombatReach() > NOMINAL_MELEE_RANGE &&
6488 (pathFailed ||
6489 m_preGeneratedPath->IsInvalidDestinationZ(target) ||
6491 {
6492 float const targetZ = target->GetPositionZ();
6493 float const angle = target->GetAngle(m_caster);
6494 bool foundWalkable = false;
6495
6496 // Find the nearest point along the melee ring facing the caster that has walkable ground.
6497 // For targets standing over a void (e.g. Kologarn), the immediate contact ring (offset 0)
6498 // hangs over the chasm, while solid bridge ground begins slightly further out.
6499 for (float distOffset = 0.0f; distOffset <= NOMINAL_MELEE_RANGE; distOffset += 0.5f)
6500 {
6501 float testX, testY;
6502 target->GetNearPoint2D(m_caster, testX, testY, distOffset, angle);
6503 float groundZ = m_caster->GetMapHeight(testX, testY, targetZ);
6504 if (groundZ > INVALID_HEIGHT && std::abs(groundZ - targetZ) <= 5.0f)
6505 {
6506 destX = testX;
6507 destY = testY;
6508 destZ = groundZ;
6509 m_caster->UpdateAllowedPositionZ(destX, destY, destZ);
6510 foundWalkable = true;
6511 break;
6512 }
6513 }
6514
6515 if (!foundWalkable)
6516 return SPELL_FAILED_NOPATH;
6517
6518 cutPath = false;
6519
6520 result = m_preGeneratedPath->CalculatePath(destX, destY, destZ, false);
6521 pathFailed = !result || (m_preGeneratedPath->GetPathType() &
6523 }
6524
6525 if (pathFailed)
6526 return SPELL_FAILED_NOPATH;
6527 else if (cutPath && m_preGeneratedPath->IsInvalidDestinationZ(target))
6528 return SPELL_FAILED_NOPATH;
6529 else if (!cutPath && std::abs(m_preGeneratedPath->GetActualEndPosition().z - destZ) > 5.0f)
6530 return SPELL_FAILED_NOPATH;
6531
6532 if (cutPath)
6533 {
6534 m_preGeneratedPath->ShortenPathUntilDist(
6535 G3D::Vector3(destX, destY, destZ), objSize);
6536 }
6537 }
6538 if (Player* player = unitCaster ? unitCaster->ToPlayer() : nullptr)
6539 player->SetCanTeleport(true);
6540 break;
6541 }
6543 {
6544 if (!unitCaster || !unitCaster->IsPlayer() || !m_targets.GetUnitTarget() || !m_targets.GetUnitTarget()->IsCreature())
6546
6549
6550 Creature* creature = m_targets.GetUnitTarget()->ToCreature();
6551 if (!creature->IsCritter() && !creature->loot.isLooted())
6553
6554 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
6555
6556 int32 skillValue = unitCaster->ToPlayer()->GetSkillValue(skill);
6557 int32 TargetLevel = m_targets.GetUnitTarget()->GetLevel();
6558 int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
6559 if (ReqValue > skillValue)
6561
6562 break;
6563 }
6565 {
6566 if (m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_TARGET &&
6567 m_spellInfo->Effects[i].TargetA.GetTarget() != TARGET_GAMEOBJECT_ITEM_TARGET)
6568 break;
6569
6570 if (!unitCaster || !unitCaster->IsPlayer() // only players can open locks, gather etc.
6571 // we need a go target in case of TARGET_GAMEOBJECT_TARGET
6572 || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget()))
6574
6575 Item* pTempItem = nullptr;
6577 {
6578 if (TradeData* pTrade = unitCaster->ToPlayer()->GetTradeData())
6579 pTempItem = pTrade->GetTraderData()->GetItem(TradeSlots(m_targets.GetItemTargetGUID().GetRawValue()));
6580 }
6582 pTempItem = unitCaster->ToPlayer()->GetItemByGuid(m_targets.GetItemTargetGUID());
6583
6584 // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
6585 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_ITEM_TARGET &&
6587 (!pTempItem || !pTempItem->GetTemplate()->LockID || !pTempItem->IsLocked()))
6589
6590 // We must also ensure the gameobject we are opening is still closed by the time the spell finishes.
6591 if (GameObject* go = m_targets.GetGOTarget())
6592 {
6593 if (go->GetGoType() == GAMEOBJECT_TYPE_DOOR && go->GetGoState() != GO_STATE_READY)
6594 {
6596 }
6597 }
6598 if (m_spellInfo->Id != 1842 || (m_targets.GetGOTarget() &&
6600 {
6601 if (m_targets.GetGOTarget() && m_targets.GetGOTarget()->GetEntry() == 179697)
6602 {
6603 if (!unitCaster->ToPlayer()->CanUseBattlegroundObject(nullptr))
6605 }
6606 else if (unitCaster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners, or Gurubashi chest
6609 }
6610
6611 // get the lock entry
6612 uint32 lockId = 0;
6613 if (GameObject* go = m_targets.GetGOTarget())
6614 {
6615 lockId = go->GetGOInfo()->GetLockId();
6616 if (!lockId)
6618 }
6619 else if (Item* itm = m_targets.GetItemTarget())
6620 lockId = itm->GetTemplate()->LockID;
6621
6622 SkillType skillId = SKILL_NONE;
6623 int32 reqSkillValue = 0;
6624 int32 skillValue = 0;
6625
6626 // check lock compatibility
6627 SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
6628 if (res != SPELL_CAST_OK)
6629 return res;
6630
6631 // chance for fail at lockpicking attempt
6632 // second check prevent fail at rechecks
6633 // herbalism and mining cannot fail as of patch 3.1.0
6634 if (skillId != SKILL_NONE && skillId != SKILL_HERBALISM && skillId != SKILL_MINING && (!m_selfContainer || ((*m_selfContainer) != this)))
6635 {
6636 // chance for failure in orange lockpick
6637 if (skillId == SKILL_LOCKPICKING && reqSkillValue > irand(skillValue - 25, skillValue + 37))
6638 {
6640 }
6641 }
6642 break;
6643 }
6645 {
6646 Unit* unitCaster = m_caster->ToUnit();
6647 if (!unitCaster)
6648 {
6650 }
6651
6652 Creature* pet = unitCaster->GetGuardianPet();
6653 if (pet)
6654 {
6655 if (pet->IsAlive())
6656 {
6658 }
6659 }
6660 else if (Player* playerCaster = unitCaster->ToPlayer())
6661 {
6662 PetStable& petStable = playerCaster->GetOrInitPetStable();
6663 if (!petStable.CurrentPet && petStable.UnslottedPets.empty())
6664 {
6665 return SPELL_FAILED_NO_PET;
6666 }
6667 }
6668
6669 break;
6670 }
6671 // This is generic summon effect
6673 {
6674 SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[i].MiscValueB);
6675 if (!SummonProperties || m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET_FIRST))
6676 break;
6677 switch (SummonProperties->Category)
6678 {
6680 if (unitCaster && unitCaster->GetPetGUID())
6682 [[fallthrough]];
6684 if (unitCaster && unitCaster->GetCharmGUID())
6686 break;
6687 }
6688 break;
6689 }
6691 {
6693 {
6698 }
6699 break;
6700 }
6702 {
6703 Unit* unitCaster = m_caster->ToUnit();
6704 if (!unitCaster)
6706
6708 {
6709 if (unitCaster && unitCaster->GetPetGUID())
6711 if (unitCaster && unitCaster->GetCharmGUID())
6713 }
6714
6715 if (unitCaster && unitCaster->IsPlayer() && unitCaster->IsClass(CLASS_WARLOCK, CLASS_CONTEXT_PET) && strict)
6716 if (Pet* pet = unitCaster->ToPlayer()->GetPet())
6717 pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); //starting cast, trigger pet stun (cast by pet so it doesn't attack player)
6718
6719 Player* playerCaster = unitCaster ? unitCaster->ToPlayer() : nullptr;
6720 if (playerCaster && playerCaster->GetPetStable())
6721 {
6722 std::pair<PetStable::PetInfo const*, PetSaveMode> info = Pet::GetLoadPetInfo(*playerCaster->GetPetStable(), m_spellInfo->Effects[i].MiscValue, 0, false);
6723 if (info.first)
6724 {
6725 if (info.first->Type == HUNTER_PET)
6726 {
6727 if (!info.first->Health)
6728 {
6729 playerCaster->SendTameFailure(PET_TAME_DEAD);
6731 }
6732
6733 CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(info.first->CreatureId);
6734 if (!creatureInfo || !creatureInfo->IsTameable(playerCaster->CanTameExoticPets()))
6735 {
6736 // if problem in exotic pet
6737 if (creatureInfo && creatureInfo->IsTameable(true))
6739 else
6741
6743 }
6744 }
6745 }
6746 else if (!m_spellInfo->Effects[i].MiscValue) // when miscvalue is present it is allowed to create new pets
6747 {
6750 }
6751 }
6752 break;
6753 }
6755 {
6756 if (!unitCaster || !unitCaster->IsPlayer())
6758 if (!unitCaster || !unitCaster->GetTarget())
6760
6761 Player* target = ObjectAccessor::FindPlayer(unitCaster->ToPlayer()->GetTarget());
6762 if (!target || (!target->IsInSameRaidWith(unitCaster->ToPlayer()) && m_spellInfo->Id != 48955)) // refer-a-friend spell
6764
6765 // Xinef: Implement summon pending error
6766 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6768
6769 // check if our map is dungeon
6770 MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
6771 if (map->IsDungeon())
6772 {
6773 uint32 mapId = m_caster->GetMap()->GetId();
6774 Difficulty difficulty = m_caster->GetMap()->GetDifficulty();
6775 /*if (map->IsRaid())
6776 if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
6777 if (targetBind->perm && targetBind != unitCaster->ToPlayer()->GetBoundInstance(mapId, difficulty))
6778 return SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE;*/
6779
6780 InstanceTemplate const* instance = sObjectMgr->GetInstanceTemplate(mapId);
6781 if (!instance)
6783 if (!target->Satisfy(sObjectMgr->GetAccessRequirement(mapId, difficulty), mapId))
6785 }
6786 break;
6787 }
6788 // RETURN HERE
6790 {
6791 if (!unitCaster || !unitCaster->IsPlayer())
6793
6794 Player* playerCaster = unitCaster->ToPlayer();
6795 //
6796 if (!(playerCaster->GetTarget()))
6798
6799 Player* target = ObjectAccessor::FindPlayer(unitCaster->ToPlayer()->GetTarget());
6800
6801 if (!target ||
6802 !(target->GetSession()->GetRecruiterId() == playerCaster->GetSession()->GetAccountId() || target->GetSession()->GetAccountId() == playerCaster->GetSession()->GetRecruiterId()))
6804
6805 // Xinef: Implement summon pending error
6806 if (target->GetSummonExpireTimer() > GameTime::GetGameTime().count())
6808
6809 break;
6810 }
6811 case SPELL_EFFECT_LEAP:
6813 {
6814 //Do not allow to cast it before BG starts.
6815 if (unitCaster && unitCaster->IsPlayer())
6816 if (Battleground const* bg = unitCaster->ToPlayer()->GetBattleground())
6817 if (bg->GetStatus() != STATUS_IN_PROGRESS)
6819 break;
6820 }
6822 {
6823 if (!m_targets.GetUnitTarget() || m_targets.GetUnitTarget() == unitCaster)
6825
6826 bool found = false;
6828 for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
6829 {
6830 if (itr->second->GetBase()->IsPassive())
6831 continue;
6832
6833 if (!itr->second->IsPositive())
6834 continue;
6835
6836 found = true;
6837 break;
6838 }
6839
6840 if (!found)
6842
6843 break;
6844 }
6846 {
6847 if (unitCaster && unitCaster->HasUnitState(UNIT_STATE_ROOT))
6848 {
6849 if (unitCaster && unitCaster->IsPlayer())
6850 return SPELL_FAILED_ROOTED;
6851 else
6853 }
6854 break;
6855 }
6856 // xinef: do not allow to use leaps while rooted
6857 case SPELL_EFFECT_JUMP:
6859 {
6860 if (unitCaster && unitCaster->HasUnitState(UNIT_STATE_ROOT))
6861 return SPELL_FAILED_ROOTED;
6862 break;
6863 }
6865 if (!sScriptMgr->CanSelectSpecTalent(this))
6867 // can't change during already started arena/battleground
6868 if (unitCaster && unitCaster->IsPlayer())
6869 if (Battleground const* bg = unitCaster->ToPlayer()->GetBattleground())
6870 if (bg->GetStatus() == STATUS_IN_PROGRESS)
6872 break;
6873 default:
6874 break;
6875 }
6876
6877 if (m_spellInfo->Effects[i].IsAura())
6878 approximateAuraEffectMask |= 1 << i;
6879 else if (m_spellInfo->Effects[i].IsEffect())
6880 nonAuraEffectMask |= 1 << i;
6881 }
6882
6883 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6884 {
6885 switch (m_spellInfo->Effects[i].ApplyAuraName)
6886 {
6887 case SPELL_AURA_DUMMY:
6888 break;
6890 {
6891 if (!unitCaster || !unitCaster->IsPlayer())
6892 return SPELL_FAILED_NO_PET;
6893
6894 Pet* pet = unitCaster->ToPlayer()->GetPet();
6895 if (!pet)
6896 return SPELL_FAILED_NO_PET;
6897
6898 if (pet->GetCharmerGUID())
6899 return SPELL_FAILED_CHARMED;
6900 break;
6901 }
6905 {
6906 if (unitCaster && unitCaster->GetCharmerGUID())
6907 return SPELL_FAILED_CHARMED;
6908
6909 // Xinef: allow SPELL_AURA_MOD_POSSESS to posses target if caster has some pet
6911 {
6912 if (unitCaster && unitCaster->GetPetGUID())
6914
6915 if (unitCaster && unitCaster->GetCharmGUID())
6917 }
6918 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS)
6919 {
6920 if (unitCaster && unitCaster->GetCharmGUID())
6922 }
6923
6924 if (Unit* target = m_targets.GetUnitTarget())
6925 {
6926 if (target->IsCreature() && target->ToCreature()->IsVehicle())
6928
6929 // Allow SPELL_AURA_MOD_POSSESS to work on mounted players,
6930 // but keep the old restriction for everything else.
6931 if (target->IsMounted())
6932 {
6933 if (!(target->IsPlayer() && m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MOD_POSSESS))
6935 }
6936
6937 if (target->GetCharmerGUID())
6938 return SPELL_FAILED_CHARMED;
6939
6940 if (target->GetOwnerGUID() && target->GetOwnerGUID().IsPlayer())
6942
6943 if (target->IsPet() && (!target->GetOwner() || target->GetOwner()->ToPlayer()))
6945
6946 int32 damage = CalculateSpellDamage(i, target);
6947 if (damage && int32(target->GetLevel()) > damage)
6949 }
6950
6951 break;
6952 }
6953 case SPELL_AURA_MOUNTED:
6954 {
6955 // Disallow casting flying mounts in water
6958
6959 // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
6960 bool allowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
6961 InstanceTemplate const* it = sObjectMgr->GetInstanceTemplate(m_caster->GetMapId());
6962 if (it)
6963 allowMount = it->AllowMount;
6964 if (unitCaster && unitCaster->IsPlayer() && !allowMount && !m_spellInfo->AreaGroupId)
6966
6967 if (unitCaster && unitCaster->IsInDisallowedMountForm())
6969
6970 // xinef: dont allow to cast mounts in specific transforms
6971 if (unitCaster && unitCaster->getTransForm())
6972 if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(unitCaster->getTransForm()))
6973 if (transformSpellInfo->HasAttribute(SPELL_ATTR0_NO_IMMUNITIES) &&
6974 !transformSpellInfo->HasAttribute(SpellAttr0(SPELL_ATTR0_ALLOW_WHILE_MOUNTED | SPELL_ATTR0_AURA_IS_DEBUFF)))
6976
6977 break;
6978 }
6980 {
6981 if (!m_targets.GetUnitTarget())
6983
6984 // can be casted at non-friendly unit or own pet/charm
6985 if (unitCaster && unitCaster->IsFriendlyTo(m_targets.GetUnitTarget()))
6987
6988 break;
6989 }
6990 case SPELL_AURA_FLY:
6992 {
6993 // Xinef: added water check
6994 if (unitCaster && unitCaster->IsInWater())
6996
6997 // not allow cast fly spells if not have req. skills (all spells is self target)
6998 // allow always ghost flight spells
7000 {
7001 Battlefield* Bf = sBattlefieldMgr->GetBattlefieldToZoneId(m_originalCaster->GetZoneId());
7002 if (AreaTableEntry const* pArea = sAreaTableStore.LookupEntry(m_originalCaster->GetAreaId()))
7003 if ((pArea->flags & AREA_FLAG_NO_FLY_ZONE) || (Bf && !Bf->CanFlyIn()))
7004 return SPELL_FAILED_NOT_HERE;
7005 }
7006 break;
7007 }
7009 {
7010 if (m_spellInfo->Effects[i].IsTargetingArea())
7011 break;
7012
7013 if (!unitCaster || !unitCaster->IsPlayer() || m_CastItem)
7014 break;
7015
7016 if (!m_targets.GetUnitTarget())
7018
7021
7022 break;
7023 }
7024 case SPELL_AURA_HOVER:
7025 {
7027 {
7029 }
7030 break;
7031 }
7033 {
7034 if (unitCaster && unitCaster->HasAura(23397)) // Nefarian Class Call (Warrior): Berserk -- Nefertum: I don't really like this but I didn't find another way.
7035 {
7037 }
7038 break;
7039 }
7040 default:
7041 break;
7042 }
7043
7044 // check if target already has the same type, but more powerful aura
7045 if (!nonAuraEffectMask && (approximateAuraEffectMask & (1 << i)) && !m_spellInfo->IsTargetingArea())
7046 if (Unit* target = m_targets.GetUnitTarget())
7047 if (!target->IsHighestExclusiveAuraEffect(m_spellInfo, AuraType(m_spellInfo->Effects[i].ApplyAuraName),
7048 m_spellInfo->Effects[i].CalcValue(m_caster, &m_spellValue->EffectBasePoints[i]), approximateAuraEffectMask, false))
7050 }
7051
7052 // check trade slot case (last, for allow catch any another cast problems)
7054 {
7055 if (m_CastItem)
7057
7058 if (!unitCaster || !unitCaster->IsPlayer())
7060
7061 TradeData* my_trade = unitCaster->ToPlayer()->GetTradeData();
7062
7063 if (!my_trade)
7065
7067 if (slot != TRADE_SLOT_NONTRADED)
7069
7070 if (!IsTriggered())
7071 if (my_trade->GetSpell())
7073 }
7074
7075 // check if caster has at least 1 combo point on target for spells that require combo points
7077 {
7079 {
7080 if (!unitCaster || !unitCaster->GetComboPoints(m_targets.GetUnitTarget()))
7081 {
7083 }
7084 }
7085 else
7086 {
7087 if (!unitCaster || !unitCaster->GetComboPoints())
7088 {
7090 }
7091 }
7092 }
7093
7094 // xinef: check relic cooldown
7096 if (unitCaster && unitCaster->HasSpellCooldown(SPELL_RELIC_COOLDOWN) && !unitCaster->HasSpellItemCooldown(SPELL_RELIC_COOLDOWN, m_CastItem->GetEntry()))
7098
7099 // all ok
7100 return SPELL_CAST_OK;
7101}
#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:39
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition Unit.h:80
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:2981
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:141
Definition GroupReference.h:27
GroupReference * next()
Definition GroupReference.h:36
Definition Group.h:178
Definition InstanceScript.h:143
bool IsLocked() const
Definition Item.h:253
ItemTemplate const * GetTemplate() const
Definition Item.cpp:538
bool IsPotion() const
Definition Item.h:338
bool IsDungeon() const
Definition Map.h:299
bool IsBattlegroundOrArena() const
Definition Map.h:307
bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const
Definition Map.cpp:1567
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 Object.h:219
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:2497
bool HaveInDiet(ItemTemplate const *item) const
Definition Pet.cpp:1475
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel) const
Definition Pet.cpp:1493
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:2548
bool IsInSameRaidWith(Player const *p) const
Definition Player.h:1915
bool CanTameExoticPets() const
Definition Player.h:2221
bool CanUseBattlegroundObject(GameObject *gameobject) const
Definition Player.cpp:13614
bool InBattleground() const
Definition Player.h:2300
PetStable * GetPetStable()
Definition Player.h:1226
Battleground * GetBattleground(bool create=false) const
Definition Player.cpp:12483
WorldSession * GetSession() const
Definition Player.h:2032
bool HasSpellCooldown(uint32 spell_id) const override
Definition Player.cpp:16784
uint32 GetLastPotionId()
Definition Player.h:1840
Group * GetGroup()
Definition Player.h:2518
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:6894
bool HasPlayerFlag(PlayerFlags flags) const
Definition Player.h:1125
std::unique_ptr< DuelInfo > duel
Definition Player.h:1907
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:2764
SpellCastResult CheckShapeshift(uint32 form) const
Definition SpellInfo.cpp:1468
uint32 Mechanic
Definition SpellInfo.h:347
uint32 GetDispelMask() const
Definition SpellInfo.cpp:1989
uint32 GetRecoveryTime() const
Definition SpellInfo.cpp:2838
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:1935
int32 AreaGroupId
Definition SpellInfo.h:415
uint32 GetExplicitTargetMask() const
Definition SpellInfo.cpp:2003
SpellCastResult CheckExplicitTarget(WorldObject const *caster, WorldObject const *target, Item const *itemTarget=nullptr) const
Definition SpellInfo.cpp:1884
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::optional< float > GetLOSCollisionHeight() const
Definition Spell.cpp:8237
std::unique_ptr< PathGenerator > m_preGeneratedPath
Definition Spell.h:810
SpellCastResult CheckSpellFocus()
Definition Spell.cpp:8098
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition Spell.cpp:8766
int32 CalculateSpellDamage(uint8 i, Unit const *target) const
Definition Spell.h:491
SpellCastResult CheckPower()
Definition Spell.cpp:7446
SpellCastResult CheckCasterAuras(bool preventionOnly) const
Definition Spell.cpp:7140
SpellCastResult CallScriptCheckCastHandlers()
Definition Spell.cpp:8975
SpellCastResult CheckItems(uint32 *param1=nullptr, uint32 *param2=nullptr)
Definition Spell.cpp:7495
GameObject * GetGameObjectCaster() const
Definition Spell.cpp:8220
SpellCastResult CheckRange(bool strict)
Definition Spell.cpp:7349
bool HasGlobalCooldown() const
Definition Spell.cpp:9251
uint32 GetSpell() const
Definition TradeData.h:49
bool IsVehicle() const
Definition Unit.h:806
Vehicle * GetVehicle() const
Definition Unit.h:1948
SpellImmuneContainer m_spellImmune[MAX_SPELL_IMMUNITY]
Definition Unit.h:2110
Unit * GetOwner() const
Definition Unit.cpp:7517
Pet * ToPet()
Definition Unit.h:735
virtual bool HasSpellCooldown(uint32) const
Definition Unit.h:1352
ShapeshiftForm GetShapeshiftForm() const
Definition Unit.h:1979
ObjectGuid GetOwnerGUID() const override
Definition Unit.h:719
virtual bool HasSpellItemCooldown(uint32, uint32) const
Definition Unit.h:1353
bool IsInDisallowedMountForm() const
Definition Unit.cpp:17023
bool HasUnitFlag2(UnitFlags2 flags) const
Definition Unit.h:759
bool IsInSanctuary() const
Definition Unit.h:1057
virtual bool IsClass(Classes unitClass, ClassContext context=CLASS_CONTEXT_NONE) const
Definition Unit.h:850
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
Definition Unit.cpp:5909
float GetCombatReach() const override
Definition Unit.h:884
UnitFlags GetUnitFlags() const
Definition Unit.h:752
bool HasStealthAura() const
Definition Unit.h:1860
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5798
std::map< uint8, AuraApplication * > VisibleAuraMap
Definition Unit.h:693
bool IsInFlight() const
Definition Unit.h:1725
void SendTameFailure(uint8 result)
Definition Unit.cpp:15670
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList, SpellInfo const *dispelSpell)
Definition Unit.cpp:5682
bool HasUnitMovementFlag(uint32 f) const
Definition Unit.h:780
virtual bool IsInWater() const
Definition Unit.cpp:4318
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=nullptr, Unit const *Caster=nullptr) const
Definition Unit.cpp:7464
bool isMoving() const
Definition Unit.h:1728
void EngageWithTarget(Unit *who)
Definition Unit.cpp:7336
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:1378
ObjectGuid GetCharmGUID() const
Definition Unit.h:727
VisibleAuraMap const * GetVisibleAuras()
Definition Unit.h:1556
bool IsMounted() const
Definition Unit.h:1908
Unit * GetVictim() const
Definition Unit.h:910
bool IsCritter() const
Definition Unit.h:839
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:7079
bool IsHighestExclusiveAuraEffect(SpellInfo const *spellInfo, AuraType auraType, int32 effectAmount, uint8 auraEffectMask, bool removeOtherAuraApplications=false)
Definition Unit.cpp:4367
uint8 GetComboPoints(Unit const *who=nullptr) const
Definition Unit.h:1028
ObjectGuid GetCharmerGUID() const
Definition Unit.h:725
uint32 getTransForm() const
Definition Unit.h:1990
virtual bool HasActivePowerType(Powers power)
Definition Unit.h:1146
void RemoveMovementImpairingAuras(bool withRoot)
Definition Unit.cpp:5302
bool IsTotem() const
Definition Unit.h:805
Guardian * GetGuardianPet() const
Definition Unit.cpp:7568
ObjectGuid GetTarget() const
Definition Unit.h:867
bool IsInCombat() const
Definition Unit.h:949
ObjectGuid GetPetGUID() const
Definition Unit.h:729
Definition Vehicle.h:28
VehicleSeatEntry const * GetSeatForPassenger(Unit const *passenger)
Definition Vehicle.cpp:670
uint32 GetMapId() const
Definition Position.h:281
uint32 GetPhaseMask() const
Definition Object.h:523
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:3152
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:3203
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:2722
uint32 GetAreaId() const
Definition Object.cpp:3186
uint32 GetZoneId() const
Definition Object.cpp:3178
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:3194
uint32 GetRecruiterId() const
Definition WorldSession.h:676
uint32 GetAccountId() const
Definition WorldSession.h:502
Seconds GetGameTime()
Definition GameTime.cpp:39
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(), GetGameObjectCaster(), 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(), GetLOSCollisionHeight(), WorldObject::GetMap(), WorldObject::GetMapHeight(), WorldLocation::GetMapId(), SpellInfo::GetMaxRange(), WorldObject::GetNearPoint2D(), SpellCastTargets::GetObjectTarget(), Pet::GetOwner(), Player::GetPet(), Unit::GetPetGUID(), Player::GetPetStable(), WorldObject::GetPhaseMask(), 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(), Object::IsGameObject(), Unit::IsInCombat(), Unit::IsInDisallowedMountForm(), Unit::IsInFlight(), Map::isInLineOfSight(), 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_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(), 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
7141{
7142 Unit* unitCaster = m_caster->ToUnit();
7143 if (!unitCaster)
7144 return SPELL_CAST_OK;
7145 // spells totally immuned to caster auras (wsg flag drop, give marks etc)
7147 return SPELL_CAST_OK;
7148
7149 uint8 school_immune = 0;
7150 uint64 mechanic_immune = 0;
7151 uint32 dispel_immune = 0;
7152
7153 // Check if the spell grants school or mechanic immunity.
7154 // We use bitmasks so the loop is done only once and not on every aura check below.
7156 {
7157 for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
7158 {
7159 if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY)
7160 school_immune |= uint32(m_spellInfo->Effects[i].MiscValue);
7161 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_MECHANIC_IMMUNITY)
7162 mechanic_immune |= 1ULL << uint32(m_spellInfo->Effects[i].MiscValue);
7163 else if (m_spellInfo->Effects[i].ApplyAuraName == SPELL_AURA_DISPEL_IMMUNITY)
7164 dispel_immune |= SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[i].MiscValue));
7165 }
7166 // immune movement impairment and loss of control
7167 // PVP trinket EMFH TOC PVP trinket Bullheaded Bestial Wrath // Beath Within // Medalion of Immunity
7168 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)
7170 }
7171
7173
7174 // Glyph of Pain Suppression
7175 // there is no other way to handle it
7176 if (m_spellInfo->Id == 33206 && !unitCaster->HasAura(63248))
7177 usableInStun = false;
7178
7179 // Check whether the cast should be prevented by any state you might have.
7180 SpellCastResult prevented_reason = SPELL_CAST_OK;
7181 // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
7182 uint32 unitflag = unitCaster->GetUnitFlags(); // Get unit state
7183
7184 // Xinef: if spell is triggered check preventionType only
7185 if (!preventionOnly)
7186 {
7187 if (unitflag & UNIT_FLAG_STUNNED)
7188 {
7189 // spell is usable while stunned, check if caster has only mechanic stun auras, another stun types must prevent cast spell
7190 if (usableInStun)
7191 {
7192 bool foundNotStun = false;
7193 uint64 mask = (1ULL << MECHANIC_STUN) | (1ULL << MECHANIC_FREEZE) | (1ULL << MECHANIC_HORROR);
7194 // Barkskin should skip sleep effects, sap and fears
7195 if (m_spellInfo->Id == 22812)
7196 mask |= 1ULL << MECHANIC_SAPPED | 1ULL << MECHANIC_HORROR | 1ULL << MECHANIC_SLEEP;
7197 // Hand of Freedom, can be used while sapped and while under fear-mechanic stuns (e.g. Intimidating Shout primary target)
7198 if (m_spellInfo->Id == 1044)
7199 mask |= (1ULL << MECHANIC_SAPPED) | (1ULL << MECHANIC_FEAR);
7200 Unit::AuraEffectList const& stunAuras = unitCaster->GetAuraEffectsByType(SPELL_AURA_MOD_STUN);
7201 for (Unit::AuraEffectList::const_iterator i = stunAuras.begin(); i != stunAuras.end(); ++i)
7202 {
7203 if ((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() && !((*i)->GetSpellInfo()->GetAllEffectsMechanicMask() & mask))
7204 {
7205 foundNotStun = true;
7206 break;
7207 }
7208 }
7209 if (foundNotStun)
7210 prevented_reason = SPELL_FAILED_STUNNED;
7211 }
7212 else
7213 prevented_reason = SPELL_FAILED_STUNNED;
7214 }
7216 prevented_reason = SPELL_FAILED_CONFUSED;
7218 prevented_reason = SPELL_FAILED_FLEEING;
7219 }
7220
7221 // Xinef: if there is no prevented_reason, check prevention types
7222 if (prevented_reason == SPELL_CAST_OK)
7223 {
7225 prevented_reason = SPELL_FAILED_SILENCED;
7227 prevented_reason = SPELL_FAILED_PACIFIED;
7228 }
7229
7230 // Attr must make flag drop spell totally immune from all effects
7231 if (prevented_reason != SPELL_CAST_OK)
7232 {
7233 if (school_immune || mechanic_immune || dispel_immune)
7234 {
7235 //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
7236 Unit::AuraApplicationMap const& auras = unitCaster->GetAppliedAuras();
7237 for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
7238 {
7239 Aura const* aura = itr->second->GetBase();
7240 SpellInfo const* auraInfo = aura->GetSpellInfo();
7241 if (auraInfo->GetAllEffectsMechanicMask() & mechanic_immune)
7242 continue;
7243 if (auraInfo->GetSchoolMask() & school_immune && !auraInfo->HasAttribute(SPELL_ATTR1_IMMUNITY_TO_HOSTILE_AND_FRIENDLY_EFFECTS))
7244 continue;
7245 if (auraInfo->GetDispelMask() & dispel_immune)
7246 continue;
7247
7248 //Make a second check for spell failed so the right SPELL_FAILED message is returned.
7249 //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
7250 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
7251 {
7252 if (AuraEffect* part = aura->GetEffect(i))
7253 {
7254 switch (part->GetAuraType())
7255 {
7257 {
7258 uint64 mask = 1ULL << MECHANIC_STUN;
7259 // Barkskin should skip sleep effects, sap and fears
7260 if (m_spellInfo->Id == 22812)
7261 mask |= 1ULL << MECHANIC_SAPPED | 1ULL << MECHANIC_HORROR | 1ULL << MECHANIC_SLEEP;
7262 // Hand of Freedom, can be used while sapped and while under fear-mechanic stuns (e.g. Intimidating Shout primary target)
7263 if (m_spellInfo->Id == 1044)
7264 mask |= (1ULL << MECHANIC_SAPPED) | (1ULL << MECHANIC_FEAR);
7265
7266 if (!usableInStun || !(auraInfo->GetAllEffectsMechanicMask() & mask))
7267 return SPELL_FAILED_STUNNED;
7268 break;
7269 }
7272 return SPELL_FAILED_CONFUSED;
7273 break;
7276 return SPELL_FAILED_FLEEING;
7277 break;
7282 return SPELL_FAILED_PACIFIED;
7284 return SPELL_FAILED_SILENCED;
7285 break;
7286 default:
7287 break;
7288 }
7289 }
7290 }
7291 }
7292 }
7293 // You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
7294 else
7295 return prevented_reason;
7296 }
7297 return SPELL_CAST_OK;
7298}
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:178
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:101
uint64 GetAllEffectsMechanicMask() const
Definition SpellInfo.cpp:1940
boost::container::flat_multimap< uint32, AuraApplication * > AuraApplicationMap
Definition Unit.h:679
AuraApplicationMap & GetAppliedAuras()
Definition Unit.h:1400

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
8909{
8910 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8912}

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
8313{
8314 Unit* unitCaster = m_caster->ToUnit();
8315 switch (m_spellInfo->Effects[eff].ApplyAuraName)
8316 {
8321 if (target->IsCreature() && target->IsVehicle())
8322 return false;
8323 if (target->IsMounted() && m_spellInfo->Effects[eff].ApplyAuraName != SPELL_AURA_MOD_POSSESS)
8324 return false;
8325 if (target->GetCharmerGUID())
8326 return false;
8327 if (int32 damage = CalculateSpellDamage(eff, target))
8328 if ((int32)target->GetLevel() > damage)
8329 return false;
8330 break;
8331 default:
8332 break;
8333 }
8334
8335 // xinef: skip los checking if spell has appropriate attribute, or target requires specific entry
8336 // 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
8337 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)))
8338 return true;
8339
8340 // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour
8343 {
8344 return true;
8345 }
8346
8348 //Check targets for LOS visibility (except spells without range limitations)
8349 switch (m_spellInfo->Effects[eff].Effect)
8350 {
8352 // player far away, maybe his corpse near?
8353 if (target != m_caster && !target->IsWithinLOSInMap(m_caster))
8354 {
8356 return false;
8357
8359 if (!corpse)
8360 return false;
8361
8362 if (target->GetGUID() != corpse->GetOwnerGUID())
8363 return false;
8364
8366 return false;
8367 }
8368 break;
8370 {
8372 {
8373 if (target->IsWithinLOSInMap(m_caster, VMAP::ModelIgnoreFlags::M2) && target->HasUnitFlag(UNIT_FLAG_SKINNABLE))
8374 return true;
8375
8376 return false;
8377 }
8378
8380 if (!corpse)
8381 return false;
8382
8383 if (target->GetGUID() != corpse->GetOwnerGUID())
8384 return false;
8385
8387 return false;
8388
8390 return false;
8391 }
8392 break;
8394 if (!unitCaster || !unitCaster->IsPlayer() || !target->IsPlayer())
8395 return false;
8396 if (unitCaster->ToPlayer()->GetSession()->IsARecruiter() && target->ToPlayer()->GetSession()->GetRecruiterId() != unitCaster->ToPlayer()->GetSession()->GetAccountId())
8397 return false;
8398 if (unitCaster->ToPlayer()->GetSession()->GetRecruiterId() != target->ToPlayer()->GetSession()->GetAccountId() && target->ToPlayer()->GetSession()->IsARecruiter())
8399 return false;
8400 if (target->ToPlayer()->GetLevel() >= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
8401 return false;
8402 break;
8403 default: // normal case
8404 {
8405 uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
8406 if (GameObject const* gobCaster = GetGameObjectCaster())
8407 {
8408 // A trap without an owner has no height to see from, so the floor under its target would block it.
8409 // An owned trap sees from its owner's height (GetLOSCollisionHeight), so a wall still blocks it.
8410 if (gobCaster->GetGOInfo()->IsIgnoringLOSChecks() ||
8411 (gobCaster->GetGoType() == GAMEOBJECT_TYPE_TRAP && !gobCaster->GetOwnerGUID()))
8412 {
8413 return true;
8414 }
8415
8416 // If spell casted by gameobject then ignore M2 models
8417 losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
8418 }
8419
8420 if (target != m_caster)
8421 {
8422 if (m_targets.HasDst())
8423 {
8424 float x = m_targets.GetDstPos()->GetPositionX();
8425 float y = m_targets.GetDstPos()->GetPositionY();
8426 float z = m_targets.GetDstPos()->GetPositionZ();
8427
8428 if (!target->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks(losChecks)))
8429 {
8430 return false;
8431 }
8432 }
8434 {
8435 return false;
8436 }
8437 }
8438 break;
8439 }
8440 }
8441
8442 return true;
8443}
@ CORPSE_FLAG_LOOTABLE
Definition Corpse.h:45
@ SPELL_DISABLE_LOS
Definition DisableMgr.h:50
@ DISABLE_TYPE_SPELL
Definition DisableMgr.h:28
@ SPELL_EFFECT_SKIN_PLAYER_CORPSE
Definition SharedDefines.h:882
@ TARGET_CHECK_ENTRY
Definition SpellInfo.h:116
@ UNIT_FLAG_NOT_SELECTABLE
Definition UnitDefines.h:282
@ CORPSE_FIELD_FLAGS
Definition UpdateFields.h:427
@ CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL
Definition WorldConfig.h:206
Definition Corpse.h:49
ObjectGuid GetOwnerGUID() const 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:677
#define sWorld
Definition World.h:337
Corpse * GetCorpse(WorldObject const &u, ObjectGuid const &guid)
Definition ObjectAccessor.cpp:203

References CalculateSpellDamage(), CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL, CORPSE_FIELD_FLAGS, CORPSE_FLAG_LOOTABLE, damage, DISABLE_TYPE_SPELL, SpellInfo::Effects, GAMEOBJECT_TYPE_TRAP, WorldSession::GetAccountId(), Unit::GetCharmerGUID(), ObjectAccessor::GetCorpse(), SpellCastTargets::GetCorpseTargetGUID(), SpellCastTargets::GetDstPos(), GetGameObjectCaster(), Object::GetGUID(), Unit::GetLevel(), GetLOSCollisionHeight(), 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(), Unit::IsMounted(), Object::IsPlayer(), IsTriggered(), Unit::IsVehicle(), WorldObject::IsWithinLOS(), WorldObject::IsWithinLOSInMap(), LINEOFSIGHT_ALL_CHECKS, VMAP::M2, m_caster, 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(), Object::ToUnit(), UNIT_FLAG_NOT_SELECTABLE, and UNIT_FLAG_SKINNABLE.

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.
7496{
7497 Unit* unitCaster = m_caster->ToUnit();
7498 if (!unitCaster)
7499 return SPELL_CAST_OK;
7500
7501 Player* player = unitCaster->ToPlayer();
7502 if (!player)
7503 {
7504 // Non-player case: Check if creature is disarmed
7506 {
7508 }
7509
7510 return SPELL_CAST_OK;
7511 }
7512
7513 if (!m_CastItem)
7514 {
7515 if (m_castItemGUID)
7517 }
7518 else
7519 {
7520 uint32 itemid = m_CastItem->GetEntry();
7521 if (!player->HasItemCount(itemid))
7523
7524 ItemTemplate const* proto = m_CastItem->GetTemplate();
7525 if (!proto)
7527
7528 for (int i = 0; i < MAX_ITEM_SPELLS; ++i)
7529 if (proto->Spells[i].SpellCharges)
7530 if (m_CastItem->GetSpellCharges(i) == 0)
7532
7533 // consumable cast item checks
7535 {
7536 // such items should only fail if there is no suitable effect at all - see Rejuvenation Potions for example
7537 SpellCastResult failReason = SPELL_CAST_OK;
7538 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
7539 {
7540 // skip check, pet not required like checks, and for TARGET_UNIT_PET m_targets.GetUnitTarget() is not the real target but the caster
7541 if (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_PET)
7542 continue;
7543
7544 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_HEAL)
7545 {
7547 {
7549 continue;
7550 }
7551 else
7552 {
7553 failReason = SPELL_CAST_OK;
7554 break;
7555 }
7556 }
7557
7558 // Mana Potion, Rage Potion, Thistle Tea(Rogue), ...
7559 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_ENERGIZE)
7560 {
7561 if (m_spellInfo->Effects[i].MiscValue < 0 || m_spellInfo->Effects[i].MiscValue >= int8(MAX_POWERS))
7562 {
7564 continue;
7565 }
7566
7567 Powers power = Powers(m_spellInfo->Effects[i].MiscValue);
7569 {
7571 continue;
7572 }
7573 else
7574 {
7575 failReason = SPELL_CAST_OK;
7576 break;
7577 }
7578 }
7579 }
7580 if (failReason != SPELL_CAST_OK)
7581 return failReason;
7582 }
7583 }
7584
7585 // check target item
7587 {
7588 if (!unitCaster->IsPlayer())
7590
7591 if (!m_targets.GetItemTarget())
7593
7596 }
7597 // if not item target then required item must be equipped
7598 else
7599 {
7600 // Xinef: this is not true in my opinion, in eg bladestorm will not be canceled after disarm
7601 //if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT))
7602 if (unitCaster->IsPlayer() && !unitCaster->ToPlayer()->HasItemFitToSpellRequirements(m_spellInfo))
7604 }
7605
7606 // do not take reagents for these item casts
7608 {
7610 // Not own traded item (in trader trade slot) requires reagents even if triggered spell
7611 if (!checkReagents)
7612 if (Item* targetItem = m_targets.GetItemTarget())
7613 if (targetItem->GetOwnerGUID() != unitCaster->GetGUID())
7614 checkReagents = true;
7615
7616 // check reagents (ignore triggered spells with reagents processed by original spell) and special reagent ignore case.
7617 if (checkReagents)
7618 {
7619 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
7620 {
7621 if (m_spellInfo->Reagent[i] <= 0)
7622 continue;
7623
7624 uint32 itemid = m_spellInfo->Reagent[i];
7625 uint32 itemcount = m_spellInfo->ReagentCount[i];
7626
7627 // if CastItem is also spell reagent
7628 if (m_CastItem && m_CastItem->GetEntry() == itemid)
7629 {
7630 ItemTemplate const* proto = m_CastItem->GetTemplate();
7631 if (!proto)
7633 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
7634 {
7635 // CastItem will be used up and does not count as reagent
7636 int32 charges = m_CastItem->GetSpellCharges(s);
7637 if (proto->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
7638 {
7639 ++itemcount;
7640 break;
7641 }
7642 }
7643 }
7644 if (!player->HasItemCount(itemid, itemcount))
7645 return SPELL_FAILED_REAGENTS;
7646 }
7647 }
7648
7649 // check totem-item requirements (items presence in inventory)
7650 uint32 totems = 2;
7651 for (int i = 0; i < 2; ++i)
7652 {
7653 if (m_spellInfo->Totem[i] != 0)
7654 {
7655 if (player->HasItemCount(m_spellInfo->Totem[i]))
7656 {
7657 totems -= 1;
7658 continue;
7659 }
7660 }
7661 else
7662 totems -= 1;
7663 }
7664 if (totems != 0)
7665 return SPELL_FAILED_TOTEMS; //0x7C
7666
7667 // Check items for TotemCategory (items presence in inventory)
7669 for (int i = 0; i < 2; ++i)
7670 {
7671 if (m_spellInfo->TotemCategory[i] != 0)
7672 {
7674 {
7675 TotemCategory -= 1;
7676 continue;
7677 }
7678 }
7679 else
7680 TotemCategory -= 1;
7681 }
7682 if (TotemCategory != 0)
7683 return SPELL_FAILED_TOTEM_CATEGORY; //0x7B
7684 }
7685
7686 // special checks for spell effects
7687 for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
7688 {
7689 switch (m_spellInfo->Effects[i].Effect)
7690 {
7693 {
7694 // m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
7695 Unit* target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
7696 if (target->IsPlayer() && !IsTriggered())
7697 {
7698 // 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,
7699 // so we need to make sure there is at least one free space in the player's inventory
7701 if (target->ToPlayer()->GetFreeInventorySpace() == 0)
7702 {
7703 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7705 }
7706
7707 if (m_spellInfo->Effects[i].ItemType)
7708 {
7709 ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(m_spellInfo->Effects[i].ItemType);
7710 if (!itemTemplate)
7712
7713 uint32 createCount = std::clamp<uint32>(m_spellInfo->Effects[i].CalcValue(), 1u, itemTemplate->GetMaxStackSize());
7714 ItemPosCountVec dest;
7715 InventoryResult msg = target->ToPlayer()->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, createCount);
7716 if (msg != EQUIP_ERR_OK)
7717 {
7719 if (!itemTemplate->ItemLimitCategory)
7720 {
7721 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7723 }
7724 else
7725 {
7726 // Conjure Food/Water/Refreshment spells
7729 else if (!(target->ToPlayer()->HasItemCount(m_spellInfo->Effects[i].ItemType)))
7730 {
7731 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7733 }
7734 else
7735 player->CastSpell(player, m_spellInfo->Effects[EFFECT_1].CalcValue(), false); // move this to anywhere
7736
7738 }
7739 }
7740 }
7741 }
7742 break;
7743 }
7745 {
7746 if (player->GetFreeInventorySpace() == 0)
7747 {
7748 player->SendEquipError(EQUIP_ERR_INVENTORY_FULL, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7750 }
7751 break;
7752 }
7754 if (m_spellInfo->Effects[i].ItemType && m_targets.GetItemTarget()
7756 {
7757 // cannot enchant vellum for other player
7758 if (m_targets.GetItemTarget()->GetOwner() != unitCaster)
7760 // do not allow to enchant vellum from scroll made by vellum-prevent exploit
7763 ItemPosCountVec dest;
7764 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, m_spellInfo->Effects[i].ItemType, 1);
7765 if (msg != EQUIP_ERR_OK)
7766 {
7767 player->SendEquipError(msg, nullptr, nullptr, m_spellInfo->Effects[i].ItemType);
7769 }
7770 }
7771 [[fallthrough]];
7773 {
7774 Item* targetItem = m_targets.GetItemTarget();
7775 if (!targetItem)
7777
7778 // Apply item level restriction
7780 {
7781 uint32 requiredLevel = targetItem->GetTemplate()->RequiredLevel;
7782 if (!requiredLevel)
7783 requiredLevel = targetItem->GetTemplate()->ItemLevel;
7784
7785 if (requiredLevel < m_spellInfo->BaseLevel)
7786 return SPELL_FAILED_LOWLEVEL;
7787 }
7788
7789 if (m_CastItem && m_spellInfo->MaxLevel > 0 && targetItem->GetTemplate()->ItemLevel > m_spellInfo->MaxLevel)
7791
7792 bool isItemUsable = false;
7793 for (uint8 e = 0; e < MAX_ITEM_PROTO_SPELLS; ++e)
7794 {
7795 ItemTemplate const* proto = targetItem->GetTemplate();
7796 if (proto->Spells[e].SpellId && (
7799 {
7800 isItemUsable = true;
7801 break;
7802 }
7803 }
7804
7805 SpellItemEnchantmentEntry const* enchantEntry = sSpellItemEnchantmentStore.LookupEntry(m_spellInfo->Effects[i].MiscValue);
7806 // do not allow adding usable enchantments to items that have use effect already
7807 if (enchantEntry)
7808 {
7809 for (uint8 s = 0; s < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++s)
7810 {
7811 switch (enchantEntry->type[s])
7812 {
7814 if (isItemUsable)
7816 break;
7818 {
7819 uint32 numSockets = 0;
7820 for (uint32 socket = 0; socket < MAX_ITEM_PROTO_SOCKETS; ++socket)
7821 if (targetItem->GetTemplate()->Socket[socket].Color)
7822 ++numSockets;
7823
7824 if (numSockets == MAX_ITEM_PROTO_SOCKETS || targetItem->GetEnchantmentId(PRISMATIC_ENCHANTMENT_SLOT))
7826 break;
7827 }
7828 }
7829 }
7830 }
7831
7832 // Not allow enchant in trade slot for some enchant type
7833 if (targetItem->GetOwner() != unitCaster)
7834 {
7835 if (!enchantEntry)
7836 return SPELL_FAILED_ERROR;
7837 if (enchantEntry->slot & ENCHANTMENT_CAN_SOULBOUND)
7839 }
7840 break;
7841 }
7843 {
7844 Item* item = m_targets.GetItemTarget();
7845 if (!item)
7847 // Not allow enchant in trade slot for some enchant type
7848 if (item->GetOwner() != unitCaster)
7849 {
7850 uint32 enchant_id = m_spellInfo->Effects[i].MiscValue;
7851 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
7852 if (!pEnchant)
7853 return SPELL_FAILED_ERROR;
7854 if (pEnchant->slot & ENCHANTMENT_CAN_SOULBOUND)
7856 }
7857
7858 // Apply item level restriction
7860 {
7861 uint32 requiredLevel = item->GetTemplate()->RequiredLevel;
7862 if (!requiredLevel)
7863 requiredLevel = item->GetTemplate()->ItemLevel;
7864
7865 if (requiredLevel < m_spellInfo->BaseLevel)
7866 return SPELL_FAILED_LOWLEVEL;
7867 }
7868
7871
7872 break;
7873 }
7875 // check item existence in effect code (not output errors at offhand hold item effect to main hand for example
7876 break;
7878 {
7879 if (!m_targets.GetItemTarget())
7881
7882 // prevent disenchanting in trade slot
7883 if (m_targets.GetItemTarget()->GetOwnerGUID() != unitCaster->GetGUID())
7885
7886 ItemTemplate const* itemProto = m_targets.GetItemTarget()->GetTemplate();
7887 if (!itemProto)
7889
7890 uint32 item_quality = itemProto->Quality;
7891 // 2.0.x addon: Check player enchanting level against the item disenchanting requirements
7892 uint32 item_disenchantskilllevel = itemProto->RequiredDisenchantSkill;
7893 if (item_disenchantskilllevel == uint32(-1))
7895 if (item_disenchantskilllevel > player->GetSkillValue(SKILL_ENCHANTING))
7897 if (item_quality > 4 || item_quality < 2)
7899 if (itemProto->Class != ITEM_CLASS_WEAPON && itemProto->Class != ITEM_CLASS_ARMOR)
7901 if (!itemProto->DisenchantID)
7903 break;
7904 }
7906 {
7907 Item* item = m_targets.GetItemTarget();
7908 if (!item)
7910 //ensure item is a prospectable ore
7913 //prevent prospecting in trade slot
7914 if (item->GetOwnerGUID() != unitCaster->GetGUID())
7916 //Check for enough skill in jewelcrafting
7917 uint32 item_prospectingskilllevel = item->GetTemplate()->RequiredSkillRank;
7918 if (item_prospectingskilllevel > player->GetSkillValue(SKILL_JEWELCRAFTING))
7920 //make sure the player has the required ores in inventory
7921 if (item->GetCount() < 5)
7922 {
7923 if (param1 && param2)
7924 {
7925 *param1 = item->GetEntry();
7926 *param2 = 5;
7927 }
7929 }
7930
7933
7934 break;
7935 }
7937 {
7938 Item* item = m_targets.GetItemTarget();
7939 if (!item)
7941 //ensure item is a millable herb
7942 if (!(item->GetTemplate()->HasFlag(ITEM_FLAG_IS_MILLABLE)))
7944 //prevent milling in trade slot
7945 if (item->GetOwnerGUID() != unitCaster->GetGUID())
7947 //Check for enough skill in inscription
7948 uint32 item_millingskilllevel = item->GetTemplate()->RequiredSkillRank;
7949 if (item_millingskilllevel > player->GetSkillValue(SKILL_INSCRIPTION))
7951 //make sure the player has the required herbs in inventory
7952 if (item->GetCount() < 5)
7953 {
7954 if (param1 && param2)
7955 {
7956 *param1 = item->GetEntry();
7957 *param2 = 5;
7958 }
7960 }
7961
7964
7965 break;
7966 }
7969 {
7970 if (!unitCaster->IsPlayer())
7972
7974 break;
7975
7976 Item* pItem = unitCaster->ToPlayer()->GetWeaponForAttack(m_attackType);
7977 if (!pItem || pItem->IsBroken())
7979
7980 switch (pItem->GetTemplate()->SubClass)
7981 {
7983 {
7984 uint32 ammo = pItem->GetEntry();
7985 if (!unitCaster->ToPlayer()->HasItemCount(ammo))
7986 return SPELL_FAILED_NO_AMMO;
7987 };
7988 break;
7992 {
7993 uint32 ammo = unitCaster->ToPlayer()->GetUInt32Value(PLAYER_AMMO_ID);
7994 if (!ammo)
7995 {
7996 // Requires No Ammo
7997 if (unitCaster->HasAura(46699))
7998 break; // skip other checks
7999
8000 return SPELL_FAILED_NO_AMMO;
8001 }
8002
8003 ItemTemplate const* ammoProto = sObjectMgr->GetItemTemplate(ammo);
8004 if (!ammoProto)
8005 return SPELL_FAILED_NO_AMMO;
8006
8007 if (ammoProto->Class != ITEM_CLASS_PROJECTILE)
8008 return SPELL_FAILED_NO_AMMO;
8009
8010 // check ammo ws. weapon compatibility
8011 switch (pItem->GetTemplate()->SubClass)
8012 {
8015 if (ammoProto->SubClass != ITEM_SUBCLASS_ARROW)
8016 return SPELL_FAILED_NO_AMMO;
8017 break;
8019 if (ammoProto->SubClass != ITEM_SUBCLASS_BULLET)
8020 return SPELL_FAILED_NO_AMMO;
8021 break;
8022 default:
8023 return SPELL_FAILED_NO_AMMO;
8024 }
8025
8026 if (!unitCaster->ToPlayer()->HasItemCount(ammo))
8027 {
8028 unitCaster->ToPlayer()->SetUInt32Value(PLAYER_AMMO_ID, 0);
8029 return SPELL_FAILED_NO_AMMO;
8030 }
8031 };
8032 break;
8034 break;
8035 default:
8036 break;
8037 }
8038 break;
8039 }
8041 {
8042 uint32 item_id = m_spellInfo->Effects[i].ItemType;
8043 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
8044
8045 if (!pProto)
8047
8048 if (Item* pitem = player->GetItemByEntry(item_id))
8049 {
8050 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
8051 if (pProto->Spells[x].SpellCharges != 0 && pitem->GetSpellCharges(x) == pProto->Spells[x].SpellCharges)
8053 }
8054 break;
8055 }
8056 default:
8057 break;
8058 }
8059 }
8060
8061 // check weapon presence in slots for main/offhand weapons
8062 if (/*never skip those checks !HasTriggeredCastFlag(TRIGGERED_IGNORE_EQUIPPED_ITEM_REQUIREMENT) &&*/ m_spellInfo->EquippedItemClass >= 0)
8063 {
8064 // main hand weapon required
8066 {
8067 Item* item = unitCaster->ToPlayer()->GetWeaponForAttack(BASE_ATTACK);
8068
8069 // skip spell if no weapon in slot or broken
8070 if (!item || item->IsBroken())
8072
8073 // skip spell if weapon not fit to triggered spell
8076 }
8077
8078 // offhand hand weapon required
8080 {
8081 Item* item = unitCaster->ToPlayer()->GetWeaponForAttack(OFF_ATTACK);
8082
8083 // skip spell if no weapon in slot or broken
8084 if (!item || item->IsBroken())
8086
8087 // skip spell if weapon not fit to triggered spell
8090 }
8091
8092 m_weaponItem = unitCaster->ToPlayer()->GetWeaponForAttack(m_attackType, true);
8093 }
8094
8095 return SPELL_CAST_OK;
8096}
@ 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:318
bool IsBroken() const
Definition Item.h:257
bool IsWeaponVellum() const
Definition Item.h:339
bool IsArmorVellum() const
Definition Item.h:340
Player * GetOwner() const
Definition Item.cpp:543
ObjectGuid GetOwnerGUID() const
Definition Item.h:231
uint32 GetCount() const
Definition Item.h:272
bool IsFitToSpellRequirements(SpellInfo const *spellInfo) const
Definition Item.cpp:878
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:12825
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:12900
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:1128
bool CanUseAttackType(WeaponAttackType attacktype) const
Definition Unit.h:1006
uint32 GetMaxPower(Powers power) const
Definition Unit.h:1150
void SetUInt32Value(uint16 index, uint32 value)
Definition Unit.cpp:17078
uint32 GetPower(Powers power) const
Definition Unit.h:1149
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)
7104{
7105 Unit* unitCaster = m_caster->ToUnit();
7106 if (unitCaster->HasUnitState(UNIT_STATE_CASTING) && !HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS)) //prevent spellcast interruption by another spellcast
7108
7109 // dead owner (pets still alive when owners ressed?)
7110 if (Unit* owner = unitCaster->GetCharmerOrOwner())
7111 if (!owner->IsAlive() && unitCaster->GetEntry() != 30230) // Rise Ally
7113
7114 if (!target && m_targets.GetUnitTarget())
7115 target = m_targets.GetUnitTarget();
7116
7118 {
7119 if (!target)
7121 m_targets.SetUnitTarget(target);
7122 }
7123
7124 // xinef: Calculate power cost here, so funciton checking power can work properly and dont return bad results
7126
7127 // cooldown
7128 if (Creature const* creatureCaster = unitCaster->ToCreature())
7129 if (creatureCaster->HasSpellCooldown(m_spellInfo->Id))
7131
7132 // Check if spell is affected by GCD
7134 if (unitCaster->GetCharmInfo() && unitCaster->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(m_spellInfo))
7136
7137 return CheckCast(true);
7138}
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:2843
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 ( )
7447{
7448 Unit* unitCaster = m_caster->ToUnit();
7449 if (!unitCaster)
7450 return SPELL_CAST_OK;
7451
7452 // item cast not used power
7453 if (m_CastItem)
7454 return SPELL_CAST_OK;
7455
7456 //While .cheat power is enabled dont check if we need power to cast the spell
7457 if (unitCaster->IsPlayer())
7458 {
7459 if (unitCaster->ToPlayer()->GetCommandStatus(CHEAT_POWER))
7460 {
7461 return SPELL_CAST_OK;
7462 }
7463 }
7464
7465 // health as power used - need check health amount
7467 {
7468 if (int32(unitCaster->GetHealth()) <= m_powerCost)
7470 return SPELL_CAST_OK;
7471 }
7472 // Check valid power type
7474 {
7475 LOG_ERROR("spells", "Spell::CheckPower: Unknown power type '{}'", m_spellInfo->PowerType);
7476 return SPELL_FAILED_UNKNOWN;
7477 }
7478
7479 //check rune cost only if a spell has PowerType == POWER_RUNE
7481 {
7483 if (failReason != SPELL_CAST_OK)
7484 return failReason;
7485 }
7486
7487 // Check power amount
7489 if (int32(unitCaster->GetPower(PowerType)) < m_powerCost)
7490 return SPELL_FAILED_NO_POWER;
7491 else
7492 return SPELL_CAST_OK;
7493}
@ 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:5607
uint32 GetHealth() const
Definition Unit.h:1122

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)
7350{
7351 Unit* unitCaster = m_caster->ToUnit();
7352 // Don't check for instant cast spells
7353 if (!strict && m_casttime == 0)
7354 return SPELL_CAST_OK;
7355
7356 uint32 range_type = 0;
7357
7359 {
7360 // check needed by 68766 51693 - both spells are cast on enemies and have 0 max range
7361 // these are triggered by other spells - possibly we should omit range check in that case?
7362 if (m_spellInfo->RangeEntry->ID == 1)
7363 return SPELL_CAST_OK;
7364
7365 range_type = m_spellInfo->RangeEntry->Flags;
7366 }
7367
7368 Unit* target = m_targets.GetUnitTarget();
7369 float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo);
7370 float min_range = m_caster->GetSpellMinRangeForTarget(target, m_spellInfo);
7371
7372 // xinef: hack for npc shooters
7373 if (min_range && unitCaster && unitCaster->IsCreature() && !unitCaster->ToCreature()->GetOwnerGUID().IsPlayer() && min_range <= 6.0f)
7374 range_type = SPELL_RANGE_RANGED;
7375
7376 if (Player* modOwner = m_caster->GetSpellModOwner())
7377 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, max_range, this);
7378
7379 // xinef: dont check max_range to strictly after cast
7380 if (range_type != SPELL_RANGE_MELEE && !strict)
7381 max_range += std::min(3.0f, max_range * 0.1f); // 10% but no more than 3yd
7382
7383 if (target)
7384 {
7385 if (target != m_caster && unitCaster)
7386 {
7387 // A vehicle passenger can neither turn nor move, and their stored position and
7388 // orientation can be stale; never fail range or facing against the vehicle
7389 // carrying them (e.g. Yogg-Saron's Constrictor Tentacle grab).
7390 bool const targetIsVehicleBase = unitCaster->GetVehicleBase() == target;
7391
7392 // Xinef: Spells with 5yd range can hit target 9yd away?
7393 if (range_type == SPELL_RANGE_MELEE)
7394 {
7395 float real_max_range = max_range;
7396
7397 if (m_caster->GetLeewayBonusRange(target) > 0.0f)
7398 real_max_range -= MIN_MELEE_REACH; // less strict when leeway applies
7399 else
7400 real_max_range -= 2 * MIN_MELEE_REACH;
7401
7402 if (!targetIsVehicleBase && !unitCaster->IsWithinMeleeRange(target, std::max(real_max_range, 0.0f)))
7404 }
7405 else if (!targetIsVehicleBase && !unitCaster->IsWithinCombatRange(target, max_range))
7406 return SPELL_FAILED_OUT_OF_RANGE; //0x5A;
7407
7408 if (!targetIsVehicleBase && unitCaster->IsPlayer() && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !unitCaster->HasInArc(static_cast<float>(M_PI), target) && !unitCaster->IsWithinBoundaryRadius(target))
7410 }
7411 // Non-Unit casters (e.g. a GameObject trap) have no combat reach/facing of their own;
7412 // just check the target is within the spell's range of the caster's actual position.
7413 else if (target != m_caster && !unitCaster && !m_caster->IsWithinDist(target, max_range))
7415
7416 // Check min range - for ranged spells, min range is the spell's min range + melee range (no leeway)
7417 if (unitCaster && range_type == SPELL_RANGE_RANGED)
7418 {
7419 float minRangeCombined = min_range + unitCaster->GetMeleeRange(target);
7420 if (unitCaster->IsWithinRange(target, minRangeCombined))
7422 }
7423 else if (unitCaster && min_range > 0 && unitCaster->IsWithinCombatRange(target, min_range))
7425 }
7426
7427 if (GameObject* goTarget = m_targets.GetGOTarget())
7428 {
7429 if (!goTarget->IsAtInteractDistance(m_caster->ToPlayer(), m_spellInfo))
7430 {
7432 }
7433 }
7434
7435 if (m_targets.HasDst() && !m_targets.HasTraj())
7436 {
7439 if (min_range && m_caster->IsWithinDist3d(m_targets.GetDstPos(), min_range))
7441 }
7442
7443 return SPELL_CAST_OK;
7444}
#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:14704
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:3988
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Object.cpp:3974
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)
5608{
5609 Unit* unitCaster = m_caster->ToUnit();
5610 if (!unitCaster)
5611 return SPELL_CAST_OK;
5612
5613 if (m_spellInfo->PowerType != POWER_RUNE || !RuneCostID)
5614 return SPELL_CAST_OK;
5615
5616 if (!unitCaster->IsPlayer())
5617 return SPELL_CAST_OK;
5618
5619 Player* player = unitCaster->ToPlayer();
5620 //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)
5621 if (player->GetCommandStatus(CHEAT_POWER))
5622 {
5623 return SPELL_CAST_OK;
5624 }
5625
5627 return SPELL_CAST_OK;
5628
5629 SpellRuneCostEntry const* src = sSpellRuneCostStore.LookupEntry(RuneCostID);
5630
5631 if (!src)
5632 return SPELL_CAST_OK;
5633
5634 if (src->NoRuneCost())
5635 return SPELL_CAST_OK;
5636
5637 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5638
5639 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5640 {
5641 runeCost[i] = src->RuneCost[i];
5642 if (Player* modOwner = unitCaster->GetSpellModOwner())
5643 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5644 }
5645
5646 runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later
5647
5648 for (uint32 i = 0; i < MAX_RUNES; ++i)
5649 {
5650 RuneType rune = player->GetCurrentRune(i);
5651 if ((player->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0))
5652 runeCost[rune]--;
5653 }
5654
5655 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5656 if (runeCost[i] > 0)
5657 runeCost[RUNE_DEATH] += runeCost[i];
5658
5659 if (runeCost[RUNE_DEATH] > MAX_RUNES)
5660 return SPELL_FAILED_NO_POWER; // not sure if result code is correct
5661
5662 return SPELL_CAST_OK;
5663}
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:2558
bool IsClass(Classes playerClass, ClassContext context=CLASS_CONTEXT_NONE) const override
Definition Player.cpp:1351
RuneType GetCurrentRune(uint8 index) const
Definition Player.h:2557
Player * GetSpellModOwner() const override
Definition Unit.cpp:12637
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
9130{
9131 // Skip if there are not any script
9132 if (!m_loadedScripts.size())
9133 return true;
9134
9135 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr)
9136 {
9137 std::list<SpellScript::ObjectTargetSelectHandler>::iterator targetSelectHookEnd = (*itr)->OnObjectTargetSelect.end(), targetSelectHookItr = (*itr)->OnObjectTargetSelect.begin();
9138 for (; targetSelectHookItr != targetSelectHookEnd; ++targetSelectHookItr)
9139 if (((*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
9140 (!(*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*targetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
9141 return false;
9142
9143 std::list<SpellScript::ObjectAreaTargetSelectHandler>::iterator areaTargetSelectHookEnd = (*itr)->OnObjectAreaTargetSelect.end(), areaTargetSelectHookItr = (*itr)->OnObjectAreaTargetSelect.begin();
9144 for (; areaTargetSelectHookItr != areaTargetSelectHookEnd; ++areaTargetSelectHookItr)
9145 if (((*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && !(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)) ||
9146 (!(*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndex) && (*areaTargetSelectHookItr).IsEffectAffected(m_spellInfo, effIndexToCheck)))
9147 return false;
9148 }
9149 return true;
9150}

References m_loadedScripts, and m_spellInfo.

Referenced by SelectEffectImplicitTargets().

◆ CheckSpellFocus()

SpellCastResult Spell::CheckSpellFocus ( )
8099{
8100 // check spell focus object
8102 {
8104 Cell cell(p);
8105
8106 GameObject* ok = nullptr;
8109
8111 Map& map = *m_caster->GetMap();
8112 cell.Visit(p, object_checker, map, *m_caster, m_caster->GetVisibilityRange());
8113
8114 if (!ok)
8116
8117 focusObject = ok; // game object found in range
8118 }
8119 return SPELL_CAST_OK;
8120}
@ 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:781
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:669

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 ( )
8123{
8124 Unit* unitCaster = m_caster->ToUnit();
8125 if (!unitCaster)// || !unitCaster->IsPlayer())
8126 return;
8127
8128 //if (m_spellState == SPELL_STATE_DELAYED)
8129 // return; // spell is active and can't be time-backed
8130
8131 if (isDelayableNoMore()) // Spells may only be delayed twice
8132 return;
8133
8135 return;
8136
8137 // spells not loosing casting time (slam, dynamites, bombs..)
8138 //if (!(m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_DAMAGE))
8139 // return;
8140
8141 //check pushback reduce
8142 int32 delaytime = 500; // spellcasting delay is normally 500ms
8143 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
8144 unitCaster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
8145 delayReduce += unitCaster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
8146 if (delayReduce >= 100)
8147 return;
8148
8149 AddPct(delaytime, -delayReduce);
8150
8151 if (m_timer + delaytime > m_casttime)
8152 {
8153 delaytime = m_casttime - m_timer;
8155 }
8156 else
8157 m_timer += delaytime;
8158
8159 LOG_DEBUG("spells", "Spell {} partially interrupted for ({}) ms at damage", m_spellInfo->Id, delaytime);
8160
8161 WorldPacket data(SMSG_SPELL_DELAYED, 8 + 4);
8162 data << m_caster->GetPackGUID();
8163 data << uint32(delaytime);
8164
8165 m_caster->SendMessageToSet(&data, true);
8166}
#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:10035
bool isDelayableNoMore()
Definition Spell.h:657
int32 GetTotalAuraModifier(AuraType auratype) const
Definition Unit.cpp:6086
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition Object.cpp:2178
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 ( )
8169{
8170 Unit* unitCaster = m_caster->ToUnit();
8171 if (!unitCaster || !unitCaster->IsPlayer() || getState() != SPELL_STATE_CASTING)
8172 return;
8173
8174 if (isDelayableNoMore()) // Spells may only be delayed twice
8175 return;
8176
8178 return;
8179
8180 //check pushback reduce
8181 // should be affected by modifiers, not take the dbc duration.
8182 int32 duration = ((m_channeledDuration > 0) ? m_channeledDuration : m_spellInfo->GetDuration());
8183
8184 int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit
8185 int32 delayReduce = 100; // must be initialized to 100 for percent modifiers
8186 unitCaster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this);
8187 delayReduce += unitCaster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100;
8188 if (delayReduce >= 100)
8189 return;
8190
8191 AddPct(delaytime, -delayReduce);
8192
8193 if (m_timer <= delaytime)
8194 {
8195 delaytime = m_timer;
8196 m_timer = 0;
8197 }
8198 else
8199 m_timer -= delaytime;
8200
8201 LOG_DEBUG("spells.aura", "Spell {} partially interrupted for {} ms, new duration: {} ms", m_spellInfo->Id, delaytime, m_timer);
8202
8203 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8204 if ((*ihit).missCondition == SPELL_MISS_NONE)
8205 if (Unit* unit = (unitCaster->GetGUID() == ihit->targetGUID) ? unitCaster : ObjectAccessor::GetUnit(*unitCaster, ihit->targetGUID))
8206 unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
8207
8208 // partially interrupt persistent area auras
8209 if (DynamicObject* dynObj = unitCaster->GetDynObject(m_spellInfo->Id))
8210 dynObj->Delay(delaytime);
8211
8213}
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:6315

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
8699{
8700 Unit* unitCaster = m_caster->ToUnit();
8701 Unit* unit = nullptr;
8702 // In case spell hit target, do all effect on that target
8703 if (targetInfo.missCondition == SPELL_MISS_NONE)
8704 unit = m_caster->GetGUID() == targetInfo.targetGUID ? unitCaster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID);
8705 // In case spell reflect from target, do all effect on caster (if hit)
8706 // gameobject casts bounce onto the original caster (e.g. a reflected trap spell freezes the trap owner)
8707 else if (targetInfo.missCondition == SPELL_MISS_REFLECT && targetInfo.reflectResult == SPELL_MISS_NONE)
8708 unit = unitCaster ? unitCaster : m_originalCaster;
8709 if (!unit)
8710 return;
8711
8712 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8713 {
8714 if (targetInfo.effectMask & (1 << i))
8715 {
8716 m_damage = 0;
8717 m_healing = 0;
8719
8720 HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET);
8721
8722 if (m_damage > 0)
8723 {
8724 // Xinef: Area Auras, AoE Targetting spells AND Chain Target spells (cleave etc.)
8725 if (m_spellInfo->Effects[i].IsAreaAuraEffect() || m_spellInfo->Effects[i].IsTargetingArea() || (m_spellInfo->Effects[i].ChainTarget > 1 && m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MAGIC))
8726 {
8729 if (unitCaster && unitCaster->IsPlayer())
8730 {
8731 uint32 targetAmount = m_UniqueTargetInfo.size();
8732 if (targetAmount > 10)
8733 m_damage = m_damage * 10 / targetAmount;
8734 }
8735 }
8736 }
8737
8738 if (m_applyMultiplierMask & (1 << i))
8739 {
8741 m_damageMultipliers[i] *= multiplier[i];
8742 }
8743 targetInfo.damage += m_damage;
8745 }
8746 }
8747
8748 // xinef: totem's inherit owner crit chance and dancing rune weapon
8749 Unit* caster = unitCaster;
8750 if (unitCaster && (unitCaster->IsTotem() || unitCaster->GetEntry() == 27893))
8751 {
8752 if (Unit* owner = unitCaster->GetOwner())
8753 caster = owner;
8754 }
8755 else if (m_originalCaster)
8756 caster = m_originalCaster;
8757
8758 if (caster)
8759 {
8760 float critChance = caster->SpellDoneCritChance(unit, m_spellInfo, m_spellSchoolMask, m_attackType, false);
8761 critChance = unit->SpellTakenCritChance(caster, m_spellInfo, m_spellSchoolMask, critChance, m_attackType, false);
8762 targetInfo.crit = roll_chance_f(std::max(0.0f, critChance));
8763 }
8764}
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:8983
float SpellDoneCritChance(Unit const *, SpellInfo const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType, bool skipEffectCheck) const
Definition Unit.cpp:8893
int32 CalculateAOEDamageReduction(int32 damage, uint32 schoolMask, bool npcCaster) const
Definition Unit.cpp:16030

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
3429{
3430 Unit* unitCaster = m_caster->ToUnit();
3431 if (target->processed) // Check target
3432 return;
3433 target->processed = true; // Target checked in apply effects procedure
3434
3435 uint32 effectMask = target->effectMask;
3436 if (!effectMask)
3437 return;
3438
3439 GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
3440 if (!go)
3441 return;
3442
3445
3446 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3447 if (effectMask & (1 << effectNumber))
3448 HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3449
3450 // xinef: inform ai about spellhit
3451 go->AI()->SpellHit(unitCaster ? unitCaster : m_originalCaster, m_spellInfo);
3452
3454
3456}
virtual void SpellHit(Unit *, SpellInfo const *)
Definition GameObjectAI.h:67
GameObjectAI * AI() const
Definition GameObject.h:326
GameObject * GetGameObject(ObjectGuid const &guid)
Definition Map.cpp:2447
void CallScriptBeforeHitHandlers(SpellMissInfo missInfo)
Definition Spell.cpp:9048
void CallScriptOnHitHandlers()
Definition Spell.cpp:9061
void CallScriptAfterHitHandlers()
Definition Spell.cpp:9074

References GameObject::AI(), CallScriptAfterHitHandlers(), CallScriptBeforeHitHandlers(), CallScriptOnHitHandlers(), Spell::GOTargetInfo::effectMask, Map::GetGameObject(), WorldObject::GetMap(), HandleEffects(), m_caster, m_originalCaster, 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
3459{
3460 uint32 effectMask = target->effectMask;
3461 if (!target->item || !effectMask)
3462 return;
3463
3466
3467 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3468 if (effectMask & (1 << effectNumber))
3469 HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3470
3472
3474}

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
2625{
2626 Unit* unitCaster = m_caster->ToUnit();
2627 if (!target || target->processed)
2628 return;
2629
2630 target->processed = true; // Target checked in apply effects procedure
2631
2632 // Get mask of effects for target
2633 uint8 mask = target->effectMask;
2634
2635 Unit* effectUnit = m_caster->GetGUID() == target->targetGUID ? unitCaster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2636 if (!effectUnit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps
2637 return;
2638
2639 if (!effectUnit || m_spellInfo->Id == 45927)
2640 {
2641 uint8 farMask = 0;
2642 // create far target mask
2643 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2644 if (m_spellInfo->Effects[i].IsFarUnitTargetEffect())
2645 if ((1 << i) & mask)
2646 farMask |= (1 << i);
2647
2648 if (!farMask)
2649 return;
2650 // find unit in world
2651 // Xinef: FindUnit Access without Map check!!! Intended
2652 effectUnit = ObjectAccessor::FindPlayer(target->targetGUID);
2653 if (!effectUnit)
2654 return;
2655
2656 // do far effects on the unit
2657 // can't use default call because of threading, do stuff as fast as possible
2658 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2659 if (farMask & (1 << i))
2660 HandleEffects(effectUnit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET);
2661 return;
2662 }
2663
2664 if (effectUnit->IsAlive() != target->alive)
2665 return;
2666
2667 // Absorb delayed projectiles launched before Sanctuary (e.g. Vanish dodging a Frostbolt in flight)
2669 (GameTime::GetGameTimeMS().count() - target->timeDelay) <= effectUnit->m_lastSanctuaryTime)
2670 return; // No missinfo in that case
2671
2672 // Absorb instant hostile spells on application within brief window after Sanctuary
2674 effectUnit->m_lastSanctuaryTime &&
2675 GameTime::GetGameTimeMS().count() <= (effectUnit->m_lastSanctuaryTime + 400))
2676 return; // No missinfo in that case
2677
2678 // Get original caster (if exist) and calculate damage/healing from him data
2679 // (can be nullptr for GameObject casts with no owner - unit-dependent handling is skipped then)
2681
2682 SpellMissInfo missInfo = target->missCondition;
2683
2684 // Need init unitTarget by default unit (can changed in code on reflect)
2685 // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
2686 unitTarget = effectUnit;
2687
2688 // Reset damage/healing counter
2689 m_damage = target->damage;
2690 m_healing = -target->damage;
2691
2692 m_spellAura = nullptr; // Set aura to null for every target-make sure that pointer is not used for unit without aura applied
2693
2695 !m_originalCaster->IsFriendlyTo(effectUnit) &&
2697 (m_spellInfo->HasInitialAggro() || effectUnit->IsEngaged()))
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 damageInfo.skipCombat = IsFromPreDeathAura();
2889
2890 // Check damage immunity
2892 {
2893 m_damage = 0;
2894
2895 // no packet found in sniffs
2896 }
2897 else
2898 {
2899 // Add bonuses and fill damageInfo struct
2900 // Dancing Rune Weapon...
2901 if (unitCaster && unitCaster->GetEntry() == 27893)
2902 {
2903 if (Unit* owner = unitCaster->GetOwner())
2904 owner->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2905 }
2906 else
2907 caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
2908
2909 // xinef: override miss info after absorb / block calculations
2910 if (missInfo == SPELL_MISS_NONE && damageInfo.damage == 0)
2911 {
2912 //if (damageInfo.absorb > 0)
2913 // missInfo = SPELL_MISS_ABSORB;
2914 if (damageInfo.blocked)
2915 missInfo = SPELL_MISS_BLOCK;
2916 }
2917
2918 // Xinef: override with forced crit, only visual result
2919 if (GetSpellValue()->ForcedCritResult)
2920 {
2921 damageInfo.HitInfo |= SPELL_HIT_TYPE_CRIT;
2922 }
2923
2924 Unit::DealDamageMods(damageInfo.target, damageInfo.damage, &damageInfo.absorb);
2925
2926 // xinef: health leech handling
2928 {
2929 uint8 effIndex = EFFECT_0;
2930 for (; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
2931 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_HEALTH_LEECH)
2932 break;
2933
2934 float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
2935
2936 // get max possible damage, don't count overkill for heal
2937 uint32 healthGain = uint32(-unitTarget->GetHealthGain(-int32(damageInfo.damage)) * healMultiplier);
2938
2939 if (unitCaster && unitCaster->IsAlive())
2940 {
2941 healthGain = unitCaster->SpellHealingBonusDone(unitCaster, m_spellInfo, healthGain, HEAL, effIndex);
2942 healthGain = unitCaster->SpellHealingBonusTaken(unitCaster, m_spellInfo, healthGain, HEAL);
2943
2944 HealInfo healInfo(unitCaster, unitCaster, healthGain, m_spellInfo, m_spellInfo->GetSchoolMask());
2945 unitCaster->HealBySpell(healInfo);
2946 }
2947 }
2948
2949 // Send log damage message to client
2950 caster->SendSpellNonMeleeDamageLog(&damageInfo);
2951 // Xinef: send info to target about reflect
2952 if (reflectedSpell)
2953 effectUnit->SendSpellNonMeleeReflectLog(&damageInfo, effectUnit);
2954
2955 procVictim |= PROC_FLAG_TAKEN_DAMAGE;
2956
2957 caster->DealSpellDamage(&damageInfo, true, this);
2958
2959 // do procs after damage, eg healing effects
2960 // no need to check if target is alive, done in procdamageandspell
2961
2962 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2963 if (canEffectTrigger)
2964 {
2965 DamageInfo dmgInfo(damageInfo, SPELL_DIRECT_DAMAGE, m_attackType, missInfo);
2966 uint32 hitMask = m_procEx | dmgInfo.GetHitMask();
2967 Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, hitMask, damageInfo.damage, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2968 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2969
2972 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, dmgInfo.GetHitMask());
2973 }
2974
2975 m_damage = damageInfo.damage;
2976 }
2977 }
2978 // Passive spell hits/misses or active spells only misses (only triggers)
2979 else
2980 {
2981 // Fill base damage struct (unitTarget - is real spell target)
2983 // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
2984 if (canEffectTrigger)
2985 {
2986 DamageInfo dmgInfo(damageInfo, NODAMAGE, m_attackType, missInfo);
2987 uint32 hitMask = m_procEx | dmgInfo.GetHitMask();
2988 Unit::ProcSkillsAndAuras(caster, unitTarget, procAttacker, procVictim, hitMask, 0, m_attackType, m_spellInfo, m_triggeredByAuraSpell.spellInfo,
2989 m_triggeredByAuraSpell.effectIndex, this, &dmgInfo);
2990
2991 // Xinef: eg. rogue poisons can proc off cheap shot, etc. so this block should be here also
2992 // Xinef: ofc count only spells that HIT the target, little hack used to fool the system
2993 if ((dmgInfo.GetHitMask() & (PROC_HIT_NORMAL | PROC_HIT_CRITICAL)) && caster->IsPlayer() && m_spellInfo->HasAttribute(SPELL_ATTR0_CANCELS_AUTO_ATTACK_COMBAT) == 0 &&
2995 caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim | PROC_FLAG_TAKEN_DAMAGE, dmgInfo.GetHitMask());
2996 }
2997
2998 // Failed Pickpocket, reveal rogue
3000 {
3002 unitTarget->ToCreature()->EngageWithTarget(unitCaster);
3003 }
3004 }
3005 }
3006 else if (m_healing > 0 && unitTarget && unitTarget->IsAlive())
3007 {
3008 // pure gameobject cast without an owner: heal anyway, mirroring the damage case below
3010 }
3011 else if (m_damage > 0 && unitTarget && unitTarget->IsAlive())
3012 {
3013 // pure gameobject cast without an owner (e.g. world traps): deal the calculated
3014 // spell damage anyway, mitigated by the victim, without caster bonuses, crits or procs
3016 m_damage = 0;
3017 else
3018 {
3022
3024 Unit::CalcAbsorbResist(dmgInfo);
3025
3026 uint32 absorb = dmgInfo.GetAbsorb();
3027 uint32 resist = dmgInfo.GetResist();
3028 damage = dmgInfo.GetDamage();
3030
3031 // log the damage with the gameobject as the source
3033
3036 }
3037 }
3038
3039 if (unitCaster)
3040 {
3041 if (missInfo != SPELL_MISS_EVADE && !unitCaster->IsFriendlyTo(effectUnit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)))
3042 {
3048
3049 // Spells that don't initiate combat shouldn't affect stand state (e.g. Premeditation, Storm Giant/Felreaver Passive)
3050 if (m_spellInfo->HasInitialAggro() && !effectUnit->IsStandState())
3052 }
3053 }
3054
3055 if (missInfo != SPELL_MISS_EVADE && effectUnit != m_caster && unitCaster && unitCaster->IsFriendlyTo(effectUnit) && m_spellInfo->IsPositive() &&
3057 {
3058 unitCaster->SetInCombatWith(effectUnit);
3059 }
3060
3061 // Check for SPELL_ATTR7_CAN_CAUSE_INTERRUPT
3062 if (caster && m_spellInfo->HasAttribute(SPELL_ATTR7_CAN_CAUSE_INTERRUPT) && !effectUnit->IsPlayer())
3063 caster->CastSpell(effectUnit, SPELL_INTERRUPT_NONPLAYER, true);
3064
3065 if (spellHitTarget)
3066 {
3067 //AI functions
3068 if (spellHitTarget->IsCreature())
3069 {
3070 if (spellHitTarget->ToCreature()->IsAIEnabled)
3071 spellHitTarget->ToCreature()->AI()->SpellHit(unitCaster ? unitCaster : m_originalCaster, m_spellInfo);
3072 }
3073
3074 if (unitCaster && unitCaster->IsCreature() && unitCaster->ToCreature()->IsAIEnabled)
3075 unitCaster->ToCreature()->AI()->SpellHitTarget(spellHitTarget, m_spellInfo);
3076
3077 // Needs to be called after dealing damage/healing to not remove breaking on damage auras
3078 DoTriggersOnSpellHit(spellHitTarget, mask);
3079
3080 // if target is fallged for pvp also flag caster if a player
3081 // xinef: do not flag spells with aura bind sight (no special attribute)
3082 if (effectUnit->IsPvP() && effectUnit != m_caster && effectUnit->GetOwnerGUID() != m_caster->GetGUID() &&
3083 unitCaster && unitCaster->IsPlayer() && !m_spellInfo->HasAttribute(SPELL_ATTR0_CU_NO_PVP_FLAG))
3084 {
3085 unitCaster->ToPlayer()->UpdatePvP(true);
3086 }
3087
3089 }
3090}
@ 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_EVADE
Definition SharedDefines.h:1529
@ 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
@ TRIGGERED_DONT_ENTER_COMBAT
Ignore spell effects - used for ritual portals.
Definition SpellDefines.h:162
@ 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:266
@ SPELL_DIRECT_DAMAGE
Definition Unit.h:263
@ HEAL
Definition Unit.h:265
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:3928
CreatureAI * AI() const
Definition Creature.h:143
Definition Unit.h:344
Definition Unit.h:393
void RestoreSpellMods(Spell *spell, uint32 ownerAuraId=0, Aura *aura=nullptr)
Definition Player.cpp:10164
void CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 procVictim, uint32 procEx)
Definition Player.cpp:7430
void UpdatePvP(bool state, bool _override=false)
Definition PlayerUpdates.cpp:1553
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:9152
SpellValue const * GetSpellValue()
Definition Spell.h:609
SpellMissInfo DoSpellHitOnUnit(Unit *unit, uint32 effectMask, bool scaleAura)
Definition Spell.cpp:3092
Position m_reflectionTargetPosition
Definition Spell.h:688
void DoTriggersOnSpellHit(Unit *unit, uint8 effMask)
Definition Spell.cpp:3359
void ForwardThreatForAssistingMe(Unit *assistant, float baseAmount, SpellInfo const *spell=nullptr, bool ignoreModifiers=false)
== AFFECT OTHERS' THREAT LISTS ==
Definition ThreatManager.cpp:797
uint32 m_lastSanctuaryTime
Definition Unit.h:2111
void DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss, Spell const *spell=nullptr)
Definition Unit.cpp:1658
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, bool skipCombat=false)
Definition Unit.cpp:990
void SetInCombatWith(Unit *enemy, bool addSecondUnitSuppressed=false)
Definition Unit.h:953
void SendSpellNonMeleeReflectLog(SpellNonMeleeDamage *log, Unit *attacker)
Definition Unit.cpp:6491
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:2233
bool CanProc()
Definition Unit.h:1574
bool IsPvP() const
Definition Unit.h:1058
uint32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:9365
void AtTargetAttacked(Unit *target, bool canInitialAggro)
Definition Unit.cpp:11279
int32 HealBySpell(HealInfo &healInfo, bool critical=false)
Definition Unit.cpp:8170
bool IsStandState() const
Definition Unit.cpp:12786
static int32 DealHeal(Unit *healer, Unit *victim, uint32 addhealth)
Definition Unit.cpp:7874
int32 GetHealthGain(int32 dVal)
Definition Unit.cpp:10816
bool IsImmunedToDamage(SpellSchoolMask schoolMask) const
Definition Unit.cpp:9694
static uint32 SpellCriticalHealingBonus(Unit const *caster, SpellInfo const *spellProto, uint32 damage, Unit const *victim)
Definition Unit.cpp:9240
void SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)
Definition Unit.cpp:6523
ThreatManager & GetThreatMgr()
Definition Unit.h:965
bool IsAIEnabled
Definition Unit.h:2118
void SetLastDamagedTargetGuid(ObjectGuid const &guid)
Definition Unit.h:985
virtual bool IsEngaged() const
Definition Unit.h:945
uint32 SpellHealingBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack=1)
Definition Unit.cpp:9485
void SetStandState(uint8 state)
Definition Unit.cpp:12801
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0, bool isAutoshot=false)
Definition Unit.cpp:5249
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:1511
static void CalcAbsorbResist(DamageInfo &dmgInfo, bool Splited=false, uint8 casterLevel=0)
Definition Unit.cpp:2344
void SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)
Definition Object.cpp:3837
void SendSpellNonMeleeDamageLog(Unit *target, SpellInfo const *spellInfo, uint32 damage, SpellSchoolMask schoolMask, uint32 absorb, uint32 resist)
Definition Object.cpp:3851
virtual uint8 getLevelForTarget(WorldObject const *) const
Definition Object.h:576
Milliseconds GetGameTimeMS()
Definition GameTime.cpp:44
Definition Position.h:27
void Relocate(float x, float y)
Definition Position.h:77
Definition Unit.h:514

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(), HasTriggeredCastFlag(), HEAL, Unit::HealBySpell(), SpellNonMeleeDamage::HitInfo, SpellInfo::Id, Unit::IsAIEnabled, Unit::IsAlive(), SpellInfo::IsAuraEffectEqual(), Unit::IsClass(), Object::IsCreature(), Unit::IsEngaged(), Unit::IsFriendlyTo(), IsFromPreDeathAura(), 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(), SpellNonMeleeDamage::skipCombat, 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(), TRIGGERED_DONT_ENTER_COMBAT, 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 
)
1740{
1741 Unit* unitCaster = m_caster->ToUnit();
1742 if (!unitTarget)
1743 return;
1744
1745 Player* player = unitTarget->ToPlayer();
1746 if (!player)
1747 {
1748 return;
1749 }
1750
1751 uint32 newitemid = itemId;
1752
1753 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid);
1754 if (!pProto)
1755 {
1756 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1757 return;
1758 }
1759
1760 uint32 addNumber = damage;
1761
1762 // bg reward have some special in code work
1763 bool SelfCast = true;
1764 switch (m_spellInfo->Id)
1765 {
1770 case SPELL_WS_MARK_TIE:
1773 SelfCast = true;
1774 break;
1776 if (player->HasAura(55629 /*SPELL_LIEUTENANT*/))
1777 addNumber = 3;
1778 else if (player->HasAura(33280 /*SPELL_CORPORAL*/))
1779 addNumber = 2;
1780 else
1781 addNumber = 1;
1782 SelfCast = true;
1783 break;
1784 }
1785
1786 if (addNumber < 1)
1787 addNumber = 1;
1788 if (addNumber > pProto->GetMaxStackSize())
1789 addNumber = pProto->GetMaxStackSize();
1790
1791 /* == gem perfection handling == */
1792
1793 // the chance of getting a perfect result
1794 float perfectCreateChance = 0.0f;
1795
1796 // the resulting perfect item if successful
1797 uint32 perfectItemType = itemId;
1798
1799 // get perfection capability and chance
1800 if (CanCreatePerfectItem(player, m_spellInfo->Id, perfectCreateChance, perfectItemType))
1801 if (roll_chance_f(perfectCreateChance)) // if the roll succeeds...
1802 newitemid = perfectItemType; // the perfect item replaces the regular one
1803
1804 /* == gem perfection handling over == */
1805
1806 /* == profession specialization handling == */
1807
1808 // init items_count to 1, since 1 item will be created regardless of specialization
1809 int32 itemsCount = 1;
1810 float additionalCreateChance = 0.0f;
1811 int32 additionalMaxNum = 0;
1812 // get the chance and maximum number for creating extra items
1813 if (canCreateExtraItems(player, m_spellInfo->Id, additionalCreateChance, additionalMaxNum))
1814 {
1815 // roll with this chance till we roll not to create or we create the max num
1816 while (roll_chance_f(additionalCreateChance) && itemsCount <= additionalMaxNum)
1817 ++itemsCount;
1818 }
1819
1820 // really will be created more items
1821 addNumber *= itemsCount;
1822
1823 /* == profession specialization handling over == */
1824
1825 // can the player store the new item?
1826 ItemPosCountVec dest;
1827 uint32 no_space = 0;
1828 InventoryResult msg = player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, newitemid, addNumber, &no_space);
1829 if (msg != EQUIP_ERR_OK)
1830 {
1831 // convert to possible store amount
1833 addNumber -= no_space;
1834 else
1835 {
1836 // if not created by another reason from full inventory or unique items amount limitation
1837 player->SendEquipError(msg, nullptr, nullptr, newitemid);
1838 return;
1839 }
1840 }
1841
1842 if (addNumber)
1843 {
1844 // create the new item and store it
1845 Item* pItem = player->StoreNewItem(dest, newitemid, true);
1846
1847 // was it successful? return error if not
1848 if (!pItem)
1849 {
1850 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
1851 return;
1852 }
1853
1854 // set the "Crafted by ..." property of the item
1855 if (unitCaster && unitCaster->IsPlayer() && pItem->GetTemplate()->HasSignature())
1856 pItem->SetGuidValue(ITEM_FIELD_CREATOR, player->GetGUID());
1857
1858 // send info to the client
1859 player->SendNewItem(pItem, addNumber, true, SelfCast);
1860
1861 sScriptMgr->OnPlayerCreateItem(player, pItem, addNumber);
1862
1863 // we succeeded in creating at least one item, so a levelup is possible
1864 if (SelfCast)
1866 }
1867}
@ 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:847
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
3093{
3094 Unit* unitCaster = m_caster->ToUnit();
3095 if (!unit || !effectMask)
3096 return SPELL_MISS_EVADE;
3097
3098 // For delayed spells immunity may be applied between missile launch and hit - check immunity for that case
3099 if (m_spellInfo->Speed && ((m_damage > 0 && unit->IsImmunedToDamage(unitCaster, m_spellInfo)) || unit->IsImmunedToSpell(m_spellInfo, this)))
3100 {
3101 return SPELL_MISS_IMMUNE;
3102 }
3103
3104 // disable effects to which unit is immune
3105 SpellMissInfo returnVal = SPELL_MISS_IMMUNE;
3106 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3107 {
3108 if (effectMask & (1 << effectNumber))
3109 {
3110 if (unit->IsImmunedToSpellEffect(m_spellInfo, effectNumber, unitCaster))
3111 effectMask &= ~(1 << effectNumber);
3112 // Xinef: Buggs out polymorph
3113 // Xinef: And this is checked in MagicSpellHitResult, why we check resistance twice?
3114 // Xinef: And why we check every spell effect basing on rand and generic dispel info? some effects will be appliend and some wont?
3115 /*else if (m_spellInfo->Effects[effectNumber].IsAura() && !m_spellInfo->IsPositiveEffect(effectNumber))
3116 {
3117 int32 debuff_resist_chance = unit->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3118 debuff_resist_chance += unit->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(m_spellInfo->Dispel));
3119
3120 if (debuff_resist_chance > 0)
3121 if (irand(0,10000) <= (debuff_resist_chance * 100))
3122 {
3123 effectMask &= ~(1 << effectNumber);
3124 returnVal = SPELL_MISS_RESIST;
3125 }
3126 }*/
3127 }
3128 }
3129 if (!effectMask)
3130 return returnVal;
3131
3132 if (unit->IsPlayer())
3133 {
3137 }
3138
3139 if (unitCaster && unitCaster->IsPlayer())
3140 {
3143 }
3144
3145 if (m_caster != unit)
3146 {
3147 // Recheck UNIT_FLAG_NON_ATTACKABLE for delayed spells
3148 // Xinef: Also check evade state
3149 if (m_spellInfo->Speed > 0.0f)
3150 {
3151 if (unit->IsCreature() && unit->ToCreature()->IsInEvadeMode())
3152 return SPELL_MISS_EVADE;
3153
3155 return SPELL_MISS_EVADE;
3156 }
3157
3158 if (m_caster->IsValidAttackTarget(unit, m_spellInfo) && /*Intervene Trigger*/ m_spellInfo->Id != 59667)
3159 {
3161 }
3162 else if (m_caster->IsFriendlyTo(unit))
3163 {
3164 // for delayed spells ignore negative spells (after duel end) for friendly targets
3166 if (!IsTriggered() && m_spellInfo->Speed > 0.0f && unit->IsPlayer() && !m_spellInfo->IsPositive())
3167 return SPELL_MISS_EVADE;
3168
3169 // assisting case, healing and resurrection
3171 {
3172 if (unitCaster)
3173 {
3174 unitCaster->SetContestedPvP();
3176 unitCaster->ToPlayer()->UpdatePvP(true);
3177 }
3178 }
3179
3180 // xinef: triggered spells should not prolong combat
3182 {
3185 unit->GetThreatMgr().ForwardThreatForAssistingMe(m_originalCaster, 0.0f, nullptr, true);
3186 }
3187 }
3188 }
3189
3190 uint8 aura_effmask = 0;
3191 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3192 if (effectMask & (1 << i) && m_spellInfo->Effects[i].IsUnitOwnedAuraEffect())
3193 aura_effmask |= 1 << i;
3194
3195 Unit* originalCaster = GetOriginalCaster();
3196 if (!originalCaster)
3197 originalCaster = unitCaster;
3198
3199 // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
3200 // Xinef: Do not increase diminishing level for self cast
3202 // xinef: do not increase diminish level for bosses (eg. Void Reaver silence is never diminished)
3203 if (((m_spellFlags & SPELL_FLAG_REFLECTED) && !(unit->HasReflectSpellsAura())) || (aura_effmask && m_diminishGroup && unit != m_caster && (!unitCaster || !unitCaster->IsCreature() || !unitCaster->ToCreature()->isWorldBoss())))
3204 {
3207
3208 uint32 flagsExtra = unit->IsCreature() ? unit->ToCreature()->GetCreatureTemplate()->flags_extra : 0;
3209
3210 // Increase Diminishing on unit, current informations for actually casts will use values above
3211 if ((type == DRTYPE_PLAYER && (unit->IsCharmedOwnedByPlayerOrPlayer() || flagsExtra & CREATURE_FLAG_EXTRA_ALL_DIMINISH ||
3213 {
3214 // Do not apply diminish return if caster is NPC
3215 // resolve through the original caster - the direct caster can be a gameobject (e.g. hunter traps)
3216 Unit* diminishSource = m_originalCaster ? m_originalCaster : unitCaster;
3217 if (diminishSource && diminishSource->IsCharmedOwnedByPlayerOrPlayer())
3218 {
3220 }
3221 }
3222 }
3223
3226
3227 if (aura_effmask)
3228 {
3229 // Select rank for aura with level requirements only in specific cases
3230 // 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
3231 SpellInfo const* aurSpellInfo = m_spellInfo;
3232 int32 basePoints[3];
3233 if (scaleAura)
3234 {
3236 ASSERT(aurSpellInfo);
3237 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3238 {
3239 basePoints[i] = aurSpellInfo->Effects[i].BasePoints;
3240 if (m_spellInfo->Effects[i].Effect != aurSpellInfo->Effects[i].Effect)
3241 {
3242 aurSpellInfo = m_spellInfo;
3243 break;
3244 }
3245 }
3246 }
3247
3248 // prefer the unit original caster, fall back to the WorldObject caster (e.g. GameObject traps)
3250
3251 bool refresh = false;
3253 m_spellAura = Aura::TryRefreshStackOrCreate(aurSpellInfo, effectMask, unit, m_originalCaster,
3254 (aurSpellInfo == m_spellInfo) ? &m_spellValue->EffectBasePoints[0] : &basePoints[0], m_CastItem, caster->GetGUID(), &refresh, refreshPeriodic);
3255
3256 // xinef: if aura was not refreshed, add proc ex
3257 if (!refresh)
3259
3260 if (m_spellAura)
3261 {
3262 // Set aura stack amount to desired value
3264 {
3265 if (!refresh)
3267 else
3269 }
3270
3271 // Now Reduce spell duration using data received at spell hit
3272 int32 duration = m_spellAura->GetMaxDuration();
3273 int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup, aurSpellInfo);
3274
3275 // Xinef: if unit == caster - test versus original unit if available
3276 float diminishMod = 1.0f;
3277 if (m_originalCaster)
3278 {
3279 if (unit == m_caster && m_targets.GetUnitTarget())
3281 else
3282 diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel, limitduration);
3283 }
3284
3285 // unit is immune to aura if it was diminished to 0 duration
3286 if (diminishMod == 0.0f)
3287 {
3290 return SPELL_MISS_IMMUNE;
3291 bool found = false;
3292 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3293 if (effectMask & (1 << i) && m_spellInfo->Effects[i].Effect != SPELL_EFFECT_APPLY_AURA)
3294 found = true;
3295 if (!found)
3296 return SPELL_MISS_IMMUNE;
3297 }
3298 else
3299 {
3300 ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
3301
3302 bool positive = m_spellAura->GetSpellInfo()->IsPositive();
3304 positive = aurApp->IsPositive();
3305
3306 duration = caster->ModSpellDuration(aurSpellInfo, unit, duration, positive, effectMask);
3307
3308 // xinef: haste affects duration of those spells twice
3311
3312 if (m_spellValue->AuraDuration != 0)
3313 {
3314 if (m_spellAura->GetMaxDuration() != -1)
3315 {
3317 }
3318
3320 }
3321 else if (duration != m_spellAura->GetMaxDuration())
3322 {
3323 m_spellAura->SetMaxDuration(duration);
3324 m_spellAura->SetDuration(duration);
3325 }
3326
3327 // xinef: apply relic cooldown, imo best place to add this
3329 if (unitCaster)
3330 unitCaster->AddSpellCooldown(SPELL_RELIC_COOLDOWN, m_CastItem->GetEntry(), duration);
3331
3334 }
3335 }
3336 }
3337
3338 int8 sanct_effect = -1;
3339
3340 for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber)
3341 {
3342 // handle sanctuary effects after aura apply!
3343 if (m_spellInfo->Effects[effectNumber].Effect == SPELL_EFFECT_SANCTUARY)
3344 {
3345 sanct_effect = effectNumber;
3346 continue;
3347 }
3348
3349 if (effectMask & (1 << effectNumber))
3350 HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET);
3351 }
3352
3353 if (sanct_effect >= 0 && (effectMask & (1 << sanct_effect)))
3354 HandleEffects(unit, nullptr, nullptr, sanct_effect, SPELL_EFFECT_HANDLE_HIT_TARGET);
3355
3356 return SPELL_MISS_NONE;
3357}
@ 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:131
void SetStackAmount(uint8 num)
Definition SpellAuras.cpp:1048
AuraApplication const * GetApplicationOfTarget(ObjectGuid guid) const
Definition SpellAuras.h:186
void SetTriggeredByAuraSpellInfo(SpellInfo const *triggeredByAuraSpellInfo)
Definition SpellAuras.cpp:2873
void _RegisterForTargets()
Definition SpellAuras.h:122
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool periodicReset=false)
Definition SpellAuras.cpp:1083
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:919
void SetMaxDuration(int32 duration)
Definition SpellAuras.h:132
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
void InheritCombatStatesFrom(Unit const *who)
Definition CombatManager.cpp:273
bool isWorldBoss() const
Definition Creature.h:123
bool IsInEvadeMode() const
Definition Creature.h:137
float GetFloatValue(uint16 index) const
Definition Object.cpp:315
uint32 StackAmount
Definition SpellInfo.h:395
SpellInfo const * GetAuraRankForLevel(uint8 level) const
Definition SpellInfo.cpp:2973
Unit * GetOriginalCaster() const
Definition Spell.h:592
Definition SpellAuras.h:291
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Definition Unit.cpp:5838
DiminishingLevels GetDiminishing(DiminishingGroup group)
Definition Unit.cpp:11419
void IncrDiminishing(DiminishingGroup group)
Definition Unit.cpp:11445
void SetContestedPvP(Player *attackedPlayer=nullptr, bool lookForNearContestedGuards=true)
Definition Unit.cpp:13336
bool HasUnitFlag(UnitFlags flags) const
Definition Unit.h:753
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
Definition Unit.cpp:11459
virtual void AddSpellCooldown(uint32, uint32, uint32, bool needSendToClient=false, bool forceSendToSpectator=false)
Definition Unit.h:1354
ObjectGuid GetCharmerOrOwnerGUID() const override
Definition Unit.h:1312
bool HasReflectSpellsAura() const
Definition Unit.h:1835
bool IsCharmedOwnedByPlayerOrPlayer() const
Definition Unit.h:1326
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo, Spell const *spell=nullptr)
Definition Unit.cpp:9888
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID=ObjectGuid::Empty, Aura *except=nullptr, bool negative=true, bool positive=true)
Definition Unit.cpp:5178
CombatManager & GetCombatManager()
Definition Unit.h:967
int32 ModSpellDuration(SpellInfo const *spellProto, Unit const *target, int32 duration, bool positive, uint32 effectMask) const
Definition Object.cpp:3402
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:4009
bool IsHostileTo(WorldObject const *target) const
Definition Object.cpp:3999
bool IsFriendlyTo(WorldObject const *target) const
Definition Object.cpp:4004
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, 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
3360{
3361 Unit* unitCaster = m_caster->ToUnit();
3362 // Apply additional spell effects to target
3364 if (m_preCastSpell)
3365 {
3366 // Avenging Wrath - also apply Immune Shield Marker
3367 if (m_preCastSpell == 61987)
3368 m_caster->CastSpell(unit, 61988, true);
3369
3370 // Fearie Fire (Feral) - damage
3371 if (m_preCastSpell == 60089)
3372 m_caster->CastSpell(unit, m_preCastSpell, true);
3373 else if (sSpellMgr->GetSpellInfo(m_preCastSpell))
3374 // Blizz seems to just apply aura without bothering to cast
3375 if (unitCaster)
3376 unitCaster->AddAura(m_preCastSpell, unit);
3377 }
3378
3379 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras
3380 // this is executed after spell proc spells on target hit
3381 // spells are triggered for each hit spell target
3382 // info confirmed with retail sniffs of permafrost and shadow weaving
3383 if (!m_hitTriggerSpells.empty())
3384 {
3385 int _duration = 0;
3386 for (HitTriggerSpellList::const_iterator i = m_hitTriggerSpells.begin(); i != m_hitTriggerSpells.end(); ++i)
3387 {
3388 if (CanExecuteTriggersOnHit(effMask, i->triggeredByAura) && roll_chance_i(i->chance))
3389 {
3390 m_caster->CastSpell(unit, i->triggeredSpell->Id, true);
3391 LOG_DEBUG("spells.aura", "Spell {} triggered spell {} by SPELL_AURA_ADD_TARGET_TRIGGER aura", m_spellInfo->Id, i->triggeredSpell->Id);
3392
3393 // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
3394 // set duration of current aura to the triggered spell
3395 if (i->triggeredSpell->GetDuration() == -1)
3396 {
3397 if (Aura* triggeredAur = unit->GetAura(i->triggeredSpell->Id, m_caster->GetGUID()))
3398 {
3399 // get duration from aura-only once
3400 if (!_duration)
3401 {
3402 Aura* aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
3403 _duration = aur ? aur->GetDuration() : -1;
3404 }
3405 triggeredAur->SetDuration(std::max(triggeredAur->GetDuration(), _duration));
3406 }
3407 }
3408 }
3409 }
3410 }
3411
3412 // trigger linked auras remove/apply
3414 if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
3415 {
3416 for (std::vector<int32>::const_iterator i = spellTriggered->begin(); i != spellTriggered->end(); ++i)
3417 if (*i < 0)
3418 {
3419 unit->RemoveAurasDueToSpell(-(*i));
3420 }
3421 else
3422 {
3423 unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
3424 }
3425 }
3426}
bool roll_chance_i(int chance)
Definition Random.h:63
@ SPELL_LINK_HIT
Definition SpellMgr.h:100
int32 GetDuration() const
Definition SpellAuras.h:135
HitTriggerSpellList m_hitTriggerSpells
Definition Spell.h:787
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0) const
Definition Unit.cpp:5658
Aura * AddAura(uint32 spellId, Unit *target)
Definition Unit.cpp:14825

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)
4457{
4459 return;
4460
4461 if (!gameObjTarget)
4462 return;
4463
4464 GameObjectActions action = GameObjectActions(m_spellInfo->Effects[effIndex].MiscValue);
4465 switch (action)
4466 {
4472 break;
4473 case GameObjectActions::Disturb: // What's the difference with Open?
4475 if (Unit* unitCaster = m_caster->ToUnit())
4476 gameObjTarget->Use(unitCaster);
4477 break;
4479 if (Unit* unitCaster = m_caster->ToUnit())
4480 gameObjTarget->UseDoorOrButton(0, false, unitCaster);
4481 [[fallthrough]];
4485 break;
4489 break;
4492 break;
4496 break;
4500 break;
4502 if (Unit* unitCaster = m_caster->ToUnit())
4503 gameObjTarget->UseDoorOrButton(0, true, unitCaster);
4504 break;
4509 {
4510 GameObjectTemplateAddon const* templateAddon = gameObjTarget->GetTemplateAddon();
4511
4512 uint32 artKitIndex = uint32(action) - uint32(GameObjectActions::UseArtKit0);
4513
4514 uint32 artKitValue = 0;
4515 if (templateAddon)
4516 artKitValue = templateAddon->artKits[artKitIndex];
4517
4518 if (artKitValue == 0)
4519 LOG_ERROR("sql.sql", "GameObject {} hit by spell {} needs `artkit{}` in `gameobject_template_addon`", gameObjTarget->GetEntry(), m_spellInfo->Id, artKitIndex);
4520 else
4521 gameObjTarget->SetGoArtKit(artKitValue);
4522
4523 break;
4524 }
4526 LOG_FATAL("spell", "Spell {} has action type NONE in effect {}", m_spellInfo->Id, int32(effIndex));
4527 break;
4528 default:
4529 LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", m_spellInfo->Id, int32(action), int32(effIndex));
4530 break;
4531 }
4532}
GameObjectActions
Definition GameObject.h:81
#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:1553
void SetGoArtKit(uint8 artkit)
Definition GameObject.cpp:1567
void SendCustomAnim(uint32 anim)
Definition GameObject.cpp:2227
void ResetDoorOrButton()
Definition GameObject.cpp:1543
void DespawnOrUnsummon(Milliseconds delay=0ms, Seconds forcedRespawnTime=0s)
Definition GameObject.cpp:1043
GameObjectTemplateAddon const * GetTemplateAddon() const
Definition GameObject.cpp:1022
void Use(Unit *user)
Definition GameObject.cpp:1603
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)
6093{
6094 Unit* unitCaster = m_caster->ToUnit();
6095 if (!unitCaster)
6096 return;
6097
6099 return;
6100
6101 if (!unitCaster->IsPlayer())
6102 return;
6103
6104 Player* player = unitCaster->ToPlayer();
6105
6107 return;
6108
6109 // needed later
6110 m_runesState = unitCaster->ToPlayer()->GetRunesState();
6111
6112 uint32 count = damage;
6113 if (count == 0) count = 1;
6114 for (uint32 j = 0; j < MAX_RUNES && count > 0; ++j)
6115 {
6116 if (player->GetRuneCooldown(j) && player->GetCurrentRune(j) == RuneType(m_spellInfo->Effects[effIndex].MiscValue))
6117 {
6118 if (m_spellInfo->Id == 45529)
6119 if (player->GetBaseRune(j) != RuneType(m_spellInfo->Effects[effIndex].MiscValueB))
6120 continue;
6121 player->SetRuneCooldown(j, 0);
6122 player->SetGracePeriod(j, player->IsInCombat()); // xinef: reset grace period
6123 --count;
6124 }
6125 }
6126
6127 // Blood Tap
6128 if (m_spellInfo->Id == 45529 && count > 0)
6129 {
6130 for (uint32 l = 0; l < MAX_RUNES && count > 0; ++l)
6131 {
6132 // Check if both runes are on cd as that is the only time when this needs to come into effect
6133 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)))
6134 {
6135 // Should always update the rune with the lowest cd
6136 if (player->GetRuneCooldown(l) >= player->GetRuneCooldown(l + 1))
6137 l++;
6138 player->SetRuneCooldown(l, 0);
6139 player->SetGracePeriod(l, player->IsInCombat()); // xinef: reset grace period
6140 --count;
6141 }
6142 else
6143 break;
6144 }
6145 }
6146
6147 // Empower rune weapon
6148 if (m_spellInfo->Id == 47568)
6149 {
6150 // Need to do this just once
6151 if (effIndex != 0)
6152 return;
6153
6154 for (uint32 i = 0; i < MAX_RUNES; ++i)
6155 {
6156 if (player->GetRuneCooldown(i) && (player->GetCurrentRune(i) == RUNE_FROST || player->GetCurrentRune(i) == RUNE_DEATH))
6157 {
6158 player->SetRuneCooldown(i, 0);
6159 player->SetGracePeriod(i, player->IsInCombat()); // xinef: reset grace period
6160 }
6161 }
6162 }
6163
6164 // is needed to push through to the client that the rune is active
6165 //player->ResyncRunes(MAX_RUNES);
6166 unitCaster->CastSpell(unitCaster, 47804, true);
6167}
@ RUNE_FROST
Definition Player.h:398
void SetRuneCooldown(uint8 index, uint32 cooldown)
Definition Player.h:2566
uint8 GetRunesState() const
Definition Player.h:2555
void SetGracePeriod(uint8 index, uint32 period)
Definition Player.h:2567
RuneType GetBaseRune(uint8 index) const
Definition Player.h:2556

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)
6495{
6497 return;
6498
6499 if (!unitTarget)
6500 return;
6501
6502 if (Player* player = unitTarget->ToPlayer())
6503 {
6504 player->ActivateSpec(damage - 1); // damage is 1 or 2, spec is 0 or 1
6505 }
6506}

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

◆ EffectAddComboPoints()

void Spell::EffectAddComboPoints ( SpellEffIndex  effIndex)
4281{
4283 {
4284 return;
4285 }
4286
4287 if (!unitTarget || damage <= 0)
4288 {
4289 return;
4290 }
4291
4293}
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)
4901{
4903 {
4904 return;
4905 }
4906
4907 if (!unitTarget || !unitTarget->IsAlive())
4908 {
4909 return;
4910 }
4911
4913
4915}
void ExecuteLogEffectExtraAttacks(uint8 effIndex, Unit *victim, uint32 attCount)
Definition Spell.cpp:5290
void AddExtraAttacks(uint32 count)
Definition Unit.cpp:2974

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

◆ EffectAddFarsight()

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

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)
2960{
2962 return;
2963
2964 if (!unitTarget->IsPlayer())
2965 return;
2966
2967 // not scale value for item based reward (/10 value expected)
2968 if (m_CastItem)
2969 {
2970 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage / 10, false);
2971 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (item {}) for player: {}",
2973 return;
2974 }
2975
2976 // do not allow to add too many honor for player (50 * 21) = 1040 at level 70, or (50 * 31) = 1550 at level 80
2977 if (damage <= 50)
2978 {
2980 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward, false);
2981 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (scale) to player: {}",
2982 m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().ToString());
2983 }
2984 else
2985 {
2986 //maybe we have correct honor_gain in damage already
2987 unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage, false);
2988 LOG_DEBUG("spells.aura", "SpellEffect::AddHonor (spell_id {}) rewards {} honor points (non scale) for player: {}",
2990 }
2991}
std::string ToString() const
Definition ObjectGuid.cpp:49
bool RewardHonor(Unit *victim, uint32 groupsize, int32 honor=-1, bool awardXP=true)
Definition Player.cpp:6291
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)
1386{
1388 return;
1389
1390 if (!m_spellAura || !unitTarget)
1391 return;
1394}
WorldObject * GetOwner() const
Definition SpellAuras.h:108
void _ApplyEffectForTargets(uint8 effIndex)
Definition SpellAuras.cpp:786

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)
4535{
4536 Unit* unitCaster = m_caster->ToUnit();
4537 if (!unitCaster)
4538 return;
4539
4541 return;
4542
4543 if (!unitCaster->IsPlayer() || m_glyphIndex >= MAX_GLYPH_SLOT_INDEX)
4544 return;
4545
4546 Player* player = unitCaster->ToPlayer();
4547
4548 // glyph sockets level requirement
4549 uint8 minLevel = 0;
4550 switch (m_glyphIndex)
4551 {
4552 case 0:
4553 case 1:
4554 minLevel = 15;
4555 break;
4556 case 2:
4557 minLevel = 50;
4558 break;
4559 case 3:
4560 minLevel = 30;
4561 break;
4562 case 4:
4563 minLevel = 70;
4564 break;
4565 case 5:
4566 minLevel = 80;
4567 break;
4568 }
4569 if (minLevel && unitCaster->GetLevel() < minLevel)
4570 {
4572 return;
4573 }
4574
4575 // apply new one
4576 if (uint32 glyph = m_spellInfo->Effects[effIndex].MiscValue)
4577 {
4578 if (GlyphPropertiesEntry const* glyphEntry = sGlyphPropertiesStore.LookupEntry(glyph))
4579 {
4580 if (GlyphSlotEntry const* glyphSlotEntry = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex)))
4581 {
4582 if (glyphEntry->TypeFlags != glyphSlotEntry->TypeFlags)
4583 {
4585 return; // glyph slot mismatch
4586 }
4587 }
4588
4589 // remove old glyph aura
4590 if (uint32 oldGlyph = player->GetGlyph(m_glyphIndex))
4591 if (GlyphPropertiesEntry const* oldGlyphEntry = sGlyphPropertiesStore.LookupEntry(oldGlyph))
4592 {
4593 player->RemoveAurasDueToSpell(oldGlyphEntry->SpellId);
4594
4595 // Removed any triggered auras
4596 Unit::AuraMap& ownedAuras = player->GetOwnedAuras();
4597 for (Unit::AuraMap::iterator iter = ownedAuras.begin(); iter != ownedAuras.end();)
4598 {
4599 Aura* aura = iter->second;
4600 if (SpellInfo const* triggeredByAuraSpellInfo = aura->GetTriggeredByAuraSpellInfo())
4601 {
4602 if (triggeredByAuraSpellInfo->Id == oldGlyphEntry->SpellId)
4603 {
4604 player->RemoveOwnedAura(iter);
4605 continue;
4606 }
4607 }
4608 ++iter;
4609 }
4610
4611 player->SendLearnPacket(oldGlyphEntry->SpellId, false); // Send packet to properly handle client-side spell tooltips
4612 }
4613
4614 player->SendLearnPacket(glyphEntry->SpellId, true); // Send packet to properly handle client-side spell tooltips
4616 player->SetGlyph(m_glyphIndex, glyph, !player->GetSession()->PlayerLoading());
4617 player->SendTalentsInfoData(false);
4618 }
4619 }
4620}
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:2887
void SendTalentsInfoData(bool pet)
Definition Player.cpp:14916
void SendLearnPacket(uint32 spellId, bool learn)
Definition Player.cpp:3143
uint32 GetGlyph(uint8 slot) const
Definition Player.h:1794
uint32 GetGlyphSlot(uint8 slot) const
Definition Player.h:1785
void SetGlyph(uint8 slot, uint32 glyph, bool save)
Definition Player.h:1786
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4763
boost::container::flat_multimap< uint32, Aura * > AuraMap
Definition Unit.h:675
AuraMap & GetOwnedAuras()
Definition Unit.h:1390
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)
6636{
6637 Unit* unitCaster = m_caster->ToUnit();
6638 if (!unitCaster)
6639 return;
6640
6642 return;
6643
6644 if (!unitTarget)
6645 return;
6646
6647 Player* player = unitTarget->ToPlayer();
6648 if (!player)
6649 {
6650 return;
6651 }
6652
6653 WorldLocation homeLoc;
6654 uint32 areaId = player->GetAreaId();
6655
6656 if (m_spellInfo->Effects[effIndex].MiscValue)
6657 areaId = m_spellInfo->Effects[effIndex].MiscValue;
6658
6659 if (m_targets.HasDst())
6660 homeLoc.WorldRelocate(*destTarget);
6661 else
6662 {
6663 homeLoc = player->GetWorldLocation();
6664 }
6665
6666 player->SetHomebind(homeLoc, areaId);
6667
6668 // binding
6669 WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4);
6670 data << float(homeLoc.GetPositionX());
6671 data << float(homeLoc.GetPositionY());
6672 data << float(homeLoc.GetPositionZ());
6673 data << uint32(homeLoc.GetMapId());
6674 data << uint32(areaId);
6675 player->SendDirectMessage(&data);
6676
6677 LOG_DEBUG("spells.aura", "EffectBind: New homebind X: {}, Y: {}, Z: {}, MapId: {}, AreaId: {}",
6678 homeLoc.GetPositionX(), homeLoc.GetPositionY(), homeLoc.GetPositionZ(), homeLoc.GetMapId(), areaId);
6679 // zone update
6680 data.Initialize(SMSG_PLAYERBOUND, 8 + 4);
6681 data << unitCaster->GetGUID();
6682 data << uint32(areaId);
6683 player->SendDirectMessage(&data);
6684}
void SendDirectMessage(WorldPacket const *data) const
Definition Player.cpp:5886
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)
4931{
4932 Unit* unitCaster = m_caster->ToUnit();
4933 if (!unitCaster)
4934 return;
4935
4937 return;
4938
4939 if (unitCaster->IsPlayer())
4940 unitCaster->ToPlayer()->SetCanBlock(true);
4941}
void SetCanBlock(bool value)
Definition Player.cpp:13521

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.

6555{
6556 Unit* unitCaster = m_caster->ToUnit();
6557 if (!unitCaster)
6558 return;
6559
6561 return;
6562
6563 if (!unitCaster->IsPlayer())
6564 return;
6565
6566 Player* p_caster = unitCaster->ToPlayer();
6567 uint32 button_id = m_spellInfo->Effects[effIndex].MiscValue + 132;
6568 uint32 n_buttons = m_spellInfo->Effects[effIndex].MiscValueB;
6569
6570 for (; n_buttons; --n_buttons, ++button_id)
6571 {
6572 ActionButton const* ab = p_caster->GetActionButton(button_id);
6573 if (!ab || ab->GetType() != ACTION_BUTTON_SPELL)
6574 continue;
6575
6578 uint32 spell_id = ab->GetAction();
6579 if (!spell_id)
6580 continue;
6581
6582 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell_id);
6583 if (!spellInfo)
6584 continue;
6585
6586 if (!p_caster->HasSpell(spell_id) || p_caster->HasSpellCooldown(spell_id))
6587 continue;
6588
6590 continue;
6591
6592 uint32 cost = spellInfo->CalcPowerCost(unitCaster, spellInfo->GetSchoolMask(), this);
6593 if (unitCaster->GetPower(POWER_MANA) < cost)
6594 continue;
6595
6597 unitCaster->CastSpell(unitCaster, spell_id, triggerFlags);
6598 }
6599}
@ 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:5845
bool HasSpell(uint32 spell) const override
Definition Player.cpp:4061
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)
5166{
5167 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5168 if (!unitCaster)
5169 return;
5170
5172 {
5173 if (!unitTarget)
5174 return;
5175
5176 ObjectGuid targetGUID = ObjectGuid::Empty;
5177 Player* player = unitCaster->ToPlayer();
5178 if (player)
5179 {
5180 // charge changes fall time
5181 player->SetFallInformation(GameTime::GetGameTime().count(), unitCaster->GetPositionZ());
5182
5184 {
5185 targetGUID = unitTarget->GetGUID();
5186 }
5187 }
5188
5189 float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE;
5190 // Spell is not using explicit target - no generated path
5191 if (!m_preGeneratedPath)
5192 {
5194 unitCaster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed, EVENT_CHARGE, nullptr, false, 0.0f, targetGUID);
5195 }
5196 else
5197 {
5198 unitCaster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed, targetGUID);
5199 }
5200
5201 if (player)
5202 {
5203 sScriptMgr->AnticheatSetUnderACKmount(player);
5204 }
5205 }
5206}
#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:825
static ObjectGuid const Empty
Definition ObjectGuid.h:123
void SetFallInformation(uint32 time, float z)
Definition Player.h:2385
MotionMaster * GetMotionMaster()
Definition Unit.h:1774
Position GetFirstCollisionPosition(float startX, float startY, float startZ, float destX, float destY)
Definition Object.cpp:2954
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)
5209{
5210 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5211 if (!unitCaster)
5212 return;
5213
5215 return;
5216
5217 if (m_targets.HasDst())
5218 {
5220
5221 if (!unitCaster->IsWithinLOS(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ()))
5222 {
5223 float angle = unitCaster->GetRelativeAngle(pos.GetPositionX(), pos.GetPositionY());
5224 float dist = unitCaster->GetDistance(pos);
5225 pos = unitCaster->GetFirstCollisionPosition(dist, angle);
5226 }
5227
5228 unitCaster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ);
5229
5230 if (unitCaster->IsPlayer())
5231 {
5232 sScriptMgr->AnticheatSetUnderACKmount(unitCaster->ToPlayer());
5233 }
5234 }
5235}

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)
1870{
1872 return;
1873
1874 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1875 ExecuteLogEffectCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
1876}
void ExecuteLogEffectCreateItem(uint8 effIndex, uint32 entry)
Definition Spell.cpp:5318
void DoCreateItem(uint8 effIndex, uint32 itemId)
Definition SpellEffects.cpp:1739

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);
1879{
1881 return;
1882
1883 if (!unitTarget)
1884 return;
1885
1886 Player* player = unitTarget->ToPlayer();
1887 if (!player)
1888 {
1889 return;
1890 }
1891
1892 uint32 itemId = m_spellInfo->Effects[effIndex].ItemType;
1893
1894 if (itemId)
1895 DoCreateItem(effIndex, itemId);
1896
1897 // special case: fake item replaced by generate using spell_loot_template
1899 {
1900 if (itemId)
1901 {
1902 if (!player->HasItemCount(itemId))
1903 return;
1904
1905 // remove reagent
1906 uint32 count = 1;
1907 player->DestroyItemCount(itemId, count, true);
1908
1909 // create some random items
1911 }
1912 else
1913 player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items
1914 }
1916}
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:13884
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);
1919{
1921 return;
1922
1923 if (!unitTarget)
1924 return;
1925
1926 Player* player = unitTarget->ToPlayer();
1927 if (!player)
1928 {
1929 return;
1930 }
1931
1932 // create some random items
1935}

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)
6170{
6172 return;
6173
6175 return;
6176
6177 uint32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
6178 Pet* pet = unitTarget->CreateTamedPetFrom(creatureEntry, m_spellInfo->Id);
6179 if (!pet)
6180 return;
6181
6182 // add to world
6183 pet->GetMap()->AddToMap(pet->ToCreature(), true);
6184
6185 // unitTarget has pet now
6186 unitTarget->SetMinion(pet, true);
6187
6188 pet->InitTalentForLevel();
6189
6190 if (unitTarget->IsPlayer())
6191 {
6194 }
6195}
@ CLASS_HUNTER
Definition SharedDefines.h:128
bool AddToMap(T *, bool checkTransport=false)
Definition Map.cpp:307
void InitTalentForLevel()
Definition Pet.cpp:2244
void SavePetToDB(PetSaveMode mode)
Definition Pet.cpp:502
void PetSpellInitialize()
Definition Player.cpp:9774
void SetMinion(Minion *minion, bool apply)
Definition Unit.cpp:7602
Pet * CreateTamedPetFrom(Creature *creatureTarget, uint32 spell_id=0)
Definition Unit.cpp:13439

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

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)
6198{
6200 return;
6201
6202 if (!unitTarget)
6203 return;
6204
6205 Player* player = unitTarget->ToPlayer();
6206 if (!player)
6207 {
6208 return;
6209 }
6210
6211 uint32 nodeid = m_spellInfo->Effects[effIndex].MiscValue;
6212 if (sTaxiNodesStore.LookupEntry(nodeid))
6213 player->GetSession()->SendDiscoverNewTaxiNode(nodeid);
6214}
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)
4680{
4681 Unit* unitCaster = m_caster->ToUnit();
4682 if (!unitCaster)
4683 return;
4684
4686 return;
4687
4689 return;
4690
4691 if (Player* caster = unitCaster->ToPlayer())
4692 {
4693 caster->UpdateCraftSkill(m_spellInfo->Id);
4694 caster->SendLoot(itemTarget->GetGUID(), LOOT_DISENCHANTING);
4695 }
4696
4697 // item will be removed at disenchanting end
4698}
@ 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)
4774{
4776 return;
4777
4778 if (!unitTarget || !unitTarget->IsPet())
4779 return;
4780
4781 Pet* pet = unitTarget->ToPet();
4782
4783 ExecuteLogEffectUnsummonObject(effIndex, pet);
4785}
@ PET_SAVE_NOT_IN_SLOT
Definition PetDefines.h:46
void Remove(PetSaveMode mode, bool returnreagent=false)
Definition Pet.cpp:932
void ExecuteLogEffectUnsummonObject(uint8 effIndex, WorldObject *obj)
Definition Spell.cpp:5336

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)
2722{
2723 Unit* unitCaster = m_caster->ToUnit();
2724 if (!unitCaster)
2725 return;
2726
2728 return;
2729
2730 if (!unitTarget)
2731 return;
2732
2733 // Create dispel mask by dispel type
2734 uint32 dispel_type = m_spellInfo->Effects[effIndex].MiscValue;
2735 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(dispel_type));
2736
2737 DispelChargesList dispel_list;
2738 unitTarget->GetDispellableAuraList(unitCaster, dispelMask, dispel_list, m_spellInfo);
2739 if (dispel_list.empty())
2740 return;
2741
2742 // Ok if exist some buffs for dispel try dispel it
2743 uint32 failCount = 0;
2744 DispelChargesList success_list;
2745 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
2746 // dispel N = damage buffs (or while exist buffs for dispel)
2747 for (int32 count = 0; count < damage && !dispel_list.empty();)
2748 {
2749 // Random select buff for dispel
2750 DispelChargesList::iterator itr = dispel_list.begin();
2751 std::advance(itr, urand(0, dispel_list.size() - 1));
2752
2753 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(unitCaster));
2754 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
2755 if (!chance)
2756 {
2757 dispel_list.erase(itr);
2758 continue;
2759 }
2760 else
2761 {
2762 if (roll_chance_i(chance))
2763 {
2764 bool alreadyListed = false;
2765 for (DispelChargesList::iterator successItr = success_list.begin(); successItr != success_list.end(); ++successItr)
2766 {
2767 if (successItr->first == itr->first)
2768 {
2769 ++successItr->second;
2770 alreadyListed = true;
2771 break;
2772 }
2773 }
2774 if (!alreadyListed)
2775 success_list.push_back(std::make_pair(itr->first, 1));
2776 --itr->second;
2777 if (itr->second <= 0)
2778 dispel_list.erase(itr);
2779 }
2780 else
2781 {
2782 if (!failCount)
2783 {
2784 // Failed to dispell
2785 dataFail << unitCaster->GetGUID(); // Caster GUID
2786 dataFail << unitTarget->GetGUID(); // Victim GUID
2787 dataFail << uint32(m_spellInfo->Id); // dispel spell id
2788 }
2789 ++failCount;
2790 dataFail << uint32(itr->first->GetId()); // Spell Id
2791 }
2792 ++count;
2793 }
2794 }
2795
2796 if (failCount)
2797 unitCaster->SendMessageToSet(&dataFail, true);
2798
2799 // put in combat
2800 if (unitTarget->IsFriendlyTo(unitCaster))
2802
2803 if (success_list.empty())
2804 return;
2805
2806 WorldPacket dataSuccess(SMSG_SPELLDISPELLOG, 8 + 8 + 4 + 1 + 4 + success_list.size() * 5);
2807 // Send packet header
2808 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
2809 dataSuccess << unitCaster->GetPackGUID(); // Caster GUID
2810 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
2811 dataSuccess << uint8(0); // not used
2812 dataSuccess << uint32(success_list.size()); // count
2813 for (DispelChargesList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
2814 {
2815 // Send dispelled spell info
2816 dataSuccess << uint32(itr->first->GetId()); // Spell Id
2817 dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
2818 unitTarget->RemoveAurasDueToSpellByDispel(itr->first->GetId(), m_spellInfo->Id, itr->first->GetCasterGUID(), unitCaster, itr->second);
2819 }
2820 unitCaster->SendMessageToSet(&dataSuccess, true);
2821
2822 // On success dispel
2823 // Devour Magic
2825 {
2826 int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue();
2827 unitCaster->CastCustomSpell(unitCaster, 19658, &heal_amount, nullptr, nullptr, true);
2828 // Glyph of Felhunter
2829 if (Unit* owner = unitCaster->GetOwner())
2830 if (owner->GetAura(56249))
2831 owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true);
2832 }
2833}
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:5002
@ 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)
5434{
5435 Unit* unitCaster = m_caster->ToUnit();
5436 if (!unitCaster)
5437 return;
5438
5440 return;
5441
5442 if (!unitTarget)
5443 return;
5444
5445 uint32 mechanic = m_spellInfo->Effects[effIndex].MiscValue;
5446
5447 std::queue<std::pair<uint32, ObjectGuid>> dispel_list;
5448
5449 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5450 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5451 {
5452 Aura* aura = itr->second;
5454 continue;
5456 {
5457 if (aura->GetSpellInfo()->GetAllEffectsMechanicMask() & (1ULL << mechanic))
5458 {
5459 dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
5460
5461 // spell only removes 1 bleed effect do not continue
5462 if (m_spellInfo->Effects[effIndex].BasePoints == 1)
5463 {
5464 break;
5465 }
5466 }
5467 }
5468 }
5469
5470 for (; dispel_list.size(); dispel_list.pop())
5471 {
5472 unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
5473 }
5474
5475 // put in combat
5476 if (unitTarget->IsFriendlyTo(unitCaster))
5478}
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition SpellAuraDefines.h:394
ObjectGuid GetCasterGUID() const
Definition SpellAuras.h:106
uint32 GetId() const
Definition SpellAuras.cpp:417
int32 CalcDispelChance(Unit *auraTarget, bool offensive) const
Definition SpellAuras.cpp:1255
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4830

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.

2850{
2852 return;
2853
2854 // Check for possible target
2855 if (!unitTarget || unitTarget->IsEngaged())
2856 return;
2857
2858 // target must be OK to do this
2860 return;
2861
2864}
@ 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:963
void SetFacingTo(float ori)
Definition Unit.cpp:16157

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)
2836{
2838 return;
2839
2841}
virtual void SetCanDualWield(bool value)
Definition Unit.h:993

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

◆ EffectDuel()

void Spell::EffectDuel ( SpellEffIndex  effIndex)
4296{
4297 Unit* unitCaster = m_caster->ToUnit();
4298 if (!unitCaster)
4299 return;
4300
4302 return;
4303
4304 if (!unitTarget || !unitCaster->IsPlayer() || !unitTarget->IsPlayer())
4305 return;
4306
4307 Player* caster = unitCaster->ToPlayer();
4308 Player* target = unitTarget->ToPlayer();
4309
4310 // caster or target already have requested duel
4311 if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID()))
4312 return;
4313
4314 // Players can only fight a duel in zones with this flag
4315 AreaTableEntry const* casterAreaEntry = sAreaTableStore.LookupEntry(caster->GetAreaId());
4316 if (casterAreaEntry && !(casterAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4317 {
4318 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4319 return;
4320 }
4321
4322 AreaTableEntry const* targetAreaEntry = sAreaTableStore.LookupEntry(target->GetAreaId());
4323 if (targetAreaEntry && !(targetAreaEntry->flags & AREA_FLAG_ALLOW_DUELS))
4324 {
4325 SendCastResult(SPELL_FAILED_NO_DUELING); // Dueling isn't allowed here
4326 return;
4327 }
4328
4329 //CREATE DUEL FLAG OBJECT
4330 uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue;
4331 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobject_id) ? new StaticTransport() : new GameObject();
4332
4333 Map* map = unitCaster->GetMap();
4334 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), unitCaster->GetOrientation());
4335 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id,
4336 map, unitCaster->GetPhaseMask(),
4337 unitCaster->GetPositionX() + (unitTarget->GetPositionX() - unitCaster->GetPositionX()) / 2,
4338 unitCaster->GetPositionY() + (unitTarget->GetPositionY() - unitCaster->GetPositionY()) / 2,
4339 unitCaster->GetPositionZ(),
4340 unitCaster->GetOrientation(), rotation, 0, GO_STATE_READY))
4341 {
4342 delete pGameObj;
4343 return;
4344 }
4345
4346 pGameObj->SetUInt32Value(GAMEOBJECT_FACTION, unitCaster->GetFaction());
4347 pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, unitCaster->GetLevel() + 1);
4348 int32 duration = m_spellInfo->GetDuration();
4349 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4350 pGameObj->SetSpellId(m_spellInfo->Id);
4351
4352 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4353
4354 unitCaster->AddGameObject(pGameObj);
4355 map->AddToMap(pGameObj, true);
4356 //END
4357
4358 // Send request
4359 WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8);
4360 data << pGameObj->GetGUID();
4361 data << caster->GetGUID();
4362 caster->SendDirectMessage(&data);
4363 target->SendDirectMessage(&data);
4364
4365 // create duel-info
4366 bool isMounted = (GetSpellInfo()->Id == 62875);
4367 caster->duel = std::make_unique<DuelInfo>(target, caster, isMounted);
4368 target->duel = std::make_unique<DuelInfo>(caster, caster, isMounted);
4369
4370 caster->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4371 target->SetGuidValue(PLAYER_DUEL_ARBITER, pGameObj->GetGUID());
4372
4373 sScriptMgr->OnPlayerDuelRequest(target, caster);
4374}
@ 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:323
void SetRespawnTime(int32 respawn)
Definition GameObject.cpp:1403
void SetSpellId(uint32 id)
Definition GameObject.h:183
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:5330
Definition Transport.h:120
void AddGameObject(GameObject *gameObj)
Definition Unit.cpp:6366
uint32 GetFaction() const override
Definition Unit.h:857
@ 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 // HoL, Arc Weld
728 case 59086:
729 {
730 if (unitCaster->IsPlayer() && unitCaster->ToPlayer()->isMoving())
731 unitCaster->CastSpell(unitCaster, 59097, true);
732
733 return;
734 }
735 }
736 break;
737 }
739 switch (m_spellInfo->Id)
740 {
741 case 31789: // Righteous Defense (step 1)
742 {
743 if (!unitTarget)
744 return;
745 // not empty (checked), copy
747
748 // remove invalid attackers
749 for (Unit::AttackerSet::iterator aItr = attackers.begin(); aItr != attackers.end();)
750 if (!(*aItr)->IsValidAttackTarget(unitCaster))
751 aItr = attackers.erase(aItr);
752 else
753 ++aItr;
754
755 // selected from list 3
756 uint32 maxTargets = std::min<uint32>(3, attackers.size());
757 for (uint32 i = 0; i < maxTargets; ++i)
758 {
759 Unit::AttackerSet::iterator aItr = attackers.begin();
760 std::advance(aItr, urand(0, attackers.size() - 1));
761 unitCaster->CastSpell((*aItr), 31790, true);
762 attackers.erase(aItr);
763 }
764
765 return;
766 }
767 }
768 break;
770 // Hunger for Blood
771 if (m_spellInfo->Id == 51662)
772 {
773 unitCaster->CastSpell(unitCaster, 63848, true);
774 return;
775 }
776 break;
777 }
778 }
779
780 // pet auras
781 if (unitCaster)
782 {
783 if (PetAura const* petSpell = sSpellMgr->GetPetAura(m_spellInfo->Id, effIndex))
784 {
785 unitCaster->AddPetAura(petSpell);
786 return;
787 }
788 }
789
790 // normal DB scripted effect
791 LOG_DEBUG("spells.aura", "Spell ScriptStart spellid {} in EffectDummy({})", m_spellInfo->Id, effIndex);
793
794 if (gameObjTarget)
795 {
796 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, gameObjTarget);
797 }
798 else if (unitTarget && unitTarget->IsCreature())
799 {
800 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, unitTarget->ToCreature());
801 }
802 else if (itemTarget)
803 {
804 sScriptMgr->OnDummyEffect(m_caster, m_spellInfo->Id, effIndex, itemTarget);
805 }
806}
ScriptMapMap sSpellScripts
Definition ObjectMgr.cpp:60
@ 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
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:469
void AddPetAura(PetAura const *petSpell)
Definition Unit.cpp:13385
std::unordered_set< Unit * > AttackerSet
Definition Unit.h:672
AttackerSet const & getAttackers() const
Definition Unit.h:907

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

◆ EffectDurabilityDamage()

void Spell::EffectDurabilityDamage ( SpellEffIndex  effIndex)
5570{
5572 return;
5573
5574 if (!unitTarget)
5575 return;
5576
5577 Player* player = unitTarget->ToPlayer();
5578 if (!player)
5579 {
5580 return;
5581 }
5582
5583 int32 slot = m_spellInfo->Effects[effIndex].MiscValue;
5584
5585 // -1 means all player equipped items and -2 all items
5586 if (slot < 0)
5587 {
5588 player->DurabilityPointsLossAll(damage, (slot < -1));
5590 return;
5591 }
5592
5593 // invalid slot value
5594 if (slot >= INVENTORY_SLOT_BAG_END)
5595 return;
5596
5597 if (Item* item = player->GetItemByPos(INVENTORY_SLOT_BAG_0, slot))
5598 {
5599 player->DurabilityPointsLoss(item, damage);
5600 ExecuteLogEffectDurabilityDamage(effIndex, unitTarget, item->GetEntry(), slot);
5601 }
5602}
@ 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:4870
void DurabilityPointsLoss(Item *item, int32 points)
Definition Player.cpp:4896
void ExecuteLogEffectDurabilityDamage(uint8 effIndex, Unit *victim, int32 itemId, int32 slot)
Definition Spell.cpp:5304

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

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)
4623{
4624 Unit* unitCaster = m_caster->ToUnit();
4625 if (!unitCaster)
4626 return;
4627
4629 return;
4630
4631 // this is only item spell effect applied to main-hand weapon of target player (players in area)
4632 if (!unitTarget)
4633 return;
4634
4635 Player* item_owner = unitTarget->ToPlayer();
4636 if (!item_owner)
4637 {
4638 return;
4639 }
4640
4642 if (!item)
4643 return;
4644
4645 // must be equipped
4646 if (!item->IsEquipped())
4647 return;
4648
4649 if (m_spellInfo->Effects[effIndex].MiscValue)
4650 {
4651 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
4652 int32 duration = m_spellInfo->GetDuration(); //Try duration index first ..
4653 if (!duration)
4654 duration = damage * IN_MILLISECONDS; //+1; //Base points after ..
4655 if (!duration)
4656 duration = 10 * IN_MILLISECONDS; //10 seconds for enchants which don't have listed duration
4657
4658 // Xinef: Venomhide poison, no other spell uses this effect...
4659 if (m_spellInfo->Id == 14792)
4660 duration = 5 * MINUTE * IN_MILLISECONDS;
4661
4662 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
4663 if (!pEnchant)
4664 return;
4665
4666 // Always go to temp enchantment slot
4668
4669 // Enchantment will not be applied if a different one already exists
4670 if (item->GetEnchantmentId(slot) && item->GetEnchantmentId(slot) != enchant_id)
4671 return;
4672
4673 // Apply the temporary enchantment
4674 item->SetEnchantment(slot, enchant_id, duration, pEnchant->charges, unitCaster->GetGUID());
4675 item_owner->ApplyEnchantment(item, slot, true);
4676 }
4677}
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:783
void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster=ObjectGuid::Empty)
Definition Item.cpp:926
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)
3010{
3011 Unit* unitCaster = m_caster->ToUnit();
3012 if (!unitCaster)
3013 return;
3014
3016 return;
3017
3018 if (!unitCaster->IsPlayer())
3019 return;
3020 if (!itemTarget)
3021 return;
3022
3023 Player* p_caster = unitCaster->ToPlayer();
3024
3025 // Handle vellums
3027 {
3028 // destroy one vellum from stack
3029 uint32 count = 1;
3030 p_caster->DestroyItemCount(itemTarget, count, true);
3031 unitTarget = p_caster;
3032 // and add a scroll
3033 DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType);
3034 itemTarget = nullptr;
3035 m_targets.SetItemTarget(nullptr);
3036 }
3037 else
3038 {
3039 // do not increase skill if vellum used
3041 p_caster->UpdateCraftSkill(m_spellInfo->Id);
3042
3043 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3044 if (!enchant_id)
3045 return;
3046
3047 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3048 if (!pEnchant)
3049 return;
3050
3051 // item can be in trade slot and have owner diff. from caster
3052 Player* item_owner = itemTarget->GetOwner();
3053 if (!item_owner)
3054 return;
3055
3056 // remove old enchanting before applying new if equipped
3058
3059 itemTarget->SetEnchantment(PERM_ENCHANTMENT_SLOT, enchant_id, 0, 0, unitCaster->GetGUID());
3060
3061 // add new enchanting if equipped
3063
3064 if (item_owner != p_caster && p_caster->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
3065 {
3066 LOG_GM(p_caster->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(perm): {} (SpellID: {} EncID: {}) on {}'s item: {} (Entry: {})",
3067 p_caster->GetName(), p_caster->GetSession()->GetAccountId(),
3068 m_spellInfo->SpellName[0], m_spellInfo->Id, enchant_id,
3069 item_owner->GetName(), itemTarget->GetTemplate()->Name1, itemTarget->GetEntry());
3070 }
3071
3072 item_owner->RemoveTradeableItem(itemTarget);
3074 }
3075}
@ PERM_ENCHANTMENT_SLOT
Definition Item.h:169
#define LOG_GM(accountId__,...)
Definition Log.h:164
void ClearSoulboundTradeable(Player *currentOwner)
Definition Item.cpp:1279
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:1701
@ 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)
3078{
3079 Unit* unitCaster = m_caster->ToUnit();
3080 if (!unitCaster)
3081 return;
3082
3084 return;
3085
3086 if (!unitCaster->IsPlayer())
3087 return;
3088 if (!itemTarget)
3089 return;
3090
3091 uint32 enchant_id = m_spellInfo->Effects[effIndex].MiscValue;
3092 if (!enchant_id)
3093 return;
3094
3095 SpellItemEnchantmentEntry const* pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id);
3096 if (!pEnchant)
3097 return;
3098
3099 // support only enchantings with add socket in this slot
3100 {
3101 bool add_socket = false;
3102 for (uint8 i = 0; i < MAX_SPELL_ITEM_ENCHANTMENT_EFFECTS; ++i)
3103 {
3104 if (pEnchant->type[i] == ITEM_ENCHANTMENT_TYPE_PRISMATIC_SOCKET)
3105 {
3106 add_socket = true;
3107 break;
3108 }
3109 }
3110 if (!add_socket)
3111 {
3112 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.",
3114 return;
3115 }
3116 }
3117
3118 // item can be in trade slot and have owner diff. from caster
3119 Player* item_owner = itemTarget->GetOwner();
3120 if (!item_owner)
3121 return;
3122
3123 Player* p_caster = m_caster->ToPlayer();
3124 if (item_owner != p_caster && p_caster->GetSession()->HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE))
3125 {
3126 LOG_GM(p_caster->GetSession()->GetAccountId(), "GM {} (Account: {}) enchanting(prismatic): {} (SpellID: {} EncID: {}) on {}'s item: {} (Entry: {})",
3127 p_caster->GetName(), p_caster->GetSession()->GetAccountId(),
3128 m_spellInfo->SpellName[0], m_spellInfo->Id, enchant_id,
3129 item_owner->GetName(), itemTarget->GetTemplate()->Name1, itemTarget->GetEntry());
3130 }
3131
3132 // remove old enchanting before applying new if equipped
3134
3135 itemTarget->SetEnchantment(PRISMATIC_ENCHANTMENT_SLOT, enchant_id, 0, 0, unitCaster->GetGUID());
3136
3137 // add new enchanting if equipped
3139
3140 item_owner->RemoveTradeableItem(itemTarget);
3142}

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

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

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
4737{
4738 Unit* unitCaster = m_caster->ToUnit();
4739 if (!unitCaster)
4740 return;
4741
4743 return;
4744
4745 Player* player = unitCaster->ToPlayer();
4746 if (!player)
4747 return;
4748
4749 Item* foodItem = itemTarget;
4750 if (!foodItem)
4751 return;
4752
4753 Pet* pet = player->GetPet();
4754 if (!pet)
4755 return;
4756
4757 if (!pet->IsAlive())
4758 return;
4759
4760 int32 benefit = pet->GetCurrentFoodBenefitLevel(foodItem->GetTemplate()->ItemLevel);
4761 if (benefit <= 0)
4762 return;
4763
4764 ExecuteLogEffectDestroyItem(effIndex, foodItem->GetEntry());
4765
4766 uint32 count = 1;
4767 player->DestroyItemCount(foodItem, count, true);
4769
4770 unitCaster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true);
4771}
void ExecuteLogEffectDestroyItem(uint8 effIndex, uint32 entry)
Definition Spell.cpp:5324

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)
1044{
1046 return;
1047
1048 if (!unitTarget)
1049 return;
1050
1051 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1052
1053 // normal case
1054 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1055
1056 if (!spellInfo)
1057 {
1058 LOG_ERROR("spells.effect", "Spell::EffectForceCast of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1059 return;
1060 }
1061
1062 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_FORCE_CAST && damage)
1063 {
1064 switch (m_spellInfo->Id)
1065 {
1066 case 52588: // Skeletal Gryphon Escape
1067 case 48598: // Ride Flamebringer Cue
1069 break;
1070 case 52463: // Hide In Mine Car
1071 case 52349: // Overtake
1072 unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID);
1073 return;
1074 case 72378: // Blood Nova
1075 case 73058: // Blood Nova
1076 m_caster->CastSpell(unitTarget, damage, true); // additional spell cast
1077 break;
1078 }
1079 }
1080
1082 // set basepoints for trigger with value effect
1084 {
1085 // maybe need to set value only when basepoints == 0?
1086 args.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
1087 args.AddSpellMod(SPELLVALUE_BASE_POINT1, damage);
1088 args.AddSpellMod(SPELLVALUE_BASE_POINT2, damage);
1089 }
1090
1091 SpellCastTargets targets;
1092 // InitExplicitTargets turns a unit target the triggered spell cannot take into that spell's
1093 // destination, which would anchor the forced cast to the original caster instead of to the
1094 // forced one (e.g. Algalon's Cosmic Smash craters, Elder Brightleaf's Unstable Sun Beams).
1096 targets.SetUnitTarget(m_caster->ToUnit());
1097
1098 unitTarget->CastSpell(std::move(targets), spellInfo, args);
1099}
@ 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:209

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)
5014{
5015 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5016 if (!unitCaster)
5017 return;
5018
5020 return;
5021
5022 // xinef: clear focus
5023 unitCaster->SendClearTarget();
5024
5026 data << unitCaster->GetGUID();
5027
5028 float dist = unitCaster->GetVisibilityRange() + VISIBILITY_COMPENSATION;
5029 Acore::MessageDistDelivererToHostile notifier(unitCaster, &data, dist);
5030 Cell::VisitObjects(unitCaster, notifier, dist);
5031
5032 // xinef: we should also force pets to remove us from current target
5033 Unit::AttackerSet attackerSet;
5034 for (Unit::AttackerSet::const_iterator itr = unitCaster->getAttackers().begin(); itr != unitCaster->getAttackers().end(); ++itr)
5035 if ((*itr)->IsCreature() && !(*itr)->CanHaveThreatList())
5036 attackerSet.insert(*itr);
5037
5038 for (Unit::AttackerSet::const_iterator itr = attackerSet.begin(); itr != attackerSet.end(); ++itr)
5039 (*itr)->AttackStop();
5040
5041 // Xinef: Mirror images code Initialize Images
5042 if (m_spellInfo->Id == 58836)
5043 {
5044 std::vector<Unit*> images;
5045 for (Unit::ControlSet::const_iterator itr = unitCaster->m_Controlled.begin(); itr != unitCaster->m_Controlled.end(); ++itr)
5046 if ((*itr)->GetEntry() == 31216 /*NPC_MIRROR_IMAGE*/)
5047 images.push_back(*itr);
5048
5049 if (images.empty())
5050 return;
5051
5052 UnitList targets;
5053 Acore::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitCaster, unitCaster, unitCaster->GetVisibilityRange()); // no VISIBILITY_COMPENSATION, distance is enough
5054 Acore::UnitListSearcher<Acore::AnyUnfriendlyUnitInObjectRangeCheck> searcher(unitCaster, targets, u_check);
5055 Cell::VisitObjects(unitCaster, searcher, unitCaster->GetVisibilityRange());
5056 for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
5057 {
5058 if (!(*iter)->HasUnitState(UNIT_STATE_CASTING))
5059 continue;
5060
5061 if (Spell* spell = (*iter)->GetCurrentSpell(CURRENT_GENERIC_SPELL))
5062 {
5063 if (spell->m_targets.GetUnitTargetGUID() == unitCaster->GetGUID())
5064 {
5065 SpellInfo const* si = spell->GetSpellInfo();
5066 if (si->HasAttribute(SPELL_ATTR6_IGNORE_PHASE_SHIFT) && (*iter)->IsCreature())
5067 {
5068 Creature* c = (*iter)->ToCreature();
5069 if ((!c->IsPet() && c->GetCreatureTemplate()->rank == CREATURE_ELITE_WORLDBOSS) || c->isWorldBoss() || c->IsDungeonBoss())
5070 continue;
5071 }
5072
5073 bool interrupt = false; // pussywizard: skip spells that don't target units, but casted on unit (eg. TARGET_DEST_TARGET_ENEMY)
5074 for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
5075 if (si->Effects[j].Effect && (si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT || si->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT_AND_DEST))
5076 {
5077 // at least one effect truly targets an unit, interrupt the spell
5078 interrupt = true;
5079 break;
5080 }
5081
5082 if (interrupt)
5083 spell->m_targets.SetUnitTarget(images.at(urand(0, images.size() - 1)));
5084 }
5085 }
5086 }
5087 }
5088}
#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:79
Definition GridNotifiers.h:884
bool IsDungeonBoss() const
Definition Creature.cpp:3374
ControlSet m_Controlled
Definition Unit.h:2095
void SendClearTarget()
Definition Unit.cpp:15962
@ 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)
6250{
6252 return;
6253
6254 if (!gameObjTarget)
6255 return;
6256
6257 Unit* caster = m_originalCaster;
6258 if (!caster)
6259 return;
6260
6261 FactionTemplateEntry const* casterFaction = caster->GetFactionTemplateEntry();
6263 // Do not allow to damage GO's of friendly factions (ie: Wintergrasp Walls/Ulduar Storm Beacons)
6264 if ((casterFaction && targetFaction && !casterFaction->IsFriendlyTo(*targetFaction)) || !targetFaction)
6266}
DBCStorage< FactionTemplateEntry > sFactionTemplateStore(FactionTemplateEntryfmt)
void ModifyHealth(int32 change, Unit *attackerOrHealer=nullptr, uint32 spellId=0)
Definition GameObject.cpp:2382
FactionTemplateEntry const * GetFactionTemplateEntry() const
Definition Unit.cpp:6864
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)
6269{
6271 return;
6272
6273 if (!gameObjTarget)
6274 return;
6275
6276 Unit* unitCaster = m_caster->ToUnit();
6277 if (!unitCaster)
6278 return;
6279
6280 gameObjTarget->ModifyHealth(damage, unitCaster);
6281}

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

◆ EffectGameObjectSetDestructionState()

void Spell::EffectGameObjectSetDestructionState ( SpellEffIndex  effIndex)
6284{
6286 return;
6287
6289 return;
6290
6293}
GameObjectDestructibleState
Definition SharedDefines.h:1630
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=nullptr, bool setHealth=false)
Definition GameObject.cpp:2445
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Unit.cpp:7533

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

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)
3910{
3911 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3912 if (!unitCaster)
3913 return;
3914
3916 return;
3917
3918 if (!unitTarget || !unitTarget->IsAlive())
3919 return;
3920
3922 {
3923 unitCaster->SendSpellDamageImmune(unitTarget, GetSpellInfo()->Id);
3924 return;
3925 }
3926
3927 int32 addhealth = 0;
3928
3929 // damage == 0 - heal for caster max health
3930 if (damage == 0)
3931 addhealth = unitCaster->GetMaxHealth();
3932 else
3933 addhealth = unitTarget->GetMaxHealth() - unitTarget->GetHealth();
3934
3935 m_healing += addhealth;
3936}
uint32 GetMaxHealth() const
Definition Unit.h:1123

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)
1707{
1708 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1710 return;
1711
1712 if (!unitTarget || !unitTarget->IsAlive() || damage < 0)
1713 return;
1714
1715 if (unitCaster)
1716 {
1719 }
1720
1721 LOG_DEBUG("spells.aura", "HealthLeech :{}", damage);
1722
1723 // xinef: handled in spell.cpp
1724 //float healMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1725
1726 m_damage += damage;
1727 // get max possible damage, don't count overkill for heal
1728 //uint32 healthGain = uint32(-unitTarget->GetHealthGain(-damage) * healMultiplier);
1729
1730 //if (unitCaster->IsAlive())
1731 //{
1732 // healthGain = unitCaster->SpellHealingBonusDone(unitCaster, m_spellInfo, healthGain, HEAL);
1733 // healthGain = unitCaster->SpellHealingBonusTaken(unitCaster, m_spellInfo, healthGain, HEAL);
1734
1735 // unitCaster->HealBySpell(unitCaster, m_spellInfo, uint32(healthGain));
1736 //}
1737}
uint32 SpellDamageBonusTaken(Unit *caster, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint32 stack=1)
Definition Unit.cpp:8711
uint32 SpellDamageBonusDone(Unit *victim, SpellInfo const *spellProto, uint32 pdamage, DamageEffectType damagetype, uint8 effIndex, float TotalMod=0.0f, uint32 stack=1)
Definition Unit.cpp:8537

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)
4701{
4703 return;
4704
4705 if (!unitTarget)
4706 return;
4707
4708 Player* player = unitTarget->ToPlayer();
4709 if (!player)
4710 {
4711 return;
4712 }
4713
4714 uint8 currentDrunk = player->GetDrunkValue();
4715 int32 drunkMod = damage;
4716
4717 if (drunkMod == 0)
4718 return;
4719
4720 // drunkMod may contain values ​​that are guaranteed to cause uint8 overflow/underflow (examples: 29690, 46874)
4721 // In addition, we would not want currentDrunk to become more than 100.
4722 // So before adding the values, let's check that everything is fine.
4723 if (drunkMod > 0 && drunkMod > static_cast<int32>(100 - currentDrunk))
4724 currentDrunk = 100;
4725 else if (drunkMod < 0 && drunkMod < static_cast<int32>(0 - currentDrunk))
4726 currentDrunk = 0;
4727 else
4728 currentDrunk += drunkMod; // Due to previous checks we can be sure that currentDrunk will not go beyond [0-100] range.
4729
4730 player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
4731
4732 if (currentDrunk == 100 && roll_chance_i(25))
4733 player->CastSpell(player, 67468, false); // Drunken Vomit
4734}
uint8 GetDrunkValue() const
Definition Player.h:2203
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId=0)
Definition Player.cpp:1035

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
3939{
3941 return;
3942
3943 if (!unitTarget || !unitTarget->IsAlive())
3944 return;
3945
3947 // also exist case: apply cooldown to interrupted cast only and to all spells
3948 // there is no CURRENT_AUTOREPEAT_SPELL spells that can be interrupted
3950 {
3952 {
3953 SpellInfo const* curSpellInfo = spell->m_spellInfo;
3954 // check if we can interrupt spell
3955 if ((spell->getState() == SPELL_STATE_CASTING
3956 || (spell->getState() == SPELL_STATE_PREPARING && spell->GetCastTime() > 0.0f))
3960 {
3961 if (m_originalCaster)
3962 {
3964 unitTarget->ProhibitSpellSchool(curSpellInfo->GetSchoolMask(), duration/*spellInfo->GetDuration()*/);
3965 }
3966 ExecuteLogEffectInterruptCast(effIndex, unitTarget, curSpellInfo->Id);
3968 }
3969 }
3970 }
3971}
@ 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:569
CurrentSpellTypes
Definition Unit.h:562
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:565
@ CURRENT_AUTOREPEAT_SPELL
Definition Unit.h:566
uint32 ChannelInterruptFlags
Definition SpellInfo.h:378
uint32 InterruptFlags
Definition SpellInfo.h:376
void ExecuteLogEffectInterruptCast(uint8 effIndex, Unit *victim, uint32 spellId)
Definition Spell.cpp:5297
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed=true, bool withInstant=true, bool bySelf=false)
Definition Unit.cpp:4007
virtual void ProhibitSpellSchool(SpellSchoolMask, uint32)
Definition Unit.h:1601
int32 CalcSpellDuration(SpellInfo const *spellProto) const
Definition Object.cpp:3383

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)
1121{
1122 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1123 if (!unitCaster)
1124 return;
1125
1127 return;
1128
1129 if (unitCaster->IsInFlight())
1130 return;
1131
1132 if (!unitTarget)
1133 return;
1134
1135 float speedXY, speedZ;
1136 CalculateJumpSpeeds(effIndex, unitCaster->GetExactDist2d(unitTarget), speedXY, speedZ);
1137 unitCaster->GetMotionMaster()->MoveJump(*unitTarget, speedXY, speedZ);
1138
1139 if (unitCaster->IsPlayer())
1140 {
1141 sScriptMgr->AnticheatSetUnderACKmount(unitCaster->ToPlayer());
1142 }
1143}
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:1212
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)
1146{
1147 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1148 if (!unitCaster)
1149 return;
1150
1152 return;
1153
1154 if (unitCaster->IsInFlight())
1155 return;
1156
1157 if (!m_targets.HasDst() || unitCaster->GetVehicle())
1158 return;
1159
1160 // Init dest coordinates
1161 float x, y, z;
1162 destTarget->GetPosition(x, y, z);
1163 // xinef: this can happen if MovePositionToFirstCollision detects that X, Y cords are invalid and returns prematurely
1164 if (!Acore::IsValidMapCoord(x, y, z) || z <= INVALID_HEIGHT)
1165 return;
1166
1167 float speedXY, speedZ;
1168 float dist = unitCaster->GetExactDist2d(x, y);
1169 CalculateJumpSpeeds(effIndex, dist, speedXY, speedZ);
1170
1171 // Override, calculations are incorrect
1172 if (m_spellInfo->Id == 49376) // feral charge
1173 {
1174 speedXY = pow(speedZ * 10, 8);
1175 unitCaster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ, 0, ObjectAccessor::GetUnit(*unitCaster, unitCaster->GetGuidValue(UNIT_FIELD_TARGET)));
1176
1177 if (Player* player = unitCaster->ToPlayer())
1178 {
1179 player->SetCanTeleport(true);
1180 }
1181
1182 if (unitCaster->IsPlayer())
1183 {
1184 sScriptMgr->AnticheatSetUnderACKmount(unitCaster->ToPlayer());
1185 }
1186
1187 return;
1188 }
1189
1190 if (m_spellInfo->Id == 57604) // death grip
1191 {
1192 speedZ = 3.0f;
1193 speedXY = 50.0f;
1194 }
1195
1196 // crash fix?
1197 if (speedXY < 1.0f)
1198 speedXY = 1.0f;
1199
1200 if (Player* player = unitCaster->ToPlayer())
1201 {
1202 player->SetCanTeleport(true);
1203 }
1204 unitCaster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ);
1205
1206 if (unitCaster->IsPlayer())
1207 {
1208 sScriptMgr->AnticheatSetUnderACKmount(unitCaster->ToPlayer());
1209 }
1210}
@ 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)
6030{
6032 return;
6033
6034 if (!unitTarget)
6035 return;
6036
6038 if (!player)
6039 {
6040 return;
6041 }
6042
6043 int32 creatureEntry = m_spellInfo->Effects[effIndex].MiscValue;
6044 if (!creatureEntry)
6045 {
6046 if (m_spellInfo->Id == 42793) // Burn Body
6047 creatureEntry = 24008; // Fallen Combatant
6048 }
6049
6050 if (creatureEntry)
6051 player->RewardPlayerAndGroupAtEvent(creatureEntry, unitTarget);
6052}
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject *pRewardSource)
Definition Player.cpp:13090

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)
6016{
6018 return;
6019
6020 if (!unitTarget)
6021 return;
6022
6024 {
6025 player->KilledMonsterCredit(m_spellInfo->Effects[effIndex].MiscValue);
6026 }
6027}

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

◆ EffectKnockBack()

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

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(), Object::IsCreature(), 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)
4944{
4946 return;
4947
4948 if (!unitTarget || unitTarget->IsInFlight())
4949 return;
4950
4951 if (!m_targets.HasDst())
4952 return;
4953
4954 Position dstpos = destTarget->GetPosition();
4956}
void NearTeleportTo(Position &pos, bool casting=false, bool vehicleTeleport=false, bool withPet=false, bool removeTransport=false)
Definition Unit.cpp:15650

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

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)
3487{
3489 return;
3490
3491 if (!unitTarget)
3492 return;
3493
3494 if (unitTarget->ToPlayer())
3495 {
3496 EffectLearnSpell(effIndex);
3497 return;
3498 }
3499 Pet* pet = unitTarget->ToPet();
3500 if (!pet)
3501 return;
3502
3503 SpellInfo const* learn_spellproto = sSpellMgr->GetSpellInfo(m_spellInfo->Effects[effIndex].TriggerSpell);
3504 if (!learn_spellproto)
3505 return;
3506
3507 pet->learnSpell(learn_spellproto->Id);
3509 pet->GetOwner()->PetSpellInitialize();
3510}
bool learnSpell(uint32 spell_id)
Definition Pet.cpp:1931
void EffectLearnSpell(SpellEffIndex effIndex)
Definition SpellEffects.cpp:2692

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

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

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)
5827{
5828 Unit* unitCaster = m_caster->ToUnit();
5829 if (!unitCaster)
5830 return;
5831
5833 return;
5834
5835 if (!unitCaster->IsPlayer())
5836 return;
5837
5838 Player* p_caster = unitCaster->ToPlayer();
5840 return;
5841
5842 if (itemTarget->GetCount() < 5)
5843 return;
5844
5845 if (sWorld->getBoolConfig(CONFIG_SKILL_MILLING))
5846 {
5847 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION);
5848 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5849 p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue);
5850 }
5851
5852 unitCaster->ToPlayer()->SendLoot(itemTarget->GetGUID(), LOOT_MILLING);
5853}
@ LOOT_MILLING
Definition LootMgr.h:87
@ CONFIG_SKILL_MILLING
Definition WorldConfig.h:49
void SendLoot(ObjectGuid guid, LootType loot_type)
Definition Player.cpp:8007
bool UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLevel, uint32 Multiplicator=1)
Definition PlayerUpdates.cpp:785

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)
5640{
5641 Unit* unitCaster = GetUnitCasterForEffectHandlers();
5642 if (!unitCaster)
5643 return;
5644
5646 return;
5647
5648 if (!unitTarget)
5649 return;
5650
5652}
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
2189{
2190 Unit* unitCaster = m_caster->ToUnit();
2191 if (!unitCaster)
2192 return;
2193
2195 return;
2196
2197 if (!unitCaster->IsPlayer())
2198 {
2199 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No Player Caster!");
2200 return;
2201 }
2202
2203 Player* player = unitCaster->ToPlayer();
2204
2205 uint32 lockId = 0;
2206 ObjectGuid guid;
2207
2208 // Get lockId
2209 if (gameObjTarget)
2210 {
2211 GameObjectTemplate const* goInfo = gameObjTarget->GetGOInfo();
2212 // Arathi Basin banner opening. /// @todo: Verify correctness of this check
2213 if ((goInfo->type == GAMEOBJECT_TYPE_BUTTON && goInfo->button.noDamageImmune) ||
2214 (goInfo->type == GAMEOBJECT_TYPE_GOOBER && goInfo->goober.losOK))
2215 {
2216 //CanUseBattlegroundObject() already called in CheckCast()
2217 // in battleground check
2218 if (Battleground* bg = player->GetBattleground())
2219 {
2220 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2221 return;
2222 }
2223 }
2224 else if (goInfo->type == GAMEOBJECT_TYPE_FLAGSTAND)
2225 {
2226 //CanUseBattlegroundObject() already called in CheckCast()
2227 // in battleground check
2228 if (Battleground* bg = player->GetBattleground())
2229 {
2230 if (bg->GetBgTypeID(true) == BATTLEGROUND_EY)
2231 bg->EventPlayerClickedOnFlag(player, gameObjTarget);
2232 return;
2233 }
2234 }
2235 else if (m_spellInfo->Id == 1842 && gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP)
2236 {
2239 {
2241 }
2242 return;
2243 }
2245 // handle outdoor pvp object opening, return true if go was registered for handling
2246 // these objects must have been spawned by outdoorpvp!
2247 else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget))
2248 return;
2249 lockId = goInfo->GetLockId();
2250 guid = gameObjTarget->GetGUID();
2251 }
2252 else if (itemTarget)
2253 {
2254 lockId = itemTarget->GetTemplate()->LockID;
2255 guid = itemTarget->GetGUID();
2256 }
2257 else
2258 {
2259 LOG_DEBUG("spells.aura", "WORLD: Open Lock - No GameObject/Item Target!");
2260 return;
2261 }
2262
2263 SkillType skillId = SKILL_NONE;
2264 int32 reqSkillValue = 0;
2265 int32 skillValue;
2266
2267 SpellCastResult res = CanOpenLock(effIndex, lockId, skillId, reqSkillValue, skillValue);
2268 if (res != SPELL_CAST_OK)
2269 {
2270 SendCastResult(res);
2271 return;
2272 }
2273
2274 if (gameObjTarget)
2275 SendLoot(guid, LOOT_SKINNING);
2276 else if (itemTarget)
2277 {
2279 if (Player* itemOwner = itemTarget->GetOwner())
2280 itemTarget->SetState(ITEM_CHANGED, itemOwner);
2281 }
2282
2283 // not allow use skill grow at item base open
2284 if (!m_CastItem && skillId != SKILL_NONE)
2285 {
2286 // update skill if really known
2287 if (uint32 pureSkillValue = player->GetPureSkillValue(skillId))
2288 {
2289 if (gameObjTarget)
2290 {
2291 // Allow one skill-up until respawned
2292 if (!gameObjTarget->IsInSkillupList(player->GetGUID()))
2293 {
2295 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2296 }
2297
2298 }
2299 else if (itemTarget)
2300 {
2301 // Do one skill-up
2302 player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue);
2303 }
2304 }
2305 }
2307}
@ GO_JUST_DEACTIVATED
Definition GameObject.h:118
@ 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:1338
LootState getLootState() const
Definition GameObject.h:230
void SetLootState(LootState s, Unit *unit=nullptr)
Definition GameObject.cpp:2547
bool IsInSkillupList(ObjectGuid const &playerGuid) const
Definition GameObject.cpp:3180
void AddToSkillupList(ObjectGuid const &playerGuid)
Definition GameObject.cpp:3174
void SetState(ItemUpdateState state, Player *forplayer=nullptr)
Definition Item.cpp:708
Definition Object.h:111
void ExecuteLogEffectOpenLock(uint8 effIndex, Object *obj)
Definition Spell.cpp:5312
void SendLoot(ObjectGuid guid, LootType loottype)
Definition SpellEffects.cpp:2123
Definition GameObjectData.h:32
uint32 GetAutoCloseTime() const
Definition GameObjectData.h:511
uint32 noDamageImmune
Definition GameObjectData.h:49
struct GameObjectTemplate::@237::@240 button
uint32 losOK
Definition GameObjectData.h:65
struct GameObjectTemplate::@237::@248 goober
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)
4918{
4919 Unit* unitCaster = m_caster->ToUnit();
4920 if (!unitCaster)
4921 return;
4922
4924 return;
4925
4926 if (unitCaster->IsPlayer())
4927 unitCaster->ToPlayer()->SetCanParry(true);
4928}
void SetCanParry(bool value)
Definition Player.cpp:13512

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

◆ EffectPersistentAA()

void Spell::EffectPersistentAA ( SpellEffIndex  effIndex)
1938{
1939 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1940 if (!unitCaster)
1941 return;
1942
1944 return;
1945
1946 if (!m_spellAura)
1947 {
1948 Unit* caster = unitCaster->GetEntry() == WORLD_TRIGGER ? m_originalCaster : unitCaster;
1949 float radius = m_spellInfo->Effects[effIndex].CalcRadius(caster);
1950
1951 // Caster not in world, might be spell triggered from aura removal
1952 if (!caster->IsInWorld() || !caster->FindMap() || !ObjectAccessor::GetUnit(*caster, caster->GetGUID())) // pussywizard: temporary crash fix (FindMap and GetUnit are mine)
1953 return;
1954 DynamicObject* dynObj = new DynamicObject();
1956 {
1957 delete dynObj;
1958 return;
1959 }
1960
1962 {
1963 m_spellAura = aura;
1966 }
1967 else
1968 return;
1969 }
1970
1973}
#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)
2867{
2868 Unit* unitCaster = m_caster->ToUnit();
2869 if (!unitCaster)
2870 return;
2871
2873 return;
2874
2875 if (!unitCaster->IsPlayer())
2876 return;
2877
2879}
@ 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)
6456{
6458 return;
6459
6460 if (!unitTarget)
6461 return;
6462
6463 Player* player = unitTarget->ToPlayer();
6464 if (!player)
6465 {
6466 return;
6467 }
6468
6469 uint32 soundid = m_spellInfo->Effects[effIndex].MiscValue;
6470
6471 if (!sSoundEntriesStore.LookupEntry(soundid))
6472 {
6473 LOG_ERROR("spells.effect", "EffectPlayMusic: Sound (Id: {}) not exist in spell {}.", soundid, m_spellInfo->Id);
6474 return;
6475 }
6476
6478}
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)
6509{
6511 return;
6512
6513 if (!unitTarget)
6514 return;
6515
6516 Player* player = unitTarget->ToPlayer();
6517 if (!player)
6518 {
6519 return;
6520 }
6521
6522 switch (m_spellInfo->Id)
6523 {
6524 case 58730: // Restricted Flight Area
6525 case 58600: // Restricted Flight Area
6527 break;
6528 default:
6529 break;
6530 }
6531
6532 uint32 soundId = m_spellInfo->Effects[effIndex].MiscValue;
6533
6534 if (!sSoundEntriesStore.LookupEntry(soundId))
6535 {
6536 LOG_ERROR("spells.effect", "EffectPlayerSound: Sound (Id: {}) not exist in spell {}.", soundId, m_spellInfo->Id);
6537 return;
6538 }
6539
6540 player->PlayDirectSound(soundId, player);
6541}
@ 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:3023

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)
1505{
1506 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1508 return;
1509
1510 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1511 return;
1512
1513 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1514
1516 return;
1517
1518 // burn x% of target's mana, up to maximum of 2x% of caster's mana (Mana Burn)
1519 if (unitCaster && m_spellInfo->Id == 8129)
1520 {
1521 int32 maxDamage = int32(CalculatePct(unitCaster->GetMaxPower(PowerType), damage * 2));
1523 damage = std::min(damage, maxDamage);
1524
1525 // Remove fear
1527 }
1528
1529 int32 power = damage;
1530 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1531 if (PowerType == POWER_MANA)
1532 power -= unitTarget->GetSpellCritDamageReduction(power);
1533
1534 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -power));
1535
1536 // NO - Not a typo - EffectPowerBurn uses effect value multiplier - not effect damage multiplier
1537 float dmgMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1538
1539 // add log data before multiplication (need power amount, not damage)
1540 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, 0.0f);
1541
1542 newDamage = int32(newDamage * dmgMultiplier);
1543
1544 m_damage += newDamage;
1545}
void ExecuteLogEffectTakeTargetPower(uint8 effIndex, Unit *target, uint32 PowerType, uint32 powerTaken, float gainMultiplier)
Definition Spell.cpp:5281
int32 ModifyPower(Powers power, int32 val, bool withPowerUpdate=true)
Definition Unit.cpp:10842
uint32 GetSpellCritDamageReduction(uint32 damage) const
Definition Unit.h:1293

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)
1422{
1423 Unit* unitCaster = GetUnitCasterForEffectHandlers();
1425 return;
1426
1427 if (m_spellInfo->Effects[effIndex].MiscValue < 0 || m_spellInfo->Effects[effIndex].MiscValue >= int8(MAX_POWERS))
1428 return;
1429
1430 Powers PowerType = Powers(m_spellInfo->Effects[effIndex].MiscValue);
1431
1433 return;
1434
1435 // add spell damage bonus
1436 if (unitCaster)
1437 {
1440 }
1441
1442 // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
1443 int32 power = damage;
1444 if (PowerType == POWER_MANA)
1445 power -= unitTarget->GetSpellCritDamageReduction(power);
1446
1447 int32 newDamage = -(unitTarget->ModifyPower(PowerType, -int32(power)));
1448
1449 float gainMultiplier = 0.0f;
1450
1451 // Don`t restore from self drain
1452 if (unitCaster && unitCaster != unitTarget)
1453 {
1454 gainMultiplier = m_spellInfo->Effects[effIndex].CalcValueMultiplier(m_originalCaster, this);
1455
1456 int32 gain = int32(newDamage * gainMultiplier);
1457
1458 unitCaster->EnergizeBySpell(unitCaster, m_spellInfo->Id, gain, PowerType);
1459 }
1460 ExecuteLogEffectTakeTargetPower(effIndex, unitTarget, PowerType, newDamage, gainMultiplier);
1461}

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)
2423{
2424 Unit* unitCaster = m_caster->ToUnit();
2425 if (!unitCaster)
2426 return;
2427
2429 return;
2430
2431 if (!unitCaster->IsPlayer())
2432 return;
2433 Player* p_target = unitCaster->ToPlayer();
2434
2436 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_WEAPON && !(p_target->GetWeaponProficiency() & subClassMask))
2437 {
2438 p_target->AddWeaponProficiency(subClassMask);
2440 }
2441 if (m_spellInfo->EquippedItemClass == ITEM_CLASS_ARMOR && !(p_target->GetArmorProficiency() & subClassMask))
2442 {
2443 p_target->AddArmorProficiency(subClassMask);
2445 }
2446}
uint32 GetArmorProficiency() const
Definition Player.h:1385
void SendProficiency(ItemClass itemClass, uint32 itemSubclassMask)
Definition Player.cpp:10298
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)
5798{
5799 Unit* unitCaster = m_caster->ToUnit();
5800 if (!unitCaster)
5801 return;
5802
5804 return;
5805
5806 if (!unitCaster->IsPlayer())
5807 return;
5808
5809 Player* p_caster = unitCaster->ToPlayer();
5811 return;
5812
5813 if (itemTarget->GetCount() < 5)
5814 return;
5815
5816 if (sWorld->getBoolConfig(CONFIG_SKILL_PROSPECTING))
5817 {
5818 uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_JEWELCRAFTING);
5819 uint32 reqSkillValue = itemTarget->GetTemplate()->RequiredSkillRank;
5820 p_caster->UpdateGatherSkill(SKILL_JEWELCRAFTING, SkillValue, reqSkillValue);
5821 }
5822
5824}
@ 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
2844{
2846 EffectNULL(effIndex);
2847}
void EffectNULL(SpellEffIndex effIndex)
Definition SpellEffects.cpp:239

References EffectNULL().

◆ EffectPullTowards()

void Spell::EffectPullTowards ( SpellEffIndex  effIndex)
5401{
5403 return;
5404
5405 if (!unitTarget)
5406 return;
5407
5408 Position pos;
5409 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_PULL_TOWARDS_DEST)
5410 {
5411 if (m_targets.HasDst())
5412 pos.Relocate(*destTarget);
5413 else
5414 return;
5415 }
5416 else //if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_PULL_TOWARDS)
5417 {
5418 // Xinef: Increase Z position a little bit, should protect from falling through textures
5420 }
5421
5422 float speedXY = float(m_spellInfo->Effects[effIndex].MiscValue) ? float(m_spellInfo->Effects[effIndex].MiscValue) * 0.1f : 30.f;
5423 float speedZ = unitTarget->GetDistance(pos) / speedXY * 0.5f * Movement::gravity;
5424
5425 unitTarget->GetMotionMaster()->MoveJump(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), speedXY, speedZ);
5426
5427 if (unitTarget->IsPlayer())
5428 {
5429 sScriptMgr->AnticheatSetUnderACKmount(unitTarget->ToPlayer());
5430 }
5431}
@ 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)
5339{
5341 return;
5342
5343 if (!unitTarget)
5344 return;
5345
5346 Player* player = unitTarget->ToPlayer();
5347 if (!player)
5348 {
5349 return;
5350 }
5351
5352 uint32 quest_id = m_spellInfo->Effects[effIndex].MiscValue;
5353
5354 Quest const* quest = sObjectMgr->GetQuestTemplate(quest_id);
5355
5356 if (!quest)
5357 return;
5358
5359 // Player has never done this quest
5360 if (player->GetQuestStatus(quest_id) == QUEST_STATUS_NONE)
5361 return;
5362
5363 // remove all quest entries for 'entry' from quest log
5364 for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot)
5365 {
5366 uint32 logQuest = player->GetQuestSlotQuestId(slot);
5367 if (logQuest == quest_id)
5368 {
5369 player->SetQuestSlot(slot, 0);
5370
5371 // we ignore unequippable quest items in this case, it's still be equipped
5372 player->TakeQuestSourceItem(logQuest, false);
5373
5374 if (quest->HasFlag(QUEST_FLAGS_FLAGS_PVP))
5375 {
5376 player->pvpInfo.IsHostile = player->pvpInfo.IsInHostileArea || player->HasPvPForcingQuest();
5377 player->UpdatePvPState();
5378 }
5379 }
5380 }
5381
5382 player->RemoveRewardedQuest(quest_id);
5383 player->RemoveActiveQuest(quest_id, false);
5384}
@ 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:1460
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:1876
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)
4985{
4987 return;
4988
4989 if (!unitTarget)
4990 return;
4991
4992 Player* player = unitTarget->ToPlayer();
4993 if (!player)
4994 {
4995 return;
4996 }
4997
4998 uint32 questId = m_spellInfo->Effects[effIndex].MiscValue;
4999 if (questId)
5000 {
5001 Quest const* quest = sObjectMgr->GetQuestTemplate(questId);
5002 if (!quest)
5003 return;
5004
5005 uint16 logSlot = player->FindQuestSlot(questId);
5006 if (logSlot < MAX_QUEST_LOG_SIZE)
5007 player->AreaExploredOrEventHappens(questId);
5008 else if (player->CanTakeQuest(quest, false)) // Check if the quest has already been turned in.
5009 player->SetRewardedQuest(questId); // If not, set status to rewarded without broadcasting it to client.
5010 }
5011}
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)
6055{
6057 return;
6058
6059 if (!unitTarget)
6060 return;
6061
6062 if (Player* player = unitTarget->ToPlayer())
6063 {
6064 player->FailQuest(m_spellInfo->Effects[effIndex].MiscValue);
6065 }
6066}

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

◆ EffectQuestStart()

void Spell::EffectQuestStart ( SpellEffIndex  effIndex)
6069{
6071 return;
6072
6073 if (!unitTarget)
6074 return;
6075
6076 Player* player = unitTarget->ToPlayer();
6077 if (!player)
6078 return;
6079
6080 if (Quest const* quest = sObjectMgr->GetQuestTemplate(m_spellInfo->Effects[effIndex].MiscValue))
6081 {
6082 if (!player->CanTakeQuest(quest, false))
6083 return;
6084
6085 if (quest->IsAutoAccept() && player->CanAddQuest(quest, false))
6086 player->AddQuestAndCheckCompletion(quest, player);
6087
6088 player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, player->GetGUID(), true);
6089 }
6090}
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:2287

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)
6602{
6603 Unit* unitCaster = m_caster->ToUnit();
6604 if (!unitCaster)
6605 return;
6606
6608 return;
6609
6610 if (!unitTarget || !unitTarget->IsPlayer())
6611 return;
6612
6613 Player* player = unitCaster->ToPlayer();
6614
6615 if (!player)
6616 return;
6617
6618 uint32 item_id = m_spellInfo->Effects[EFFECT_0].ItemType;
6619
6620 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id);
6621 if (!pProto)
6622 {
6623 player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
6624 return;
6625 }
6626
6627 if (Item* pItem = player->GetItemByEntry(item_id))
6628 {
6629 for (int x = 0; x < MAX_ITEM_PROTO_SPELLS; ++x)
6630 pItem->SetSpellCharges(x, pProto->Spells[x].SpellCharges);
6631 pItem->SetState(ITEM_CHANGED, player);
6632 }
6633}

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)
6237{
6238 Unit* unitCaster = GetUnitCasterForEffectHandlers();
6239 if (!unitCaster)
6240 return;
6241
6243 return;
6244
6245 if (unitTarget)
6247}
void RegisterRedirectThreat(uint32 spellId, ObjectGuid const &victim, uint32 pct)
== REDIRECT SYSTEM ==
Definition ThreatManager.cpp:868

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)
6544{
6546 return;
6547
6548 if (!unitTarget)
6549 return;
6550 // there may be need of specifying casterguid of removed auras
6551 unitTarget->RemoveAurasDueToSpell(m_spellInfo->Effects[effIndex].TriggerSpell);
6552}

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

◆ EffectRenamePet()

void Spell::EffectRenamePet ( SpellEffIndex  effIndex)
6444{
6446 return;
6447
6448 if (!unitTarget || !unitTarget->IsCreature() ||
6450 return;
6451
6453}
@ 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)
4959{
4961 return;
4962
4963 if (!unitTarget)
4964 return;
4965
4966 Player* player = unitTarget->ToPlayer();
4967 if (!player)
4968 {
4969 return;
4970 }
4971
4972 float repChange = static_cast<float>(damage);
4973
4974 uint32 factionId = m_spellInfo->Effects[effIndex].MiscValue;
4975
4976 FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId);
4977 if (!factionEntry)
4978 return;
4979
4980 repChange = player->CalculateReputationGain(REPUTATION_SOURCE_SPELL, 0, repChange, factionId);
4981 player->GetReputationMgr().ModifyReputation(factionEntry, repChange);
4982}
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:6062
ReputationMgr & GetReputationMgr()
Definition Player.h:2157
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)
4865{
4866 Unit* unitCaster = m_caster->ToUnit();
4867 if (!unitCaster)
4868 return;
4869
4871 return;
4872
4873 if (!unitTarget)
4874 return;
4875
4876 if (!unitTarget)
4877 return;
4878
4879 Player* target = unitTarget->ToPlayer();
4880 if (!target)
4881 {
4882 return;
4883 }
4884
4885 if (unitTarget->IsAlive() || !unitTarget->IsInWorld())
4886 return;
4887
4888 if (target->isResurrectRequested()) // already have one active request
4889 return;
4890
4891 uint32 health = target->CountPctFromMaxHealth(damage);
4893
4894 ExecuteLogEffectResurrect(effIndex, target);
4895
4896 target->setResurrectRequestData(unitCaster->GetGUID(), unitCaster->GetMapId(), unitCaster->GetPositionX(), unitCaster->GetPositionY(), unitCaster->GetPositionZ(), health, mana);
4897 SendResurrectRequest(target);
4898}
void setResurrectRequestData(ObjectGuid guid, uint32 mapId, float X, float Y, float Z, uint32 health, uint32 mana)
Definition Player.h:1845
bool isResurrectRequested() const
Definition Player.h:1857
void ExecuteLogEffectResurrect(uint8 effIndex, Unit *target)
Definition Spell.cpp:5342
void SendResurrectRequest(Player *target)
Definition Spell.cpp:5412

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
5481{
5482 Unit* unitCaster = m_caster->ToUnit();
5483 if (!unitCaster)
5484 return;
5485
5487 return;
5488
5489 if (damage < 0)
5490 return;
5491
5492 Player* player = unitCaster->ToPlayer();
5493 if (!player)
5494 {
5495 return;
5496 }
5497
5498 Pet* pet = player->GetPet();
5499 if (!pet)
5500 {
5501 // Position passed to SummonPet is irrelevant with current implementation,
5502 // pet will be relocated without using these coords in Pet::LoadPetFromDB
5503 player->SummonPet(0, 0.0f, 0.0f, 0.0f, 0.0f, SUMMON_PET, 0ms, damage);
5504 return;
5505 }
5506
5508 if (pet->IsAlive())
5509 {
5510 return;
5511 }
5512
5513 // Reposition the pet's corpse before reviving so as not to grab aggro
5514 // We can use a different, more accurate version of GetClosePoint() since we have a pet
5515 float x, y, z; // Will be used later to reposition the pet if we have one
5516 player->GetClosePoint(x, y, z, pet->GetCombatReach(), PET_FOLLOW_DIST, pet->GetFollowAngle());
5517 pet->NearTeleportTo(x, y, z, player->GetOrientation());
5518 pet->Relocate(x, y, z, player->GetOrientation()); // This is needed so SaveStayPosition() will get the proper coords.
5522 pet->ClearUnitState(uint32(UNIT_STATE_ALL_STATE & ~(UNIT_STATE_POSSESSED))); // xinef: just in case
5524 pet->SetDisplayId(pet->GetNativeDisplayId());
5525
5526 // xinef: restore movement
5527 if (auto ci = pet->GetCharmInfo())
5528 {
5529 ci->SetIsAtStay(false);
5530 ci->SetIsFollowing(false);
5531 }
5532
5534}
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:654
void SetDisplayId(uint32 modelId, std::optional< float > displayScale={}) override
Definition Pet.cpp:2441
Pet * SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, Milliseconds duration=0ms, uint32 healthPct=0)
Definition Player.cpp:9194
void ReplaceAllDynamicFlags(uint32 flag) override
Definition Unit.h:775
void SetHealth(uint32 val)
Definition Unit.cpp:12020
uint32 GetNativeDisplayId() const
Definition Unit.h:1998
void RemoveUnitFlag(UnitFlags flags)
UnitFlags available in UnitDefines.h.
Definition Unit.h:755
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:2832

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

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:145
@ MAXDAMAGE
Definition Unit.h:146
uint8 GetStackAmount() const
Definition SpellAuras.h:150
std::array< uint32, 2 > SpellVisual
Definition SpellInfo.h:403
float GetTotalAttackPowerValue(WeaponAttackType attType, Unit *pVictim=nullptr) const
Definition Unit.cpp:11970
float ApplyEffectModifiers(SpellInfo const *spellProto, uint8 effect_index, float value) const
Definition Unit.cpp:11397
virtual uint32 GetShieldBlockValue() const =0
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:4985
uint32 GetAttackTime(WeaponAttackType att) const
Definition Unit.h:923
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
Definition Unit.h:1454

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

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

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
1464{
1465 // we do not handle a flag dropping or clicking on flag in battleground by sendevent system
1468 return;
1469
1470 WorldObject* target = nullptr;
1471
1472 // call events for object target if present
1474 {
1475 if (unitTarget)
1476 target = unitTarget;
1477 else if (gameObjTarget)
1478 target = gameObjTarget;
1479 }
1480 else // if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1481 {
1482 // let's prevent executing effect handler twice in case when spell effect is capable of targeting an object
1483 // this check was requested by scripters, but it has some downsides:
1484 // now it's impossible to script (using sEventScripts) a cast which misses all targets
1485 // or to have an ability to script the moment spell hits dest (in a case when there are object targets present)
1486 if (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_GAMEOBJECT_MASK))
1487 return;
1488 // some spells have no target entries in dbc and they use focus target
1489 if (focusObject)
1490 target = focusObject;
1492 }
1493
1494 LOG_DEBUG("spells.aura", "Spell ScriptStart {} for spellid {} in EffectSendEvent ", m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
1495
1496 if (ZoneScript* zoneScript = m_caster->GetZoneScript())
1497 zoneScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1498 else if (InstanceScript* instanceScript = m_caster->GetInstanceScript()) // needed in case Player is the caster
1499 instanceScript->ProcessEvent(target, m_spellInfo->Effects[effIndex].MiscValue);
1500
1501 m_caster->GetMap()->ScriptsStart(sEventScripts, m_spellInfo->Effects[effIndex].MiscValue, m_caster, target);
1502}
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)
5387{
5389 return;
5390
5391 if (!unitTarget)
5392 return;
5393
5394 if (Player* player = unitTarget->ToPlayer())
5395 {
5396 player->ActivateTaxiPathTo(m_spellInfo->Effects[effIndex].MiscValue, m_spellInfo->Id);
5397 }
5398}

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

◆ EffectSkill()

void Spell::EffectSkill ( SpellEffIndex  effIndex)
5856{
5858 return;
5859
5860 LOG_DEBUG("spells.aura", "WORLD: SkillEFFECT");
5861}

References effectHandleMode, LOG_DEBUG, and SPELL_EFFECT_HANDLE_HIT.

◆ EffectSkinning()

void Spell::EffectSkinning ( SpellEffIndex  effIndex)
5135{
5136 Unit* unitCaster = m_caster->ToUnit();
5137 if (!unitCaster)
5138 return;
5139
5141 return;
5142
5143 if (!unitTarget->IsCreature())
5144 return;
5145 if (!unitCaster->IsPlayer())
5146 return;
5147
5148 Creature* creature = unitTarget->ToCreature();
5149 int32 targetLevel = creature->GetLevel();
5150
5151 uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
5152
5155 unitCaster->ToPlayer()->SendLoot(creature->GetGUID(), LOOT_SKINNING);
5156
5157 int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel - 10) * 10 : targetLevel * 5;
5158
5159 int32 skillValue = unitCaster->ToPlayer()->GetPureSkillValue(skill);
5160
5161 // Double chances for elites
5162 unitCaster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
5163}
@ UNIT_DYNFLAG_LOOTABLE
Definition SharedDefines.h:3354
bool isElite() const
Definition Creature.h:114
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)
5887{
5888 Unit* unitCaster = m_caster->ToUnit();
5889 if (!unitCaster)
5890 return;
5891
5893 return;
5894
5895 LOG_DEBUG("spells.aura", "Effect: SkinPlayerCorpse");
5896 if ((!unitCaster->IsPlayer()) || (!unitTarget->IsPlayer()) || (unitTarget->IsAlive()))
5897 return;
5898
5899 unitTarget->ToPlayer()->RemovedInsignia(unitCaster->ToPlayer());
5900
5901 // We have a corpse object as the target.
5902 // This target was deleted in RemovedInsignia() -> ConvertCorpseToBones().
5904}
void RemovedInsignia(Player *looterPlr)
Definition Player.cpp:7968
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)
6481{
6483 return;
6484
6485 if (!unitTarget)
6486 return;
6487
6488 if (Player* player = unitTarget->ToPlayer())
6489 {
6490 player->UpdateSpecCount(damage);
6491 }
6492}

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

◆ EffectSpiritHeal()

void Spell::EffectSpiritHeal ( SpellEffIndex  effIndex)
5868{
5870 return;
5871
5872 /*
5873 if (!unitTarget->IsPlayer())
5874 return;
5875 if (!unitTarget->IsInWorld())
5876 return;
5877
5878 //m_spellInfo->Effects[i].BasePoints; == 99 (percent?)
5879 //unitTarget->ToPlayer()->setResurrect(unitCaster->GetGUID(), unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), unitTarget->GetMaxHealth(), unitTarget->GetMaxPower(POWER_MANA));
5880 unitTarget->ToPlayer()->ResurrectPlayer(1.0f);
5881 unitTarget->ToPlayer()->SpawnCorpseBones();
5882 */
5883}

References effectHandleMode, and SPELL_EFFECT_HANDLE_HIT_TARGET.

◆ EffectStealBeneficialBuff()

void Spell::EffectStealBeneficialBuff ( SpellEffIndex  effIndex)
5907{
5908 Unit* unitCaster = m_caster->ToUnit();
5909 if (!unitCaster)
5910 return;
5911
5913 return;
5914
5915 LOG_DEBUG("spells.aura", "Effect: StealBeneficialBuff");
5916
5917 if (!unitTarget || unitTarget == unitCaster) // can't steal from self
5918 return;
5919
5920 DispelChargesList steal_list;
5921
5922 // Create dispel mask by dispel type
5923 uint32 dispelMask = SpellInfo::GetDispelMask(DispelType(m_spellInfo->Effects[effIndex].MiscValue));
5924 Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
5925 for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5926 {
5927 Aura* aura = itr->second;
5929 if (!aurApp)
5930 continue;
5931
5932 if ((aura->GetSpellInfo()->GetDispelMask()) & dispelMask)
5933 {
5934 // Need check for passive? this
5935 if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellInfo()->HasAttribute(SPELL_ATTR4_CANNOT_BE_STOLEN))
5936 continue;
5937
5938 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
5939 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
5940 // Polymorph instead of 1 / (5 + 1) -> 16%.
5941 bool dispel_charges = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR7_DISPEL_REMOVES_CHARGES);
5942 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
5943 if (charges > 0)
5944 steal_list.push_back(std::make_pair(aura, charges));
5945 }
5946 }
5947
5948 if (steal_list.empty())
5949 return;
5950
5951 // Ok if exist some buffs for dispel try dispel it
5952 uint32 failCount = 0;
5953 DispelList success_list;
5954 WorldPacket dataFail(SMSG_DISPEL_FAILED, 8 + 8 + 4 + 4 + damage * 4);
5955 // dispel N = damage buffs (or while exist buffs for dispel)
5956 for (int32 count = 0; count < damage && !steal_list.empty();)
5957 {
5958 // Random select buff for dispel
5959 DispelChargesList::iterator itr = steal_list.begin();
5960 std::advance(itr, urand(0, steal_list.size() - 1));
5961
5962 int32 chance = itr->first->CalcDispelChance(unitTarget, !unitTarget->IsFriendlyTo(unitCaster));
5963 // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
5964 if (!chance)
5965 {
5966 steal_list.erase(itr);
5967 continue;
5968 }
5969 else
5970 {
5971 if (roll_chance_i(chance))
5972 {
5973 success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
5974 --itr->second;
5975 if (itr->second <= 0)
5976 steal_list.erase(itr);
5977 }
5978 else
5979 {
5980 if (!failCount)
5981 {
5982 // Failed to dispell
5983 dataFail << unitCaster->GetGUID(); // Caster GUID
5984 dataFail << unitTarget->GetGUID(); // Victim GUID
5985 dataFail << uint32(m_spellInfo->Id); // dispel spell id
5986 }
5987 ++failCount;
5988 dataFail << uint32(itr->first->GetId()); // Spell Id
5989 }
5990 ++count;
5991 }
5992 }
5993
5994 if (failCount)
5995 unitCaster->SendMessageToSet(&dataFail, true);
5996
5997 if (success_list.empty())
5998 return;
5999
6000 WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8 + 8 + 4 + 1 + 4 + damage * 5);
6001 dataSuccess << unitTarget->GetPackGUID(); // Victim GUID
6002 dataSuccess << unitCaster->GetPackGUID(); // Caster GUID
6003 dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
6004 dataSuccess << uint8(0); // not used
6005 dataSuccess << uint32(success_list.size()); // count
6006 for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
6007 {
6008 dataSuccess << uint32(itr->first); // Spell Id
6009 dataSuccess << uint8(0); // 0 - steals !=0 transfers
6010 unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, unitCaster);
6011 }
6012 unitCaster->SendMessageToSet(&dataSuccess, true);
6013}
@ 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:2720
bool IsPositive() const
Definition SpellAuras.h:69
uint8 GetCharges() const
Definition SpellAuras.h:143
bool IsPassive() const
Definition SpellAuras.cpp:1148
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit *stealer)
Definition Unit.cpp:5066
@ 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)
4377{
4378 Unit* unitCaster = m_caster->ToUnit();
4379 if (!unitCaster)
4380 return;
4381
4383 return;
4384
4385 if (!unitCaster->IsPlayer())
4386 return;
4387
4388 Player* target = unitCaster->ToPlayer();
4389 if (target->IsInFlight())
4390 return;
4391
4392 // xinef: if player is dead - teleport to graveyard
4393 if (!target->IsAlive())
4394 {
4395 if (target->HasPreventResurectionAura())
4396 return;
4397
4398 // xinef: player is in corpse
4399 if (!target->HasPlayerFlag(PLAYER_FLAGS_GHOST))
4400 target->BuildPlayerRepop();
4401 target->RepopAtGraveyard();
4402 return;
4403 }
4404
4405 // xinef: no hearthstone in bag or on cooldown
4406 Item* hearthStone = target->GetItemByEntry(6948);
4407 if (!hearthStone || target->HasSpellCooldown(8690))
4408 {
4409 float o = rand_norm() * 2 * M_PI;
4410 Position pos = *target;
4411 target->MovePositionToFirstCollision(pos, 5.0f, o);
4412 target->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), target->GetOrientation());
4413 return;
4414 }
4415
4416 // xinef: we have hearthstone not on cooldown, just use it
4418}
@ PLAYER_FLAGS_GHOST
Definition Player.h:463
double rand_norm()
Definition Random.cpp:85
void RepopAtGraveyard()
Definition Player.cpp:5028
void BuildPlayerRepop()
Definition Player.cpp:4530
bool HasPreventResurectionAura() const
Definition Unit.h:1826
void MovePositionToFirstCollision(Position &pos, float dist, float angle)
Definition Object.cpp:2991

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)
2310{
2311 Unit* unitCaster = m_caster->ToUnit();
2312 if (!unitCaster)
2313 return;
2314
2316 return;
2317
2318 if (!unitCaster->IsPlayer())
2319 return;
2320
2321 Player* player = unitCaster->ToPlayer();
2322
2323 // applied only to using item
2324 if (!m_CastItem)
2325 return;
2326
2327 // ... only to item in own inventory/bank/equip_slot
2328 if (m_CastItem->GetOwnerGUID() != player->GetGUID())
2329 return;
2330
2331 uint32 newitemid = m_spellInfo->Effects[effIndex].ItemType;
2332 if (!newitemid)
2333 return;
2334
2335 uint16 pos = m_CastItem->GetPos();
2336
2337 Item* pNewItem = Item::CreateItem(newitemid, 1, player);
2338 if (!pNewItem)
2339 return;
2340
2341 // Client-side enchantment durations update
2343
2347
2349 {
2351 player->DurabilityLoss(pNewItem, lossPercent);
2352 }
2353
2354 if (player->IsInventoryPos(pos))
2355 {
2356 ItemPosCountVec dest;
2357 InventoryResult msg = player->CanStoreItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2358 if (msg == EQUIP_ERR_OK)
2359 {
2360 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2361
2362 // prevent crash at access and unexpected charges counting with item update queue corrupt
2364 m_targets.SetItemTarget(nullptr);
2365
2366 m_CastItem = nullptr;
2368
2369 player->StoreItem(dest, pNewItem, true);
2370 player->ItemAddedQuestCheck(pNewItem->GetEntry(), 1);
2371 return;
2372 }
2373 }
2374 else if (player->IsBankPos(pos))
2375 {
2376 ItemPosCountVec dest;
2377 uint8 msg = player->CanBankItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), dest, pNewItem, true);
2378 if (msg == EQUIP_ERR_OK)
2379 {
2380 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2381
2382 // prevent crash at access and unexpected charges counting with item update queue corrupt
2384 m_targets.SetItemTarget(nullptr);
2385
2386 m_CastItem = nullptr;
2388
2389 player->BankItem(dest, pNewItem, true);
2390 return;
2391 }
2392 }
2393 else if (player->IsEquipmentPos(pos))
2394 {
2395 uint16 dest;
2396
2397 player->DestroyItem(m_CastItem->GetBagSlot(), m_CastItem->GetSlot(), true);
2398
2399 uint8 msg = player->CanEquipItem(m_CastItem->GetSlot(), dest, pNewItem, true);
2400
2401 if (msg == EQUIP_ERR_OK || msg == EQUIP_ERR_CANT_DO_RIGHT_NOW)
2402 {
2404
2405 // prevent crash at access and unexpected charges counting with item update queue corrupt
2407 m_targets.SetItemTarget(nullptr);
2408
2409 m_CastItem = nullptr;
2411
2412 player->EquipItem(dest, pNewItem, true);
2413 player->AutoUnequipOffhandIfNeed();
2414 return;
2415 }
2416 }
2417
2418 // fail
2419 delete pNewItem;
2420}
@ 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:1099
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:778
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:12770
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)
4788{
4789 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4790 if (!unitCaster)
4791 return;
4792
4794 return;
4795
4796 uint32 gameobjectId = m_spellInfo->Effects[effIndex].MiscValue;
4797
4798 uint8 slot = 0;
4799 switch (m_spellInfo->Effects[effIndex].Effect)
4800 {
4802 slot = 0;
4803 break;
4805 slot = 1;
4806 break;
4808 slot = 2;
4809 break;
4811 slot = 3;
4812 break;
4813 default:
4814 return;
4815 }
4816
4817 if (unitCaster)
4818 {
4819 ObjectGuid guid = unitCaster->m_ObjectSlot[slot];
4820 if (guid)
4821 {
4822 if (GameObject* gameObject = unitCaster->GetMap()->GetGameObject(guid))
4823 {
4824 // Recast case - null spell id to make auras not be removed on object remove from world
4825 if (m_spellInfo->Id == gameObject->GetSpellId())
4826 gameObject->SetSpellId(0);
4827 unitCaster->RemoveGameObject(gameObject, true);
4828 }
4829 unitCaster->m_ObjectSlot[slot].Clear();
4830 }
4831 }
4832
4833 GameObject* pGameObj = sObjectMgr->IsGameObjectStaticTransport(gameobjectId) ? new StaticTransport() : new GameObject();
4834
4835 float x, y, z;
4836 // If dest location if present
4837 if (m_targets.HasDst())
4838 destTarget->GetPosition(x, y, z);
4839 // Summon in random point all other units if location present
4840 else
4841 unitCaster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
4842
4843 Map* map = unitCaster->GetMap();
4844 G3D::Quat rotation = G3D::Quat::fromAxisAngleRotation(G3D::Vector3::unitZ(), unitCaster->GetOrientation());
4845 if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobjectId, map, unitCaster->GetPhaseMask(), x, y, z, unitCaster->GetOrientation(), rotation, 0, GO_STATE_READY))
4846 {
4847 delete pGameObj;
4848 return;
4849 }
4850
4851 //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, unitCaster->GetLevel());
4852 int32 duration = m_spellInfo->GetDuration();
4853 pGameObj->SetRespawnTime(duration > 0 ? duration / IN_MILLISECONDS : 0);
4854 pGameObj->SetSpellId(m_spellInfo->Id);
4855 unitCaster->AddGameObject(pGameObj);
4856
4857 ExecuteLogEffectSummonObject(effIndex, pGameObj);
4858
4859 map->AddToMap(pGameObj, true);
4860
4861 unitCaster->m_ObjectSlot[slot] = pGameObj->GetGUID();
4862}
#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:2100

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

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

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)
4421{
4422 Unit* unitCaster = GetUnitCasterForEffectHandlers();
4423 if (!unitCaster)
4424 return;
4425
4426 // workaround - this effect should not use target map
4428 return;
4429
4430 if (!unitTarget)
4431 return;
4432
4433 Player* player = unitTarget->ToPlayer();
4434 if (!player)
4435 {
4436 return;
4437 }
4438
4439 // Evil Twin (ignore player summon, but hide this for summoner)
4440 // Xinef: Unit Target may be on other map!!!, Need workaround
4441 if (unitTarget->HasAura(23445))
4442 return;
4443
4444 float x, y, z;
4445 unitCaster->GetPosition(x, y, z);
4446
4447 player->SetSummonPoint(unitCaster->GetMapId(), x, y, z);
4448
4449 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
4450 data << unitCaster->GetGUID(); // summoner guid
4451 data << uint32(unitCaster->GetZoneId()); // summoner zone
4452 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
4453 player->SendDirectMessage(&data);
4454}
#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:16769
@ 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)
6687{
6688 Unit* unitCaster = m_caster->ToUnit();
6689 if (!unitCaster)
6690 return;
6691
6693 return;
6694
6695 if (!unitCaster->IsPlayer())
6696 return;
6697
6698 if (!unitTarget)
6699 return;
6700
6701 Player* player = unitTarget->ToPlayer();
6702 if (!player)
6703 {
6704 return;
6705 }
6706
6707 float x, y, z;
6708 unitCaster->GetPosition(x, y, z);
6709 unitTarget->ToPlayer()->SetSummonPoint(unitCaster->GetMapId(), x, y, z);
6710 WorldPacket data(SMSG_SUMMON_REQUEST, 8 + 4 + 4);
6711 data << unitCaster->GetGUID();
6712 data << uint32(unitCaster->GetZoneId());
6713 data << uint32(MAX_PLAYER_SUMMON_DELAY * IN_MILLISECONDS); // auto decline after msecs
6714 player->SendDirectMessage(&data);
6715}

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)
2449{
2451 return;
2452
2453 uint32 entry = m_spellInfo->Effects[effIndex].MiscValue;
2454
2455 if (m_spellValue->MiscVal[effIndex])
2456 entry = m_spellValue->MiscVal[effIndex];
2457
2458 if (!entry)
2459 return;
2460
2461 SummonPropertiesEntry const* properties = sSummonPropertiesStore.LookupEntry(m_spellInfo->Effects[effIndex].MiscValueB);
2462 if (!properties)
2463 {
2464 LOG_ERROR("spells.effect", "EffectSummonType: Unhandled summon type {}", m_spellInfo->Effects[effIndex].MiscValueB);
2465 return;
2466 }
2467
2468 // prefer the unit original caster, fall back to the WorldObject caster (e.g. GameObject traps)
2470 Unit* unitCaster = m_originalCaster;
2471
2472 bool personalSpawn = (properties->Flags & SUMMON_PROP_FLAG_ONLY_VISIBLE_TO_SUMMONER) != 0;
2473 int32 duration = m_spellInfo->GetDuration();
2474 if (Player* modOwner = caster->GetSpellModOwner())
2475 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2476
2477 TempSummon* summon = nullptr;
2478
2479 // determine how many units should be summoned
2480 uint32 numSummons;
2481
2482 // some spells need to summon many units, for those spells number of summons is stored in effect value
2483 // however so far noone found a generic check to find all of those (there's no related data in summonproperties.dbc
2484 // and in spell attributes, possibly we need to add a table for those)
2485 // so here's a list of MiscValueB values, which is currently most generic check
2486 switch (properties->Id)
2487 {
2488 case 64:
2489 case 61:
2490 case 1101:
2491 case 66:
2492 case 648:
2493 case 2301:
2494 case 1061:
2495 case 1261:
2496 case 629:
2497 case 181:
2498 case 715:
2499 case 1562:
2500 case 833:
2501 case 1161:
2502 case 713: // xinef, bloodworms
2503 numSummons = (damage > 0) ? damage : 1;
2504 break;
2505 default:
2506 numSummons = 1;
2507 break;
2508 }
2509
2510 switch (properties->Category)
2511 {
2515 if (properties->Flags & 512)
2516 {
2517 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2518 break;
2519 }
2520 switch (properties->Type)
2521 {
2522 case SUMMON_TYPE_PET:
2525 case SUMMON_TYPE_MINION:
2526 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2527 break;
2528 // Summons a vehicle, but doesn't force anyone to enter it (see SUMMON_CATEGORY_VEHICLE)
2531 if (!unitCaster)
2532 return;
2533
2534 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, personalSpawn);
2535 break;
2537 case SUMMON_TYPE_TOTEM:
2538 {
2539 if (!unitCaster)
2540 return;
2541
2542 // protection code
2543 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, personalSpawn);
2544 if (!summon || !summon->IsTotem())
2545 return;
2546
2547 // Mana Tide Totem
2548 if (m_spellInfo->Id == 16190)
2549 damage = unitCaster->CountPctFromMaxHealth(10);
2550
2551 if (damage && properties->Type != SUMMON_TYPE_LIGHTWELL) // Health set in script for lightwell
2552 {
2553 summon->SetMaxHealth(damage);
2554 summon->SetHealth(damage);
2555 }
2556 break;
2557 }
2559 if (!unitCaster)
2560 return;
2561
2562 // For companions, recalculate the position to ensure they spawn at the intended π/4 angle.
2563 destTarget->Relocate(unitCaster->GetNearPosition(
2566 ));
2567 [[fallthrough]];
2568 case SUMMON_TYPE_JEEVES:
2569 {
2570 if (!unitCaster)
2571 return;
2572
2573 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, personalSpawn);
2574 if (!summon || !summon->HasUnitTypeMask(UNIT_MASK_MINION))
2575 return;
2576
2577 summon->SelectLevel(); // some summoned creaters have different from 1 DB data for level/hp
2579
2580 summon->SetImmuneToAll(true);
2582
2583 // Xinef: Pet can have some auras in creature_addon or in scripts, do not remove them instantly
2584 //summon->AI()->EnterEvadeMode();
2585 if (properties->Type != SUMMON_TYPE_JEEVES)
2586 {
2587 summon->SetFacingToObject(unitCaster);
2588 summon->GetMotionMaster()->Clear(false);
2590 }
2591 break;
2592 }
2593 default:
2594 {
2595 float radius = m_spellInfo->Effects[effIndex].CalcRadius();
2596
2597 TempSummonType summonType = (duration <= 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
2598
2599 WorldObject* summoner = caster;
2600 if (Unit* unitSummoner = summoner->ToUnit())
2601 if (unitSummoner->IsPet())
2602 if (Unit* owner = unitSummoner->GetOwner())
2603 summoner = owner;
2604
2605 for (uint32 count = 0; count < numSummons; ++count)
2606 {
2607 Position pos;
2608 if (count == 0)
2609 pos = *destTarget;
2610 else
2611 // randomize position for multiple summons
2612 pos = caster->GetRandomPoint(*destTarget, radius);
2613
2614 summon = summoner->SummonCreature(entry, pos, summonType, duration, 0, nullptr, personalSpawn);
2615 if (!summon)
2616 continue;
2617
2618 summon->SetTempSummonType(summonType);
2619
2620 if (properties->Category == SUMMON_CATEGORY_ALLY)
2621 {
2622 summon->SetOwnerGUID(summoner->GetGUID());
2623 summon->SetFaction(summoner->GetFaction());
2624 }
2625
2626 ExecuteLogEffectSummonObject(effIndex, summon);
2627 }
2628 return;
2629 }
2630 }//switch
2631 break;
2633 // Xinef: SummonGuardian function can summon a few npcs of same type, remove old summons with same entry here
2634 if (m_originalCaster)
2636 SummonGuardian(effIndex, entry, properties, numSummons, personalSpawn);
2637 break;
2639 if (!unitCaster)
2640 return;
2641
2642 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, personalSpawn);
2643 break;
2645 if (!unitCaster)
2646 return;
2647
2648 // Summoning spells (usually triggered by npc_spellclick) that spawn a vehicle and that cause the clicker
2649 // to cast a ride vehicle spell on the summoned unit.
2650 //float x, y, z;
2651 //unitCaster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE);
2652 // xinef: vehicles summoned in air, eg. Cold Hearted quest
2653 if (std::fabs(unitCaster->GetPositionZ() - destTarget->GetPositionZ()) > 6.0f)
2654 destTarget->m_positionZ = unitCaster->GetPositionZ();
2655
2656 summon = unitCaster->GetMap()->SummonCreature(entry, *destTarget, properties, duration, unitCaster, m_spellInfo->Id, 0, personalSpawn);
2657 if (!summon || !summon->IsVehicle())
2658 return;
2659
2660 // The spell that this effect will trigger. It has SPELL_AURA_CONTROL_VEHICLE
2662 int32 basePoints = m_spellInfo->Effects[effIndex].CalcValue();
2663 if (basePoints > 1) // xinef: some summoning spells have value 1 - indicates vehicle seat
2664 {
2665 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(basePoints);
2666 if (spellInfo && spellInfo->HasAura(SPELL_AURA_CONTROL_VEHICLE))
2667 spellId = spellInfo->Id;
2668 }
2669
2670 // xinef: if we have small value, it indicates seat position
2671 if (basePoints > 0 && basePoints < MAX_VEHICLE_SEATS)
2672 unitCaster->CastCustomSpell(spellId, SPELLVALUE_BASE_POINT0, basePoints, summon, true);
2673 else
2674 unitCaster->CastSpell(summon, spellId, true);
2675
2676 // xinef: i think this is wrong, found only 2 vehicles with faction override and one of them should inherit caster faction...
2677 //uint32 faction = properties->Faction;
2678 //if (!faction)
2679 uint32 faction = unitCaster->GetFaction();
2680
2681 summon->SetFaction(faction);
2682 break;
2683 }
2684
2685 if (summon)
2686 {
2687 summon->SetCreatorGUID(caster->GetGUID());
2688 ExecuteLogEffectSummonObject(effIndex, summon);
2689 }
2690}
@ 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
@ TEMPSUMMON_TIMED_DESPAWN
Definition Object.h:52
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:574
@ VEHICLE_SPELL_RIDE_HARDCODED
Definition VehicleDefines.h:52
void SelectLevel(bool changelevel=true)
Definition Creature.cpp:1511
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:2253
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
Definition TemporarySummon.h:50
void SetTempSummonType(TempSummonType type)
Definition TemporarySummon.cpp:287
void SetFacingToObject(WorldObject *object, Milliseconds timed=0ms)
Definition Unit.cpp:16167
void SetFaction(uint32 faction)
Definition Unit.cpp:6886
void SetOwnerGUID(ObjectGuid owner)
Definition Unit.cpp:7490
uint32 HasUnitTypeMask(uint32 mask) const
Definition Unit.h:747
void SetMaxHealth(uint32 val)
Definition Unit.cpp:12070
void SetCreatorGUID(ObjectGuid creator)
Definition Unit.h:722
void ReplaceAllNpcFlags(NPCFlags flags)
Definition Unit.h:772
void RemoveAllMinionsByEntry(uint32 entry)
Definition Unit.cpp:7780
void SetImmuneToAll(bool apply, bool keepCombat=false)
Definition Unit.h:938
Position GetNearPosition(float dist, float angle)
Definition Object.cpp:2861
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:1322
virtual uint32 GetFaction() const
Definition Object.h:769
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:2460
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(), WorldObject::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)
3312{
3313 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3314 if (!unitCaster)
3315 return;
3316
3318 return;
3319
3320 if (unitCaster->GetPetGUID())
3321 return;
3322
3323 if (!unitTarget)
3324 return;
3325
3326 if (!unitTarget->IsCreature())
3327 return;
3328
3329 Creature* creatureTarget = unitTarget->ToCreature();
3330
3331 if (creatureTarget->IsPet())
3332 return;
3333
3334 if (!unitCaster->IsClass(CLASS_HUNTER, CLASS_CONTEXT_PET))
3335 return;
3336
3337 // cast finish successfully
3338 //SendChannelUpdate(0);
3339 finish();
3340
3341 Pet* pet = unitCaster->CreateTamedPetFrom(creatureTarget, m_spellInfo->Id);
3342 if (!pet) // in very specific state like near world end/etc.
3343 return;
3344
3345 // "kill" original creature
3346 creatureTarget->DespawnOrUnsummon();
3347
3348 uint8 level = (creatureTarget->GetLevel() < (unitCaster->GetLevel() - 5)) ? (unitCaster->GetLevel() - 5) : creatureTarget->GetLevel();
3349
3350 // prepare visual effect for levelup
3351 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);
3352
3353 // add to world
3354 pet->GetMap()->AddToMap(pet->ToCreature(), true);
3355
3356 // visual effect for levelup
3357 pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);
3358
3359 // caster have pet now
3360 unitCaster->SetMinion(pet, true);
3361
3362 pet->InitTalentForLevel();
3363
3364 if (unitCaster->IsPlayer())
3365 {
3367 unitCaster->ToPlayer()->PetSpellInitialize();
3368 }
3369}
@ 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)
3513{
3514 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3515 if (!unitCaster)
3516 return;
3517
3519 return;
3520
3521 if (!unitTarget)
3522 return;
3523
3524 // xinef: Hand of Reckoning, cast before checking canhavethreatlist. fixes damage against pets
3525 if (m_spellInfo->Id == 62124 && unitTarget->GetVictim() != unitCaster)
3526 unitCaster->CastSpell(unitTarget, 67485, true);
3527
3529 {
3531 return;
3532 }
3533
3535 if (mgr.GetCurrentVictim() == unitCaster)
3536 {
3538 return;
3539 }
3540
3541 if (!mgr.IsThreatListEmpty())
3542 mgr.MatchUnitThreatToHighestThreat(unitCaster);
3543}
Definition ThreatManager.h:90
Unit * GetCurrentVictim()
Definition ThreatManager.cpp:266
bool IsThreatListEmpty(bool includeOffline=false) const
Definition ThreatManager.cpp:289
void MatchUnitThreatToHighestThreat(Unit *target)
Definition ThreatManager.cpp:532
bool CanHaveThreatList(bool skipAliveCheck=false) const
Definition Unit.cpp:11249

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

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)
3890{
3891 Unit* unitCaster = GetUnitCasterForEffectHandlers();
3892 if (!unitCaster)
3893 return;
3894
3896 return;
3897
3898 if (!unitTarget || !unitTarget->IsAlive() || !unitCaster->IsAlive())
3899 return;
3900
3901 // xinef: skip if target cannot have threat list or caster is friendly (ghoul leap)
3902 if (!unitTarget->CanHaveThreatList() || unitCaster->IsFriendlyTo(unitTarget))
3903 return;
3904
3905 // SPELL_EFFECT_THREAT adds flat threat that should not be modified by threat reduction
3906 unitTarget->GetThreatMgr().AddThreat(unitCaster, float(damage), m_spellInfo, true);
3907}
void AddThreat(Unit *target, float amount, SpellInfo const *spell=nullptr, bool ignoreModifiers=false, bool ignoreRedirects=false)
== AFFECT MY THREAT LIST ==
Definition ThreatManager.cpp:410

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)
6217{
6218 Unit* unitCaster = m_caster->ToUnit();
6219 if (!unitCaster)
6220 return;
6221
6223 return;
6224
6225 if (unitCaster->IsPlayer())
6226 {
6227 if (Aura* aur = unitCaster->GetAura(49152))
6228 aur->RecalculateAmountOfEffects();
6229 else
6230 unitCaster->CastSpell(unitTarget, 49152, true); // damage reduction
6231
6232 unitCaster->ToPlayer()->SetCanTitanGrip(true);
6233 }
6234}
void SetCanTitanGrip(bool value)
Definition Player.cpp:13530

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)
2994{
2995 Unit* unitCaster = m_caster->ToUnit();
2996 if (!unitCaster)
2997 return;
2998
3000 return;
3001
3002 if (!unitCaster->IsPlayer())
3003 return;
3004 // uint32 skillid = m_spellInfo->Effects[i].MiscValue;
3005 // uint16 skillmax = unitTarget->ToPlayer()->(skillid);
3006 // unitCaster->ToPlayer()->SetSkill(skillid, skillval?skillval:1, skillmax+75);
3007}

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

◆ EffectTransmitted()

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

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

◆ EffectTriggerMissileSpell()

void Spell::EffectTriggerMissileSpell ( SpellEffIndex  effIndex)
985{
988 return;
989
990 Unit* unitCaster = GetUnitCasterForEffectHandlers();
991
992 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
993
994 // normal case
995 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
996 if (!spellInfo)
997 {
998 LOG_DEBUG("spells.aura", "Spell::EffectTriggerMissileSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
999 return;
1000 }
1001
1002 SpellCastTargets targets;
1004 {
1005 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
1006 return;
1007 targets.SetUnitTarget(unitTarget);
1008 }
1009 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT)
1010 {
1011 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
1012 return;
1013
1015 targets.SetDst(m_targets);
1016
1017 if (Unit* unit = m_caster->ToUnit())
1018 targets.SetUnitTarget(unit);
1019 else if (GameObject* go = m_caster->ToGameObject())
1020 targets.SetGOTarget(go);
1021 }
1022
1024 // set basepoints for trigger with value effect
1026 {
1027 // maybe need to set value only when basepoints == 0?
1028 args.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
1029 args.AddSpellMod(SPELLVALUE_BASE_POINT1, damage);
1030 args.AddSpellMod(SPELLVALUE_BASE_POINT2, damage);
1031 }
1032
1033 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
1034 if (unitCaster && unitCaster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
1035 {
1036 unitCaster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
1037 }
1038
1039 // original caster guid only for GO cast
1040 m_caster->CastSpell(std::move(targets), spellInfo->Id, args);
1041}
@ 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)
1102{
1104 return;
1105
1106 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
1107 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
1108
1109 if (!spellInfo)
1110 {
1111 LOG_ERROR("spells.effect", "EffectTriggerRitualOfSummoning of spell {}: triggering unknown spell id {}", m_spellInfo->Id, triggered_spell_id);
1112 return;
1113 }
1114
1115 finish();
1116
1117 m_caster->CastSpell(nullptr, spellInfo->Id, true);
1118}

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
809{
812 return;
813
814 Unit* unitCaster = GetUnitCasterForEffectHandlers();
815 uint32 triggered_spell_id = m_spellInfo->Effects[effIndex].TriggerSpell;
816
818 if (m_spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_TRIGGER_SPELL
820 {
821 // special cases
822 switch (triggered_spell_id)
823 {
824 // Mirror Image
825 case 58832:
826 {
827 if (!unitCaster)
828 break;
829
830 // Glyph of Mirror Image
831 if (unitCaster->HasAura(63093))
832 unitCaster->CastSpell(unitCaster, 65047, true); // Mirror Image
833
834 break;
835 }
836 // Demonic Empowerment -- succubus
837 case 54437:
838 {
842
843 // Cast Lesser Invisibility
844 unitTarget->CastSpell(unitTarget, 7870, true);
845 return;
846 }
847 // just skip
848 case 23770: // Sayge's Dark Fortune of *
849 // not exist, common cooldown can be implemented in scripts if need.
850 return;
851 // Brittle Armor - (need add max stack of 24575 Brittle Armor)
852 case 29284:
853 {
854 if (!unitCaster)
855 return;
856
857 // Brittle Armor
858 SpellInfo const* spell = sSpellMgr->GetSpellInfo(24575);
859 if (!spell)
860 return;
861
862 for (uint32 j = 0; j < spell->StackAmount; ++j)
863 unitCaster->CastSpell(unitTarget, spell->Id, true);
864 return;
865 }
866 // Mercurial Shield - (need add max stack of 26464 Mercurial Shield)
867 case 29286:
868 {
869 if (!unitCaster)
870 return;
871
872 // Mercurial Shield
873 SpellInfo const* spell = sSpellMgr->GetSpellInfo(26464);
874 if (!spell)
875 return;
876
877 for (uint32 j = 0; j < spell->StackAmount; ++j)
878 unitCaster->CastSpell(unitTarget, spell->Id, true);
879 return;
880 }
881 // Cloak of Shadows
882 case 35729:
883 {
884 if (!unitCaster)
885 return;
886
889 for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
890 {
891 // remove all harmful spells on you...
892 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
893
894 // Pounce Bleed shouldn't be removed by Cloak of Shadows.
895 if (spell->GetAllEffectsMechanicMask() & (1ULL << MECHANIC_BLEED))
896 return;
897
898 bool dmgClassNone = false;
900 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
901 {
902 if ((iter->second->GetEffectMask() & (1 << i)) &&
903 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_DAMAGE &&
904 spell->Effects[i].ApplyAuraName != SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
905 spell->Effects[i].ApplyAuraName != SPELL_AURA_DUMMY)
906 {
907 dmgClassNone = false;
908 break;
909 }
910 dmgClassNone = true;
911 }
912
913 if ((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC || (spell->GetDispelMask() & dispelMask) || dmgClassNone) &&
914 // ignore positive and passive auras
915 !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive() &&
916 // Xinef: Ignore NPC spells having INVULNERABILITY attribute
918 {
919 unitCaster->RemoveAura(iter);
920 }
921 else
922 ++iter;
923 }
924 return;
925 }
926 }
927 }
928
929 // normal case
930 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(triggered_spell_id);
931 if (!spellInfo)
932 {
933 LOG_DEBUG("spells.aura", "Spell::EffectTriggerSpell spell {} tried to trigger unknown spell {}", m_spellInfo->Id, triggered_spell_id);
934 return;
935 }
936
937 SpellCastTargets targets;
939 {
940 if (!spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex))
941 return;
942 targets.SetUnitTarget(unitTarget);
943 }
944 else //if (effectHandleMode == SPELL_EFFECT_HANDLE_LAUNCH)
945 {
946 if (spellInfo->NeedsToBeTriggeredByCaster(m_spellInfo, effIndex) && (m_spellInfo->Effects[effIndex].GetProvidedTargetMask() & TARGET_FLAG_UNIT_MASK))
947 return;
948
950 targets.SetDst(m_targets);
951
952 if (Unit* target = m_targets.GetUnitTarget())
953 targets.SetUnitTarget(target);
954 else
955 {
956 if (Unit* unit = m_caster->ToUnit())
957 targets.SetUnitTarget(unit);
958 else if (GameObject* go = m_caster->ToGameObject())
959 targets.SetGOTarget(go);
960 }
961 }
962
965 // set basepoints for trigger with value effect
967 {
968 // maybe need to set value only when basepoints == 0?
969 args.AddSpellMod(SPELLVALUE_BASE_POINT0, damage);
970 args.AddSpellMod(SPELLVALUE_BASE_POINT1, damage);
971 args.AddSpellMod(SPELLVALUE_BASE_POINT2, damage);
972 }
973
974 // Remove spell cooldown (not category) if spell triggering spell with cooldown and same category
975 if (unitCaster && unitCaster->IsPlayer() && spellInfo->CategoryRecoveryTime && m_spellInfo->GetCategory() == spellInfo->GetCategory())
976 {
977 unitCaster->ToPlayer()->RemoveSpellCooldown(spellInfo->Id);
978 }
979
980 // original caster guid only for GO cast
981 m_caster->CastSpell(std::move(targets), spellInfo->Id, args);
982}
@ 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)
1397{
1398 Unit* unitCaster = m_caster->ToUnit();
1399 if (!unitCaster)
1400 return;
1401
1403 return;
1404
1405 if (!unitTarget)
1406 return;
1407
1408 Player* player = unitTarget->ToPlayer();
1409 if (!player)
1410 {
1411 return;
1412 }
1413
1414 uint32 spellToUnlearn = m_spellInfo->Effects[effIndex].TriggerSpell;
1415
1416 player->removeSpell(spellToUnlearn, SPEC_MASK_ALL, false);
1417 LOG_DEBUG("spells.aura", "Spell: Player {} has unlearned spell {} from Npc: {}",
1418 player->GetGUID().ToString(), spellToUnlearn, unitCaster->GetGUID().ToString());
1419}
#define SPEC_MASK_ALL
Definition Player.h:178
void removeSpell(uint32 spellId, uint8 removeSpecMask, bool onlyTemporary, bool sendPacket=true)
Definition Player.cpp:3513

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)
2914{
2915 Unit* unitCaster = m_caster->ToUnit();
2916 if (!unitCaster)
2917 return;
2918
2920 return;
2921
2922 if (!unitTarget || unitCaster->IsPlayer())
2923 return;
2924
2925 if (ObjectGuid guid = unitCaster->GetGUID()) // the trainer is the caster
2927}
void SendTalentWipeConfirm(ObjectGuid guid)
Definition Player.cpp:9143

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

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 
)
5319{
5320 InitEffectExecuteData(effIndex);
5321 *m_effectExecuteData[effIndex] << uint32(entry);
5322}
void InitEffectExecuteData(uint8 effIndex)
Definition Spell.cpp:8891

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectCreateItem().

◆ ExecuteLogEffectDestroyItem()

void Spell::ExecuteLogEffectDestroyItem ( uint8  effIndex,
uint32  entry 
)
5325{
5326 InitEffectExecuteData(effIndex);
5327 *m_effectExecuteData[effIndex] << uint32(entry);
5328}

References InitEffectExecuteData(), and m_effectExecuteData.

Referenced by EffectFeedPet().

◆ ExecuteLogEffectDurabilityDamage()

void Spell::ExecuteLogEffectDurabilityDamage ( uint8  effIndex,
Unit *  victim,
int32  itemId,
int32  slot 
)
5305{
5306 InitEffectExecuteData(effIndex);
5307 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5308 *m_effectExecuteData[effIndex] << int32(itemId);
5309 *m_effectExecuteData[effIndex] << int32(slot);
5310}

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

Referenced by EffectDurabilityDamage().

◆ ExecuteLogEffectExtraAttacks()

void Spell::ExecuteLogEffectExtraAttacks ( uint8  effIndex,
Unit *  victim,
uint32  attCount 
)
5291{
5292 InitEffectExecuteData(effIndex);
5293 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5294 *m_effectExecuteData[effIndex] << uint32(attCount);
5295}

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

Referenced by EffectAddExtraAttacks().

◆ ExecuteLogEffectInterruptCast()

void Spell::ExecuteLogEffectInterruptCast ( uint8  effIndex,
Unit *  victim,
uint32  spellId 
)
5298{
5299 InitEffectExecuteData(effIndex);
5300 *m_effectExecuteData[effIndex] << victim->GetPackGUID();
5301 *m_effectExecuteData[effIndex] << uint32(spellId);
5302}

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

Referenced by EffectInterruptCast().

◆ ExecuteLogEffectOpenLock()

void Spell::ExecuteLogEffectOpenLock ( uint8  effIndex,
Object *  obj 
)
5313{
5314 InitEffectExecuteData(effIndex);
5315 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5316}

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

Referenced by EffectOpenLock().

◆ ExecuteLogEffectResurrect()

void Spell::ExecuteLogEffectResurrect ( uint8  effIndex,
Unit *  target 
)
5343{
5344 InitEffectExecuteData(effIndex);
5345 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5346}

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 
)
5282{
5283 InitEffectExecuteData(effIndex);
5284 *m_effectExecuteData[effIndex] << target->GetPackGUID();
5285 *m_effectExecuteData[effIndex] << uint32(powerTaken);
5286 *m_effectExecuteData[effIndex] << uint32(PowerType);
5287 *m_effectExecuteData[effIndex] << float(gainMultiplier);
5288}

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 
)
5337{
5338 InitEffectExecuteData(effIndex);
5339 *m_effectExecuteData[effIndex] << obj->GetPackGUID();
5340}

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

Referenced by EffectDismissPet().

◆ finish()

void Spell::finish ( bool  ok = true)
4636{
4638 return;
4639
4640 // the state must be set even for non-unit casters, otherwise the SpellEvent
4641 // never finishes and re-executes the spell every update tick
4643
4644 // FindMap() check: pending spell events are destroyed after the caster has left the map,
4645 // where resolving a unit-summoned caster's owner through ObjectAccessor would assert
4646 if (Player* modOwner = m_caster->FindMap() ? m_caster->GetSpellModOwner() : nullptr)
4647 modOwner->SetSpellModTakingSpell(this, false);
4648
4649 Unit* unitCaster = m_caster->ToUnit();
4650 if (!unitCaster)
4651 return;
4652
4653 if (m_spellInfo->IsChanneled())
4654 unitCaster->UpdateInterruptMask();
4655
4656 if (unitCaster->HasUnitState(UNIT_STATE_CASTING) && !unitCaster->IsNonMeleeSpellCast(false, false, true))
4658
4659 // Unsummon summon as possessed creatures on spell cancel
4660 if (m_spellInfo->IsChanneled() && unitCaster->IsPlayer())
4661 {
4662 if (Unit* charm = unitCaster->GetCharm())
4663 if (charm->IsCreature()
4664 && charm->ToCreature()->HasUnitTypeMask(UNIT_MASK_PUPPET)
4665 && charm->GetUInt32Value(UNIT_CREATED_BY_SPELL) == m_spellInfo->Id)
4666 ((Puppet*)charm)->UnSummon();
4667 }
4668
4669 if (Creature* creatureCaster = unitCaster->ToCreature())
4670 creatureCaster->ReleaseFocus(this);
4671
4672 if (ok)
4673 {
4675 unitCaster->ToPlayer()->RemoveSpellCooldown(m_spellInfo->Id, true);
4676 }
4677 else
4678 {
4679 if (unitCaster->IsPlayer())
4680 {
4681 // Xinef: Restore spell mods in case of fail cast
4682 unitCaster->ToPlayer()->RestoreSpellMods(this);
4683
4684 // Xinef: Reset cooldown event in case of fail cast
4686 unitCaster->ToPlayer()->SendCooldownEvent(m_spellInfo, 0, 0, false);
4687 }
4688
4689 return;
4690 }
4691
4692 // pussywizard:
4695
4696 if (unitCaster->IsCreature() && unitCaster->ToCreature()->IsSummon())
4697 {
4698 // Unsummon statue
4699 uint32 spell = unitCaster->GetUInt32Value(UNIT_CREATED_BY_SPELL);
4700 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell);
4701 if (spellInfo && spellInfo->SpellIconID == 2056)
4702 {
4703 LOG_DEBUG("spells.aura", "Statue {} is unsummoned in spell {} finish", unitCaster->GetGUID().ToString(), m_spellInfo->Id);
4705 return;
4706 }
4707 }
4708
4709 // potions disabled by client, send event "not in combat" if need
4710 if (unitCaster->IsPlayer() && !m_triggeredByAuraSpell)
4711 unitCaster->ToPlayer()->UpdatePotionCooldown(this);
4712
4713 // Take mods after trigger spell (needed for 14177 to affect 48664)
4714 // mods are taken only on succesfull cast and independantly from targets of the spell
4715 if (Player* player = unitCaster->GetSpellModOwner())
4716 player->RemoveSpellMods(this);
4717
4718 // xinef: clear reactive auras states after spell cast
4721
4722 // Stop Attack for some spells
4724 unitCaster->AttackStop();
4725}
@ 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:2967
void UpdatePotionCooldown(Spell *spell=nullptr)
Definition PlayerUpdates.cpp:1580
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool setCooldown=true)
Definition Player.cpp:11309
Definition TemporarySummon.h:125
virtual void setDeathState(DeathState s, bool despawn=false)
Definition Unit.cpp:11182
void UpdateInterruptMask()
Definition Unit.cpp:892
void ModifyAuraState(AuraStateType flag, bool apply)
Definition Unit.cpp:7414
bool AttackStop()
Force the unit to stop attacking. This will clear UNIT_STATE_MELEE_ATTACKING, Interrupt current spell...
Definition Unit.cpp:7270

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
8887{
8889}
void SendLogExecute()
Definition Spell.cpp:5247

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
9367{
9368 std::stringstream sstr;
9369 sstr << std::boolalpha
9370 << "Id: " << GetSpellInfo()->Id << " OriginalCaster: " << m_originalCasterGUID.ToString()
9371 << " State: " << getState();
9372 return sstr.str();
9373}

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

◆ GetDelayMoment()

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

References m_delayMoment.

Referenced by SpellEvent::Execute().

◆ GetDelayStart()

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

References m_delayStart.

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

◆ GetDelayTrajectory()

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

References m_delayTrajectory.

◆ GetGameObjectCaster()

GameObject * Spell::GetGameObjectCaster ( ) const
8221{
8222 if (GameObject* gameObject = m_caster->ToGameObject())
8223 return gameObject;
8224
8227
8228 // spells cast for a GameObject through a summoned world trigger
8230 if (Unit* unitCaster = m_caster->ToUnit())
8231 if (TempSummon* tempSummon = unitCaster->ToTempSummon())
8232 return tempSummon->GetSummonerGameObject();
8233
8234 return nullptr;
8235}
bool IsGameObject() const
Definition ObjectGuid.h:175

References Object::GetEntry(), Map::GetGameObject(), WorldObject::GetMap(), ObjectGuid::IsGameObject(), m_caster, m_originalCasterGUID, Object::ToGameObject(), Unit::ToTempSummon(), Object::ToUnit(), and WORLD_TRIGGER.

Referenced by CheckCast(), and CheckEffectTarget().

◆ GetLOSCollisionHeight()

std::optional< float > Spell::GetLOSCollisionHeight ( ) const
8238{
8239 // A GameObject has no collision height, so a line of sight check from it starts on the
8240 // floor and aims at the target's feet, which a WMO floor (dungeons) blocks. Measure an
8241 // owned GameObject's casts at its owner's height, as the trap's own target search does.
8242 if (GameObject const* gameObject = m_caster->ToGameObject())
8243 if (Unit const* owner = gameObject->GetOwner())
8244 return owner->GetCollisionHeight();
8245
8246 return { };
8247}

References WorldObject::GetCollisionHeight(), Unit::GetOwner(), m_caster, and Object::ToGameObject().

Referenced by CheckCast(), and CheckEffectTarget().

◆ GetOriginalCaster()

Unit * Spell::GetOriginalCaster ( ) const
inline

◆ GetOriginalTarget()

Unit * Spell::GetOriginalTarget ( ) const
8216{
8218}
ObjectGuid m_originalTargetGUID
Definition Spell.h:637

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

Referenced by _handle_finish_phase().

◆ GetPowerCost()

int32 Spell::GetPowerCost ( ) const
inline
602{ 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
620{ return m_spellSchoolMask; }

References m_spellSchoolMask.

Referenced by Unit::IsImmunedToSpell().

◆ GetSpellValue()

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

References _triggeredCastFlags.

◆ GetUniqueTargetInfo()

◆ GetUnitCasterForEffectHandlers()

◆ handle_delayed()

uint64 Spell::handle_delayed ( uint64  t_offset)
4312{
4313 if (!UpdatePointers())
4314 {
4315 // finish the spell if UpdatePointers() returned false, something wrong happened there
4316 finish(false);
4317 return 0;
4318 }
4319
4320 Player* modOwner = m_caster->GetSpellModOwner();
4321 if (modOwner)
4322 modOwner->SetSpellModTakingSpell(this, true);
4323
4324 uint64 next_time = m_delayTrajectory;
4325
4327
4328 if (!m_immediateHandled && m_delayTrajectory <= t_offset)
4329 {
4331 m_immediateHandled = true;
4333 next_time = 0;
4334 }
4335
4336 bool single_missile = (m_targets.HasDst());
4337
4338 // 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)
4339 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4340 {
4341 if (ihit->processed == false)
4342 {
4343 if (single_missile || ihit->timeDelay <= t_offset)
4344 {
4345 ihit->timeDelay = t_offset;
4346 DoAllEffectOnTarget(&(*ihit));
4347 }
4348 else if (next_time == 0 || ihit->timeDelay < next_time)
4349 next_time = ihit->timeDelay;
4350 }
4351 }
4352
4353 // now recheck gameobject targeting correctness
4354 for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
4355 {
4356 if (ighit->processed == false)
4357 {
4358 if (single_missile || ighit->timeDelay <= t_offset)
4359 DoAllEffectOnTarget(&(*ighit));
4360 else if (next_time == 0 || ighit->timeDelay < next_time)
4361 next_time = ighit->timeDelay;
4362 }
4363 }
4364
4366
4367 if (modOwner)
4368 modOwner->SetSpellModTakingSpell(this, false);
4369
4370 // All targets passed - need finish phase
4371 if (next_time == 0)
4372 {
4373 // spell is finished, perform some last features of the spell here
4375
4376 finish(true); // successfully finish spell cast
4377
4378 // return zero, spell is finished now
4379 return 0;
4380 }
4381 else
4382 {
4383 // spell is unfinished, return next execution time
4384 return next_time;
4385 }
4386}
void _handle_finish_phase()
Definition Spell.cpp:4416
void PrepareTargetProcessing()
Definition Spell.cpp:8881
void _handle_immediate_phase()
Definition Spell.cpp:4388
void FinishTargetProcessing()
Definition Spell.cpp:8886

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 ( )
4241{
4242 Unit* unitCaster = m_caster->ToUnit();
4243 // start channeling if applicable
4244 if (m_spellInfo->IsChanneled())
4245 {
4246 int32 duration = m_spellInfo->GetDuration();
4248 duration = -1;
4249
4250 if (duration > 0)
4251 {
4252 // First mod_duration then haste - see Missile Barrage
4253 // Apply duration mod
4254 if (Player* modOwner = m_caster->GetSpellModOwner())
4255 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
4256
4257 // Apply haste mods
4259 duration = int32(duration * unitCaster->GetFloatValue(UNIT_MOD_CAST_SPEED));
4260
4262 if (unitCaster)
4264 m_channeledDuration = duration;
4265 SendChannelStart(duration);
4266 }
4267 else if (duration == -1)
4268 {
4270 if (unitCaster)
4272 SendChannelStart(duration);
4273 }
4274 }
4275
4277
4278 // process immediate effects (items, ground, etc.) also initialize some variables
4280
4281 // Sync persistent area aura duration with hasted channel duration
4284 {
4287 }
4288
4289 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
4290 DoAllEffectOnTarget(&(*ihit));
4291
4292 for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
4293 DoAllEffectOnTarget(&(*ihit));
4294
4296
4297 // spell is finished, perform some last features of the spell here
4299
4300 // Remove used for cast item if need (it can be already nullptr after TakeReagents call
4301 TakeCastItem();
4302
4303 // handle ammo consumption for Hunter's volley spell
4305 TakeAmmo();
4306
4308 finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
4309}
@ DYNOBJ_AURA_TYPE
Definition SpellAuraDefines.h:386
AuraObjectType GetType() const
Definition SpellAuras.cpp:438
void SendChannelStart(uint32 duration)
Definition Spell.cpp:5384
void TakeAmmo()
Definition Spell.cpp:5573
void AddInterruptMask(uint32 mask)
Definition Unit.h:1621

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 
)
5849{
5851 return;
5852
5853 effectHandleMode = mode;
5854 unitTarget = pUnitTarget;
5855 itemTarget = pItemTarget;
5856 gameObjTarget = pGOTarget;
5858
5859 uint8 eff = m_spellInfo->Effects[i].Effect;
5860
5861 LOG_DEBUG("spells.aura", "Spell: {} Effect : {}", m_spellInfo->Id, eff);
5862
5863 // we do not need DamageMultiplier here.
5864 damage = CalculateSpellDamage(i, nullptr);
5865
5866 bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode);
5867
5868 if (!preventDefault && eff < TOTAL_SPELL_EFFECTS)
5869 {
5870 (this->*SpellEffects[eff])((SpellEffIndex)i);
5871 }
5872}
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:9000
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
8620{
8621 Unit* unitCaster = m_caster->ToUnit();
8622 // handle effects with SPELL_EFFECT_HANDLE_LAUNCH mode
8623 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8624 {
8625 // don't do anything for empty effect
8626 if (!m_spellInfo->Effects[i].IsEffect())
8627 continue;
8628
8629 HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH);
8630 }
8631
8632 float multiplier[MAX_SPELL_EFFECTS];
8633 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
8634 if (m_applyMultiplierMask & (1 << i))
8635 multiplier[i] = m_spellInfo->Effects[i].CalcDamageMultiplier(m_originalCaster, this);
8636
8638 if (unitCaster)
8639 {
8641 for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
8642 {
8643 if ((*j)->IsAffectedOnSpell(m_spellInfo))
8644 usesAmmo = false;
8645 }
8646 }
8647
8649
8650 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
8651 {
8652 TargetInfo& target = *ihit;
8653
8654 uint32 mask = target.effectMask;
8655 if (!mask)
8656 continue;
8657
8658 // do not consume ammo anymore for Hunter's volley spell
8660 usesAmmo = false;
8661
8662 if (usesAmmo)
8663 {
8664 bool ammoTaken = false;
8665 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; i++)
8666 {
8667 if (!(mask & 1 << i))
8668 continue;
8669 switch (m_spellInfo->Effects[i].Effect)
8670 {
8676 ammoTaken = true;
8677 TakeAmmo();
8678 }
8679 if (ammoTaken)
8680 break;
8681 }
8682 }
8683
8686 {
8687 Unit* targetUnit = m_caster->GetGUID() == target.targetGUID ? unitCaster : ObjectAccessor::GetUnit(*m_caster, target.targetGUID);
8688 if (targetUnit && !m_originalCaster->IsFriendlyTo(targetUnit) && (!m_spellInfo->IsPositive() || m_spellInfo->HasEffect(SPELL_EFFECT_DISPEL)) && (m_spellInfo->HasInitialAggro() || targetUnit->IsEngaged()))
8689 m_originalCaster->SetInCombatWith(targetUnit, true);
8690 }
8691
8692 DoAllEffectOnLaunchTarget(target, multiplier);
8693 }
8694
8696}
@ 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:8698

References DoAllEffectOnLaunchTarget(), TargetInfo::effectMask, SpellInfo::Effects, FinishTargetProcessing(), Unit::GetAuraEffectsByType(), Object::GetGUID(), ObjectAccessor::GetUnit(), HandleEffects(), SpellInfo::HasAttribute(), SpellInfo::HasEffect(), SpellInfo::HasInitialAggro(), HasTriggeredCastFlag(), 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, Object::ToUnit(), and TRIGGERED_DONT_ENTER_COMBAT.

Referenced by _cast().

◆ HandleThreatSpells()

void Spell::HandleThreatSpells ( )
5792{
5793 if (m_UniqueTargetInfo.empty())
5794 return;
5795
5797 return;
5798
5800 if (!unitCaster)
5801 return;
5802
5803 float threat = 0.0f;
5804 if (SpellThreatEntry const* threatEntry = sSpellMgr->GetSpellThreatEntry(m_spellInfo->Id))
5805 {
5806 if (threatEntry->apPctMod != 0.0f)
5807 threat += threatEntry->apPctMod * unitCaster->GetTotalAttackPowerValue(BASE_ATTACK);
5808
5809 threat += threatEntry->flatMod;
5810 }
5812 threat += m_spellInfo->SpellLevel;
5813
5814 // past this point only multiplicative effects occur
5815 if (threat == 0.0f)
5816 return;
5817
5818 // 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
5819 threat /= m_UniqueTargetInfo.size();
5820
5821 for (auto& ihit : m_UniqueTargetInfo)
5822 {
5823 float threatToAdd = threat;
5824 if (ihit.missCondition != SPELL_MISS_NONE)
5825 threatToAdd = 0.0f;
5826
5827 Unit* target = ObjectAccessor::GetUnit(*unitCaster, ihit.targetGUID);
5828 if (!target)
5829 continue;
5830
5831 // positive spells distribute threat among all units that are in combat with target, like healing
5833 target->GetThreatMgr().ForwardThreatForAssistingMe(unitCaster, threatToAdd, m_spellInfo);
5834 // for negative spells threat gets distributed among affected targets
5835 // ignoreModifiers=true because flat SpellThreatEntry threat should not have modifiers applied twice
5836 else
5837 {
5838 if (!target->CanHaveThreatList())
5839 continue;
5840 if (IsFromPreDeathAura() && !target->IsEngagedBy(unitCaster))
5841 continue;
5842 target->GetThreatMgr().AddThreat(unitCaster, threatToAdd, m_spellInfo, true);
5843 }
5844 }
5845 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()));
5846}
@ SPELL_ATTR0_CU_NO_INITIAL_THREAT
Definition SpellInfo.h:181
bool _IsPositiveSpell() const
Definition SpellInfo.cpp:3278
bool IsEngagedBy(Unit const *who) const
Definition Unit.h:946
Definition SpellMgr.h:377

References SpellInfo::_IsPositiveSpell(), ThreatManager::AddThreat(), BASE_ATTACK, Unit::CanHaveThreatList(), ThreatManager::ForwardThreatForAssistingMe(), Unit::GetThreatMgr(), Unit::GetTotalAttackPowerValue(), ObjectAccessor::GetUnit(), SpellInfo::HasAttribute(), SpellInfo::Id, Unit::IsEngagedBy(), IsFromPreDeathAura(), 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
9252{
9253 Unit* unitCaster = m_caster->ToUnit();
9254 if (!unitCaster)
9255 return false;
9256
9257 // Only player or controlled units have global cooldown
9258 if (unitCaster->GetCharmInfo())
9260 else if (unitCaster->IsPlayer())
9262 else
9263 return false;
9264}

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
8482{
8483 for (std::list<TargetInfo>::const_iterator itr = m_UniqueTargetInfo.begin(); itr != m_UniqueTargetInfo.end(); ++itr)
8484 if (itr->effectMask & (1 << effect))
8485 return true;
8486
8487 for (std::list<GOTargetInfo>::const_iterator itr = m_UniqueGOTargetInfo.begin(); itr != m_UniqueGOTargetInfo.end(); ++itr)
8488 if (itr->effectMask & (1 << effect))
8489 return true;
8490
8491 for (std::list<ItemTargetInfo>::const_iterator itr = m_UniqueItemInfo.begin(); itr != m_UniqueItemInfo.end(); ++itr)
8492 if (itr->effectMask & (1 << effect))
8493 return true;
8494
8495 return false;
8496}

References m_UniqueGOTargetInfo, m_UniqueItemInfo, and m_UniqueTargetInfo.

◆ InitEffectExecuteData()

void Spell::InitEffectExecuteData ( uint8  effIndex)
protected
8892{
8893 ASSERT(effIndex < MAX_SPELL_EFFECTS);
8894 if (!m_effectExecuteData[effIndex])
8895 {
8896 m_effectExecuteData[effIndex] = new ByteBuffer(0x20);
8897 // first dword - target counter
8898 *m_effectExecuteData[effIndex] << uint32(1);
8899 }
8900 else
8901 {
8902 // increase target counter by one
8903 uint32 count = (*m_effectExecuteData[effIndex]).read<uint32>(0);
8904 (*m_effectExecuteData[effIndex]).put<uint32>(0, ++count);
8905 }
8906}

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?
8456{
8459 {
8460 return false;
8461 }
8462
8464 {
8465 return false;
8466 }
8467
8468 return true;
8469}
@ 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
658 {
659 if (m_delayAtDamageCount >= 2)
660 return true;
661
663 return false;
664 }

References m_delayAtDamageCount.

Referenced by Delayed(), and DelayedChannel().

◆ IsDeletable()

◆ IsFromPreDeathAura()

bool Spell::IsFromPreDeathAura ( ) const
inline
571{ return _fromPreDeathAura; }
bool _fromPreDeathAura
Definition Spell.h:801

References _fromPreDeathAura.

Referenced by _cast(), Unit::DealDamage(), DoAllEffectOnTarget(), and HandleThreatSpells().

◆ IsIgnoringCooldowns()

bool Spell::IsIgnoringCooldowns ( ) const

◆ IsInterruptable()

bool Spell::IsInterruptable ( ) const
inline
578{ 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
8612{
8613 if (target->IsAlive())
8615
8617}
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 ( )
8915{
8916 if (_scriptsLoaded)
8917 return;
8918 _scriptsLoaded = true;
8919 sScriptMgr->CreateSpellScripts(m_spellInfo->Id, m_loadedScripts);
8920 for (std::list<SpellScript*>::iterator itr = m_loadedScripts.begin(); itr != m_loadedScripts.end();)
8921 {
8922 if (!(*itr)->_Load(this))
8923 {
8924 std::list<SpellScript*>::iterator bitr = itr;
8925 ++itr;
8926 delete (*bitr);
8927 m_loadedScripts.erase(bitr);
8928 continue;
8929 }
8930 LOG_DEBUG("spells.aura", "Spell::LoadScripts: Script `{}` for spell `{}` is loaded now", (*itr)->_GetScriptName()->c_str(), m_spellInfo->Id);
8931 (*itr)->Register();
8932 ++itr;
8933 }
8934}

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 ( )
9336{
9337 Unit* unitCaster = m_caster->ToUnit();
9338 if (!unitCaster || !unitCaster->IsInWorld())
9339 return;
9340
9341 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(24390);
9342
9343 // Make sure the player is sending a valid GO target and lock ID. SPELL_EFFECT_OPEN_LOCK
9344 // can succeed with a lockId of 0
9345 if (m_spellInfo->Id == 21651)
9346 {
9347 if (GameObject* go = m_targets.GetGOTarget())
9348 {
9349 LockEntry const* lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->GetLockId());
9350 if (lockInfo && lockInfo->Index[1] == LOCKTYPE_SLOW_OPEN)
9351 {
9352 Spell* visual = new Spell(unitCaster, spellInfo, TRIGGERED_NONE);
9353 visual->prepare(&m_targets);
9354 }
9355 }
9356 }
9357}
@ 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 &&

3566{
3567 Unit* unitCaster = m_caster->ToUnit();
3568 if (m_CastItem)
3569 {
3571 }
3572 else
3573 {
3575 }
3576
3577 InitExplicitTargets(*targets);
3578
3579 if (!sScriptMgr->CanPrepare(this, targets, triggeredByAura))
3580 {
3581 finish(false);
3582 return SPELL_FAILED_UNKNOWN;
3583 }
3584
3585 // Fill aura scaling information
3586 if (sScriptMgr->CanScalingEverything(this) || (unitCaster && unitCaster->IsTotem()) || (unitCaster && unitCaster->IsControlledByPlayer() && !m_spellInfo->IsPassive() && m_spellInfo->SpellLevel && !m_spellInfo->IsChanneled() && !HasTriggeredCastFlag(TRIGGERED_IGNORE_AURA_SCALING)))
3587 {
3588 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3589 {
3590 if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_APPLY_AURA ||
3593 {
3594 // Change aura with ranks only if basepoints are taken from spellInfo and aura is positive
3596 {
3597 m_auraScaleMask |= (1 << i);
3598 if (m_spellValue->EffectBasePoints[i] != m_spellInfo->Effects[i].BasePoints)
3599 {
3600 m_auraScaleMask = 0;
3601 break;
3602 }
3603 }
3604 }
3605 }
3606 }
3607
3609
3610 if (triggeredByAura)
3611 {
3612 m_triggeredByAuraSpell.Init(triggeredByAura);
3613
3614 // e.g. Seed of Corruption detonating on an enemy after its warlock died and got resurrected
3615 if (triggeredByAura->GetCasterGUID() == m_originalCasterGUID &&
3616 triggeredByAura->GetBase()->HasCasterDiedSinceApply(m_originalCaster))
3617 _fromPreDeathAura = true;
3618 }
3619
3620 // e.g. Darkmoon Card: Death proccing off a bleed tick the druid applied before dying
3622 _fromPreDeathAura = true;
3623
3626
3627 // create and add update event for this spell
3628 _spellEvent = new SpellEvent(this);
3630
3631 if (sDisableMgr->IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, unitCaster))
3632 {
3634 finish(false);
3636 }
3637
3638 //Prevent casting at cast another spell (ServerSide check)
3639 if (!HasTriggeredCastFlag(TRIGGERED_IGNORE_CAST_IN_PROGRESS) && unitCaster && unitCaster->IsNonMeleeSpellCast(false, true, true, m_spellInfo->Id == 75) && m_cast_count)
3640 {
3642 finish(false);
3644 }
3645
3646 LoadScripts();
3647
3648 OnSpellLaunch();
3649
3651
3652 // Set combo point requirement
3654 m_needComboPoints = false;
3655
3656 SpellCastResult result = CheckCast(true);
3657 if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
3658 {
3659 // Periodic auras should be interrupted when aura triggers a spell which can't be cast
3660 // for example bladestorm aura should be removed on disarm as of patch 3.3.5
3661 // channeled periodic spells should be affected by this (arcane missiles, penance, etc)
3662 // a possible alternative sollution for those would be validating aura target on unit state change
3663 if (unitCaster && unitCaster->IsPlayer() && triggeredByAura && triggeredByAura->IsPeriodic() && !triggeredByAura->GetBase()->IsPassive())
3664 {
3666 triggeredByAura->GetBase()->SetDuration(0);
3667 }
3668
3669 // Allows to cast melee attack spell if result is SPELL_FAILED_OUT_OF_RANGE
3671 {
3672 SendCastResult(result);
3673
3674 finish(false);
3675 return result;
3676 }
3677 }
3678
3679 // Prepare data for triggers
3680 prepareDataForTriggerSystem(triggeredByAura);
3681
3682 // calculate cast time (calculated after first CheckCast check to prevent charge counting for first CheckCast fail)
3684
3685 if (unitCaster && unitCaster->IsPlayer())
3686 if (unitCaster->ToPlayer()->GetCommandStatus(CHEAT_CASTTIME))
3687 m_casttime = 0;
3688
3689 // don't allow channeled spells / spells with cast time to be casted while moving
3690 // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
3691 if ((m_spellInfo->IsChanneled() || m_casttime) && unitCaster && unitCaster->IsPlayer() && unitCaster->isMoving() && m_spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_MOVEMENT && !IsTriggered())
3692 {
3693 // 1. Has casttime, 2. Or doesn't have flag to allow action during channel
3695 {
3697 finish(false);
3698 return SPELL_FAILED_MOVING;
3699 }
3700 }
3701
3702 // xinef: if spell have nearby target entry only, do not allow to cast if no targets are found
3703 if (m_CastItem)
3704 {
3705 bool selectTargets = false;
3706 bool nearbyDest = false;
3707
3708 for (uint8 i = EFFECT_0; i < MAX_SPELL_EFFECTS; ++i)
3709 {
3710 if (!m_spellInfo->Effects[i].IsEffect())
3711 continue;
3712
3713 if (m_spellInfo->Effects[i].TargetA.GetSelectionCategory() != TARGET_SELECT_CATEGORY_NEARBY || m_spellInfo->Effects[i].TargetA.GetCheckType() != TARGET_CHECK_ENTRY)
3714 {
3715 selectTargets = false;
3716 break;
3717 }
3718
3719 if (m_spellInfo->Effects[i].TargetA.GetObjectType() == TARGET_OBJECT_TYPE_DEST)
3720 {
3721 nearbyDest = true;
3722 }
3723
3724 // xinef: by default set it to false, and to true if any valid target is found
3725 selectTargets = true;
3726 }
3727
3728 if (selectTargets)
3729 {
3731 _spellTargetsSelected = true;
3732 bool spellFailed = false;
3733
3734 if (m_UniqueTargetInfo.empty() && m_UniqueGOTargetInfo.empty())
3735 {
3736 // no valid nearby target unit or game object found; check if nearby destination type
3737 if (nearbyDest)
3738 {
3739 if (!m_targets.HasDst())
3740 {
3741 // no valid target destination
3742 spellFailed = true;
3743 }
3744 }
3745 else
3746 {
3747 spellFailed = true;
3748 }
3749 }
3750
3751 if (spellFailed)
3752 {
3754 finish(false);
3756 }
3757 }
3758 }
3759
3760 // set timer base at cast time
3761 ReSetTimer();
3762
3763 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());
3764
3765 // prevent exploit that allows to cast spell while sitting
3768
3769 //Containers for channeled spells have to be set
3770 //TODO:Apply this to all casted spells if needed
3771 // Why check duration? 29350: channelled triggers channelled
3773 cast(true);
3774 else
3775 {
3776 // stealth must be removed at cast starting (at show channel bar)
3777 // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
3779 {
3780 // Farsight spells exception
3781 uint32 exceptSpellId = 0;
3783 {
3784 exceptSpellId = m_spellInfo->Id;
3785 }
3786
3787 unitCaster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CAST, exceptSpellId, m_spellInfo->Id == 75);
3789 }
3790
3791 if (unitCaster)
3792 unitCaster->SetCurrentCastedSpell(this);
3794
3795 // Call CreatureAI hook OnSpellStart for spells with cast time or channeled spells
3796 if (m_casttime > 0 || m_spellInfo->IsChanneled())
3797 if (Creature* caster = unitCaster ? unitCaster->ToCreature() : nullptr)
3798 if (caster->IsAIEnabled)
3799 caster->AI()->OnSpellStart(GetSpellInfo());
3800
3801 // set target for proper facing
3802 // channels that allow actions must not lock target and facing, the creature keeps fighting while channeling
3804 {
3805 if (unitCaster && unitCaster->IsCreature() && !unitCaster->ToCreature()->IsInEvadeMode() &&
3807 {
3808 // Xinef: Creature should focus to cast target if there is explicit target or self if casting positive spell
3809 // Xinef: Creature should not rotate when casting spell... based on halion behavior
3810 unitCaster->ToCreature()->FocusTarget(this, m_targets.GetObjectTarget() != nullptr ? m_targets.GetObjectTarget() : unitCaster);
3811 }
3812 }
3813
3814 //item: first cast may destroy item and second cast causes crash
3815 // xinef: removed !m_spellInfo->StartRecoveryTime
3816 // second los check failed in events
3817 // xinef: removed itemguid check, currently there is no such item in database
3819 cast(true);
3820
3823 }
3824
3825 sScriptMgr->OnSpellPrepare(this, unitCaster, m_spellInfo);
3826
3827 return SPELL_CAST_OK;
3828}
@ 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:3624
Definition Spell.cpp:556
bool IsActionAllowedChannel() const
Definition SpellInfo.cpp:1306
int32 GetMaxDuration() const
Definition SpellInfo.cpp:2785
uint32 Attributes
Definition SpellInfo.h:348
bool IsBreakingStealth() const
Definition SpellInfo.cpp:1316
void LoadScripts()
Definition Spell.cpp:8914
void cast(bool skipCheck=false)
Definition Spell.cpp:3915
void prepareDataForTriggerSystem(AuraEffect const *triggeredByAura)
Definition Spell.cpp:2301
void SendSpellStart()
Definition Spell.cpp:4888
void TriggerGlobalCooldown()
Definition Spell.cpp:9266
void OnSpellLaunch()
Definition Spell.cpp:9335
CurrentSpellTypes GetCurrentContainer() const
Definition Spell.cpp:8300
void ReSetTimer()
Definition Spell.h:565
void InitExplicitTargets(SpellCastTargets const &targets)
Definition Spell.cpp:766
void SetCurrentCastedSpell(Spell *pSpell)
Definition Unit.cpp:3900
bool IsSitState() const
Definition Unit.cpp:12777
bool IsInPreDeathAuraTick() const
Definition Unit.h:1809
void Init(AuraEffect const *aurEff)
Definition Spell.cpp:9359

References _fromPreDeathAura, _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(), AuraEffect::GetCasterGUID(), Player::GetCommandStatus(), GetCurrentContainer(), Object::GetEntry(), Object::GetGUID(), SpellInfo::GetMaxDuration(), SpellCastTargets::GetObjectTarget(), GetSpellInfo(), SpellCastTargets::GetTargetMask(), Aura::HasCasterDiedSinceApply(), 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::IsInPreDeathAuraTick(), 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_originalCasterGUID, 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_DONT_ENTER_COMBAT, 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
8995{
8996 for (std::list<SpellScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr)
8997 (*scritr)->_InitHit();
8998}

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
9169{
9170 Unit* unitCaster = m_caster->ToUnit();
9171 if (!unitCaster)
9172 return;
9173
9176 {
9177 SpellInfo const* excludeCasterSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeCasterAuraSpell);
9178 if (excludeCasterSpellInfo && !excludeCasterSpellInfo->IsPositive())
9180 SpellInfo const* excludeTargetSpellInfo = sSpellMgr->GetSpellInfo(m_spellInfo->ExcludeTargetAuraSpell);
9181 if (excludeTargetSpellInfo && !excludeTargetSpellInfo->IsPositive())
9183 }
9184
9187 {
9189 {
9190 if (m_spellInfo->SpellFamilyFlags[1] & 0x40000000)
9191 {
9193 for(Unit::AuraEffectList::const_iterator itr = mVindication.begin(); itr != mVindication.end(); ++itr)
9194 {
9195 if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 26017 )
9196 {
9197 m_preCastSpell = 26017;
9198 break;
9199 }
9200 else if ((*itr)->GetSpellInfo()->Effects[EFFECT_0].TriggerSpell == 67 )
9201 m_preCastSpell = 67;
9202 }
9203 }
9204 break;
9205 }
9206 case SPELLFAMILY_DRUID:
9207 {
9208 // Faerie Fire (Feral)
9209 if (m_spellInfo->Id == 16857 && (unitCaster->GetShapeshiftForm() == FORM_BEAR || unitCaster->GetShapeshiftForm() == FORM_DIREBEAR))
9210 m_preCastSpell = 60089;
9211
9212 break;
9213 }
9214 }
9215
9216 // handle SPELL_AURA_ADD_TARGET_TRIGGER auras:
9217 // save auras which were present on spell caster on cast, to prevent triggered auras from affecting caster
9218 // and to correctly calculate proc chance when combopoints are present
9219 Unit::AuraEffectList const& targetTriggers = unitCaster->GetAuraEffectsByType(SPELL_AURA_ADD_TARGET_TRIGGER);
9220 for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
9221 {
9222 if (!(*i)->IsAffectedOnSpell(m_spellInfo))
9223 continue;
9224 SpellInfo const* auraSpellInfo = (*i)->GetSpellInfo();
9225 uint32 auraSpellIdx = (*i)->GetEffIndex();
9226 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(auraSpellInfo->Effects[auraSpellIdx].TriggerSpell))
9227 {
9228 // calculate the chance using spell base amount, because aura amount is not updated on combo-points change
9229 // this possibly needs fixing
9230 int32 auraBaseAmount = (*i)->GetBaseAmount();
9231 // proc chance is stored in effect amount
9232 int32 chance = unitCaster->CalculateSpellDamage(nullptr, auraSpellInfo, auraSpellIdx, &auraBaseAmount);
9233 // build trigger and add to the list
9234 HitTriggerSpell spellTriggerInfo;
9235 spellTriggerInfo.triggeredSpell = spellInfo;
9236 spellTriggerInfo.triggeredByAura = auraSpellInfo;
9237 spellTriggerInfo.triggeredByEffIdx = (*i)->GetEffIndex();
9238 spellTriggerInfo.chance = chance * (*i)->GetBase()->GetStackAmount();
9239 m_hitTriggerSpells.push_back(spellTriggerInfo);
9240 }
9241 }
9242}
@ 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:580

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:9129
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:2528
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:2590
void CallScriptObjectTargetSelectHandlers(WorldObject *&target, SpellEffIndex effIndex, SpellImplicitTargetInfo const &targetType)
Definition Spell.cpp:9101

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:4055
Unit * GetMeleeHitRedirectTarget(Unit *victim, SpellInfo const *spellInfo)
Definition Object.cpp:4064

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:9087
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:575
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:9115
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:16862
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:2759
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:388

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

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

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

References SpellDestination::_position, SpellImplicitTargetInfo::CalcDirectionAngle(), CallScriptDestinationTargetSelectHandlers(), CheckDst(), SpellInfo::Effects, SpellCastTargets::GetDst(), SpellImplicitTargetInfo::GetTarget(), m_caster, m_spellInfo, m_targets, SpellCastTargets::ModDst(), WorldObject::MovePositionToFirstCollision(), 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:1949
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:2619
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
4833{
4834 if (result == SPELL_CAST_OK)
4835 return;
4836
4837 WorldPacket data(SMSG_CAST_FAILED, 1 + 4 + 1);
4838 WriteCastResultInfo(data, caster, spellInfo, castCount, result, customError);
4839
4840 caster->SendDirectMessage(&data);
4841}
static void WriteCastResultInfo(WorldPacket &data, Player *caster, SpellInfo const *spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError)
Definition Spell.cpp:4727
@ 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)
4844{
4845 Unit* unitCaster = m_caster->ToUnit();
4846 if (!unitCaster)
4847 return;
4848
4849 if (result == SPELL_CAST_OK)
4850 return;
4851
4852 if (!unitCaster->IsPlayer() || unitCaster->IsCharmed())
4853 return;
4854
4855 if (unitCaster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
4856 return;
4857
4858 // 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
4860 result = SPELL_FAILED_DONT_REPORT;
4861
4863}
@ 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:1327

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)
5385{
5386 Unit* unitCaster = m_caster->ToUnit();
5387 if (!unitCaster)
5388 return;
5389
5390 ObjectGuid channelTarget = m_targets.GetObjectTargetGUID();
5391 if (!channelTarget && !m_spellInfo->NeedsExplicitUnitTarget())
5392 if (m_UniqueTargetInfo.size() + m_UniqueGOTargetInfo.size() == 1) // this is for TARGET_SELECT_CATEGORY_NEARBY
5393 channelTarget = !m_UniqueTargetInfo.empty() ? m_UniqueTargetInfo.front().targetGUID : m_UniqueGOTargetInfo.front().targetGUID;
5394
5395 WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
5396 data << m_caster->GetPackGUID();
5397 data << uint32(m_spellInfo->Id);
5398 data << uint32(duration);
5399
5400 m_caster->SendMessageToSet(&data, true);
5401
5402 if (unitCaster->IsPlayer() && unitCaster->ToPlayer()->NeedSendSpectatorData())
5403 ArenaSpectator::SendCommand_Spell(unitCaster->FindMap(), unitCaster->GetGUID(), "SPE", m_spellInfo->Id, -((int32)duration));
5404
5405 m_timer = duration;
5406 if (channelTarget)
5407 unitCaster->SetGuidValue(UNIT_FIELD_CHANNEL_OBJECT, channelTarget);
5408
5410}
@ 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)
5366{
5367 Unit* unitCaster = m_caster->ToUnit();
5368 if (!unitCaster)
5369 return;
5370
5371 if (time == 0)
5372 {
5374 unitCaster->SetUInt32Value(UNIT_CHANNEL_SPELL, 0);
5375 }
5376
5377 WorldPacket data(MSG_CHANNEL_UPDATE, 8 + 4);
5378 data << m_caster->GetPackGUID();
5379 data << uint32(time);
5380
5381 m_caster->SendMessageToSet(&data, true);
5382}
@ 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)
5349{
5350 WorldPacket data(SMSG_SPELL_FAILURE, (8 + 1 + 4 + 1));
5351 data << m_caster->GetPackGUID();
5352 data << uint8(m_cast_count);
5353 data << uint32(m_spellInfo->Id);
5354 data << uint8(result);
5355 m_caster->SendMessageToSet(&data, true);
5356
5357 data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 1 + 4 + 1));
5358 data << m_caster->GetPackGUID();
5359 data << uint8(m_cast_count);
5360 data << uint32(m_spellInfo->Id);
5361 data << uint8(result);
5362 m_caster->SendMessageToSet(&data, true);
5363}
@ 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 ( )
5248{
5249 WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
5250
5251 data << m_caster->GetPackGUID();
5252
5253 data << uint32(m_spellInfo->Id);
5254
5255 uint8 effCount = 0;
5256 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5257 {
5258 if (m_effectExecuteData[i])
5259 ++effCount;
5260 }
5261
5262 if (!effCount)
5263 return;
5264
5265 data << uint32(effCount);
5266 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
5267 {
5268 if (!m_effectExecuteData[i])
5269 continue;
5270
5271 data << uint32(m_spellInfo->Effects[i].Effect); // spell effect
5272
5273 data.append(*m_effectExecuteData[i]);
5274
5275 delete m_effectExecuteData[i];
5276 m_effectExecuteData[i] = nullptr;
5277 }
5278 m_caster->SendMessageToSet(&data, true);
5279}
@ 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
2124{
2125 Unit* unitCaster = m_caster->ToUnit();
2126 if (!unitCaster)
2127 return;
2128
2129 Player* player = unitCaster->ToPlayer();
2130 if (!player)
2131 return;
2132
2133 if (gameObjTarget)
2134 {
2135 // Players shouldn't be able to loot gameobjects that are currently despawned
2136 if (!gameObjTarget->isSpawned() && !player->IsGameMaster())
2137 {
2138 LOG_ERROR("spells.effect", "Possible hacking attempt: Player {} [{}] tried to loot a gameobject [{}] which is on respawn time without being in GM mode!",
2139 player->GetName(), player->GetGUID().ToString(), gameObjTarget->GetGUID().ToString());
2140 return;
2141 }
2142 // special case, already has GossipHello inside so return and avoid calling twice
2144 {
2145 gameObjTarget->Use(unitCaster);
2146 return;
2147 }
2148
2149 if (sScriptMgr->OnGossipHello(player, gameObjTarget))
2150 return;
2151
2152 if (gameObjTarget->AI()->GossipHello(player, false))
2153 return;
2154
2155 switch (gameObjTarget->GetGoType())
2156 {
2158 gameObjTarget->UseDoorOrButton(0, false, player);
2159 return;
2161 gameObjTarget->UseDoorOrButton(0, false, player);
2162
2163 // Xinef: properly link possible traps
2164 if (uint32 trapEntry = gameObjTarget->GetGOInfo()->button.linkedTrap)
2165 gameObjTarget->TriggeringLinkedGameObject(trapEntry, player);
2166 return;
2170 return;
2171
2173 // triggering linked GO
2175 gameObjTarget->TriggeringLinkedGameObject(trapEntry, unitCaster);
2176 return;
2177
2178 // Don't return, let loots been taken
2179 default:
2180 break;
2181 }
2182 }
2183
2184 // Send loot
2185 player->SendLoot(guid, loottype);
2186}
@ 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:196
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
Definition GameObject.cpp:1500
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::@237::@241 questgiver
struct GameObjectTemplate::@237::@246 spellFocus
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)
4866{
4867 Unit* unitCaster = m_caster->ToUnit();
4868 if (!unitCaster)
4869 return;
4870
4871 if (result == SPELL_CAST_OK)
4872 return;
4873
4874 Unit* owner = unitCaster->GetCharmerOrOwner();
4875 if (!owner)
4876 return;
4877
4878 Player* player = owner->ToPlayer();
4879 if (!player)
4880 return;
4881
4882 WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1);
4884
4885 player->SendDirectMessage(&data);
4886}
@ 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)
5413{
5414 Unit* unitCaster = m_caster->ToUnit();
5415 if (!unitCaster)
5416 return;
5417
5418 // get resurrector name for creature resurrections, otherwise packet will be not accepted
5419 // for player resurrections the name is looked up by guid
5420 std::string const sentName(unitCaster->IsPlayer()
5421 ? ""
5422 : unitCaster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()));
5423
5424 WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + sentName.size() + 1 + 1 + 1 + 4));
5425 data << unitCaster->GetGUID();
5426 data << uint32(sentName.size() + 1);
5427
5428 data << sentName;
5429 data << uint8(0); // null terminator
5430
5431 data << uint8(unitCaster->IsPlayer() ? 0 : 1); // "you'll be afflicted with resurrection sickness"
5432 // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute
5434 data << uint32(0);
5435 target->SendDirectMessage(&data);
5436}
@ 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 ( )
4499{
4500 Unit* unitCaster = m_caster->ToUnit();
4501 if (!unitCaster)
4502 return;
4503
4504 // xinef: properly add creature cooldowns
4505 if (!unitCaster->IsPlayer())
4506 {
4508 {
4509 // xinef: this should be added here
4510 //unitCaster->AddSpellCooldown(m_spellInfo->Id, 0, 0);
4511
4512 // xinef: this adds cooldowns to vehicle spells which misses them client-side (when we overwrote dbc info in eg.)
4514 if (Player* player = unitCaster->GetCharmerOrOwnerPlayerOrPlayerItself())
4515 {
4516 WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4);
4517 data << unitCaster->GetGUID();
4519 data << uint32(m_spellInfo->Id);
4521 player->SendDirectMessage(&data);
4522 }
4523 }
4524 return;
4525 }
4526
4527 Player* _player = unitCaster->ToPlayer();
4528
4529 // mana/health/etc potions, disabled by client (until combat out as declarate)
4531 {
4532 // need in some way provided data for Spell::finish SendCooldownEvent
4533 _player->SetLastPotionId(m_CastItem->GetEntry());
4534 return;
4535 }
4536
4537 // have infinity cooldown but set at aura apply
4538 // do not set cooldown for triggered spells (needed by reincarnation)
4543 return;
4544
4546}
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition Unit.h:639
void SetLastPotionId(uint32 item_id)
Definition Player.h:1841
void AddSpellAndCategoryCooldowns(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool infinityCooldown=false)
Definition Player.cpp:11111
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 ( )
4970{
4971 Unit* unitCaster = m_caster->ToUnit();
4972 // not send invisible spell casting
4973 if (!IsNeedSendToClient(true))
4974 return;
4975
4976 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_GO id={}", m_spellInfo->Id);
4977
4978 uint32 castFlags = CAST_FLAG_UNKNOWN_9;
4979
4980 // triggered spells with spell visual != 0
4982 castFlags |= CAST_FLAG_PENDING;
4983
4985 castFlags |= CAST_FLAG_PROJECTILE; // arrows/bullets visual
4986
4987 // should only be sent to self, but the current messaging doesn't make that possible
4988 if (unitCaster && (unitCaster->IsPlayer() || unitCaster->IsPet()))
4989 {
4990 switch (m_spellInfo->PowerType)
4991 {
4992 case POWER_HEALTH:
4993 break;
4994 case POWER_RUNE:
4995 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4996 break;
4997 default:
4998 if (m_powerCost != 0)
4999 {
5000 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
5001 }
5002 break;
5003 }
5004 }
5005
5006 if (unitCaster && (unitCaster->IsPlayer())
5010 {
5011 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
5012 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
5013 }
5014
5016 castFlags |= CAST_FLAG_RUNE_LIST; // rune cooldowns list
5017
5018 if (m_targets.HasTraj())
5019 castFlags |= CAST_FLAG_ADJUST_MISSILE;
5020
5022 castFlags |= CAST_FLAG_NO_GCD;
5023
5024 PackedGuid realCasterGUID = m_caster->GetPackGUID();
5025 if (TempSummon const* tempSummon = unitCaster ? unitCaster->ToTempSummon() : nullptr)
5026 {
5027 if (tempSummon->GetEntry() == WORLD_TRIGGER)
5028 {
5029 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
5030 {
5031 realCasterGUID = casterGameobject->GetPackGUID();
5032 }
5033 }
5034 }
5035
5036 WorldPacket data(SMSG_SPELL_GO, 150); // guess size
5037
5038 if (m_CastItem)
5039 data << m_CastItem->GetPackGUID();
5040 else
5041 data << realCasterGUID;
5042
5043 data << realCasterGUID;
5044 data << uint8(m_cast_count); // pending spell cast?
5045 data << uint32(m_spellInfo->Id); // spellId
5046 data << uint32(castFlags); // cast flags
5047 data << uint32(GameTime::GetGameTimeMS().count()); // timestamp
5048
5049 WriteSpellGoTargets(&data);
5050
5051 m_targets.Write(data);
5052
5053 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
5054 data << uint32(unitCaster ? unitCaster->GetPower((Powers)m_spellInfo->PowerType) : 0);
5055
5056 if (castFlags & CAST_FLAG_RUNE_LIST) // rune cooldowns list
5057 {
5058 //TODO: There is a crash caused by a spell with CAST_FLAG_RUNE_LIST casted by a creature
5059 //The creature is the mover of a player, so HandleCastSpellOpcode uses it as the caster
5060 if (Player* player = unitCaster ? unitCaster->ToPlayer() : nullptr)
5061 {
5062 uint8 runeMaskInitial = m_runesState;
5063 uint8 runeMaskAfterCast = player->GetRunesState();
5064 data << uint8(runeMaskInitial); // runes state before
5065 data << uint8(runeMaskAfterCast); // runes state after
5066 for (uint8 i = 0; i < MAX_RUNES; ++i)
5067 {
5068 uint8 mask = (1 << i);
5069 if (mask & runeMaskInitial && !(mask & runeMaskAfterCast)) // usable before andon cooldown now...
5070 {
5071 // float casts ensure the division is performed on floats as we need float result
5072 float baseCd = float(player->GetRuneBaseCooldown(i, true));
5073 data << uint8((baseCd - float(player->GetRuneCooldown(i))) / baseCd * 255); // rune cooldown passed
5074 }
5075 }
5076 }
5077 }
5078 if (castFlags & CAST_FLAG_ADJUST_MISSILE)
5079 {
5080 data << m_targets.GetElevation();
5082 }
5083
5084 if (castFlags & CAST_FLAG_PROJECTILE)
5085 WriteAmmoToPacket(&data);
5086
5087 if (castFlags & CAST_FLAG_VISUAL_CHAIN)
5088 {
5089 data << uint32(0);
5090 data << uint32(0);
5091 }
5092
5094 {
5095 data << uint8(0);
5096 }
5097
5098 m_caster->SendMessageToSet(&data, true);
5099}
@ 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:5187
void WriteAmmoToPacket(WorldPacket *data)
Definition Spell.cpp:5101
bool IsNeedSendToClient(bool go) const
Definition Spell.cpp:8471
@ 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 ( )
4889{
4890 Unit* unitCaster = m_caster->ToUnit();
4891 if (!IsNeedSendToClient(false))
4892 return;
4893
4894 //LOG_DEBUG("spells.aura", "Sending SMSG_SPELL_START id={}", m_spellInfo->Id);
4895
4896 uint32 castFlags = CAST_FLAG_HAS_TRAJECTORY;
4897
4899 castFlags |= CAST_FLAG_PENDING;
4900
4902 castFlags |= CAST_FLAG_PROJECTILE;
4903
4904 if (unitCaster && (unitCaster->IsPlayer() || unitCaster->IsPet()))
4905 {
4906 switch (m_spellInfo->PowerType)
4907 {
4908 case POWER_HEALTH:
4909 break;
4910 case POWER_RUNE:
4911 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4912 break;
4913 default:
4914 if (m_powerCost != 0)
4915 {
4916 castFlags |= CAST_FLAG_POWER_LEFT_SELF;
4917 }
4918 break;
4919 }
4920 }
4921
4923 castFlags |= CAST_FLAG_NO_GCD; // not needed, but Blizzard sends it
4924
4925 PackedGuid realCasterGUID = m_caster->GetPackGUID();
4926 if (TempSummon const* tempSummon = unitCaster ? unitCaster->ToTempSummon() : nullptr)
4927 {
4928 if (tempSummon->GetEntry() == WORLD_TRIGGER)
4929 {
4930 if (GameObject* casterGameobject = tempSummon->GetSummonerGameObject())
4931 {
4932 realCasterGUID = casterGameobject->GetPackGUID();
4933 }
4934 }
4935 }
4936
4937 WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
4938 if (m_CastItem)
4939 data << m_CastItem->GetPackGUID();
4940 else
4941 data << realCasterGUID;
4942
4943 data << realCasterGUID;
4944 data << uint8(m_cast_count); // pending spell cast?
4945 data << uint32(m_spellInfo->Id); // spellId
4946 data << uint32(castFlags); // cast flags
4947 data << int32(m_timer); // delay?
4948
4949 m_targets.Write(data);
4950
4951 if (castFlags & CAST_FLAG_POWER_LEFT_SELF)
4952 data << uint32(unitCaster ? unitCaster->GetPower((Powers)m_spellInfo->PowerType) : 0);
4953
4954 if (castFlags & CAST_FLAG_PROJECTILE)
4955 WriteAmmoToPacket(&data);
4956
4957 if (castFlags & CAST_FLAG_UNKNOWN_23)
4958 {
4959 data << uint32(0);
4960 data << uint32(0);
4961 }
4962
4963 m_caster->SendMessageToSet(&data, true);
4964
4965 if (!m_spellInfo->IsChanneled() && unitCaster && unitCaster->IsPlayer() && unitCaster->ToPlayer()->NeedSendSpectatorData())
4966 ArenaSpectator::SendCommand_Spell(unitCaster->FindMap(), unitCaster->GetGUID(), "SPE", m_spellInfo->Id, m_timer);
4967}
@ 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
581{ m_delayStart = m_time; }

References m_delayStart.

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

◆ SetExecutedCurrently()

void Spell::SetExecutedCurrently ( bool  yes)
inline
579{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 
)
8842{
8843 switch (mod)
8844 {
8846 m_spellValue->EffectBasePoints[0] = m_spellInfo->Effects[EFFECT_0].CalcBaseValue(value);
8847 break;
8849 m_spellValue->EffectBasePoints[1] = m_spellInfo->Effects[EFFECT_1].CalcBaseValue(value);
8850 break;
8852 m_spellValue->EffectBasePoints[2] = m_spellInfo->Effects[EFFECT_2].CalcBaseValue(value);
8853 break;
8855 m_spellValue->RadiusMod = (float)value / 10000;
8856 break;
8859 break;
8862 break;
8864 m_spellValue->AuraDuration = value;
8865 break;
8867 m_spellValue->ForcedCritResult = (bool)value;
8868 break;
8870 m_spellValue->MiscVal[0] = value;
8871 break;
8873 m_spellValue->MiscVal[1] = value;
8874 break;
8876 m_spellValue->MiscVal[2] = value;
8877 break;
8878 }
8879}
@ 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
6296{
6297 Unit* unitCaster = GetUnitCasterForEffectHandlers();
6298 Unit* caster = m_originalCaster;
6299 if (!caster)
6300 return;
6301
6302 if (caster->IsTotem())
6303 caster = caster->ToTotem()->GetOwner();
6304 else if (caster->IsPet())
6305 if (Unit* owner = caster->GetOwner())
6306 caster = owner;
6307
6308 // in another case summon new
6309 uint8 summonLevel = caster->GetLevel();
6310
6311 // level of pet summoned using engineering item based at engineering skill level
6312 if (m_CastItem && caster->IsPlayer())
6313 if (ItemTemplate const* proto = m_CastItem->GetTemplate())
6314 {
6315 // xinef: few special cases
6316 if (proto->RequiredSkill == SKILL_ENGINEERING)
6317 {
6318 if (uint16 skill202 = caster->ToPlayer()->GetSkillValue(SKILL_ENGINEERING))
6319 summonLevel = skill202 / 5;
6320 }
6321
6322 switch (m_spellInfo->Id)
6323 {
6324 // Target dummies use RequiredSkillRank/5, not player's current skill
6325 case 4071: // Target Dummy
6326 case 4072: // Advanced Target Dummy
6327 case 19805: // Masterwork Target Dummy
6328 summonLevel = proto->RequiredSkillRank / 5;
6329 break;
6330
6331 // Dragon's Call
6332 case 13049:
6333 summonLevel = 55;
6334 break;
6335
6336 // Cleansed Timberling Heart: Summon Timberling
6337 case 5666:
6338 summonLevel = 7;
6339 break;
6340
6341 // Glowing Cat Figurine: Summon Ghost Saber
6342 case 6084:
6343 // minLevel 19, maxLevel 20
6344 summonLevel = 20;
6345 break;
6346
6347 // Spiked Collar: Summon Felhunter
6348 case 8176:
6349 summonLevel = 30;
6350 break;
6351
6352 // Dog Whistle: Summon Tracking Hound
6353 case 9515:
6354 summonLevel = 30;
6355 break;
6356
6357 // Barov Peasant Caller: Death by Peasant
6358 case 18307:
6359 case 18308:
6360 summonLevel = 60;
6361 break;
6362
6363 // Thornling Seed: Plant Thornling
6364 case 22792:
6365 summonLevel = 60;
6366 break;
6367
6368 // Cannonball Runner: Summon Crimson Cannon
6369 case 6251:
6370 summonLevel = 61;
6371 break;
6372 }
6373 }
6374
6375 summonLevel = std::min<uint8>(sWorld->getIntConfig(CONFIG_MAX_PLAYER_LEVEL) + sWorld->getIntConfig(CONFIG_WORLD_BOSS_LEVEL_DIFF), std::max<uint8>(1U, summonLevel));
6376
6377 float radius = 5.0f;
6378 int32 duration = m_spellInfo->GetDuration();
6379
6380 if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6381 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
6382
6383 //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN;
6384 Map* map = caster->GetMap();
6385 TempSummon* summon = nullptr;
6386
6387 uint32 currMinionsCount = unitCaster->m_Controlled.size();
6388 uint32 totalNumGuardians = numGuardians + currMinionsCount;
6389
6390 for (uint32 count = 0; count < numGuardians; ++count)
6391 {
6392 Position pos;
6393
6394 // xinef: do not use precalculated position for effect summon pet in this function
6395 // it means it was cast by NPC and should have its position overridden unless the
6396 // target position is specified in the DB AND the effect has no or zero radius
6397 if ((numGuardians == 1 && GetSpellInfo()->Effects[i].Effect != SPELL_EFFECT_SUMMON_PET) ||
6398 (GetSpellInfo()->Effects[i].TargetA.GetTarget() == TARGET_DEST_DB &&
6399 (!GetSpellInfo()->Effects[i].HasRadius() || GetSpellInfo()->Effects[i].RadiusEntry->RadiusMax == 0)))
6400 {
6401 pos = *destTarget;
6402 }
6403 else
6404 {
6405 // randomize position
6406 pos = unitCaster->GetRandomPoint(*destTarget, radius);
6407 }
6408
6409 summon = map->SummonCreature(entry, pos, properties, duration, caster, m_spellInfo->Id, 0, personalSpawn);
6410 if (!summon)
6411 return;
6412
6413 // xinef: set calculated level
6414 summon->SetLevel(summonLevel);
6415
6416 // if summonLevel changed, set stats for calculated level
6417 if (summonLevel != caster->GetLevel())
6418 {
6419 ((Guardian*)summon)->InitStatsForLevel(summonLevel);
6420 }
6421
6422 // xinef: if we have more than one guardian, change follow angle
6423 if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && totalNumGuardians > 1)
6424 ((Minion*)summon)->SetFollowAngle(unitCaster->GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()));
6425 //else if (summon->HasUnitTypeMask(UNIT_MASK_MINION) && m_targets.HasDst())
6426 // ((Minion*)summon)->SetFollowAngle(unitCaster->GetAngle(summon));
6427
6428 // xinef: move this here, some auras are added in initstatsforlevel!
6429 if (!summon->IsInCombat() && !summon->IsTrigger())
6430 {
6431 // summon->AI()->EnterEvadeMode();
6432 summon->GetMotionMaster()->Clear(false);
6434 }
6435
6436 if (properties && properties->Category == SUMMON_CATEGORY_ALLY)
6437 summon->SetFaction(caster->GetFaction());
6438
6440 }
6441}
@ SKILL_ENGINEERING
Definition SharedDefines.h:3156
@ CONFIG_MAX_PLAYER_LEVEL
Definition WorldConfig.h:195
@ CONFIG_WORLD_BOSS_LEVEL_DIFF
Definition WorldConfig.h:245
bool IsTrigger() const
Definition Creature.h:79
Definition TemporarySummon.h:87
Unit * GetOwner() const
Definition TemporarySummon.cpp:390
void SetLevel(uint8 lvl, bool showLevelChange=true)
Definition Unit.cpp:12002
virtual float GetFollowAngle() const
Definition Unit.h:1917

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 ( )
5574{
5575 Unit* unitCaster = m_caster->ToUnit();
5576 if (!unitCaster)
5577 return;
5578
5580 {
5581 Item* pItem = unitCaster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK);
5582
5583 // wands don't have ammo
5584 if (!pItem || pItem->IsBroken() || pItem->GetTemplate()->SubClass == ITEM_SUBCLASS_WEAPON_WAND)
5585 return;
5586
5587 if (pItem->GetTemplate()->InventoryType == INVTYPE_THROWN)
5588 {
5589 if (pItem->GetMaxStackCount() == 1)
5590 {
5591 // decrease durability for non-stackable throw weapon
5593 }
5594 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5595 {
5596 // decrease items amount for stackable throw weapon
5597 uint32 count = 1;
5598 unitCaster->ToPlayer()->DestroyItemCount(pItem, count, true);
5599 }
5600 }
5601 else if (!sWorld->getBoolConfig(CONFIG_ENABLE_INFINITEAMMO))
5602 if (uint32 ammo = unitCaster->ToPlayer()->GetUInt32Value(PLAYER_AMMO_ID))
5603 unitCaster->ToPlayer()->DestroyItemCount(ammo, 1, true);
5604 }
5605}
@ 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:152
uint32 GetMaxStackCount() const
Definition Item.h:274
void DurabilityPointLossForEquipSlot(EquipmentSlots slot)
Definition Player.cpp:4926

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 ( )
5439{
5440 Unit* unitCaster = m_caster->ToUnit();
5441 if (!unitCaster)
5442 return;
5443
5444 if (!m_CastItem || !unitCaster->IsPlayer())
5445 return;
5446
5447 // not remove cast item at triggered spell (equipping, weapon damage, etc)
5449 return;
5450
5451 ItemTemplate const* proto = m_CastItem->GetTemplate();
5452
5453 if (!proto)
5454 {
5455 // This code is to avoid a crash
5456 // I'm not sure, if this is really an error, but I guess every item needs a prototype
5457 LOG_ERROR("spells", "Cast item has no item prototype {}", m_CastItem->GetGUID().ToString());
5458 return;
5459 }
5460
5461 bool expendable = false;
5462 bool withoutCharges = false;
5463
5464 for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
5465 {
5466 if (proto->Spells[i].SpellId)
5467 {
5468 // item has limited charges
5469 if (proto->Spells[i].SpellCharges)
5470 {
5471 if (proto->Spells[i].SpellCharges < 0)
5472 expendable = true;
5473
5474 int32 charges = m_CastItem->GetSpellCharges(i);
5475
5476 // item has charges left
5477 if (charges)
5478 {
5479 (charges > 0) ? --charges : ++charges; // std::abs(charges) less at 1 after use
5480 if (proto->Stackable == 1)
5481 m_CastItem->SetSpellCharges(i, charges);
5482 m_CastItem->SetState(ITEM_CHANGED, unitCaster->ToPlayer());
5483 }
5484
5485 // all charges used
5486 withoutCharges = (charges == 0);
5487 }
5488 }
5489 }
5490
5491 if (expendable && withoutCharges)
5492 {
5493 uint32 count = 1;
5494 unitCaster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
5495
5496 // prevent crash at access to deleted m_targets.GetItemTarget
5498 m_targets.SetItemTarget(nullptr);
5499
5500 m_CastItem = nullptr;
5502 }
5503}
void SetSpellCharges(uint8 index, int32 value)
Definition Item.h:319
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 ( )
5506{
5507 Unit* unitCaster = m_caster->ToUnit();
5508 if (!unitCaster)
5509 return;
5510
5512 return;
5513
5514 //Don't take power if the spell is cast while .cheat power is enabled.
5515 if (unitCaster->IsPlayer())
5516 if (unitCaster->ToPlayer()->GetCommandStatus(CHEAT_POWER))
5517 return;
5518
5520 bool hit = true;
5521 if (unitCaster->IsPlayer())
5522 {
5524 if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID())
5525 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5526 if (ihit->targetGUID == targetGUID)
5527 {
5528 if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_BLOCK && ihit->missCondition != SPELL_MISS_ABSORB && ihit->missCondition != SPELL_MISS_REFLECT)
5529 {
5530 hit = false;
5531 //lower spell cost on fail (by talent aura)
5532 if (Player* modOwner = unitCaster->ToPlayer()->GetSpellModOwner())
5533 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost, this);
5534 }
5535 break;
5536 }
5537 }
5538
5539 if (PowerType == POWER_RUNE)
5540 {
5541 TakeRunePower(hit);
5542 return;
5543 }
5544
5545 if (!m_powerCost)
5546 return;
5547
5548 // health as power used
5549 if (PowerType == POWER_HEALTH)
5550 {
5551 unitCaster->ModifyHealth(-(int32)m_powerCost);
5552 return;
5553 }
5554
5555 if (PowerType >= MAX_POWERS)
5556 {
5557 LOG_ERROR("spells", "Spell::TakePower: Unknown power type '{}'", PowerType);
5558 return;
5559 }
5560
5561 if (hit)
5562 unitCaster->ModifyPower(PowerType, -m_powerCost);
5563 else
5564 unitCaster->ModifyPower(PowerType, -irand(0, m_powerCost / 4));
5565
5566 // Set the five second timer
5567 if (PowerType == POWER_MANA && m_powerCost > 0)
5568 {
5569 unitCaster->SetLastManaUse(GameTime::GetGameTimeMS().count());
5570 }
5571}
@ SPELL_MISS_ABSORB
Definition SharedDefines.h:1533
@ SPELLMOD_SPELL_COST_REFUND_ON_FAIL
Definition SpellDefines.h:114
void TakeRunePower(bool didHit)
Definition Spell.cpp:5665
int32 ModifyHealth(int32 val)
Definition Unit.cpp:10784
void SetLastManaUse(uint32 spellCastTime)
Definition Unit.h:1165

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 ( )
5739{
5740 Unit* unitCaster = m_caster->ToUnit();
5741 if (!unitCaster)
5742 return;
5743
5744 if (!unitCaster->IsPlayer())
5745 return;
5746
5747 ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr;
5748
5749 // do not take reagents for these item casts
5750 if (castItemTemplate && castItemTemplate->HasFlag(ITEM_FLAG_NO_REAGENT_COST))
5751 return;
5752
5753 Player* p_caster = unitCaster->ToPlayer();
5754 if (p_caster->CanNoReagentCast(m_spellInfo))
5755 return;
5756
5757 for (uint32 x = 0; x < MAX_SPELL_REAGENTS; ++x)
5758 {
5759 if (m_spellInfo->Reagent[x] <= 0)
5760 continue;
5761
5762 uint32 itemid = m_spellInfo->Reagent[x];
5763 uint32 itemcount = m_spellInfo->ReagentCount[x];
5764
5765 // if CastItem is also spell reagent
5766 if (castItemTemplate && castItemTemplate->ItemId == itemid)
5767 {
5768 for (int s = 0; s < MAX_ITEM_PROTO_SPELLS; ++s)
5769 {
5770 // CastItem will be used up and does not count as reagent
5771 int32 charges = m_CastItem->GetSpellCharges(s);
5772 if (castItemTemplate->Spells[s].SpellCharges < 0 && std::abs(charges) < 2)
5773 {
5774 ++itemcount;
5775 break;
5776 }
5777 }
5778
5779 m_CastItem = nullptr;
5781 }
5782
5783 // if GetItemTarget is also spell reagent
5784 if (m_targets.GetItemTargetEntry() == itemid)
5785 m_targets.SetItemTarget(nullptr);
5786
5787 p_caster->DestroyItemCount(itemid, itemcount, true);
5788 }
5789}
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)
5666{
5667 Unit* unitCaster = m_caster->ToUnit();
5668 if (!unitCaster)
5669 return;
5670
5671 if (!unitCaster->IsPlayer() || !unitCaster->IsClass(CLASS_DEATH_KNIGHT, CLASS_CONTEXT_ABILITY))
5672 return;
5673
5674 SpellRuneCostEntry const* runeCostData = sSpellRuneCostStore.LookupEntry(m_spellInfo->RuneCostID);
5675 if (!runeCostData || (runeCostData->NoRuneCost() && runeCostData->NoRunicPowerGain()))
5676 return;
5677
5678 Player* player = unitCaster->ToPlayer();
5679 m_runesState = player->GetRunesState(); // store previous state
5680
5681 int32 runeCost[NUM_RUNE_TYPES]; // blood, frost, unholy, death
5682
5683 for (uint32 i = 0; i < RUNE_DEATH; ++i)
5684 {
5685 runeCost[i] = runeCostData->RuneCost[i];
5686 if (Player* modOwner = unitCaster->GetSpellModOwner())
5687 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this);
5688 }
5689
5690 runeCost[RUNE_DEATH] = 0; // calculated later
5691
5692 for (uint32 i = 0; i < MAX_RUNES; ++i)
5693 {
5694 RuneType rune = player->GetCurrentRune(i);
5695 if (!player->GetRuneCooldown(i) && runeCost[rune] > 0)
5696 {
5697 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5698 player->SetLastUsedRune(rune);
5699 runeCost[rune]--;
5700 }
5701 }
5702
5703 // Xinef: firstly consume death runes of base type
5704 // Xinef: in second loop consume all available
5705 for (uint8 loop = 0; loop < 2; ++loop)
5706 {
5707 runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST];
5708 if (runeCost[RUNE_DEATH] > 0)
5709 {
5710 for (uint8 i = 0; i < MAX_RUNES; ++i)
5711 {
5712 RuneType rune = player->GetCurrentRune(i);
5713 if (!player->GetRuneCooldown(i) && rune == RUNE_DEATH && (loop ? true : (runeCost[player->GetBaseRune(i)] > 0)))
5714 {
5715 player->SetRuneCooldown(i, didHit ? player->GetRuneBaseCooldown(i, false) : uint32(RUNE_MISS_COOLDOWN));
5716 player->SetLastUsedRune(rune);
5717 runeCost[rune]--;
5718 if (!loop)
5719 runeCost[player->GetBaseRune(i)]--;
5720
5721 // keep Death Rune type if missed
5722 if (didHit)
5723 player->RestoreBaseRune(i);
5724
5725 if (runeCost[RUNE_DEATH] == 0)
5726 break;
5727 }
5728 }
5729 }
5730 }
5731
5732 // you can gain some runic power when use runes
5733 if (didHit)
5734 if (int32 rp = int32(runeCostData->runePowerGain * sWorld->getRate(RATE_POWER_RUNICPOWER_INCOME)))
5735 player->ModifyPower(POWER_RUNIC_POWER, int32(rp));
5736}
@ 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:408
void SetLastUsedRune(RuneType type)
Definition Player.h:2563
uint32 GetRuneBaseCooldown(uint8 index, bool skipGrace)
Definition Player.cpp:13764
void RestoreBaseRune(uint8 index)
Definition Player.cpp:13793
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
9267{
9268 Unit* unitCaster = m_caster->ToUnit();
9269 if (!unitCaster)
9270 return;
9271
9273 if (!gcd)
9274 {
9275 // Xinef: fix for charmed pet spells with no cooldown info
9276 if (m_spellInfo->RecoveryTime == 0 && m_spellInfo->CategoryRecoveryTime == 0 && unitCaster->GetCharmInfo())
9277 gcd = MIN_GCD;
9278 else
9279 return;
9280 }
9281
9282 if (unitCaster->IsPlayer())
9283 if (unitCaster->ToPlayer()->GetCommandStatus(CHEAT_COOLDOWN))
9284 return;
9285
9286 // Global cooldown can't leave range 1..1.5 secs
9287 // There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
9288 // but as tests show are not affected by any spell mods.
9290 {
9291 // gcd modifier auras are applied only to own spells and only players have such mods
9292 if (unitCaster->IsPlayer())
9293 unitCaster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_GLOBAL_COOLDOWN, gcd, this);
9294
9295 // Apply haste rating
9298 {
9299 gcd = int32(float(gcd) * unitCaster->GetFloatValue(UNIT_MOD_CAST_SPEED));
9300 }
9301
9302 if (gcd < MIN_GCD)
9303 gcd = MIN_GCD;
9304 else if (gcd > MAX_GCD)
9305 gcd = MAX_GCD;
9306 }
9307
9308 // Only players or controlled units have global cooldown
9309 if (unitCaster->GetCharmInfo())
9311 else if (unitCaster->IsPlayer())
9313}
@ SPELLMOD_GLOBAL_COOLDOWN
Definition SpellDefines.h:105
@ MIN_GCD
Definition Spell.cpp:9247
@ MAX_GCD
Definition Spell.cpp:9248
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)
4549{
4550 Unit* unitCaster = m_caster->ToUnit();
4551 // update pointers based at it's GUIDs
4552 if (!UpdatePointers())
4553 {
4554 // cancel the spell if UpdatePointers() returned false, something wrong happened there
4555 cancel();
4556 return;
4557 }
4558
4560 {
4561 LOG_DEBUG("spells.aura", "Spell {} is cancelled due to removal of target.", m_spellInfo->Id);
4562 cancel();
4563 return;
4564 }
4565
4566 // check if the player caster has moved before the spell finished
4567 // xinef: added preparing state (real cast, skip channels as they have other flags for this)
4568 if ((unitCaster && unitCaster->IsPlayer() && m_timer != 0) &&
4571 {
4572 // don't cancel for melee, autorepeat, triggered and instant spells
4574 cancel(true);
4575 }
4576
4577 switch (m_spellState)
4578 {
4580 {
4581 if (m_timer > 0)
4582 {
4583 if (difftime >= (uint32)m_timer)
4584 m_timer = 0;
4585 else
4586 m_timer -= difftime;
4587 }
4588
4589 if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
4590 // don't CheckCast for instant spells - done in spell::prepare, skip duplicate checks, needed for range checks for example
4591 cast(!m_casttime);
4592 break;
4593 }
4595 {
4596 if (m_timer)
4597 {
4598 if (m_timer > 0)
4599 {
4600 if (difftime >= (uint32)m_timer)
4601 m_timer = 0;
4602 else
4603 m_timer -= difftime;
4604 }
4605 }
4606
4607 if (m_timer == 0)
4608 {
4610
4611 finish();
4612
4613 // 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
4614 if (Creature* creatureCaster = unitCaster ? unitCaster->ToCreature() : nullptr)
4615 if (creatureCaster->IsAIEnabled)
4616 creatureCaster->AI()->OnChannelFinished(m_spellInfo);
4617 }
4618 // Xinef: Dont update channeled target list on last tick, allow auras to update duration properly
4619 // Xinef: Added this strange check because of diffrent update routines for players / creatures
4620 // Xinef: If creature gets new aura in 800ms and in 840ms its updated with diff 270, not 40 is removed from duration but 270
4621 // Xinef: so the aura can be removed in different updates for all units
4622 else if ((m_timer < 0 || m_timer > 300) && !UpdateChanneledTargetList())
4623 {
4624 LOG_DEBUG("spells.aura", "Channeled spell {} is removed due to lack of targets", m_spellInfo->Id);
4626 finish();
4627 }
4628 break;
4629 }
4630 default:
4631 break;
4632 }
4633}
bool UpdateChanneledTargetList()
Definition Spell.cpp:3476

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
3477{
3478 Unit* unitCaster = m_caster->ToUnit();
3479 // Not need check return true
3481 return true;
3482
3483 uint8 channelTargetEffectMask = m_channelTargetEffectMask;
3484 uint8 channelAuraMask = 0;
3485 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
3487 channelAuraMask |= 1 << i;
3488
3489 channelAuraMask &= channelTargetEffectMask;
3490
3491 float range = 0;
3492 if (channelAuraMask)
3493 {
3495 if (range == 0)
3496 for(int i = EFFECT_0; i <= EFFECT_2; ++i)
3497 if (channelAuraMask & (1 << i) && m_spellInfo->Effects[i].RadiusEntry)
3498 {
3499 range = m_spellInfo->Effects[i].CalcRadius(nullptr, nullptr);
3500 break;
3501 }
3502
3503 if (Player* modOwner = m_caster->GetSpellModOwner())
3504 modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
3505
3506 // xinef: add little tolerance level
3507 range += std::min(3.0f, range * 0.1f); // 10% but no more than 3yd
3508 }
3509
3510 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3511 {
3512 if (ihit->missCondition == SPELL_MISS_NONE && (channelTargetEffectMask & ihit->effectMask))
3513 {
3514 Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? unitCaster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3515
3516 if (!unit)
3517 continue;
3518
3519 if (IsValidDeadOrAliveTarget(unit))
3520 {
3521 if (channelAuraMask & ihit->effectMask)
3522 {
3524 {
3525 if (m_caster != unit)
3526 {
3527 if (!m_caster->IsWithinDistInMap(unit, range))
3528 {
3529 ihit->effectMask &= ~aurApp->GetEffectMask();
3530 unit->RemoveAura(aurApp);
3531 continue;
3532 }
3533 // Xinef: Update Orientation server side (non players wont sent appropriate packets)
3534 else if (unitCaster && !unitCaster->IsPlayer() && m_spellInfo->HasAttribute(SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL))
3535 unitCaster->UpdateOrientation(unitCaster->GetAngle(unit));
3536 }
3537 }
3538 else // aura is dispelled
3539 continue;
3540 }
3541
3542 channelTargetEffectMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
3543 }
3544 }
3545 }
3546
3547 // Xinef: not all effects are covered, remove applications from all targets
3548 if (channelTargetEffectMask != 0)
3549 {
3550 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3551 if (ihit->missCondition == SPELL_MISS_NONE && (channelAuraMask & ihit->effectMask))
3552 if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? unitCaster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
3553 if (IsValidDeadOrAliveTarget(unit))
3555 {
3556 ihit->effectMask &= ~aurApp->GetEffectMask();
3557 unit->RemoveAura(aurApp);
3558 }
3559 }
3560
3561 // is all effects from m_needAliveTargetMask have alive targets
3562 return channelTargetEffectMask == 0;
3563}
@ SPELL_ATTR1_TRACK_TARGET_IN_CHANNEL
Definition SharedDefines.h:421
bool IsValidDeadOrAliveTarget(Unit const *target) const
Definition Spell.cpp:8611
AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint8 reqEffMask=0, AuraApplication *except=nullptr) const
Definition Unit.cpp:5639
void UpdateOrientation(float orientation)
Only server-side orientation update, does not broadcast to client.
Definition Unit.cpp:15734
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 ( )
8250{
8251 Unit* unitCaster = m_caster->ToUnit();
8253 m_originalCaster = unitCaster;
8254 else
8255 {
8258 m_originalCaster = nullptr;
8259 }
8260
8261 if (m_castItemGUID && unitCaster && unitCaster->IsPlayer())
8262 {
8264 // cast item not found, somehow the item is no longer where we expected
8265 if (!m_CastItem)
8266 return false;
8267 }
8268 else
8269 m_CastItem = nullptr;
8270
8272
8273 // further actions done only for dest targets
8274 if (!m_targets.HasDst())
8275 return true;
8276
8277 // cache last transport
8278 WorldObject* transport = nullptr;
8279
8280 // update effect destinations (in case of moved transport dest target)
8281 for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex)
8282 {
8283 SpellDestination& dest = m_destTargets[effIndex];
8284 if (!dest._transportGUID)
8285 continue;
8286
8287 if (!transport || transport->GetGUID() != dest._transportGUID)
8289
8290 if (transport)
8291 {
8292 dest._position.Relocate(transport);
8294 }
8295 }
8296
8297 return true;
8298}
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)
5102{
5103 Unit* unitCaster = m_caster->ToUnit();
5104 uint32 ammoInventoryType = 0;
5105 uint32 ammoDisplayID = 0;
5106
5107 if (unitCaster && unitCaster->IsPlayer())
5108 {
5109 Item* pItem = unitCaster->ToPlayer()->GetWeaponForAttack(RANGED_ATTACK);
5110 if (pItem)
5111 {
5112 ammoInventoryType = pItem->GetTemplate()->InventoryType;
5113 if (ammoInventoryType == INVTYPE_THROWN)
5114 ammoDisplayID = pItem->GetTemplate()->DisplayInfoID;
5115 else
5116 {
5117 uint32 ammoID = unitCaster->ToPlayer()->GetUInt32Value(PLAYER_AMMO_ID);
5118 if (ammoID)
5119 {
5120 ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(ammoID);
5121 if (pProto)
5122 {
5123 ammoDisplayID = pProto->DisplayInfoID;
5124 ammoInventoryType = pProto->InventoryType;
5125 }
5126 }
5127 else if (unitCaster->HasAura(46699)) // Requires No Ammo
5128 {
5129 ammoDisplayID = 5996; // normal arrow
5130 ammoInventoryType = INVTYPE_AMMO;
5131 }
5132 }
5133 }
5134 }
5135 else if (unitCaster)
5136 {
5137 uint32 nonRangedAmmoDisplayID = 0;
5138 uint32 nonRangedAmmoInventoryType = 0;
5139 for (uint8 i = 0; i < 3; ++i)
5140 {
5141 if (uint32 item_id = unitCaster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i))
5142 {
5143 if (ItemEntry const* itemEntry = sItemStore.LookupEntry(item_id))
5144 {
5145 if (itemEntry->ClassID == ITEM_CLASS_WEAPON)
5146 {
5147 switch (itemEntry->SubclassID)
5148 {
5150 ammoDisplayID = itemEntry->DisplayInfoID;
5151 ammoInventoryType = itemEntry->InventoryType;
5152 break;
5155 ammoDisplayID = 5996; // is this need fixing?
5156 ammoInventoryType = INVTYPE_AMMO;
5157 break;
5159 ammoDisplayID = 5998; // is this need fixing?
5160 ammoInventoryType = INVTYPE_AMMO;
5161 break;
5162 default:
5163 nonRangedAmmoDisplayID = itemEntry->DisplayInfoID;
5164 nonRangedAmmoInventoryType = itemEntry->InventoryType;
5165 break;
5166 }
5167
5168 if (ammoDisplayID)
5169 break;
5170 }
5171 }
5172 }
5173 }
5174
5175 if (!ammoDisplayID && !ammoInventoryType)
5176 {
5177 ammoDisplayID = nonRangedAmmoDisplayID;
5178 ammoInventoryType = nonRangedAmmoInventoryType;
5179 }
5180 }
5181
5182 *data << uint32(ammoDisplayID);
5183 *data << uint32(ammoInventoryType);
5184}
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
4728{
4729 data << uint8(castCount); // single cast or multi 2.3 (0/1)
4730 data << uint32(spellInfo->Id);
4731 data << uint8(result); // problem
4732 switch (result)
4733 {
4735 data << uint32(spellInfo->RequiresSpellFocus); // SpellFocusObject.dbc id
4736 break;
4737 case SPELL_FAILED_REQUIRES_AREA: // AreaTable.dbc id
4738 // hardcode areas limitation case
4739 switch (spellInfo->Id)
4740 {
4741 case 41617: // Cenarion Mana Salve
4742 case 41619: // Cenarion Healing Salve
4743 data << uint32(3905);
4744 break;
4745 case 41618: // Bottled Nethergon Energy
4746 case 41620: // Bottled Nethergon Vapor
4747 data << uint32(3842);
4748 break;
4749 case 45373: // Bloodberry Elixir
4750 data << uint32(4075);
4751 break;
4752 default: // default case (don't must be)
4753 data << uint32(0);
4754 break;
4755 }
4756 break;
4758 if (spellInfo->Totem[0])
4759 data << uint32(spellInfo->Totem[0]);
4760 if (spellInfo->Totem[1])
4761 data << uint32(spellInfo->Totem[1]);
4762 break;
4764 if (spellInfo->TotemCategory[0])
4765 data << uint32(spellInfo->TotemCategory[0]);
4766 if (spellInfo->TotemCategory[1])
4767 data << uint32(spellInfo->TotemCategory[1]);
4768 break;
4772 data << uint32(spellInfo->EquippedItemClass);
4773 data << uint32(spellInfo->EquippedItemSubClassMask);
4774 break;
4776 {
4777 uint32 item = 0;
4778 for (int8 eff = 0; eff < MAX_SPELL_EFFECTS; eff++)
4779 if (spellInfo->Effects[eff].ItemType)
4780 item = spellInfo->Effects[eff].ItemType;
4781 ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item);
4782 if (proto && proto->ItemLimitCategory)
4783 data << uint32(proto->ItemLimitCategory);
4784 break;
4785 }
4787 data << uint32(customError);
4788 break;
4790 {
4791 uint32 missingItem = 0;
4792 for (uint32 i = 0; i < MAX_SPELL_REAGENTS; i++)
4793 {
4794 if (spellInfo->Reagent[i] <= 0)
4795 continue;
4796
4797 uint32 itemid = spellInfo->Reagent[i];
4798 uint32 itemcount = spellInfo->ReagentCount[i];
4799
4800 if (!caster->HasItemCount(itemid, itemcount))
4801 {
4802 missingItem = itemid;
4803 break;
4804 }
4805 }
4806
4807 data << uint32(missingItem); // first missing item
4808 break;
4809 }
4811 data << uint32(spellInfo->Mechanic);
4812 break;
4814 data << uint32(spellInfo->EquippedItemSubClassMask);
4815 break;
4817 data << uint32(0); // Item entry
4818 data << uint32(0); // Count
4819 break;
4821 data << uint32(0); // SkillLine.dbc Id
4822 data << uint32(0); // Amount
4823 break;
4825 data << uint32(0); // Skill level
4826 break;
4827 default:
4828 break;
4829 }
4830}
@ 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.

5188{
5189 // This function also fill data for channeled spells:
5190 // m_needAliveTargetMask req for stop channelig if one target die
5191 for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5192 {
5193 if ((*ihit).effectMask == 0) // No effect apply - all immuned add state
5194 // possibly SPELL_MISS_IMMUNE2 for this??
5195 ihit->missCondition = SPELL_MISS_IMMUNE2;
5196 }
5197
5198 // Hit and miss target counts are both uint8, that limits us to 255 targets for each
5199 // sending more than 255 targets crashes the client (since count sent would be wrong)
5200 // Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
5201 // target conditions but we still need to limit the number of targets sent and keeping
5202 // correct count for both hit and miss).
5203
5204 uint32 hit = 0;
5205 std::size_t hitPos = data->wpos();
5206 *data << (uint8)0; // placeholder
5207 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && hit < 255; ++ihit)
5208 {
5209 if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
5210 {
5211 *data << ihit->targetGUID;
5212 // Xinef: No channeled spell checked, no anything
5213 //m_channelTargetEffectMask |=ihit->effectMask;
5214 ++hit;
5215 }
5216 }
5217
5218 for (std::list<GOTargetInfo>::const_iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end() && hit < 255; ++ighit)
5219 {
5220 *data << ighit->targetGUID; // Always hits
5221 ++hit;
5222 }
5223
5224 uint32 miss = 0;
5225 std::size_t missPos = data->wpos();
5226 *data << (uint8)0; // placeholder
5227 for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end() && miss < 255; ++ihit)
5228 {
5229 if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
5230 {
5231 *data << ihit->targetGUID;
5232 *data << uint8(ihit->missCondition);
5233 if (ihit->missCondition == SPELL_MISS_REFLECT)
5234 *data << uint8(ihit->reflectResult);
5235 ++miss;
5236 }
5237 }
5238 // Reset m_needAliveTargetMask for non channeled spell
5239 // Xinef: Why do we reset something that is not set??????
5240 //if (!m_spellInfo->IsChanneled())
5241 // m_channelTargetEffectMask = 0;
5242
5243 data->put<uint8>(hitPos, (uint8)hit);
5244 data->put<uint8>(missPos, (uint8)miss);
5245}
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

◆ _fromPreDeathAura

bool Spell::_fromPreDeathAura {false}
protected
801{false};

Referenced by IsFromPreDeathAura(), and prepare().

◆ _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(), EffectTransmitted(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), EffectTriggerSpell(), EffectUnlearnSpecialization(), EffectUntrainTalents(), finish(), GetCaster(), GetGameObjectCaster(), GetLOSCollisionHeight(), 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: