OregonCore  revision be9e804-git
Your Favourite TBC server
Spell Class Reference

#include <Spell.h>

Classes

struct  GOTargetInfo
 
struct  ItemTargetInfo
 
struct  TargetInfo
 

Public Member Functions

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 EffectPersistentAA (SpellEffIndex effIndex)
 
void EffectEnergize (SpellEffIndex effIndex)
 
void EffectOpenLock (SpellEffIndex effIndex)
 
void EffectSummonChangeItem (SpellEffIndex effIndex)
 
void EffectOpenSecretSafe (SpellEffIndex effIndex)
 
void EffectProficiency (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 EffectHealMechanical (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 SummonClassPet (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 EffectEnchantHeldItem (SpellEffIndex effIndex)
 
void EffectSummonObject (SpellEffIndex effIndex)
 
void EffectResurrect (SpellEffIndex effIndex)
 
void EffectParry (SpellEffIndex effIndex)
 
void EffectBlock (SpellEffIndex effIndex)
 
void EffectMomentMove (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 EffectSelfResurrect (SpellEffIndex effIndex)
 
void EffectSkinning (SpellEffIndex effIndex)
 
void EffectCharge (SpellEffIndex effIndex)
 
void EffectProspecting (SpellEffIndex effIndex)
 
void EffectSendTaxi (SpellEffIndex effIndex)
 
void EffectSummonCritter (SpellEffIndex effIndex)
 
void EffectKnockBack (SpellEffIndex effIndex)
 
void EffectPlayerPull (SpellEffIndex effIndex)
 
void EffectDispelMechanic (SpellEffIndex effIndex)
 
void EffectSummonDeadPet (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 EffectTriggerSpellWithValue (SpellEffIndex effIndex)
 
void EffectTriggerRitualOfSummoning (SpellEffIndex effIndex)
 
void EffectKillCredit (SpellEffIndex effIndex)
 
void EffectQuestFail (SpellEffIndex effIndex)
 
void EffectRedirectThreat (SpellEffIndex effIndex)
 
void EffectSummonFriend (SpellEffIndex effIndex)
 
 Spell (Unit *Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID=0, Spell **triggeringContainer=NULL, bool skipCheck=false)
 
 ~Spell ()
 
void prepare (SpellCastTargets *targets, Aura *triggeredByAura=NULL)
 
void cancel (bool sendInterrupt=true)
 
void update (uint32 difftime)
 
void cast (bool skipCheck=false)
 
void finish (bool ok=true)
 
void TakePower ()
 
void TakeReagents ()
 
void TakeCastItem ()
 
void TriggerSpell ()
 
SpellCastResult CheckCast (bool strict)
 
SpellCastResult CheckPetCast (Unit *target)
 
SpellCastResult CheckDummyCast (uint32 effIndex)
 
bool CanAutoCast (Unit *target)
 
void handle_immediate ()
 
uint64 handle_delayed (uint64 t_offset)
 
void _handle_immediate_phase ()
 
void _handle_finish_phase ()
 
SpellCastResult CheckItems ()
 
SpellCastResult CheckRange (bool strict)
 
SpellCastResult CheckPower ()
 
SpellCastResult CheckCasterAuras () const
 
int32 CalculateDamage (uint8 i, Unit *target)
 
bool HaveTargetsForEffect (uint8 effect) const
 
void Delayed ()
 
void DelayedChannel ()
 
uint32 getState () const
 
void setState (uint32 state)
 
void DoCreateItem (uint32 i, uint32 itemtype)
 
void WriteSpellGoTargets (WorldPacket *data)
 
void WriteAmmoToPacket (WorldPacket *data)
 
void FillTargetMap ()
 
void SetTargetMap (uint32 i, uint32 cur)
 
UnitSelectMagnetTarget ()
 
void HandleHitTriggerAura ()
 
bool CheckTarget (Unit *target, uint32 eff)
 
void CheckSrc ()
 
void CheckDst ()
 
void SendCastResult (SpellCastResult result)
 
void SendSpellStart ()
 
void SendSpellGo ()
 
void SendSpellCooldown ()
 
void SendLogExecute ()
 
void SendInterrupted (uint8 result)
 
void SendChannelUpdate (uint32 time)
 
void SendChannelStart (uint32 duration)
 
void SendResurrectRequest (Player *target)
 
void SendPlaySpellVisual (uint32 SpellID)
 
void HandleEffects (Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, float DamageMultiplier=1.0)
 
void HandleThreatSpells ()
 
int32 GetCastTime () const
 
bool IsAutoRepeat () const
 
void SetAutoRepeat (bool rep)
 
void ReSetTimer ()
 
bool IsNextMeleeSwingSpell () const
 
bool IsRangedSpell () const
 
bool IsChannelActive () const
 
bool IsAutoActionResetSpell () 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
 
CurrentSpellTypes GetCurrentContainer ()
 
UnitGetCaster () const
 
UnitGetOriginalCaster () const
 
int32 GetPowerCost () const
 
void UpdatePointers ()
 
void CalculateHitResults ()
 
bool IsAffectedBy (SpellEntry const *spellInfo, uint32 effectId)
 
bool CheckTargetCreatureType (Unit *target) const
 
void AddTriggeredSpell (SpellEntry const *spell)
 
void CleanupTargetList ()
 
void SetSpellValue (SpellValueMod mod, int32 value)
 

Public Attributes

const SpellEntry *const m_spellInfo
 
int32 m_currentBasePoints [3]
 
Itemm_CastItem
 
uint64 m_castItemGUID
 
uint8 m_cast_count
 
SpellCastTargets m_targets
 

Protected Types

typedef std::vector< SpellEntry const * > TriggerSpells
 
typedef std::vector< std::pair< SpellEntry const *, int32 > > ChanceTriggerSpells
 

Protected Member Functions

void SendLoot (uint64 guid, LootType loottype)
 
int32 GetNextDelayAtDamageMsTime ()
 
void prepareDataForTriggerSystem ()
 
void AddUnitTarget (Unit *target, uint32 effIndex)
 
void AddUnitTarget (uint64 unitGUID, uint32 effIndex)
 
void AddGOTarget (GameObject *target, uint32 effIndex)
 
void AddGOTarget (uint64 goGUID, uint32 effIndex)
 
void AddItemTarget (Item *target, uint32 effIndex)
 
void DoAllEffectOnTarget (TargetInfo *target)
 
void DoSpellHitOnUnit (Unit *unit, uint32 effectMask)
 
void DoAllEffectOnTarget (GOTargetInfo *target)
 
void DoAllEffectOnTarget (ItemTargetInfo *target)
 
bool IsAliveUnitPresentInTargetList ()
 
void SearchAreaTarget (std::list< Unit * > &unitList, float radius, const uint32 type, SpellTargets TargetType, uint32 entry=0)
 
void SearchChainTarget (std::list< Unit * > &unitList, float radius, uint32 unMaxTargets, SpellTargets TargetType)
 
WorldObjectSearchNearbyTarget (float range, SpellTargets TargetType)
 
bool IsValidSingleTargetEffect (Unit const *target, Targets type) const
 
bool IsValidSingleTargetSpell (Unit const *target) const
 
void CalculateDamageDoneForAllTargets ()
 
int32 CalculateDamageDone (Unit *unit, const uint32 effectMask, float *multiplier)
 
void SpellDamageSchoolDmg (SpellEffIndex effIndex)
 
void SpellDamageWeaponDmg (SpellEffIndex effIndex)
 
void SpellDamageHeal (SpellEffIndex effIndex)
 
void GetSummonPosition (uint32 i, Position &pos, float radius=0.0f)
 
void SummonGuardian (uint32 i, uint32 entry, SummonPropertiesEntry const *properties)
 
SpellCastResult CanOpenLock (uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
 

Protected Attributes

Unit *const m_caster
 
SpellValue *const m_spellValue
 
uint64 m_originalCasterGUID
 
Unitm_originalCaster
 
Spell ** m_selfContainer
 
Spell ** m_triggeringContainer
 
SpellSchoolMask m_spellSchoolMask
 
WeaponAttackType m_attackType
 
int32 m_powerCost
 
int32 m_casttime
 
bool m_canReflect
 
bool m_autoRepeat
 
bool m_isNeedSendToClient
 
bool m_isCastTimeHidden
 
uint8 m_delayAtDamageCount
 
uint64 m_delayStart
 
uint64 m_delayMoment
 
bool m_immediateHandled
 
bool m_referencedFromCurrentSpell
 
bool m_executedCurrently
 
bool m_needSpellLog
 
bool m_needComboPoints
 
uint8 m_applyMultiplierMask
 
float m_damageMultipliers [3]
 
UnitunitTarget
 
ItemitemTarget
 
GameObjectgameObjTarget
 
int32 damage
 
DiminishingLevels m_diminishLevel
 
DiminishingGroup m_diminishGroup
 
GameObjectfocusObject
 
int32 m_damage
 
int32 m_healing
 
int32 m_healthLeech
 
bool m_canTrigger
 
uint32 m_procAttacker
 
uint32 m_procVictim
 
uint32 m_countOfHit
 
uint32 m_countOfMiss
 
std::list< TargetInfom_UniqueTargetInfo
 
uint8 m_needAliveTargetMask
 
bool m_destroyed
 
std::list< GOTargetInfom_UniqueGOTargetInfo
 
std::list< ItemTargetInfom_UniqueItemInfo
 
TriggerSpells m_TriggerSpells
 
ChanceTriggerSpells m_ChanceTriggerSpells
 
uint32 m_spellState
 
int32 m_timer
 
float m_castPositionX
 
float m_castPositionY
 
float m_castPositionZ
 
float m_castOrientation
 
bool m_IsTriggeredSpell
 
SpellEntry const * m_triggeredByAuraSpell
 
uint32 m_customAttr
 
bool m_skipCheck
 

Friends

struct Oregon::SpellNotifierCreatureAndPlayer
 
void Unit::SetCurrentCastedSpell (Spell *pSpell)
 

Detailed Description

Definition at line 249 of file Spell.h.

Member Typedef Documentation

typedef std::vector< std::pair<SpellEntry const*, int32> > Spell::ChanceTriggerSpells
protected

Definition at line 677 of file Spell.h.

typedef std::vector<SpellEntry const*> Spell::TriggerSpells
protected

Definition at line 675 of file Spell.h.

Constructor & Destructor Documentation

Spell::Spell ( Unit Caster,
SpellEntry const *  info,
bool  triggered,
uint64  originalCasterGUID = 0,
Spell **  triggeringContainer = NULL,
bool  skipCheck = false 
)

Definition at line 257 of file Spell.cpp.

References SpellEntry::Attributes, SpellEntry::AttributesEx, SpellEntry::AttributesEx2, SpellEntry::AttributesEx3, SpellEntry::AttributesEx4, BASE_ATTACK, CLASSMASK_WAND_USERS, CleanupTargetList(), SpellEntry::DmgClass, SpellValue::EffectBasePoints, focusObject, gameObjTarget, Unit::getClassMask(), Object::GetGUID(), GetSpellSchoolMask(), Object::GetTypeId(), ObjectAccessor::GetUnit(), Player::GetWeaponForAttack(), SpellEntry::Id, IsAutoRepeatRangedSpell(), IsChanneledSpell(), Object::IsInWorld(), IsPassiveSpell(), IsPositiveSpell(), itemTarget, m_applyMultiplierMask, m_attackType, m_autoRepeat, m_canReflect, m_cast_count, m_caster, m_CastItem, m_castItemGUID, m_castPositionX, m_castPositionY, m_castPositionZ, m_casttime, m_currentBasePoints, m_customAttr, m_delayAtDamageCount, m_delayStart, m_destroyed, m_executedCurrently, m_healthLeech, m_isNeedSendToClient, m_IsTriggeredSpell, m_needAliveTargetMask, m_needComboPoints, m_originalCaster, m_originalCasterGUID, m_powerCost, m_referencedFromCurrentSpell, m_selfContainer, m_skipCheck, m_spellInfo, m_spellSchoolMask, m_spellState, m_spellValue, m_timer, m_triggeredByAuraSpell, m_triggeringContainer, m_TriggerSpells, NeedsComboPoints(), OFF_ATTACK, RANGED_ATTACK, SpellEntry::speed, SPELL_ATTR0_ABILITY, SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY, SPELL_ATTR1_CANT_BE_REFLECTED, SPELL_ATTR2_AUTOREPEAT_FLAG, SPELL_ATTR3_REQ_OFFHAND, SPELL_ATTR4_TRIGGERED, SPELL_DAMAGE_CLASS_MAGIC, SPELL_DAMAGE_CLASS_MELEE, SPELL_DAMAGE_CLASS_RANGED, SPELL_STATE_NULL, SpellEntry::SpellVisual, sSpellMgr, Object::ToPlayer(), TYPEID_PLAYER, and unitTarget.

Referenced by EffectDummy(), EffectTriggerMissileSpell(), EffectTriggerRitualOfSummoning(), and TriggerSpell().

258  : m_spellInfo(info)
259  , m_caster(Caster)
261 {
262  m_customAttr = sSpellMgr.GetSpellCustomAttr(m_spellInfo->Id);
263  m_skipCheck = skipCheck;
264  m_selfContainer = NULL;
265  m_triggeringContainer = triggeringContainer;
267  m_executedCurrently = false;
269  m_delayStart = 0;
271  m_destroyed = false;
272 
274 
275  // Get data for type of attack
276  switch (m_spellInfo->DmgClass)
277  {
281  else
283  break;
286  break;
287  default:
288  // Wands
291  else
293  break;
294  }
295 
296  m_spellSchoolMask = GetSpellSchoolMask(info); // Can be override for some spell (wand shoot for example)
297 
299  // wand case
302  m_spellSchoolMask = SpellSchoolMask(1 << pItem->GetProto()->Damage->DamageType);
303 
304  // Set health leech amount to zero
305  m_healthLeech = 0;
306 
307  if (originalCasterGUID)
308  m_originalCasterGUID = originalCasterGUID;
309  else
311 
314  else
315  {
318  m_originalCaster = NULL;
319  }
320 
321  for (int i = 0; i < 3; ++i)
323 
325 
327  m_TriggerSpells.clear();
328  m_IsTriggeredSpell = bool(triggered || info->AttributesEx4 & SPELL_ATTR4_TRIGGERED);
329  //m_AreaAura = false;
330  m_CastItem = NULL;
331  m_castItemGUID = 0;
332 
333  unitTarget = NULL;
334  itemTarget = NULL;
335  gameObjTarget = NULL;
336  focusObject = NULL;
337  m_cast_count = 0;
338  m_triggeredByAuraSpell = NULL;
339 
340  //Auto Shot & Shoot
342 
343  m_powerCost = 0; // setup to correct value in Spell::prepare, don't must be used before.
344  m_casttime = 0; // setup to correct value in Spell::prepare, don't must be used before.
345  m_timer = 0; // will set to castime in prepare
346 
348 
349  // Determine if spell can be reflected back to the caster
350  // Patch 1.2 notes: Spell Reflection no longer reflects abilities
354 
357 
359 }
GameObject * focusObject
Definition: Spell.h:593
GameObject * gameObjTarget
Definition: Spell.h:585
bool m_destroyed
Definition: Spell.h:628
Unit *const m_caster
Definition: Spell.h:541
uint32 m_spellState
Definition: Spell.h:680
uint32 AttributesEx
Definition: DBCStructure.h:680
bool m_isNeedSendToClient
Definition: Spell.h:559
uint64 m_castItemGUID
Definition: Spell.h:441
int32 m_currentBasePoints[3]
Definition: Spell.h:439
int32 m_casttime
Definition: Spell.h:556
bool IsPassiveSpell(uint32 spellId)
Definition: SpellMgr.cpp:278
float m_castPositionZ
Definition: Spell.h:685
bool m_canReflect
Definition: Spell.h:557
SpellSchoolMask
uint32 SpellVisual
Definition: DBCStructure.h:743
uint64 m_delayStart
Definition: Spell.h:570
bool IsAutoRepeatRangedSpell(SpellEntry const *spellInfo)
Definition: SpellMgr.h:464
bool NeedsComboPoints(SpellEntry const *spellInfo)
Definition: SpellMgr.h:476
int32 EffectBasePoints[3]
Definition: Spell.h:217
uint32 AttributesEx2
Definition: DBCStructure.h:681
bool m_skipCheck
Definition: Spell.h:695
uint32 DmgClass
Definition: DBCStructure.h:763
int32 m_timer
Definition: Spell.h:681
Item * m_CastItem
Definition: Spell.h:440
SpellValue *const m_spellValue
Definition: Spell.h:543
float m_castPositionX
Definition: Spell.h:683
float m_castPositionY
Definition: Spell.h:684
Player * ToPlayer()
Definition: Object.h:368
bool m_autoRepeat
Definition: Spell.h:558
Item * GetWeaponForAttack(WeaponAttackType attackType, bool useable=false) const
Definition: Player.cpp:8569
SpellSchoolMask GetSpellSchoolMask(SpellEntry const *spellInfo)
Definition: SpellMgr.h:481
uint8 m_needAliveTargetMask
Definition: Spell.h:627
uint32 Attributes
Definition: DBCStructure.h:679
uint64 GetGUID() const
Definition: Object.h:177
uint8 GetTypeId() const
Definition: Object.h:192
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
uint32 AttributesEx3
Definition: DBCStructure.h:682
const bool & IsInWorld() const
Definition: Object.h:150
Unit * unitTarget
Definition: Spell.h:583
Unit * m_originalCaster
Definition: Spell.h:547
SpellEntry const * m_triggeredByAuraSpell
Definition: Spell.h:692
TriggerSpells m_TriggerSpells
Definition: Spell.h:676
int32 m_healthLeech
Definition: Spell.h:598
Definition: Item.h:196
#define sSpellMgr
Definition: SpellMgr.h:1239
Item * itemTarget
Definition: Spell.h:584
Spell ** m_triggeringContainer
Definition: Spell.h:550
void CleanupTargetList()
Definition: Spell.cpp:711
uint64 m_originalCasterGUID
Definition: Spell.h:545
bool IsChanneledSpell(SpellEntry const *spellInfo)
Definition: SpellMgr.h:471
WeaponAttackType m_attackType
Definition: Spell.h:554
bool IsPositiveSpell(uint32 spellId)
Definition: SpellMgr.cpp:773
bool m_IsTriggeredSpell
Definition: Spell.h:687
uint32 getClassMask() const
Definition: Unit.h:1063
bool m_executedCurrently
Definition: Spell.h:576
uint32 m_customAttr
Definition: Spell.h:694
#define CLASSMASK_WAND_USERS
uint8 m_applyMultiplierMask
Definition: Spell.h:579
uint8 m_delayAtDamageCount
Definition: Spell.h:563
SpellSchoolMask m_spellSchoolMask
Definition: Spell.h:553
static Unit * GetUnit(WorldObject const &, uint64 guid)
uint8 m_cast_count
Definition: Spell.h:442
Spell ** m_selfContainer
Definition: Spell.h:549
bool m_referencedFromCurrentSpell
Definition: Spell.h:575
bool m_needComboPoints
Definition: Spell.h:578
int32 m_powerCost
Definition: Spell.h:555
Spell::~Spell ( )

Definition at line 361 of file Spell.cpp.

References m_destroyed, and m_spellValue.

362 {
363  m_destroyed = true;
364 
365  delete m_spellValue;
366 }
bool m_destroyed
Definition: Spell.h:628
SpellValue *const m_spellValue
Definition: Spell.h:543

Member Function Documentation

void Spell::_handle_finish_phase ( )

Definition at line 2743 of file Spell.cpp.

References m_caster, m_needComboPoints, m_needSpellLog, SendLogExecute(), and Object::ToPlayer().

Referenced by handle_delayed(), and handle_immediate().

2744 {
2745  // Take for real after all targets are processed
2746  if (m_needComboPoints)
2747  if (Player* player = m_caster->ToPlayer())
2748  player->ClearComboPoints();
2749 
2750  // spell log
2751  if (m_needSpellLog)
2752  SendLogExecute();
2753 }
Unit *const m_caster
Definition: Spell.h:541
Player * ToPlayer()
Definition: Object.h:368
void SendLogExecute()
Definition: Spell.cpp:3295
bool m_needSpellLog
Definition: Spell.h:577
Definition: Player.h:923
bool m_needComboPoints
Definition: Spell.h:578
void Spell::_handle_immediate_phase ( )

Definition at line 2697 of file Spell.cpp.

References CalculateDamageDoneForAllTargets(), DIMINISHING_LEVEL_1, DIMINISHING_NONE, DoAllEffectOnTarget(), SpellEntry::Effect, HandleEffects(), HandleThreatSpells(), SpellCastTargets::HasDst(), m_caster, m_customAttr, m_diminishGroup, m_diminishLevel, m_isNeedSendToClient, m_needSpellLog, m_originalCaster, m_spellInfo, m_targets, m_UniqueItemInfo, MAX_SPELL_EFFECTS, SpellCastTargets::setDst(), SPELL_ATTR_CU_DIRECT_DAMAGE, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_REQUIRE_DEST, SPELL_REQUIRE_NONE, sSpellMgr, and TakeCastItem().

Referenced by handle_delayed(), and handle_immediate().

2698 {
2699  // handle some immediate features of the spell here
2700 
2703 
2705  TakeCastItem();
2706 
2708 
2709  // initialize Diminishing Returns Data
2712 
2713  // process items
2714  for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2715  DoAllEffectOnTarget(&(*ihit));
2716 
2717  if (!m_originalCaster)
2718  return;
2719 
2720  // handle effects with SPELL_EFFECT_HANDLE_HIT mode
2721  for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2722  {
2723  // don't do anything for empty effect
2724  if (m_spellInfo->Effect[j] == 0)
2725  continue;
2726 
2727  // call effect handlers to handle destination hit
2728  if (sSpellMgr.EffectTargetType[m_spellInfo->Effect[j]] == SPELL_REQUIRE_DEST)
2729  {
2730  if (!m_targets.HasDst()) // FIXME: this will ignore dest set in effect
2732  HandleEffects(m_originalCaster, nullptr, nullptr, j);
2733  }
2734  else if (sSpellMgr.EffectTargetType[m_spellInfo->Effect[j]] == SPELL_REQUIRE_NONE)
2735  HandleEffects(m_originalCaster, nullptr, nullptr, j);
2736 
2737  // Don't do spell log, if is school damage spell
2739  m_needSpellLog = false;
2740  }
2741 }
Unit *const m_caster
Definition: Spell.h:541
bool m_isNeedSendToClient
Definition: Spell.h:559
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition: Spell.h:645
DiminishingLevels m_diminishLevel
Definition: Spell.h:589
SpellCastTargets m_targets
Definition: Spell.h:443
void TakeCastItem()
Definition: Spell.cpp:3472
uint32 Effect[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:724
void DoAllEffectOnTarget(TargetInfo *target)
Definition: Spell.cpp:920
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
Unit * m_originalCaster
Definition: Spell.h:547
bool HasDst() const
Definition: Spell.h:171
#define sSpellMgr
Definition: SpellMgr.h:1239
void setDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition: Spell.cpp:108
void CalculateDamageDoneForAllTargets()
Definition: Spell.cpp:6220
bool m_needSpellLog
Definition: Spell.h:577
void HandleThreatSpells()
Definition: Spell.cpp:3645
uint32 m_customAttr
Definition: Spell.h:694
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:670
DiminishingGroup m_diminishGroup
Definition: Spell.h:590
ACE_UINT32 uint32
Definition: Define.h:71
void HandleEffects(Unit *pUnitTarget, Item *pItemTarget, GameObject *pGOTarget, uint32 i, float DamageMultiplier=1.0)
Definition: Spell.cpp:3693
void Spell::AddGOTarget ( GameObject target,
uint32  effIndex 
)
protected

Definition at line 842 of file Spell.cpp.

References Spell::GOTargetInfo::deleted, SpellEntry::Effect, Spell::GOTargetInfo::effectMask, WorldObject::GetDistance(), Object::GetGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), m_caster, m_countOfHit, m_delayMoment, m_spellInfo, m_UniqueGOTargetInfo, Spell::GOTargetInfo::processed, SpellEntry::speed, Spell::GOTargetInfo::targetGUID, and Spell::GOTargetInfo::timeDelay.

Referenced by AddGOTarget(), CheckCast(), and SetTargetMap().

843 {
844  if (m_spellInfo->Effect[effIndex] == 0)
845  return;
846 
847  uint64 targetGUID = pVictim->GetGUID();
848 
849  // Lookup target in already in list
850  for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
851  {
852  if (ihit->deleted)
853  continue;
854 
855  if (targetGUID == ihit->targetGUID) // Found in list
856  {
857  ihit->effectMask |= (1 << effIndex); // Add only effect mask
858  return;
859  }
860  }
861 
862  // This is new target calculate data for him
863 
864  GOTargetInfo target;
865  target.targetGUID = targetGUID;
866  target.effectMask = (1 << effIndex);
867  target.processed = false; // Effects not apply on target
868  target.deleted = false;
869 
870  // Spell have speed - need calculate incoming time
871  if (m_spellInfo->speed > 0.0f)
872  {
873  // calculate spell incoming interval
874  float dist = m_caster->GetDistance(pVictim->GetPositionX(), pVictim->GetPositionY(), pVictim->GetPositionZ());
875  if (dist < 5.0f)
876  dist = 5.0f;
877  target.timeDelay = (uint64) floor(dist / m_spellInfo->speed * 1000.0f);
878  if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
879  m_delayMoment = target.timeDelay;
880  }
881  else
882  target.timeDelay = 0LL;
883 
884  ++m_countOfHit;
885 
886  // Add target to list
887  m_UniqueGOTargetInfo.push_back(target);
888 }
Unit *const m_caster
Definition: Spell.h:541
uint32 Effect[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:724
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
float GetDistance(const WorldObject *obj) const
Definition: Object.h:694
uint64 m_delayMoment
Definition: Spell.h:571
uint32 m_countOfHit
Definition: Spell.h:612
ACE_UINT64 uint64
Definition: Define.h:70
std::list< GOTargetInfo > m_UniqueGOTargetInfo
Definition: Spell.h:638
void Spell::AddGOTarget ( uint64  goGUID,
uint32  effIndex 
)
protected

Definition at line 890 of file Spell.cpp.

References AddGOTarget(), Map::GetGameObject(), WorldObject::GetMap(), and m_caster.

891 {
892  GameObject* go = m_caster->GetMap()->GetGameObject(goGUID);
893  if (go)
894  AddGOTarget(go, effIndex);
895 }
Unit *const m_caster
Definition: Spell.h:541
Map * GetMap() const
Definition: Object.h:817
void AddGOTarget(GameObject *target, uint32 effIndex)
Definition: Spell.cpp:842
GameObject * GetGameObject(uint64 guid)
Definition: Map.cpp:2636
void Spell::AddItemTarget ( Item target,
uint32  effIndex 
)
protected

Definition at line 897 of file Spell.cpp.

References SpellEntry::Effect, Spell::ItemTargetInfo::effectMask, Spell::ItemTargetInfo::item, m_spellInfo, and m_UniqueItemInfo.

Referenced by FillTargetMap(), and SetTargetMap().

898 {
899  if (m_spellInfo->Effect[effIndex] == 0)
900  return;
901 
902  // Lookup target in already in list
903  for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
904  {
905  if (pitem == ihit->item) // Found in list
906  {
907  ihit->effectMask |= (1 << effIndex); // Add only effect mask
908  return;
909  }
910  }
911 
912  // This is new target add data
913 
914  ItemTargetInfo target;
915  target.item = pitem;
916  target.effectMask = (1 << effIndex);
917  m_UniqueItemInfo.push_back(target);
918 }
std::list< ItemTargetInfo > m_UniqueItemInfo
Definition: Spell.h:645
uint32 Effect[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:724
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
void Spell::AddTriggeredSpell ( SpellEntry const *  spell)
inline

Definition at line 529 of file Spell.h.

References value.

530  {
531  m_TriggerSpells.push_back(spell);
532  }
TriggerSpells m_TriggerSpells
Definition: Spell.h:676
void Spell::AddUnitTarget ( Unit target,
uint32  effIndex 
)
protected

Definition at line 728 of file Spell.cpp.

References CheckTarget(), Spell::TargetInfo::crit, Spell::TargetInfo::damage, Spell::TargetInfo::deleted, SpellEntry::Effect, Spell::TargetInfo::effectMask, Object::GetGUID(), m_spellInfo, m_UniqueTargetInfo, Spell::TargetInfo::processed, and Spell::TargetInfo::targetGUID.

Referenced by AddUnitTarget(), CheckCast(), EffectDummy(), FillTargetMap(), HandleHitTriggerAura(), SelectMagnetTarget(), and SetTargetMap().

729 {
730  if (m_spellInfo->Effect[effIndex] == 0)
731  return;
732 
733  if (!CheckTarget(pVictim, effIndex))
734  return;
735 
736  // Lookup target in already in list
737  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
738  {
739  if (ihit->deleted)
740  continue;
741 
742  if (pVictim->GetGUID() == ihit->targetGUID) // Found in list
743  {
744  ihit->effectMask |= 1 << effIndex; // Add only effect
745  return;
746  }
747  }
748 
749  // Get spell hit result on target
750  TargetInfo target;
751  target.targetGUID = pVictim->GetGUID(); // Store target GUID
752  target.effectMask = 1 << effIndex;
753  target.processed = false; // Effects not apply on target
754  target.damage = 0;
755  target.crit = false;
756  target.deleted = false;
757 
758  // Add target to list
759  m_UniqueTargetInfo.push_back(target);
760 }
uint32 Effect[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:724
uint64 GetGUID() const
Definition: Object.h:177
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:626
bool CheckTarget(Unit *target, uint32 eff)
Definition: Spell.cpp:5872
void Spell::AddUnitTarget ( uint64  unitGUID,
uint32  effIndex 
)
protected

Definition at line 835 of file Spell.cpp.

References AddUnitTarget(), Object::GetGUID(), ObjectAccessor::GetUnit(), and m_caster.

836 {
837  Unit* unit = m_caster->GetGUID() == unitGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, unitGUID);
838  if (unit)
839  AddUnitTarget(unit, effIndex);
840 }
Unit *const m_caster
Definition: Spell.h:541
uint64 GetGUID() const
Definition: Object.h:177
void AddUnitTarget(Unit *target, uint32 effIndex)
Definition: Spell.cpp:728
static Unit * GetUnit(WorldObject const &, uint64 guid)
Definition: Unit.h:908
int32 Spell::CalculateDamage ( uint8  i,
Unit target 
)
inline

Definition at line 383 of file Spell.h.

Referenced by CheckCast(), EffectEnchantItemTmp(), HandleEffects(), and SpellDamageWeaponDmg().

384  {
385  if (m_originalCaster)
388  }
Unit *const m_caster
Definition: Spell.h:541
int32 m_currentBasePoints[3]
Definition: Spell.h:439
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
Unit * m_originalCaster
Definition: Spell.h:547
int32 CalculateSpellDamage(SpellEntry const *spellProto, uint8 effect_index, int32 basePoints, Unit const *target)
Definition: Unit.cpp:10476
int32 Spell::CalculateDamageDone ( Unit unit,
const uint32  effectMask,
float *  multiplier 
)
protected

Definition at line 6267 of file Spell.cpp.

References Unit::GetMaxNegativeAuraModifier(), IsAreaEffectTarget, MAX_SPELL_EFFECTS, SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, SPELL_EFFECT_HEAL, SPELL_EFFECT_NORMALIZED_WEAPON_DMG, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE, SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL, and SPELL_EFFECT_WEAPON_PERCENT_DAMAGE.

6268 {
6269  int32 damageDone = 0;
6270  unitTarget = unit;
6271  for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
6272  {
6273  if (effectMask & (1 << i))
6274  {
6275  m_damage = 0;
6276  damage = CalculateDamage(i, NULL);
6277 
6278  switch (m_spellInfo->Effect[i])
6279  {
6282  break;
6288  break;
6289  case SPELL_EFFECT_HEAL:
6291  break;
6292  }
6293 
6294  if (m_damage > 0)
6295  {
6297  {
6299  m_damage = m_damage * (100 + reducedPct) / 100;
6300  }
6301  }
6302  if (m_applyMultiplierMask & (1 << i))
6303  {
6305  m_damageMultipliers[i] *= multiplier[i];
6306  }
6307 
6308  damageDone += m_damage;
6309  }
6310  }
6311 
6312  return damageDone;
6313 }
int32 CalculateDamage(uint8 i, Unit *target)
Definition: Spell.h:383
bool IsAreaEffectTarget[TOTAL_SPELL_TARGETS]
Definition: SpellMgr.cpp:28
ACE_INT32 int32
Definition: Define.h:67
int32 GetMaxNegativeAuraModifier(AuraType auratype) const
Definition: Unit.cpp:3737
uint32 Effect[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:724
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
Unit * unitTarget
Definition: Spell.h:583
int32 damage
Definition: Spell.h:586
void SpellDamageHeal(SpellEffIndex effIndex)
uint32 EffectImplicitTargetB[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:732
SpellEffIndex
Definition: SharedDefines.h:24
uint32 EffectImplicitTargetA[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:731
int32 m_damage
Definition: Spell.h:596
void SpellDamageSchoolDmg(SpellEffIndex effIndex)
void SpellDamageWeaponDmg(SpellEffIndex effIndex)
float m_damageMultipliers[3]
Definition: Spell.h:580
uint8 m_applyMultiplierMask
Definition: Spell.h:579
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:670
ACE_UINT32 uint32
Definition: Define.h:71
void Spell::CalculateDamageDoneForAllTargets ( )
protected

Definition at line 6220 of file Spell.cpp.

References Spell::TargetInfo::crit, Spell::TargetInfo::damage, Spell::TargetInfo::effectMask, Object::GetGUID(), Unit::GetSpellModOwner(), ObjectAccessor::GetUnit(), MAX_SPELL_EFFECTS, Spell::TargetInfo::missCondition, Spell::TargetInfo::reflectResult, SPELL_MISS_NONE, SPELL_MISS_REFLECT, SPELLMOD_EFFECT_PAST_FIRST, and Spell::TargetInfo::targetGUID.

Referenced by _handle_immediate_phase().

6221 {
6222  float multiplier[3];
6223  for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
6224  {
6225  if (m_applyMultiplierMask & (1 << i))
6226  {
6227  // Get multiplier
6228  multiplier[i] = m_spellInfo->DmgMultiplier[i];
6229  // Apply multiplier mods
6230  if (m_originalCaster)
6231  if (Player* modOwner = m_originalCaster->GetSpellModOwner())
6232  modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_EFFECT_PAST_FIRST, multiplier[i], this);
6233  }
6234  }
6235 
6236  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
6237  {
6238  if (ihit->deleted)
6239  continue;
6240 
6241  TargetInfo& target = *ihit;
6242 
6243  uint32 mask = target.effectMask;
6244  if (!mask)
6245  continue;
6246 
6247  Unit* unit = m_caster->GetGUID() == target.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target.targetGUID);
6248  if (!unit)
6249  continue;
6250 
6251  if (target.missCondition == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
6252  {
6253  target.damage += CalculateDamageDone(unit, mask, multiplier);
6255  }
6256  else if (target.missCondition == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
6257  {
6258  if (target.reflectResult == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
6259  {
6260  target.damage += CalculateDamageDone(m_caster, mask, multiplier);
6262  }
6263  }
6264  }
6265 }
Unit *const m_caster
Definition: Spell.h:541
int32 CalculateDamageDone(Unit *unit, const uint32 effectMask, float *multiplier)
Definition: Spell.cpp:6267
float DmgMultiplier[3]
Definition: DBCStructure.h:766
uint64 GetGUID() const
Definition: Object.h:177
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
Unit * m_originalCaster
Definition: Spell.h:547
bool isSpellCrit(Unit *victim, SpellEntry const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType=BASE_ATTACK)
Definition: Unit.cpp:8497
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:626
WeaponAttackType m_attackType
Definition: Spell.h:554
Player * GetSpellModOwner() const
Definition: Unit.cpp:11862
uint8 m_applyMultiplierMask
Definition: Spell.h:579
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:670
SpellSchoolMask m_spellSchoolMask
Definition: Spell.h:553
static Unit * GetUnit(WorldObject const &, uint64 guid)
ACE_UINT32 uint32
Definition: Define.h:71
Definition: Unit.h:908
Definition: Player.h:923
void Spell::CalculateHitResults ( )

Definition at line 762 of file Spell.cpp.

References Spell::TargetInfo::effectMask, WorldObject::GetDistance(), Object::GetGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), ObjectAccessor::GetUnit(), IsChanneledSpell(), Unit::IsImmuneToSpellEffect(), m_canReflect, m_caster, m_countOfHit, m_countOfMiss, m_delayMoment, m_IsTriggeredSpell, m_needAliveTargetMask, m_originalCaster, m_skipCheck, m_spellInfo, m_triggeredByAuraSpell, m_UniqueTargetInfo, Spell::TargetInfo::missCondition, Spell::TargetInfo::reflectResult, SpellEntry::speed, SPELL_MISS_EVADE, SPELL_MISS_IMMUNE, SPELL_MISS_NONE, SPELL_MISS_PARRY, SPELL_MISS_REFLECT, Unit::SpellHitResult(), Spell::TargetInfo::targetGUID, and Spell::TargetInfo::timeDelay.

Referenced by cast().

763 {
764  for (std::list<TargetInfo>::iterator it = m_UniqueTargetInfo.begin(); it != m_UniqueTargetInfo.end(); ++it)
765  {
766  TargetInfo& target = *it;
767 
768  Unit* pVictim = m_caster->GetGUID() == target.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target.targetGUID);
769 
770  if (!pVictim)
771  continue;
772 
773  // Remove effects the target is immune to
774  for (uint32 effIndex = 0; effIndex < 3; ++effIndex)
775  {
776  if (target.effectMask & (1 << effIndex))
777  if (pVictim->IsImmuneToSpellEffect(m_spellInfo, effIndex, false))
778  target.effectMask &= ~(1 << effIndex);
779 
781  if (target.effectMask & (1 << effIndex))
782  m_needAliveTargetMask |= (1 << effIndex);
783  }
784 
785  // Calculate hit result
786  if (m_originalCaster)
787  {
788  bool canMiss = (m_triggeredByAuraSpell || !m_IsTriggeredSpell);
789  target.missCondition = m_originalCaster->SpellHitResult(pVictim, m_spellInfo, m_canReflect, canMiss);
790  if (m_skipCheck && target.missCondition != SPELL_MISS_IMMUNE)
791  target.missCondition = SPELL_MISS_NONE;
792  }
793  else
794  target.missCondition = SPELL_MISS_EVADE; //SPELL_MISS_NONE;
795 
796  if (target.missCondition == SPELL_MISS_NONE)
797  ++m_countOfHit;
798  else
799  ++m_countOfMiss;
800 
801  // Spell have speed - need calculate incoming time
802  if (m_spellInfo->speed > 0.0f)
803  {
804  // calculate spell incoming interval
805  float dist = m_caster->GetDistance(pVictim->GetPositionX(), pVictim->GetPositionY(), pVictim->GetPositionZ());
806 
807  if (dist < 5.0f)
808  dist = 5.0f;
809  target.timeDelay = (uint64)std::floor(dist / m_spellInfo->speed * 1000.0f);
810 
811  // Calculate minimum incoming time
812  if (m_delayMoment == 0 || m_delayMoment > target.timeDelay)
813  m_delayMoment = target.timeDelay;
814  }
815  else
816  target.timeDelay = 0LL;
817 
818  // If target reflect spell back to caster
819  if (target.missCondition == SPELL_MISS_REFLECT)
820  {
821  // Calculate reflected spell result on caster
822  target.reflectResult = m_caster->SpellHitResult(m_caster, m_spellInfo, m_canReflect);
823 
824  if (target.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
825  target.reflectResult = SPELL_MISS_PARRY;
826 
827  // Increase time interval for reflected spells by 1.5
828  target.timeDelay += target.timeDelay >> 1;
829  }
830  else
831  target.reflectResult = SPELL_MISS_NONE;
832  }
833 }
SpellMissInfo SpellHitResult(Unit *victim, SpellEntry const *spell, bool canReflect=false, bool canMiss=true)
Definition: Unit.cpp:3062
Unit *const m_caster
Definition: Spell.h:541
bool m_canReflect
Definition: Spell.h:557
bool m_skipCheck
Definition: Spell.h:695
uint8 m_needAliveTargetMask
Definition: Spell.h:627
uint64 GetGUID() const
Definition: Object.h:177
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
Unit * m_originalCaster
Definition: Spell.h:547
SpellEntry const * m_triggeredByAuraSpell
Definition: Spell.h:692
float GetDistance(const WorldObject *obj) const
Definition: Object.h:694
float GetPositionY() const
Definition: Position.h:98
uint64 m_delayMoment
Definition: Spell.h:571
float GetPositionZ() const
Definition: Position.h:99
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:626
uint32 m_countOfHit
Definition: Spell.h:612
bool IsChanneledSpell(SpellEntry const *spellInfo)
Definition: SpellMgr.h:471
ACE_UINT64 uint64
Definition: Define.h:70
bool m_IsTriggeredSpell
Definition: Spell.h:687
uint32 m_countOfMiss
Definition: Spell.h:613
static Unit * GetUnit(WorldObject const &, uint64 guid)
ACE_UINT32 uint32
Definition: Define.h:71
float GetPositionX() const
Definition: Position.h:97
Definition: Unit.h:908
virtual bool IsImmuneToSpellEffect(SpellEntry const *spellInfo, uint32 index, bool castOnSelf) const
Definition: Unit.cpp:9042
bool Spell::CanAutoCast ( Unit target)

Definition at line 5182 of file Spell.cpp.

References CheckPetCast(), SpellEntry::Effect, FillTargetMap(), Unit::GetAuras(), Object::GetGUID(), Unit::HasAura(), SpellEntry::Id, IsAreaAuraEffect(), m_spellInfo, m_UniqueTargetInfo, SPELL_CAST_OK, SPELL_EFFECT_APPLY_AURA, SPELL_FAILED_UNIT_NOT_INFRONT, and SpellEntry::StackAmount.

Referenced by PetAI::UpdateAI().

5183 {
5184  uint64 targetguid = target->GetGUID();
5185 
5186  for (uint32 j = 0; j < 3; j++)
5187  {
5189  {
5190  if (m_spellInfo->StackAmount <= 1)
5191  {
5192  if (target->HasAura(m_spellInfo->Id, j))
5193  return false;
5194  }
5195  else
5196  {
5197  if (target->GetAuras().count(Unit::spellEffectPair(m_spellInfo->Id, j)) >= m_spellInfo->StackAmount)
5198  return false;
5199  }
5200  }
5201  else if (IsAreaAuraEffect(m_spellInfo->Effect[j]))
5202  {
5203  if (target->HasAura(m_spellInfo->Id, j))
5204  return false;
5205  }
5206  }
5207 
5208  FillTargetMap();
5209  SpellCastResult result = CheckPetCast(target);
5210 
5211  if (result == SPELL_CAST_OK || result == SPELL_FAILED_UNIT_NOT_INFRONT)
5212  {
5213  //check if among target units, our WANTED target is as well (->only self cast spells return false)
5214  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
5215  {
5216  if (ihit->deleted)
5217  continue;
5218 
5219  if (ihit->targetGUID == targetguid)
5220  return true;
5221  }
5222  }
5223  return false; //target invalid
5224 }
bool IsAreaAuraEffect(uint32 effect)
Definition: SpellMgr.h:432
AuraMap & GetAuras()
Definition: Unit.h:1739
std::pair< uint32, uint8 > spellEffectPair
Definition: Unit.h:915
uint32 Effect[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:724
uint64 GetGUID() const
Definition: Object.h:177
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
uint32 StackAmount
Definition: DBCStructure.h:717
void FillTargetMap()
Definition: Spell.cpp:389
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:626
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:4758
ACE_UINT64 uint64
Definition: Define.h:70
SpellCastResult
ACE_UINT32 uint32
Definition: Define.h:71
bool HasAura(uint32 spellId, uint8 effIndex=0) const
Definition: Unit.h:1262
void Spell::cancel ( bool  sendInterrupt = true)

Definition at line 2340 of file Spell.cpp.

References SpellEntry::Attributes, finish(), Object::GetGUID(), Object::GetTypeId(), ObjectAccessor::GetUnit(), SpellEntry::Id, Unit::IsAlive(), IsChanneledSpell(), m_autoRepeat, m_caster, m_selfContainer, m_spellInfo, m_spellState, m_UniqueTargetInfo, Unit::RemoveAurasByCasterSpell(), Unit::RemoveDynObject(), Unit::RemoveGameObject(), Player::RemoveSpellCooldown(), SendCastResult(), SendChannelUpdate(), SendInterrupted(), SetReferencedFromCurrent(), SPELL_ATTR0_DISABLED_WHILE_ACTIVE, SPELL_FAILED_INTERRUPTED, SPELL_MISS_NONE, SPELL_STATE_CASTING, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, SPELL_STATE_PREPARING, Object::ToPlayer(), and TYPEID_PLAYER.

Referenced by SpellEvent::Abort(), cast(), SpellEvent::Execute(), Unit::InterruptSpell(), Unit::RemoveAura(), update(), and SpellEvent::~SpellEvent().

2341 {
2343  return;
2344 
2345  uint32 oldState = m_spellState;
2347 
2348  m_autoRepeat = false;
2349  switch (oldState)
2350  {
2351  case SPELL_STATE_PREPARING:
2352  case SPELL_STATE_DELAYED:
2353  {
2354  SendInterrupted(0);
2355  if (sendInterrupt)
2357  }
2358  break;
2359 
2360  case SPELL_STATE_CASTING:
2361  {
2362  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2363  {
2364  if (ihit->deleted)
2365  continue;
2366 
2367  if (ihit->missCondition == SPELL_MISS_NONE)
2368  {
2369  Unit* unit = m_caster->GetGUID() == (*ihit).targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
2370  if (unit && unit->IsAlive())
2372  }
2373  }
2374 
2376  SendChannelUpdate(0);
2377 
2378  // Do not send interrupt for channeling spells to avoid a visual bug
2379  // that happens when a caster recasts the spell before the channeling ended
2381  {
2382  SendInterrupted(0);
2383  if (sendInterrupt)
2385  }
2386  }
2387  break;
2388  default:
2389  {
2390  } break;
2391  }
2392 
2393  SetReferencedFromCurrent(false);
2394  if (m_selfContainer && *m_selfContainer == this)
2395  *m_selfContainer = nullptr;
2396 
2398  if (IsChanneledSpell(m_spellInfo)) // if not channeled then the object for the current cast wasn't summoned yet
2399  {
2401 
2402  // reset cooldown state for disabled while active spells
2403  if (m_caster->GetTypeId() == TYPEID_PLAYER)
2404  {
2407  }
2408  }
2409 
2410  //set state back so finish will be processed
2411  m_spellState = oldState;
2412 
2413  finish(false);
2414 }
Unit *const m_caster
Definition: Spell.h:541
uint32 m_spellState
Definition: Spell.h:680
Player * ToPlayer()
Definition: Object.h:368
bool m_autoRepeat
Definition: Spell.h:558
uint32 Attributes
Definition: DBCStructure.h:679
uint64 GetGUID() const
Definition: Object.h:177
void RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID)
Definition: Unit.cpp:4190
uint8 GetTypeId() const
Definition: Object.h:192
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
void finish(bool ok=true)
Definition: Spell.cpp:2969
void RemoveDynObject(uint32 spellid)
Definition: Unit.cpp:4685
bool IsAlive() const
Definition: Unit.h:1336
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition: Player.cpp:3298
void SendChannelUpdate(uint32 time)
Definition: Spell.cpp:3410
void SendCastResult(SpellCastResult result)
Definition: Spell.cpp:3039
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:626
bool IsChanneledSpell(SpellEntry const *spellInfo)
Definition: SpellMgr.h:471
void RemoveGameObject(GameObject *gameObj, bool del)
Definition: Unit.cpp:4760
static Unit * GetUnit(WorldObject const &, uint64 guid)
void SetReferencedFromCurrent(bool yes)
Definition: Spell.h:482
void SendInterrupted(uint8 result)
Definition: Spell.cpp:3396
ACE_UINT32 uint32
Definition: Define.h:71
Spell ** m_selfContainer
Definition: Spell.h:549
Definition: Unit.h:908
SpellCastResult Spell::CanOpenLock ( uint32  effIndex,
uint32  lockid,
SkillType skillid,
int32 reqSkillValue,
int32 skillValue 
)
protected

Definition at line 6315 of file Spell.cpp.

References LockEntry::key, LockEntry::keytype, LOCK_KEY_ITEM, LOCK_KEY_SKILL, LockEntry::requiredlockskill, SKILL_NONE, SkillByLockType(), sLockStore, SPELL_CAST_OK, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_LOW_CASTLEVEL, and TYPEID_PLAYER.

Referenced by CheckCast().

6316 {
6317  if (!lockId) // possible case for GO and maybe for items.
6318  return SPELL_CAST_OK;
6319 
6320  // Get LockInfo
6321  LockEntry const* lockInfo = sLockStore.LookupEntry(lockId);
6322 
6323  if (!lockInfo)
6324  return SPELL_FAILED_BAD_TARGETS;
6325 
6326  bool reqKey = false; // some locks not have reqs
6327 
6328  for (int j = 0; j < 5; ++j)
6329  {
6330  switch (lockInfo->keytype[j])
6331  {
6332  // check key item (many fit cases can be)
6333  case LOCK_KEY_ITEM:
6334  if (lockInfo->key[j] && m_CastItem && m_CastItem->GetEntry() == lockInfo->key[j])
6335  return SPELL_CAST_OK;
6336  reqKey = true;
6337  break;
6338  // check key skill (only single first fit case can be)
6339  case LOCK_KEY_SKILL:
6340  {
6341  reqKey = true;
6342 
6343  // wrong locktype, skip
6344  if (uint32(m_spellInfo->EffectMiscValue[effIndex]) != lockInfo->key[j])
6345  continue;
6346 
6347  skillId = SkillByLockType(LockType(lockInfo->key[j]));
6348 
6349  if (skillId != SKILL_NONE)
6350  {
6351  reqSkillValue = lockInfo->requiredlockskill;
6352 
6353  // castitem check: rogue using skeleton keys. the skill values should not be added in this case.
6354  skillValue = m_CastItem || m_caster->GetTypeId() != TYPEID_PLAYER ?
6355  0 : m_caster->ToPlayer()->GetSkillValue(skillId);
6356 
6357  if (skillValue < reqSkillValue)
6359  }
6360 
6361  return SPELL_CAST_OK;
6362  }
6363  }
6364  }
6365 
6366  if (reqKey)
6367  return SPELL_FAILED_BAD_TARGETS;
6368 
6369  return SPELL_CAST_OK;
6370 }
Unit *const m_caster
Definition: Spell.h:541
uint32 requiredlockskill
Definition: DBCStructure.h:500
DBCStorage< LockEntry > sLockStore(LockEntryfmt)
Item * m_CastItem
Definition: Spell.h:440
LockType
Player * ToPlayer()
Definition: Object.h:368
uint8 GetTypeId() const
Definition: Object.h:192
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
uint32 key[5]
Definition: DBCStructure.h:497
uint32 keytype[5]
Definition: DBCStructure.h:495
uint16 GetSkillValue(uint32 skill) const
Definition: Player.cpp:5480
int32 EffectMiscValue[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:739
SkillType SkillByLockType(LockType locktype)
uint32 GetEntry() const
Definition: Object.h:186
ACE_UINT32 uint32
Definition: Define.h:71
void Spell::cast ( bool  skipCheck = false)

Definition at line 2416 of file Spell.cpp.

References SpellEntry::AttributesEx, AURA_INTERRUPT_FLAG_ATTACK, CalculateHitResults(), Unit::CalculateSpellDamage(), cancel(), Unit::CastSpell(), CHEAT_COOLDOWN, CheckCast(), CheckPower(), Unit::ClearUnitState(), EffectCharge(), SpellEntry::EffectTriggerSpell, FillTargetMap(), finish(), Unit::GetAurasByType(), Player::GetCommandStatus(), ObjectAccessor::GetCreature(), Unit::GetPetGUID(), Object::GetTypeId(), SpellCastTargets::getUnitTarget(), SpellCastTargets::getUnitTargetGUID(), handle_immediate(), Unit::HasUnitState(), SpellEntry::Id, IsAffectedBy(), IsAutoRepeat(), IsChanneledSpell(), IsNonCombatSpell(), Unit::IsNonMeleeSpellCast(), m_caster, m_ChanceTriggerSpells, m_customAttr, m_immediateHandled, m_IsTriggeredSpell, m_spellInfo, m_spellState, m_targets, Unit::RemoveAurasDueToSpell(), Unit::RemoveAurasWithInterruptFlags(), Player::RemoveSpellCooldown(), SendCastResult(), SendInterrupted(), SendSpellCooldown(), SendSpellGo(), SetDelayStart(), SetExecutedCurrently(), Unit::SetInFront(), SpellEntry::speed, SPELL_ATTR1_DISMISS_PET, SPELL_ATTR_CU_CHARGE, SPELL_ATTR_CU_LINK_CAST, SPELL_AURA_ADD_TARGET_TRIGGER, SPELL_CAST_OK, SPELL_STATE_DELAYED, SPELL_STATE_FINISHED, sSpellMgr, sSpellStore, TakePower(), TakeReagents(), Object::ToPlayer(), TYPEID_PLAYER, UNIT_STATE_CASTING, UpdatePointers(), and SpellCastTargets::updateTradeSlotItem().

Referenced by Unit::AttackerStateUpdate(), prepare(), and update().

2417 {
2418  if (m_spellInfo->Id > MAX_SPELL_ID)
2419  return;
2420 
2421  // update pointers base at GUIDs to prevent access to non-existed already object
2422  UpdatePointers();
2423 
2424  // cancel at lost main target unit
2426  {
2427  cancel();
2428  return;
2429  }
2430 
2431  SetExecutedCurrently(true);
2432  SpellCastResult castResult = SPELL_CAST_OK;
2433 
2436 
2437  if (!m_IsTriggeredSpell)
2438  {
2439  castResult = CheckPower();
2440  if (castResult != SPELL_CAST_OK)
2441  {
2442  SendCastResult(castResult);
2443  finish(false);
2444  SetExecutedCurrently(false);
2445  return;
2446  }
2447  }
2448 
2449  // triggered cast called from Spell::prepare where it was already checked
2450  if (!skipCheck)
2451  {
2452  FillTargetMap();
2453 
2454  castResult = CheckCast(false);
2455  if (castResult != SPELL_CAST_OK)
2456  {
2457  SendCastResult(castResult);
2458  SendInterrupted(0);
2459  finish(false);
2460  SetExecutedCurrently(false);
2461  return;
2462  }
2463  }
2464  // Check if some auras need to be interrupted when casting combat auto-repeating spells
2467 
2468  if (m_spellState == SPELL_STATE_FINISHED) // stop cast if spell marked as finish somewhere in Take*/FillTargetMap
2469  {
2470  SendInterrupted(0);
2471  finish(false);
2472  SetExecutedCurrently(false);
2473  return;
2474  }
2475 
2478  pet->DespawnOrUnsummon();
2479 
2480  // traded items have trade slot instead of guid in m_itemTargetGUID
2481  // set to real guid to be sent later to the client
2483 
2484  if (!m_IsTriggeredSpell)
2485  TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
2486 
2487  // CAST SPELL
2489 
2490  // calc miss, reflect, parry, etc.
2492 
2493  SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
2494 
2495  //handle SPELL_AURA_ADD_TARGET_TRIGGER auras
2496  //are there any spells need to be triggered after hit?
2498  for (Unit::AuraList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
2499  {
2500  SpellEntry const* auraSpellInfo = (*i)->GetSpellProto();
2501  uint32 auraSpellIdx = (*i)->GetEffIndex();
2502  if (IsAffectedBy(auraSpellInfo, auraSpellIdx))
2503  {
2504  if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(auraSpellInfo->EffectTriggerSpell[auraSpellIdx]))
2505  {
2506  // Calculate chance at that moment (can be depend for example from combo points)
2507  int32 chance = m_caster->CalculateSpellDamage(auraSpellInfo, auraSpellIdx, (*i)->GetBasePoints(), NULL);
2508  m_ChanceTriggerSpells.push_back(std::make_pair(spellInfo, chance * (*i)->GetStackAmount()));
2509  }
2510  }
2511  }
2512 
2515 
2516  // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
2517  // @TODO: Find similarities for spells such as Ruthlessness and run the proper check here
2518  if ((m_spellInfo->speed > 0.0f && !IsChanneledSpell(m_spellInfo)) || m_spellInfo->Id == 14157)
2519  {
2520  // Okay, maps created, now prepare flags
2521  m_immediateHandled = false;
2523  SetDelayStart(0);
2524 
2525  if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !m_caster->IsNonMeleeSpellCast(false, false, true))
2527  }
2528  else
2529  {
2530  // Immediate spell, no big deal
2531  handle_immediate();
2532  }
2533 
2534  // combo points should not be taken before SPELL_AURA_ADD_TARGET_TRIGGER auras are handled
2535  if (!m_IsTriggeredSpell)
2536  TakePower();
2537 
2539  {
2540  if (const std::vector<int32>* spell_triggered = sSpellMgr.GetSpellLinked(m_spellInfo->Id))
2541  {
2542  for (std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
2543  if (*i < 0)
2545  else
2547  }
2548  }
2549 
2550  // Clear spell cooldowns after every spell is cast if .cheat cooldown is enabled.
2551  if (m_caster->GetTypeId() == TYPEID_PLAYER)
2552  {
2555  }
2556 
2557  SetExecutedCurrently(false);
2558 }
void handle_immediate()
Definition: Spell.cpp:2560
Unit *const m_caster
Definition: Spell.h:541
uint32 m_spellState
Definition: Spell.h:680
uint32 AttributesEx
Definition: DBCStructure.h:680
uint32 EffectTriggerSpell[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:741
void UpdatePointers()
Definition: Spell.cpp:5812
SpellCastTargets m_targets
Definition: Spell.h:443
bool IsNonMeleeSpellCast(bool withDelayed, bool skipChanneled=false, bool skipAutorepeat=false) const
Definition: Unit.cpp:3578
void SendSpellGo()
Definition: Spell.cpp:3146
SpellCastResult CheckPower()
Definition: Spell.cpp:5318
bool IsAutoRepeat() const
Definition: Spell.h:449
Unit * getUnitTarget() const
Definition: Spell.h:118
ACE_INT32 int32
Definition: Define.h:67
std::list< Aura * > AuraList
Definition: Unit.h:917
bool m_immediateHandled
Definition: Spell.h:572
void cancel(bool sendInterrupt=true)
Definition: Spell.cpp:2340
void CalculateHitResults()
Definition: Spell.cpp:762
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
void SetExecutedCurrently(bool yes)
Definition: Spell.h:490
Player * ToPlayer()
Definition: Object.h:368
void SetInFront(Unit const *target)
Definition: Unit.h:1675
bool GetCommandStatus(uint32 command) const
Definition: Player.h:1049
void RemoveAurasDueToSpell(uint32 spellId, Aura *except=NULL)
Definition: Unit.cpp:4402
void ClearUnitState(uint32 f)
Definition: Unit.h:1034
uint8 GetTypeId() const
Definition: Object.h:192
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
void finish(bool ok=true)
Definition: Spell.cpp:2969
void TakePower()
Definition: Spell.cpp:3534
static Creature * GetCreature(WorldObject const &u, uint64 guid)
void RemoveAurasWithInterruptFlags(uint32 flags, uint32 except=0)
Definition: Unit.cpp:773
ChanceTriggerSpells m_ChanceTriggerSpells
Definition: Spell.h:678
void CastSpell(Unit *Victim, uint32 spellId, bool triggered, Item *castItem=NULL, Aura *triggeredByAura=NULL, uint64 originalCaster=0)
Definition: Unit.cpp:1260
void RemoveSpellCooldown(uint32 spell_id, bool update=false)
Definition: Player.cpp:3298
SpellEffIndex
Definition: SharedDefines.h:24
#define sSpellMgr
Definition: SpellMgr.h:1239
void SendCastResult(SpellCastResult result)
Definition: Spell.cpp:3039
void FillTargetMap()
Definition: Spell.cpp:389
bool IsChanneledSpell(SpellEntry const *spellInfo)
Definition: SpellMgr.h:471
void SendSpellCooldown()
Definition: Spell.cpp:2755
int32 CalculateSpellDamage(SpellEntry const *spellProto, uint8 effect_index, int32 basePoints, Unit const *target)
Definition: Unit.cpp:10476
bool m_IsTriggeredSpell
Definition: Spell.h:687
uint64 GetPetGUID() const
Definition: Unit.h:1378
SpellCastResult CheckCast(bool strict)
Definition: Spell.cpp:3735
void SetDelayStart(uint64 m_time)
Definition: Spell.h:498
uint32 m_customAttr
Definition: Spell.h:694
void TakeReagents()
Definition: Spell.cpp:3590
bool IsNonCombatSpell(SpellEntry const *spellInfo)
Definition: SpellMgr.h:315
bool HasUnitState(const uint32 f) const
Definition: Unit.h:1030
SpellCastResult
AuraList const & GetAurasByType(AuraType type) const
Definition: Unit.h:1747
void SendInterrupted(uint8 result)
Definition: Spell.cpp:3396
bool IsAffectedBy(SpellEntry const *spellInfo, uint32 effectId)
Definition: Spell.cpp:5828
ACE_UINT32 uint32
Definition: Define.h:71
uint64 getUnitTargetGUID() const
Definition: Spell.h:114
void updateTradeSlotItem()
Definition: Spell.h:156
void EffectCharge(SpellEffIndex effIndex)
SpellCastResult Spell::CheckCast ( bool  strict)

Definition at line 3735 of file Spell.cpp.

References InstanceTemplate::access_id, AddGOTarget(), AddUnitTarget(), InstanceTemplate::allowMount, SpellEntry::AreaId, SpellEntry::Attributes, SpellEntry::AttributesEx, SpellEntry::AttributesEx2, SpellEntry::AttributesEx3, SpellEntry::AttributesEx4, AURA_INTERRUPT_FLAG_NOT_SEATED, SpellEntry::AuraInterruptFlags, SpellEntry::baseLevel, CalculateDamage(), CanOpenLock(), Pet::CanTakeMoreActiveSpells(), Player::CanUseBattlegroundObject(), SpellEntry::CasterAuraState, SpellEntry::CasterAuraStateNot, SummonPropertiesEntry::Category, CheckCasterAuras(), CheckDummyCast(), CheckItems(), CheckPower(), CheckRange(), CheckTargetCreatureType(), CLASS_HUNTER, Oregon::ComputeCellCoord(), CONDITION_SOURCE_TYPE_SPELL, CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET, CONDITION_SPELL_SCRIPT_TARGET, Condition::ConditionTarget, CONFIG_RAF_LEVEL_LIMIT, VMAP::VMapFactory::createOrGetVMapManager(), Player::doesOwnPet(), SpellEntry::Effect, SpellEntry::EffectApplyAuraName, SpellEntry::EffectBasePoints, SpellEntry::EffectImplicitTargetA, SpellEntry::EffectImplicitTargetB, SpellEntry::EffectMiscValue, SpellEntry::EffectMiscValueB, SpellEntry::EffectTriggerSpell, Condition::ErrorType, focusObject, FORM_AQUA, FORM_BEAR, FORM_CAT, FORM_CREATUREBEAR, FORM_DIREBEAR, FORM_FLIGHT, FORM_FLIGHT_EPIC, FORM_GHOSTWOLF, FORM_MOONKIN, FORM_SPIRITOFREDEMPTION, FORM_TRAVEL, FORM_TREE, GAMEOBJECT_TYPE_TRAP, WorldObject::GetAreaId(), Unit::GetAuras(), Player::GetBattleground(), Player::GetBoundInstance(), Unit::GetCharmerGUID(), Unit::GetCharmerOrOwnerGUID(), Unit::GetCharmGUID(), Unit::getClass(), Creature::GetCreatureTemplate(), Pet::GetCurrentFoodBenefitLevel(), Map::GetDifficulty(), WorldObject::GetDistance(), Unit::GetDynObject(), GetErrorAtShapeshiftedCast(), GameObject::GetGOInfo(), SpellCastTargets::getGOTarget(), Unit::GetGuardianPet(), Unit::GetHealth(), Map::GetId(), ObjectMgr::GetInstanceTemplate(), Player::GetItemByGuid(), SpellCastTargets::getItemTarget(), SpellCastTargets::getItemTargetGUID(), Oregon::NearestGameObjectEntryInObjectRangeCheck::GetLastRange(), Oregon::NearestCreatureEntryWithLiveStateInObjectRangeCheck::GetLastRange(), Unit::getLevel(), WorldObject::GetMap(), WorldLocation::GetMapId(), Unit::GetMaxHealth(), Unit::GetMaxPower(), WorldObject::GetName(), Position::GetOrientation(), Pet::GetOwner(), Player::GetPet(), Unit::GetPetGUID(), Position::GetPositionX(), Position::GetPositionY(), Position::GetPositionZ(), Unit::getPowerType(), Item::GetProto(), CreatureInfo::GetRequiredLootSkill(), Player::GetSelection(), Player::GetSkillValue(), GetSpellMaxRange(), GetSpellRecoveryTime(), Player::GetTransport(), Object::GetTypeId(), SpellCastTargets::getUnitTarget(), WorldObject::GetZoneId(), SpellEntry::HasAttribute(), Unit::HasAuraState(), Object::HasByteFlag(), Object::HasFlag(), Unit::HasHigherRankOfAura(), WorldObject::HasInArc(), Unit::HasShapeshiftChangingModel(), Unit::HasStealthAura(), Pet::HasTPForSpell(), Unit::HasUnitMovementFlag(), Unit::HasUnitState(), Unit::HasUnitTypeMask(), Pet::HaveInDiet(), SpellEntry::Id, IN_MILLISECONDS, Player::InBattleground(), irand(), Unit::IsAlive(), IsAreaOfEffectSpell(), IsAutoRepeat(), Map::IsBattlegroundOrArena(), Unit::IsCritter(), IsDeathOnlySpell(), IsDispel(), Map::IsDungeon(), MapEntry::IsDungeon(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), Unit::IsInCombat(), Unit::IsInFlight(), Unit::IsInPartyWith(), Player::IsInSameRaidWith(), Unit::IsInWater(), Object::IsInWorld(), VMAP::IVMapManager::isLineOfSightCalcEnabled(), Item::IsLocked(), Loot::isLooted(), Unit::IsMounted(), Unit::isMoving(), Map::IsOutdoors(), IsPassiveSpell(), Player::isPetDeadAndRemoved(), Player::isPetDismissed(), Unit::IsPetInCombat(), Unit::IsPlayer(), IsPositiveEffect(), IsPositiveSpell(), MapEntry::IsRaid(), IsSpellAllowedInLocation(), IsSpellIgnoringLOS(), Creature::IsTrigger(), WorldObject::IsWithinLOSInMap(), ItemTemplate::ItemLevel, ItemTemplate::LockID, Creature::loot, m_caster, m_CastItem, m_customAttr, Unit::m_form, m_IsTriggeredSpell, m_needComboPoints, m_originalCaster, m_selfContainer, m_spellInfo, SpellCastTargets::m_targetMask, m_targets, m_triggeredByAuraSpell, m_UniqueTargetInfo, MAX_SPELL_EFFECTS, ConditionSourceInfo::mConditionTargets, MINUTE, ConditionSourceInfo::mLastFailedCondition, MOVEMENTFLAG_FALLINGFAR, POWER_MANA, RAF_ERR_NO_TARGET, RAF_ERR_NOT_IN_PARTY, RAF_ERR_ONLY_UNTIL_60_2, SpellEntry::rangeIndex, Unit::RemoveAurasDueToSpell(), sAreaStore, Player::Satisfy(), sConditionMgr, Player::SendReferFriendError(), SpellCastTargets::setDst(), Cell::SetNoCreate(), SKILL_LOCKPICKING, SKILL_NONE, sLog, sMapStore, sObjectMgr, SPELL_ATTR0_CANT_USED_IN_COMBAT, SPELL_ATTR0_CASTABLE_WHILE_DEAD, SPELL_ATTR0_CASTABLE_WHILE_MOUNTED, SPELL_ATTR0_INDOORS_ONLY, SPELL_ATTR0_ONLY_STEALTHED, SPELL_ATTR0_OUTDOORS_ONLY, SPELL_ATTR0_PASSIVE, SPELL_ATTR1_CANT_TARGET_IN_COMBAT, SPELL_ATTR1_DISMISS_PET, SPELL_ATTR2_REQUIRE_TAPPED_BY_CASTER, SPELL_ATTR3_BATTLEGROUND, SPELL_ATTR3_PLAYERS_ONLY, SPELL_ATTR4_NOT_USABLE_IN_ARENA, SPELL_ATTR4_USABLE_IN_ARENA, SPELL_ATTR_CU_CAST_BY_ITEM_ONLY, SPELL_AURA_AOE_CHARM, SPELL_AURA_BIND_SIGHT, SPELL_AURA_DUMMY, SPELL_AURA_FLY, SPELL_AURA_MOD_CHARM, SPELL_AURA_MOD_FLIGHT_SPEED_MOUNTED, SPELL_AURA_MOD_POSSESS, SPELL_AURA_MOD_POSSESS_PET, SPELL_AURA_MOUNTED, SPELL_AURA_PERIODIC_MANA_LEECH, SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS, SPELL_AURA_WATER_WALK, SPELL_CAST_OK, SPELL_EFFECT_APPLY_AURA, SPELL_EFFECT_CHARGE, SPELL_EFFECT_DISMISS_PET, SPELL_EFFECT_DUMMY, SPELL_EFFECT_ENERGIZE, SPELL_EFFECT_FEED_PET, SPELL_EFFECT_LEAP, SPELL_EFFECT_LEARN_PET_SPELL, SPELL_EFFECT_LEARN_SPELL, SPELL_EFFECT_OPEN_LOCK, SPELL_EFFECT_OPEN_LOCK_ITEM, SPELL_EFFECT_PERSISTENT_AREA_AURA, SPELL_EFFECT_POWER_BURN, SPELL_EFFECT_POWER_DRAIN, SPELL_EFFECT_SCHOOL_DAMAGE, SPELL_EFFECT_SKINNING, SPELL_EFFECT_STEAL_BENEFICIAL_BUFF, SPELL_EFFECT_STUCK, SPELL_EFFECT_SUMMON, SPELL_EFFECT_SUMMON_DEAD_PET, SPELL_EFFECT_SUMMON_FRIEND, SPELL_EFFECT_SUMMON_PET, SPELL_EFFECT_SUMMON_PLAYER, SPELL_EFFECT_TELEPORT_UNITS, SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER, SPELL_EFFECT_TRIGGER_SPELL_2, SPELL_FAILED_AFFECTING_COMBAT, SPELL_FAILED_ALREADY_HAVE_CHARM, SPELL_FAILED_ALREADY_HAVE_SUMMON, SPELL_FAILED_AURA_BOUNCED, SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_CANT_CAST_ON_TAPPED, SPELL_FAILED_CASTER_AURASTATE, SPELL_FAILED_CASTER_DEAD, SPELL_FAILED_CHARMED, SPELL_FAILED_DONT_REPORT, SPELL_FAILED_FOOD_LOWLEVEL, SPELL_FAILED_HIGHLEVEL, 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_NOT_BEHIND, SPELL_FAILED_NOT_FLYING, 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_READY, SPELL_FAILED_NOT_SHAPESHIFT, SPELL_FAILED_NOTHING_TO_DISPEL, 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_UNAVAILABLE, SPELL_FAILED_TARGET_AFFECTING_COMBAT, SPELL_FAILED_TARGET_AURASTATE, SPELL_FAILED_TARGET_FRIENDLY, SPELL_FAILED_TARGET_IS_PLAYER, SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE, SPELL_FAILED_TARGET_NOT_DEAD, SPELL_FAILED_TARGET_NOT_IN_INSTANCE, SPELL_FAILED_TARGET_NOT_LOOTED, SPELL_FAILED_TARGET_UNSKINNABLE, SPELL_FAILED_TARGETS_DEAD, SPELL_FAILED_TOO_MANY_SKILLS, SPELL_FAILED_TRAINING_POINTS, SPELL_FAILED_TRY_AGAIN, SPELL_FAILED_UNKNOWN, SPELL_FAILED_WRONG_PET_FOOD, SPELL_TARGET_TYPE_CREATURE, SPELL_TARGET_TYPE_DEAD, SPELL_TARGET_TYPE_GAMEOBJECT, SPELLFAMILY_DRUID, SPELLFAMILY_PRIEST, SpellEntry::SpellFamilyFlags, SpellEntry::SpellFamilyName, SpellEntry::spellLevel, SpellEntry::SpellVisual, sSpellMgr, sSpellRangeStore, sSpellStore, sSummonPropertiesStore, STATUS_IN_PROGRESS, STATUS_WAIT_LEAVE, SUMMON_CATEGORY_PET, SUMMON_CATEGORY_PUPPET, sWorld, TARGET_DST_NEARBY_ENTRY, TARGET_FLAG_ITEM, TARGET_GAMEOBJECT, TARGET_GAMEOBJECT_ITEM, TARGET_UNIT_CASTER, TARGET_UNIT_NEARBY_ENTRY, TARGET_UNIT_PET, SpellEntry::TargetAuraState, SpellEntry::TargetAuraStateNot, Object::ToCreature(), Unit::ToPet(), Object::ToPlayer(), GameObjectInfo::type, TYPEID_PLAYER, TYPEID_UNIT, UNIT_FIELD_BYTES_2, UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE, UNIT_MASK_PET, UNIT_STATE_ROOT, urand(), and Cell::Visit().

Referenced by cast(), CheckPetCast(), prepare(), and GameObject::Use().

3736 {
3737  // check death state
3739  return SPELL_FAILED_CASTER_DEAD;
3740 
3741  // check cooldowns to prevent cheating
3742  if (!m_IsTriggeredSpell)
3743  if (Player* plr = m_caster->ToPlayer())
3744  if (plr->HasSpellCooldown(m_spellInfo->Id) || (strict && plr->HasGlobalCooldown(m_spellInfo)))
3745  return SPELL_FAILED_NOT_READY;
3746 
3747  // only triggered spells can be processed an ended battleground
3750  if (bg->GetStatus() == STATUS_WAIT_LEAVE)
3751  return SPELL_FAILED_DONT_REPORT;
3752 
3754  {
3758 
3762  }
3763 
3764  // only check at first call, Stealth auras are already removed at second call
3765  // for now, ignore triggered spells
3766  if (strict && !m_IsTriggeredSpell)
3767  {
3768  // Cannot be used in this stance/form
3770  if (shapeError != SPELL_CAST_OK)
3771  return shapeError;
3772 
3775  }
3776 
3777  // caster state requirements
3782 
3783  // cancel autorepeat spells if cast start when moving
3784  // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
3786  {
3787  // skip stuck spell to allow use it in falling case and apply spell limitations at movement
3790  return SPELL_FAILED_MOVING;
3791  }
3792 
3793  // check spell cast conditions from database
3794  {
3796  condInfo.mConditionTargets[1] = m_targets.getUnitTarget();
3797  ConditionList conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
3798  if (!conditions.empty() && !sConditionMgr.IsObjectMeetToConditions(condInfo, conditions))
3799  {
3800  // mLastFailedCondition can be NULL if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
3801  if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
3803 
3804  if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
3806 
3807  return SPELL_FAILED_BAD_TARGETS;
3808  }
3809  }
3810 
3813 
3814  Unit* target = m_targets.getUnitTarget();
3815 
3816  if (target)
3817  {
3818  // target state requirements (not allowed state), apply to self also
3821 
3824 
3825  // @todo Find a way to check for form instead of checking byte flag, probably no problem either way
3826  // Not allow casting on Spirit of Redemption form, includes the priest IN redemption form, except for triggered spells
3828  return SPELL_FAILED_BAD_TARGETS;
3829 
3830  if (target != m_caster)
3831  {
3832  // target state requirements (apply to non-self only), to allow cast affects to self like Dirty Deeds
3835 
3836  // Not allow casting on flying player
3837  if (target->IsInFlight())
3838  return SPELL_FAILED_BAD_TARGETS;
3839 
3840  // Must be behind the target.
3841  if (m_spellInfo->AttributesEx2 == 0x100000 && (m_spellInfo->AttributesEx & 0x200) == 0x200 && target->HasInArc(static_cast<float>(M_PI), m_caster)
3842  && (m_spellInfo->SpellFamilyName != SPELLFAMILY_DRUID || m_spellInfo->SpellFamilyFlags != 0x0000000000020000LL))
3843  return SPELL_FAILED_NOT_BEHIND;
3844 
3845  // Target must be facing you.
3846  if ((m_spellInfo->Attributes == 0x150010) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
3847  return SPELL_FAILED_NOT_INFRONT;
3848 
3849  // Do not allow these spells to target creatures not tapped by us (Banish, Polymorph, many quest spells)
3851  if (Creature const* targetCreature = target->ToCreature())
3852  if (targetCreature->hasLootRecipient() && !targetCreature->isTappedBy(m_caster->ToPlayer()))
3854 
3856  return SPELL_FAILED_BAD_TARGETS;
3857 
3858  bool isTrigger = (target->ToCreature() && target->ToCreature()->IsTrigger());
3859  if (!isTrigger)
3860  {
3861  WorldObject* losTarget = target;
3864  losTarget = dynObj;
3865 
3868  }
3869 
3870  // auto selection spell rank implemented in WorldSession::HandleCastSpellOpcode
3871  // this case can be triggered if rank not found (too low-level target for first rank)
3873  {
3874  for (int i = 0; i < 3; i++)
3875  {
3877  if (target->getLevel() + 10 < m_spellInfo->spellLevel)
3878  return SPELL_FAILED_LOWLEVEL;
3879  }
3880  }
3881  }
3882 
3883  // check pet presence
3884  for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3885  {
3887  {
3888  target = m_caster->GetGuardianPet();
3889  if (!target)
3890  {
3891  if (m_triggeredByAuraSpell) // not report pet not existence for triggered spells
3892  return SPELL_FAILED_DONT_REPORT;
3893  else
3894  return SPELL_FAILED_NO_PET;
3895  }
3896  else if (!target->IsAlive())
3898  break;
3899  }
3900  }
3901 
3902  //check creature type
3903  //ignore self casts (including area casts when caster selected as target)
3904  if (target != m_caster)
3905  {
3906  if (!CheckTargetCreatureType(target))
3907  {
3908  if (target->GetTypeId() == TYPEID_PLAYER)
3910  else
3911  return SPELL_FAILED_BAD_TARGETS;
3912  }
3913  }
3914 
3915  // @todo this check can be applied and for player to prevent cheating when IsPositiveSpell will return always correct result.
3916  // check target for pet/charmed casts (not self targeted), self targeted cast used for area effects and etc
3918  {
3919  // check correctness positive/negative cast target (pet cast real check and cheating check)
3921  {
3922  //dispel positivity is dependant on target, don't check it
3923  if (m_caster->IsHostileTo(target) && !IsDispel(m_spellInfo))
3924  return SPELL_FAILED_BAD_TARGETS;
3925  }
3926  else
3927  {
3928  if (m_caster->IsFriendlyTo(target))
3929  return SPELL_FAILED_BAD_TARGETS;
3930  }
3931  }
3932 
3933  // spells cannot be cast if player is in fake combat also
3936  }
3937 
3938  // Spell casted only in battleground
3940  if (!m_caster->ToPlayer()->InBattleground())
3942 
3943  // do not allow spells to be cast in arenas
3944  // - with greater than 15 min CD without SPELL_ATTR4_USABLE_IN_ARENA flag
3945  // - with SPELL_ATTR4_NOT_USABLE_IN_ARENA flag
3948  if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
3949  if (mapEntry->IsBattleArena())
3951 
3952  // zone check
3953  if (m_caster->GetTypeId() == TYPEID_PLAYER)
3954  {
3956  if (locRes != SPELL_CAST_OK)
3957  return locRes;
3958  }
3959 
3960  // not let players cast spells at mount (and let do it to creatures)
3963  {
3964  if (m_caster->IsInFlight())
3965  return SPELL_FAILED_NOT_FLYING;
3966  else
3967  return SPELL_FAILED_NOT_MOUNTED;
3968  }
3969 
3972 
3973  SpellCastResult castResult = SPELL_CAST_OK;
3974 
3975  // always (except passive spells) check items (focus object can be required for any type casts)
3976  if (!IsPassiveSpell(m_spellInfo->Id))
3977  {
3978  castResult = CheckItems();
3979  if (castResult != SPELL_CAST_OK)
3980  return castResult;
3981  }
3982 
3983  if (!m_IsTriggeredSpell)
3984  {
3986  {
3987  castResult = CheckRange(strict);
3988  if (castResult != SPELL_CAST_OK)
3989  return castResult;
3990  }
3991  }
3992 
3993  // ImpliciteTargetA-B = 38, If fact there is 0 Spell with ImpliciteTargetB=38
3994  if (m_UniqueTargetInfo.empty()) // skip second canCast apply (for delayed spells for example)
3995  {
3996  for (uint8 j = 0; j < MAX_SPELL_EFFECTS; j++)
3997  {
4002  {
4003  ConditionList conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET, m_spellInfo->Id);
4004  if (conditions.empty())
4005  sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = TARGET_UNIT_NEARBY_ENTRY or TARGET_DST_NEARBY_ENTRY, but does not have record in conditions.", m_spellInfo->Id);
4006 
4007  SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
4008  float range = GetSpellMaxRange(srange);
4009 
4010  Creature* creatureScriptTarget = NULL;
4011  GameObject* goScriptTarget = NULL;
4012 
4013  for (ConditionList::const_iterator i_spellST = conditions.begin(); i_spellST != conditions.end(); ++i_spellST)
4014  {
4015  if ((*i_spellST)->Type != CONDITION_SPELL_SCRIPT_TARGET)
4016  continue;
4017  switch((*i_spellST)->ConditionValue1)
4018  {
4020  {
4021  GameObject* p_GameObject = NULL;
4022 
4023  if ((*i_spellST)->ConditionValue2)
4024  {
4026  Cell cell(p);
4027 
4028  Oregon::NearestGameObjectEntryInObjectRangeCheck go_check(*m_caster, (*i_spellST)->ConditionValue2, range);
4030 
4032  cell.Visit(p, object_checker, *m_caster->GetMap(), *m_caster, range);
4033 
4034  if (p_GameObject)
4035  {
4036  // remember found target and range, next attempt will find more near target with another entry
4037  creatureScriptTarget = NULL;
4038  goScriptTarget = p_GameObject;
4039  range = go_check.GetLastRange();
4040  }
4041  }
4042  else if (focusObject) //Focus Object
4043  {
4044  float frange = m_caster->GetDistance(focusObject);
4045  if (range >= frange)
4046  {
4047  creatureScriptTarget = NULL;
4048  goScriptTarget = focusObject;
4049  range = frange;
4050  }
4051  }
4052  break;
4053  }
4056  default:
4057  {
4058  Creature* p_Creature = NULL;
4059 
4061  Cell cell(p);
4062  cell.SetNoCreate(); // Really don't know what is that???
4063 
4064  Oregon::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster, (*i_spellST)->ConditionValue2, (*i_spellST)->ConditionValue1 != SPELL_TARGET_TYPE_DEAD, range);
4066 
4068 
4069  cell.Visit(p, grid_creature_searcher, *m_caster->GetMap(), *m_caster, range);
4070 
4071  if (p_Creature)
4072  {
4073  creatureScriptTarget = p_Creature;
4074  goScriptTarget = NULL;
4075  range = u_check.GetLastRange();
4076  }
4077  break;
4078  }
4079  }
4080  }
4081 
4082  if (creatureScriptTarget)
4083  {
4084  // store coordinates for TARGET_DST_NEARBY_ENTRY
4087  {
4088  m_targets.setDst(creatureScriptTarget->GetPositionX(), creatureScriptTarget->GetPositionY(), creatureScriptTarget->GetPositionZ(), creatureScriptTarget->GetOrientation());
4089 
4091  AddUnitTarget(creatureScriptTarget, j);
4092  }
4093  // store explicit target for TARGET_UNIT_NEARBY_ENTRY
4094  else
4095  AddUnitTarget(creatureScriptTarget, j);
4096  }
4097  else if (goScriptTarget)
4098  {
4099  // store coordinates for TARGET_DST_NEARBY_ENTRY
4102  {
4103  m_targets.setDst(goScriptTarget->GetPositionX(), goScriptTarget->GetPositionY(), goScriptTarget->GetPositionZ(), goScriptTarget->GetOrientation());
4104 
4106  AddGOTarget(goScriptTarget, j);
4107  }
4108  // store explicit target for TARGET_UNIT_NEARBY_ENTRY
4109  else
4110  AddGOTarget(goScriptTarget, j);
4111  }
4112  //Missing DB Entry or targets for this spellEffect.
4113  else
4114  {
4115  // not report target not existence for triggered spells
4117  return SPELL_FAILED_DONT_REPORT;
4118  else
4119  return SPELL_FAILED_BAD_TARGETS;
4120  }
4121  }
4122  }
4123  }
4124 
4125  if (!m_IsTriggeredSpell)
4126  {
4127  SpellCastResult castResult;
4128 
4129  castResult = CheckRange(strict);
4130  if (castResult != SPELL_CAST_OK)
4131  return castResult;
4132 
4133  castResult = CheckPower();
4134  if (castResult != SPELL_CAST_OK)
4135  return castResult;
4136 
4137  castResult = CheckCasterAuras();
4138  if (castResult != SPELL_CAST_OK)
4139  return castResult;
4140  }
4141 
4142  // check for effect-specific restrictions
4143  for (uint32 i = 0; i < MAX_SPELL_EFFECTS; i++)
4144  {
4145  // for effects of spells that have only one target
4146  switch (m_spellInfo->Effect[i])
4147  {
4148  case SPELL_EFFECT_DUMMY:
4149  {
4150  if (SpellCastResult result = CheckDummyCast(i))
4151  if (result != SPELL_CAST_OK)
4152  return result;
4153  break;
4154  }
4156  {
4157  // Hammer of Wrath
4158  if (m_spellInfo->SpellVisual == 7250)
4159  {
4160  if (!m_targets.getUnitTarget())
4162 
4164  return SPELL_FAILED_BAD_TARGETS;
4165  }
4166  break;
4167  }
4169  {
4170  // report single-target "buff degrading" (dont report for triggered spells)
4171  // also works only for positive spells and the buffed is always able to degrade
4172  // his own buffs
4173  if (strict && target != m_caster && target)
4176  if (sSpellMgr.IsNoStackSpellDueToSpell(m_spellInfo->Id, m_spellInfo->Id, false))
4177  if (target->HasHigherRankOfAura(m_spellInfo->Id, i))
4179 
4180  switch(m_spellInfo->EffectApplyAuraName[i])
4181  {
4182  case SPELL_AURA_BIND_SIGHT:
4183  {
4184  // Cannot bind sight across instances/continents.
4185  // Does not affect the same instance/continent, no matter the range.
4186  if(target == m_caster)
4187  return SPELL_FAILED_BAD_TARGETS;
4188  break;
4189  }
4190  }
4191  break;
4192  }
4194  {
4195  if (m_caster->GetTypeId() != TYPEID_PLAYER)
4196  return SPELL_FAILED_BAD_TARGETS;
4197 
4199  break;
4200 
4201  Pet* pet = m_caster->ToPlayer()->GetPet();
4202 
4203  if (!pet)
4204  return SPELL_FAILED_NO_PET;
4205 
4206  SpellEntry const* learn_spellproto = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[i]);
4207 
4208  if (!learn_spellproto)
4209  return SPELL_FAILED_NOT_KNOWN;
4210 
4211  if (!pet->CanTakeMoreActiveSpells(learn_spellproto->Id))
4213 
4214  if (m_spellInfo->spellLevel > pet->getLevel())
4215  return SPELL_FAILED_LOWLEVEL;
4216 
4217  if (!pet->HasTPForSpell(learn_spellproto->Id))
4219 
4220  break;
4221  }
4222  case SPELL_EFFECT_TRIGGER_SPELL_2: // Only Ritual of Summoning
4223  {
4226  break;
4227  }
4229  {
4230  if (m_caster->GetTypeId() != TYPEID_PLAYER)
4231  return SPELL_FAILED_BAD_TARGETS;
4232 
4233  Pet* pet = m_caster->ToPlayer()->GetPet();
4234  if (!pet)
4235  return SPELL_FAILED_NO_PET;
4236 
4237  SpellEntry const* learn_spellproto = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[i]);
4238 
4239  if (!learn_spellproto)
4240  return SPELL_FAILED_NOT_KNOWN;
4241 
4242  if (!pet->CanTakeMoreActiveSpells(learn_spellproto->Id))
4244 
4245  if (m_spellInfo->spellLevel > pet->getLevel())
4246  return SPELL_FAILED_LOWLEVEL;
4247 
4248  if (!pet->HasTPForSpell(learn_spellproto->Id))
4250 
4251  break;
4252  }
4253  case SPELL_EFFECT_FEED_PET:
4254  {
4256  return SPELL_FAILED_BAD_TARGETS;
4257 
4258  Pet* pet = m_caster->ToPlayer()->GetPet();
4259 
4260  if (!pet)
4261  return SPELL_FAILED_NO_PET;
4262 
4263  if (!pet->HaveInDiet(m_targets.getItemTarget()->GetProto()))
4265 
4268 
4269  if (m_caster->IsInCombat() || pet->IsInCombat())
4271 
4272  break;
4273  }
4276  {
4277  // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
4278  if (m_caster->GetTypeId() == TYPEID_PLAYER)
4279  if (Unit* target = m_targets.getUnitTarget())
4280  if (target != m_caster)
4281  {
4282  // Targets have power type mana even if they're not mana
4283  // users, so if it's mana we need to check max is >= 1
4284  bool hasPower = int32(target->getPowerType()) == m_spellInfo->EffectMiscValue[i];
4285 
4286  if (!hasPower ||
4287  (target->getPowerType() == POWER_MANA &&
4288  target->GetMaxPower(POWER_MANA) == 0))
4289  return SPELL_FAILED_BAD_TARGETS;
4290  }
4291  break;
4292  }
4293  case SPELL_EFFECT_CHARGE:
4294  {
4295  if (Unit* target = m_targets.getUnitTarget())
4296  if (!target->IsAlive())
4297  return SPELL_FAILED_BAD_TARGETS;
4298 
4300  return SPELL_FAILED_ROOTED;
4301 
4302  break;
4303  }
4304  case SPELL_EFFECT_SKINNING:
4305  {
4307  return SPELL_FAILED_BAD_TARGETS;
4308 
4311 
4312  Creature* creature = m_targets.getUnitTarget()->ToCreature();
4313  if (!creature->IsCritter() && !creature->loot.isLooted())
4315 
4316  uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4317 
4318  int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
4319  int32 TargetLevel = m_targets.getUnitTarget()->getLevel();
4320  int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
4321  if (ReqValue > skillValue)
4323 
4324  // chance for fail at orange skinning attempt
4325  if ((m_selfContainer && (*m_selfContainer) == this) &&
4326  skillValue < sWorld.GetConfigMaxSkillValue() &&
4327  (ReqValue < 0 ? 0 : ReqValue) > irand(skillValue - 25, skillValue + 37))
4328  return SPELL_FAILED_TRY_AGAIN;
4329 
4330  break;
4331  }
4334  {
4337  break;
4338 
4339  // we need a go target in case of TARGET_GAMEOBJECT
4341  return SPELL_FAILED_BAD_TARGETS;
4342 
4343  Item* pTempItem = nullptr;
4346 
4347  // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
4349  !m_targets.getGOTarget() &&
4350  (!pTempItem || !pTempItem->GetProto()->LockID || !pTempItem->IsLocked()))
4351  return SPELL_FAILED_BAD_TARGETS;
4352 
4353  if (m_spellInfo->Id != 1842 || (m_targets.getGOTarget() &&
4355  if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners
4357  return SPELL_FAILED_TRY_AGAIN;
4358 
4359  // get the lock entry
4360  uint32 lockId = 0;
4361  if (GameObject* go = m_targets.getGOTarget())
4362  {
4363  lockId = go->GetGOInfo()->GetLockId();
4364  if (!lockId)
4365  return SPELL_FAILED_BAD_TARGETS;
4366  }
4367  else if (Item* itm = m_targets.getItemTarget())
4368  lockId = itm->GetProto()->LockID;
4369 
4370  SkillType skillId = SKILL_NONE;
4371  int32 reqSkillValue = 0;
4372  int32 skillValue = 0;
4373 
4374  // check lock compatibility
4375  SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
4376  if (res != SPELL_CAST_OK)
4377  return res;
4378 
4379  // chance for fail at lockpicking attempt
4380  // second check prevent fail at rechecks
4381  if (skillId != SKILL_NONE && (!m_selfContainer || ((*m_selfContainer) != this)))
4382  {
4383  bool canFailAtMax = skillId == SKILL_LOCKPICKING;
4384 
4385  // chance for failure in orange lockpick
4386  if ((canFailAtMax || skillValue < sWorld.GetConfigMaxSkillValue()) && reqSkillValue > irand(skillValue - 25, skillValue + 37))
4387  return SPELL_FAILED_TRY_AGAIN;
4388  }
4389  break;
4390  }
4391  // Bring the pet back to the land of the living
4393  {
4394  Creature* pet = m_caster->GetGuardianPet();
4395  if (pet && pet->IsAlive())
4397 
4398  // Do not revive dismissed pets, they are not dead
4401 
4402  // Attempting to revive a non existing pet?
4403  if (m_caster->IsPlayer() && !m_caster->ToPlayer()->doesOwnPet())
4404  return SPELL_FAILED_NO_PET;
4405 
4406  break;
4407  }
4408  // Called when we start channeling 'Dismiss pet' spell
4410  {
4411  // Don't start dismissing the pet if it's dead!
4412  Pet* pet = m_caster->ToPlayer()->GetPet();
4413  if (!pet || !pet->IsAlive())
4415 
4416  break;
4417  }
4418  // This is generic summon effect
4419  case SPELL_EFFECT_SUMMON:
4420  {
4421  SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]);
4422  if (!SummonProperties)
4423  break;
4424  switch (SummonProperties->Category)
4425  {
4426  case SUMMON_CATEGORY_PET:
4429  // intentional missing break, check both GetPetGUID() and GetCharmGUID for SUMMON_CATEGORY_PET
4431  if (m_caster->GetCharmGUID())
4433  break;
4434  }
4435  break;
4436  }
4438  {
4439  // Check these things only for player hunters
4441  {
4442  // Player should not be able to call the pet if he doesn't own one...
4443  if (!m_caster->ToPlayer()->doesOwnPet())
4444  return SPELL_FAILED_NO_PET;
4445 
4446  // ... or the pet is dead ...
4449  }
4450  if (m_caster->GetPetGUID()) // let warlock do a replacement summon
4451  {
4452  if (m_caster->IsPlayer())
4453  {
4454  if (strict) // starting cast, trigger pet stun (cast by pet so it doesn't attack player)
4455  if (Pet* pet = m_caster->ToPlayer()->GetPet())
4456  pet->CastSpell(pet, 32752, true, NULL, NULL, pet->GetGUID());
4457  }
4460  }
4461 
4462  if (m_caster->GetCharmGUID())
4464 
4465  break;
4466  }
4468  {
4469  if (m_caster->GetTypeId() != TYPEID_PLAYER)
4470  return SPELL_FAILED_BAD_TARGETS;
4471  if (!m_caster->ToPlayer()->GetSelection())
4472  return SPELL_FAILED_BAD_TARGETS;
4473 
4474  Player* target = sObjectMgr.GetPlayer(m_caster->ToPlayer()->GetSelection());
4475  if (!target || m_caster->ToPlayer() == target || !target->IsInSameRaidWith(m_caster->ToPlayer()))
4476  return SPELL_FAILED_BAD_TARGETS;
4477 
4478  // check if our map is dungeon
4479  MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
4480 
4481  if (map->IsDungeon())
4482  {
4483  uint32 mapId = m_caster->GetMap()->GetId();
4484  DungeonDifficulty difficulty = m_caster->GetMap()->GetDifficulty();
4485  if (map->IsRaid())
4486  if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
4487  if (InstancePlayerBind* casterBind = m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
4488  if (targetBind->perm && targetBind->save != casterBind->save)
4490 
4491  InstanceTemplate const* instance = ObjectMgr::GetInstanceTemplate(mapId);
4492  if (!instance)
4494  if (!target->Satisfy(sObjectMgr.GetAccessRequirement(instance->access_id), m_caster->GetMapId()))
4495  return SPELL_FAILED_BAD_TARGETS;
4496  }
4497  break;
4498  }
4500  {
4501  if (m_caster->GetTypeId() != TYPEID_PLAYER)
4502  return SPELL_FAILED_BAD_TARGETS;
4503 
4504  Player* buddy = sObjectMgr.GetRAFLinkedBuddyForPlayer(m_caster->ToPlayer());
4505 
4506  if (!buddy || !buddy->IsInWorld())
4507  {
4509  return SPELL_FAILED_DONT_REPORT;
4510  }
4511 
4512  if (!buddy->IsAlive())
4514 
4515  if (!m_caster->ToPlayer()->IsInPartyWith(buddy))
4516  {
4518  return SPELL_FAILED_DONT_REPORT;
4519  }
4520 
4521  if (buddy->getLevel() > sWorld.getConfig(CONFIG_RAF_LEVEL_LIMIT))
4522  {
4524  return SPELL_FAILED_DONT_REPORT;
4525  }
4526 
4527  // check if our map is dungeon
4528  if (sMapStore.LookupEntry(m_caster->GetMapId())->IsDungeon())
4529  {
4531  if (!instance)
4533  if (!buddy->Satisfy(sObjectMgr.GetAccessRequirement(instance->access_id), m_caster->GetMapId()))
4534  return SPELL_FAILED_BAD_TARGETS;
4535  }
4536  break;
4537  }
4538  case SPELL_EFFECT_LEAP:
4540  {
4541  //Do not allow to cast it before BG starts.
4542  if (m_caster->GetTypeId() == TYPEID_PLAYER)
4543  if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
4544  if (bg->GetStatus() != STATUS_IN_PROGRESS)
4545  return SPELL_FAILED_TRY_AGAIN;
4546  break;
4547  }
4549  {
4550  //Do not allow use of Trinket before BG starts
4551  if (m_caster->GetTypeId() == TYPEID_PLAYER)
4552  if (m_spellInfo->Id == 22563 || m_spellInfo->Id == 22564)
4553  if (Battleground const* bg = m_caster->ToPlayer()->GetBattleground())
4554  if (bg->GetStatus() != STATUS_IN_PROGRESS)
4555  return SPELL_FAILED_TRY_AGAIN;
4556  break;
4557  }
4559  {
4560  if (m_targets.getUnitTarget() == m_caster)
4561  return SPELL_FAILED_BAD_TARGETS;
4562  break;
4563  }
4564  case SPELL_EFFECT_ENERGIZE:
4565  {
4566  // Consume Magic
4567  if (m_spellInfo->Id == 32676)
4568  {
4569  if (m_caster->GetTypeId() != TYPEID_PLAYER)
4570  return SPELL_FAILED_UNKNOWN;
4571 
4572  std::vector<uint32> priest_buffs;
4573  priest_buffs.clear();
4574  Unit::AuraMap& Auras = m_caster->GetAuras();
4575  for (Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
4576  {
4577  // get only priests auras
4578  SpellEntry const* spellInfo = i->second->GetSpellProto();
4579  if (spellInfo->SpellFamilyName != SPELLFAMILY_PRIEST)
4580  continue;
4581  // do not select passive auras
4582  if (i->second->IsPassive())
4583  continue;
4584  // only beneficial effects count
4585  if (!IsPositiveSpell(spellInfo->Id))
4586  continue;
4587  priest_buffs.push_back(spellInfo->Id);
4588  }
4589  if (!priest_buffs.empty())
4590  {
4591  // remove random aura from caster
4592  uint32 rand_buff = urand(0, priest_buffs.size() - 1);
4593  m_caster->RemoveAurasDueToSpell(priest_buffs[rand_buff]);
4594  }
4595  else // if nothing to dispell, send error and break a spell
4597  }
4598  break;
4599  }
4600  default:
4601  break;
4602  }
4603  }
4604 
4605  for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
4606  {
4607  switch (m_spellInfo->EffectApplyAuraName[i])
4608  {
4609  case SPELL_AURA_DUMMY:
4610  {
4611  if (SpellCastResult result = CheckDummyCast(i))
4612  if (result != SPELL_CAST_OK)
4613  return result;
4614  break;
4615  }
4617  {
4618  if (m_caster->GetTypeId() != TYPEID_PLAYER)
4619  return SPELL_FAILED_NO_PET;
4620 
4621  Pet* pet = m_caster->ToPlayer()->GetPet();
4622  if (!pet)
4623  return SPELL_FAILED_NO_PET;
4624 
4625  if (pet->GetCharmerGUID())
4626  return SPELL_FAILED_CHARMED;
4627  break;
4628  }
4630  case SPELL_AURA_MOD_CHARM:
4631  case SPELL_AURA_AOE_CHARM:
4632  {
4633  if (m_caster->GetCharmerGUID())
4634  return SPELL_FAILED_CHARMED;
4635 
4638  {
4641 
4642  if (m_caster->GetCharmGUID())
4644  }
4645 
4646  if (!m_targets.getUnitTarget())
4648 
4650  // dont allow charming/possessing of pet that caster doesn't own
4652  return SPELL_FAILED_CHARMED;
4653 
4655  return SPELL_FAILED_HIGHLEVEL;
4656 
4658  {
4659  int32 lvlBounds = (m_spellInfo->EffectBasePoints[i] + 1) - m_spellInfo->baseLevel;
4660  if (int32(m_targets.getUnitTarget()->getLevel()) > int32(m_caster->getLevel()) + lvlBounds)
4661  return SPELL_FAILED_HIGHLEVEL;
4662  }
4663  break;
4664  }
4665  case SPELL_AURA_MOUNTED:
4666  {
4667  if (m_caster->IsInWater())
4669 
4672 
4673  // Ignore map check if spell have AreaId. AreaId already checked and this prevent special mount spells
4674  bool AllowMount = !m_caster->GetMap()->IsDungeon() || m_caster->GetMap()->IsBattlegroundOrArena();
4675  InstanceTemplate const* it = sObjectMgr.GetInstanceTemplate(m_caster->GetMapId());
4676  if (it)
4677  AllowMount = it->allowMount;
4680 
4681  ShapeshiftForm form = m_caster->m_form;
4682  if (form == FORM_CAT || form == FORM_TREE || form == FORM_TRAVEL ||
4683  form == FORM_AQUA || form == FORM_BEAR || form == FORM_DIREBEAR ||
4684  form == FORM_CREATUREBEAR || form == FORM_GHOSTWOLF || form == FORM_FLIGHT ||
4685  form == FORM_FLIGHT_EPIC || form == FORM_MOONKIN)
4687 
4688  break;
4689  }
4691  {
4692  if (!m_targets.getUnitTarget())
4694 
4695  // can be casted at non-friendly unit or own pet/charm
4698 
4699  break;
4700  }
4701  case SPELL_AURA_FLY:
4703  {
4704  if (m_caster->IsInWater())
4706 
4708  {
4709  if (AreaTableEntry const* pArea = sAreaStore.LookupEntry(m_originalCaster->GetAreaId()))
4710  if (pArea->flags & 0x20000000)
4711  return SPELL_FAILED_NOT_HERE;
4712  }
4713  break;
4714  }
4716  {
4717  if (!m_targets.getUnitTarget())
4719 
4721  break;
4722 
4725  return SPELL_FAILED_BAD_TARGETS;
4726 
4727  break;
4728  }
4729  case SPELL_AURA_WATER_WALK:
4730  {
4731  if (!m_targets.getUnitTarget())
4733 
4735  {
4736  Player const* player = static_cast<Player const*>(m_targets.getUnitTarget());
4737 
4738  // Player is not allowed to cast water walk on shapeshifted/mounted player
4739  if (player->HasShapeshiftChangingModel() || player->IsMounted())
4740  return SPELL_FAILED_BAD_TARGETS;
4741  }
4742 
4743  break;
4744  }
4745  }
4746  }
4747 
4748  // check if caster has at least 1 combo point for spells that require combo points
4749  if (m_needComboPoints)
4750  if (Player* plrCaster = m_caster->ToPlayer())
4751  if (!plrCaster->GetComboPoints())
4753 
4754  // all ok
4755  return SPELL_CAST_OK;
4756 }
bool HasStealthAura() const
Definition: Unit.h:1270
uint32 ItemLevel
GameObject * focusObject
Definition: Spell.h:593
uint32 AuraInterruptFlags
Definition: DBCStructure.h:700
bool HasHigherRankOfAura(uint32 spellid, uint8 effIndex) const
Definition: Unit.cpp:847
uint32 spellLevel
Definition: DBCStructure.h:707
bool IsBattlegroundOrArena() const
Definition: Map.h:447
uint32 CasterAuraStateNot
Definition: DBCStructure.h:694
ShapeshiftForm
Definition: Unit.h:191
ItemTemplate const * GetProto() const
Definition: Item.cpp:460
Unit *const m_caster
Definition: Spell.h:541
uint32 AttributesEx
Definition: DBCStructure.h:680
DungeonDifficulty GetDifficulty() const
Definition: Map.h:419
uint64 GetCharmGUID() const
Definition: Unit.h:1370
bool HasUnitMovementFlag(uint32 f) const
Definition: Unit.h:1906
Guardian * GetGuardianPet() const
Definition: Unit.cpp:7711
int32 CalculateDamage(uint8 i, Unit *target)
Definition: Spell.h:383
uint32 GetMaxHealth() const
Definition: Unit.h:1075
Battleground * GetBattleground() const
Definition: Player.cpp:19415
uint32 EffectTriggerSpell[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:741
SpellCastResult CheckItems()
Definition: Spell.cpp:5345
bool doesOwnPet() const
Definition: Player.h:2527
SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType &skillid, int32 &reqSkillValue, int32 &skillValue)
Definition: Spell.cpp:6315
Map * GetMap() const
Definition: Object.h:817
bool IsPassiveSpell(uint32 spellId)
Definition: SpellMgr.cpp:278
bool IsDispel(SpellEntry const *spellInfo)
Definition: SpellMgr.h:442
GameObject * getGOTarget() const
Definition: Spell.h:132
DBCStorage< SummonPropertiesEntry > sSummonPropertiesStore(SummonPropertiesfmt)
uint32 SpellVisual
Definition: DBCStructure.h:743
SpellCastResult CheckDummyCast(uint32 effIndex)
Definition: Spell.cpp:4807
uint32 CasterAuraState
Definition: DBCStructure.h:692
DynamicObject * GetDynObject(uint32 spellId, uint32 effIndex)
Definition: Unit.cpp:4715
SpellCastTargets m_targets
Definition: Spell.h:443
uint64 GetCharmerGUID() const
Definition: Unit.h:1362
SpellCastResult CheckPower()
Definition: Spell.cpp:5318
Pet * ToPet()
Definition: Unit.h:1054
AuraMap & GetAuras()
Definition: Unit.h:1739
std::list< Condition * > ConditionList
Definition: ConditionMgr.h:223
bool isPetDismissed() const
Definition: Player.h:2523
bool IsInPartyWith(Unit const *unit) const
Definition: Unit.cpp:13393
uint32 GetZoneId() const
Definition: Object.cpp:1202
bool IsInCombat() const
Definition: Unit.h:1243
bool IsLocked() const
Definition: Item.h:228
uint32 AttributesEx2
Definition: DBCStructure.h:681
Loot loot
Definition: Creature.h:595
bool HasByteFlag(uint16 index, uint8 offset, uint8 flag) const
Definition: Object.h:298
int32 irand(int32 min, int32 max)
Definition: Util.cpp:28
bool IsAutoRepeat() const
Definition: Spell.h:449
#define sLog
Log class singleton.
Definition: Log.h:187
uint32 baseLevel
Definition: DBCStructure.h:706
bool IsInFlight() const
Definition: Unit.h:1239
Transport * GetTransport() const
Definition: Player.h:2391
Unit * getUnitTarget() const
Definition: Spell.h:118
ACE_INT32 int32
Definition: Define.h:67
bool IsWithinLOSInMap(const WorldObject *obj) const
Definition: Object.cpp:1252
bool IsTrigger() const
Definition: Creature.h:497
bool IsDungeon() const
Definition: Map.h:427
uint32 Effect[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:724
uint64 getItemTargetGUID() const
Definition: Spell.h:143
Item * m_CastItem
Definition: Spell.h:440
bool IsPetInCombat() const
Definition: Unit.h:1244
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:729
DungeonDifficulty
SpellCastResult CheckRange(bool strict)
Definition: Spell.cpp:5226
#define sObjectMgr
Definition: ObjectMgr.h:1317
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
uint32 EffectApplyAuraName[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:734
uint32 rangeIndex
Definition: DBCStructure.h:714
Player * ToPlayer()
Definition: Object.h:368
uint8 getLevel() const
Definition: Unit.h:1057
static InstanceTemplate const * GetInstanceTemplate(uint32 map)
Definition: ObjectMgr.h:653
bool IsDeathOnlySpell(SpellEntry const *spellInfo)
Definition: SpellMgr.h:287
uint64 GetCharmerOrOwnerGUID() const
Definition: Unit.h:1387
bool isMoving() const
Definition: Unit.h:1332
bool HasTPForSpell(uint32 spellid)
Definition: Pet.cpp:774
void RemoveAurasDueToSpell(uint32 spellId, Aura *except=NULL)
Definition: Unit.cpp:4402
Definition: Common.h:179
uint32 Attributes
Definition: DBCStructure.h:679
void AddGOTarget(GameObject *target, uint32 effIndex)
Definition: Spell.cpp:842
uint32 GetId(void) const
Definition: Map.h:333
uint64 GetGUID() const
Definition: Object.h:177
Powers getPowerType() const
Definition: Unit.h:1094
bool HasAttribute(SpellAttributes attribute) const
Definition: DBCStructure.h:774
bool HasShapeshiftChangingModel() const
Definition: Unit.cpp:13483
uint8 GetTypeId() const
Definition: Object.h:192
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
void AddUnitTarget(Unit *target, uint32 effIndex)
Definition: Spell.cpp:728
uint32 ErrorType
Definition: ConditionMgr.h:190
ACE_UINT8 uint8
Definition: Define.h:73
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:1097
float GetOrientation() const
Definition: Position.h:100
uint32 AttributesEx3
Definition: DBCStructure.h:682
int32 EffectMiscValueB[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:740
bool CanUseBattlegroundObject(GameObject *gameobject)
Definition: Player.cpp:20489
const bool & IsInWorld() const
Definition: Object.h:150
Unit * m_originalCaster
Definition: Spell.h:547
SpellEntry const * m_triggeredByAuraSpell
Definition: Spell.h:692
uint32 AttributesEx4
Definition: DBCStructure.h:683
Definition: Unit.h:194
bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
Definition: SpellMgr.cpp:561
bool isLineOfSightCalcEnabled() const
Definition: IVMapManager.h:85
bool IsAlive() const
Definition: Unit.h:1336
float GetDistance(const WorldObject *obj) const
Definition: Object.h:694
float GetPositionY() const
Definition: Position.h:98
bool HasAuraState(AuraState flag) const
Definition: Unit.h:1820
Definition: Item.h:196
void CastSpell(Unit *Victim, uint32 spellId, bool triggered, Item *castItem=NULL, Aura *triggeredByAura=NULL, uint64 originalCaster=0)
Definition: Unit.cpp:1260
bool allowMount
Definition: Map.h:242
uint32 EffectImplicitTargetB[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:732
#define sSpellMgr
Definition: SpellMgr.h:1239
Player * GetOwner()
Definition: Pet.h:286
float GetPositionZ() const
Definition: Position.h:99
std::multimap< spellEffectPair, Aura * > AuraMap
Definition: Unit.h:916
uint8 ConditionTarget
Definition: ConditionMgr.h:194
uint16 GetSkillValue(uint32 skill) const
Definition: Player.cpp:5480
uint32 m_targetMask
Definition: Spell.h:179
void setDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition: Spell.cpp:108
uint64 SpellFamilyFlags
Definition: DBCStructure.h:761
const uint64 & GetSelection() const
Definition: Player.h:1556
bool IsFriendlyTo(Unit const *unit) const
Definition: Unit.cpp:7374
uint32 EffectImplicitTargetA[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:731
uint32 TargetAuraStateNot
Definition: DBCStructure.h:695
SpellCastResult GetErrorAtShapeshiftedCast(SpellEntry const *spellInfo, uint32 form)
Definition: SpellMgr.cpp:842
bool IsDungeon() const
Definition: DBCStructure.h:550
InstancePlayerBind * GetBoundInstance(uint32 mapid, uint8 difficulty)
Definition: Player.cpp:15857
std::list< TargetInfo > m_UniqueTargetInfo
Definition: Spell.h:626
#define sConditionMgr
Definition: ConditionMgr.h:312
uint32 GetMapId() const
Definition: Object.h:567
Item * getItemTarget() const
Definition: Spell.h:147
uint32 GetAreaId() const
Definition: Object.cpp:1207
bool isPetDeadAndRemoved() const
Definition: Player.h:2519
int32 EffectMiscValue[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:739
AuraState
Condition * mLastFailedCondition
Definition: ConditionMgr.h:169
bool IsSpellIgnoringLOS(SpellEntry const *spellInfo)
Definition: SpellMgr.h:158
bool IsRaid() const
Definition: DBCStructure.h:558
bool IsPositiveSpell(uint32 spellId)
Definition: SpellMgr.cpp:773
CellCoord ComputeCellCoord(float x, float y)
Definition: GridDefines.h:167
const char * GetName() const
Definition: Object.h:680
uint32 TargetAuraState
Definition: DBCStructure.h:693
bool CanTakeMoreActiveSpells(uint32 SpellIconID)
Definition: Pet.cpp:738
bool m_IsTriggeredSpell
Definition: Spell.h:687
Definition: Cell.h:46
bool IsInSameRaidWith(Player const *p) const
Definition: Player.h:1805
uint64 GetPetGUID() const
Definition: Unit.h:1378
bool InBattleground() const
Definition: Player.h:2195
bool HasInArc(float arcangle, const Position *pos) const
Definition: Object.cpp:1416
CreatureInfo const * GetCreatureTemplate() const
Definition: Creature.h:565
bool IsPlayer() const
Definition: Unit.h:1238
bool isLooted() const
Definition: LootMgr.h:355
bool HaveInDiet(ItemTemplate const *item) const
Definition: Pet.cpp:1206
bool IsCritter() const
Definition: Unit.h:1237
uint32 AreaId
Definition: DBCStructure.h:771
SpellCastResult IsSpellAllowedInLocation(SpellEntry const *spellInfo, uint32 map_id, uint32 zone_id, uint32 area_id)
Definition: SpellMgr.cpp:2903
uint32 m_customAttr
Definition: Spell.h:694
Creature * ToCreature()
Definition: Object.h:371
GameObjectInfo const * GetGOInfo() const
Definition: GameObject.h:609
uint32 SpellFamilyName
Definition: DBCStructure.h:760
void SendReferFriendError(ReferFriendError err, const char *name=0)
Definition: Player.cpp:11558
uint32 GetCurrentFoodBenefitLevel(uint32 itemlevel)
Definition: Pet.cpp:1224
uint8 getClass() const
Definition: Unit.h:1062
bool Satisfy(AccessRequirement const *, uint32 target_map, bool report=false)
Definition: Player.cpp:16053
bool IsHostileTo(Unit const *unit) const
Definition: Unit.cpp:7369
bool IsAreaOfEffectSpell(SpellEntry const *spellInfo)
Definition: SpellMgr.h:404
virtual bool IsInWater() const
Definition: Unit.cpp:3685
uint32 HasUnitTypeMask(uint32 mask) const
Definition: Unit.h:1044
bool HasUnitState(const uint32 f) const
Definition: Unit.h:1030
SkillType GetRequiredLootSkill() const
Definition: Creature.h:201
static IVMapManager * createOrGetVMapManager()
bool IsMounted() const
Definition: Unit.h:1163
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:670
bool CheckTargetCreatureType(Unit *target) const
Definition: Spell.cpp:5833
SpellCastResult
SkillType
bool IsOutdoors(float x, float y, float z) const
Definition: Map.cpp:1651
#define sWorld
Definition: World.h:860
WorldObject * mConditionTargets[MAX_CONDITION_TARGETS]
Definition: ConditionMgr.h:168
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.h:281
uint32 access_id
Definition: Map.h:236
ACE_UINT32 uint32
Definition: Define.h:71
must be cast from item, never directly
Definition: SpellMgr.h:848
float GetPositionX() const
Definition: Position.h:97
uint32 GetHealth() const
Definition: Unit.h:1074
Pet * GetPet() const
Definition: Player.cpp:17123
SpellCastResult CheckCasterAuras() const
Definition: Spell.cpp:5084
Spell ** m_selfContainer
Definition: Spell.h:549
Definition: Unit.h:908
Definition: Player.h:923
DBCStorage< SpellRangeEntry > sSpellRangeStore(SpellRangefmt)
bool m_needComboPoints
Definition: Spell.h:578
Definition: Pet.h:146
Item * GetItemByGuid(uint64 guid) const
Definition: Player.cpp:8520
uint32 GetSpellRecoveryTime(SpellEntry const *spellInfo)
Definition: SpellMgr.h:151
uint32 urand(uint32 min, uint32 max)
Definition: Util.cpp:33
ShapeshiftForm m_form
Definition: Unit.h:1612
DBCStorage< AreaTableEntry > sAreaStore(AreaTableEntryfmt)
float GetSpellMaxRange(SpellRangeEntry const *range)
Definition: SpellMgr.h:143
SpellCastResult Spell::CheckCasterAuras ( ) const

Definition at line 5084 of file Spell.cpp.

References SpellEntry::AttributesEx, SpellEntry::AttributesEx5, SpellEntry::AttributesEx6, SpellEntry::EffectApplyAuraName, SpellEntry::EffectMiscValue, Unit::GetAuras(), GetDispelMask(), GetSpellMechanicMask(), GetSpellSchoolMask(), Unit::HasAuraType(), Object::HasFlag(), IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK, IsSpellRemoveAllMovementAndControlLossEffects(), m_caster, m_spellInfo, MAX_SPELL_EFFECTS, SpellEntry::PreventionType, SPELL_ATTR1_DISPEL_AURAS_ON_IMMUNITY, SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE, SPELL_ATTR5_USABLE_WHILE_CONFUSED, SPELL_ATTR5_USABLE_WHILE_FEARED, SPELL_ATTR5_USABLE_WHILE_STUNNED, SPELL_ATTR6_IGNORE_CASTER_AURAS, SPELL_AURA_DISPEL_IMMUNITY, SPELL_AURA_MECHANIC_IMMUNITY, SPELL_AURA_MOD_CONFUSE, SPELL_AURA_MOD_FEAR, SPELL_AURA_MOD_PACIFY, SPELL_AURA_MOD_PACIFY_SILENCE, SPELL_AURA_MOD_SILENCE, SPELL_AURA_MOD_STUN, SPELL_AURA_SCHOOL_IMMUNITY, SPELL_CAST_OK, SPELL_FAILED_CONFUSED, SPELL_FAILED_FLEEING, SPELL_FAILED_PACIFIED, SPELL_FAILED_SILENCED, SPELL_FAILED_STUNNED, SPELL_PREVENTION_TYPE_PACIFY, SPELL_PREVENTION_TYPE_SILENCE, UNIT_FIELD_FLAGS, UNIT_FLAG_CONFUSED, UNIT_FLAG_FLEEING, UNIT_FLAG_PACIFIED, and UNIT_FLAG_SILENCED.

Referenced by CheckCast().

5085 {
5086  // spells totally immuned to caster auras (wsg flag drop, give marks etc)
5088  return SPELL_CAST_OK;
5089 
5090  uint8 school_immune = 0;
5091  uint32 mechanic_immune = 0;
5092  uint32 dispel_immune = 0;
5093 
5094  //Check if the spell grants school or mechanic immunity.
5095  //We use bitmasks so the loop is done only once and not on every aura check below.
5097  {
5098  for (int i = 0; i < MAX_SPELL_EFFECTS; i ++)
5099  {
5101  school_immune |= uint32(m_spellInfo->EffectMiscValue[i]);
5103  mechanic_immune |= 1 << uint32(m_spellInfo->EffectMiscValue[i]);
5105  dispel_immune |= GetDispelMask(DispelType(m_spellInfo->EffectMiscValue[i]));
5106  }
5107 
5108  // immune movement impairment and loss of control (spell data have special structure for mark this case)
5111  }
5112 
5113  //Check whether the cast should be prevented by any state you might have.
5114  SpellCastResult prevented_reason = SPELL_CAST_OK;
5115  // Have to check if there is a stun aura. Otherwise will have problems with ghost aura apply while logging out
5117  prevented_reason = SPELL_FAILED_STUNNED;
5119  prevented_reason = SPELL_FAILED_CONFUSED;
5121  prevented_reason = SPELL_FAILED_FLEEING;
5123  prevented_reason = SPELL_FAILED_SILENCED;
5125  prevented_reason = SPELL_FAILED_PACIFIED;
5126 
5127  // Attr must make flag drop spell totally immune from all effects
5128  if (prevented_reason != SPELL_CAST_OK)
5129  {
5130  if (school_immune || mechanic_immune || dispel_immune)
5131  {
5132  //Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
5133  Unit::AuraMap const& auras = m_caster->GetAuras();
5134  bool trapped;
5135  for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
5136  {
5137  if (itr->second)
5138  {
5139  trapped = false;
5140 
5141  if (GetSpellMechanicMask(itr->second->GetSpellProto(), itr->second->GetEffIndex()) & mechanic_immune)
5142  continue;
5143  if (GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune && // we match school mask and
5144  !(trapped = (itr->second->GetSpellProto()->AttributesEx & SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE))) // the aura doesn't block us
5145  continue;
5146  if ((1 << (itr->second->GetSpellProto()->Dispel)) & dispel_immune)
5147  continue;
5148 
5149  //Make a second check for spell failed so the right SPELL_FAILED message is returned.
5150  //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
5151  switch (itr->second->GetModifier()->m_auraname)
5152  {
5153  case SPELL_AURA_MOD_STUN:
5155  return SPELL_FAILED_STUNNED;
5158  return SPELL_FAILED_CONFUSED;
5159  case SPELL_AURA_MOD_FEAR:
5161  return SPELL_FAILED_FLEEING;
5163  case SPELL_AURA_MOD_PACIFY:
5166  return SPELL_FAILED_PACIFIED;
5168  return SPELL_FAILED_SILENCED;
5169  default:
5170  break;
5171  }
5172  }
5173  }
5174  }
5175  //You are prevented from casting and the spell casted does not grant immunity. Return a failed error.
5176  else
5177  return prevented_reason;
5178  }
5179  return SPELL_CAST_OK; // all ok
5180 }
Unit *const m_caster
Definition: Spell.h:541
uint32 AttributesEx
Definition: DBCStructure.h:680
uint32 AttributesEx6
Definition: DBCStructure.h:685
AuraMap & GetAuras()
Definition: Unit.h:1739
#define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK
DispelType
uint32 EffectApplyAuraName[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:734
SpellSchoolMask GetSpellSchoolMask(SpellEntry const *spellInfo)
Definition: SpellMgr.h:481
uint32 GetDispelMask(DispelType dispel)
Definition: SpellMgr.h:505
const SpellEntry *const m_spellInfo
Definition: Spell.h:438
ACE_UINT8 uint8
Definition: Define.h:73
std::multimap< spellEffectPair, Aura * > AuraMap
Definition: Unit.h:916
bool IsSpellRemoveAllMovementAndControlLossEffects(SpellEntry const *spellProto)
Definition: SpellMgr.h:278
int32 EffectMiscValue[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:739
uint32 PreventionType
Definition: DBCStructure.h:764
uint32 GetSpellMechanicMask(SpellEntry const *spellInfo, int32 effect)
Definition: SpellMgr.h:486
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:670
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:869
SpellCastResult
bool HasFlag(uint16 index, uint32 flag) const
Definition: Object.h:281
ACE_UINT32 uint32
Definition: Define.h:71
uint32 AttributesEx5
Definition: DBCStructure.h:684
void Spell::CheckDst ( )
inline

Definition at line 418 of file Spell.h.

Referenced by SearchAreaTarget().

419  {
421  }
Unit *const m_caster
Definition: Spell.h:541
SpellCastTargets m_targets
Definition: Spell.h:443
bool HasDst() const
Definition: Spell.h:171
void setDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition: Spell.cpp:108
SpellCastResult Spell::CheckDummyCast ( uint32  effIndex)

Definition at line 4807 of file Spell.cpp.

References ALLIANCE, SpellDummyConditionEntry::bitMaskCondition, SpellDummyConditionEntry::condition, SpellDummyConditionEntry::conditions, SpellDummyConditionEntry::data, EFFECT_0, EFFECT_1, EFFECT_2, CreatureInfo::family, Unit::GetCharmGUID(), Creature::GetCreatureTemplate(), Object::GetEntry(), Unit::GetHealth(), Unit::GetHealthPct(), Unit::getLevel(), Unit::GetMaxHealth(), Unit::GetMaxPower(), Unit::GetPetGUID(), Unit::GetPower(), Player::GetQuestRewardStatus(), Player::GetQuestStatus(), Player::GetTeam(), SpellCastTargets::getUnitTarget(), Unit::HasAura(), WorldObject::HasInArc(), Player::HasSpell(), HORDE, SpellEntry::Id, Unit::isDead(), Unit::IsFriendlyTo(), Unit::IsHostileTo(), m_caster, m_spellInfo, m_targets, POWER_MANA, QUEST_STATUS_INCOMPLETE, SDC_ACTIVE_EVENT, SDC_AURA_CASTER, SDC_AURA_TARGET, SDC_BTM_CASTER_MUST_NOT_HAVE_CHARM, SDC_BTM_CASTER_MUST_NOT_HAVE_PET, SDC_BTM_NEEDS_SCRIPT_CHECK, SDC_BTM_TARGET_MUST_BE_CREATURE, SDC_BTM_TARGET_MUST_BE_DEAD, SDC_BTM_TARGET_MUST_BE_FRIENDLY, SDC_BTM_TARGET_MUST_BE_HOSTILE, SDC_BTM_TARGET_MUST_BE_PLAYER, SDC_BTM_TARGET_MUST_NOT_BE_HIER_LEVEL, SDC_CASTER_HP_PCT, SDC_CASTER_MANA_PCT, SDC_HAS_SPELL, SDC_NONE, SDC_QUEST_REWARDED, SDC_QUEST_TAKEN, SDC_TARGET_EXACT_ENTRY, SDC_TARGET_FAMILY, SDC_TARGET_HP_PCT, SDC_TARGET_IN_ARC, SDC_TARGET_MANA_PCT, SDC_TARGET_TYPE_FLAGS, SDC_TEAM, sGameEventMgr, sLog, SPELL_CAST_OK, SPELL_FAILED_ALREADY_HAVE_CHARM, SPELL_FAILED_ALREADY_HAVE_SUMMON, SPELL_FAILED_BAD_IMPLICIT_TARGETS, SPELL_FAILED_BAD_TARGETS, SPELL_FAILED_HIGHLEVEL, SPELL_FAILED_NOT_INFRONT, SPELL_FAILED_SPELL_UNAVAILABLE, SPELL_FAILED_TARGET_ENEMY, SPELL_FAILED_TARGET_FRIENDLY, SPELL_FAILED_TARGET_NOT_DEAD, sSpellMgr, Object::ToCreature(), Object::ToPlayer(), CreatureInfo::type, CreatureInfo::type_flags, and unitTarget.

Referenced by CheckCast().

4808 {
4809  SpellDummyConditionEntry const* sdcEntry = sSpellMgr.GetSpellDummyCondition(m_spellInfo->Id, effIndex);
4810 
4811  if (!sdcEntry)
4812  return SPELL_CAST_OK;
4813 
4815 
4816  if (sdcEntry->bitMaskCondition)
4817  {
4819  if (m_caster->GetPetGUID())
4821 
4823  if (m_caster->GetCharmGUID())
4825 
4826  bool creature = sdcEntry->bitMaskCondition & SDC_BTM_TARGET_MUST_BE_CREATURE;
4827  bool player = sdcEntry->bitMaskCondition & SDC_BTM_TARGET_MUST_BE_PLAYER;
4828 
4829  // creature && !player = TARGET MUST BE CREATURE
4830  // !creature && player = TARGET MUST BE PLAYER
4831  // creature && player = TARGET MUST BE ANY UNIT
4832  // !creature && !player = TARGET is not required
4833 
4834  // operations with target, prevent crash if there's no target
4842 
4843  if (creature)
4844  {
4845  if (!player && !unitTarget->ToCreature())
4846  return SPELL_FAILED_BAD_TARGETS;
4847  }
4848  else if (player && !unitTarget->ToPlayer())
4849  return SPELL_FAILED_BAD_TARGETS;
4850 
4851  bool friendly = (sdcEntry->bitMaskCondition & SDC_BTM_TARGET_MUST_BE_FRIENDLY);
4852  bool hostile = (sdcEntry->bitMaskCondition & SDC_BTM_TARGET_MUST_BE_HOSTILE);
4853 
4854  // Note: IsHostileTo returns true even if target is neutral ( <= neutral)
4855  // IsFriendlyTo returns true only if target is friendly ( > neutral)
4856 
4857  if (!friendly)
4858  {
4859  if (hostile)
4860  {
4861  if (!m_caster->IsHostileTo(unitTarget))
4862  // return SPELL_FAILED_BAD_TARGETS;
4864  }
4865  }
4866  else if (!hostile && !m_caster->IsFriendlyTo(unitTarget))
4868 
4870  if (!unitTarget->isDead())
4872 
4874  if (unitTarget->getLevel() > m_caster->getLevel())
4875  return SPELL_FAILED_HIGHLEVEL;
4876 
4877  // 14 upper bits are for Creature Type
4878  if (sdcEntry->bitMaskCondition >> 18) // 32 - 14 = 18
4879  {
4880  // we have some SDC_BTM_TYPE set
4881  if (!unitTarget)
4883 
4884  Creature* c = unitTarget->ToCreature();
4885  if (!c)
4886  return SPELL_FAILED_BAD_TARGETS;
4887 
4888  if (!(sdcEntry->bitMaskCondition & (1 << (c->GetCreatureTemplate()->type + 17))))
4889  return SPELL_FAILED_BAD_TARGETS;
4890  }
4891 
4893  {
4894  //switch (m_spellInfo->Id)
4895  //{
4896  //default:
4897  sLog.outError("Spell %u has SDC_BTM_NEEDS_SCRIPT_CHECK in bitMaskCondition (spell_dummy_condition), but hasn't been implemented, yet.", m_spellInfo->Id);
4898  // break;
4899  //}
4900  }
4901  }
4902 
4903  for (uint32 i = 0; i < sizeof(sdcEntry->conditions) / sizeof(*sdcEntry->conditions); i++)
4904  {
4905  int32 data = sdcEntry->conditions[i].data;
4906  switch (sdcEntry->conditions[i].condition)
4907  {
4908  case SDC_NONE:
4909  break;
4910  case SDC_AURA_TARGET:
4911  if (!unitTarget)
4912  return SPELL_FAILED_BAD_TARGETS;
4913 
4914  if (data > 0)
4915  {
4916  if (!unitTarget->HasAura(data, EFFECT_0) &&
4917  !unitTarget->HasAura(data, EFFECT_1) &&
4918  !unitTarget->HasAura(data, EFFECT_2))
4919  return SPELL_FAILED_BAD_TARGETS;
4920  }
4921  else
4922  {
4923  data = -data;
4924  if (unitTarget->HasAura(data, EFFECT_0) &&
4925  unitTarget->HasAura(data, EFFECT_1) &&
4926  unitTarget->HasAura(data, EFFECT_2))
4927  return SPELL_FAILED_BAD_TARGETS;
4928  }
4929  break;
4930  case SDC_AURA_CASTER:
4931  if (data > 0)
4932  {
4933  if (!m_caster->HasAura(data, EFFECT_0) &&
4934  !m_caster->HasAura(data, EFFECT_1) &&
4935  !m_caster->HasAura(data, EFFECT_2))
4936  return SPELL_FAILED_BAD_TARGETS;
4937  }
4938  else
4939  {
4940  data = -data;
4941  if (m_caster->HasAura(data, EFFECT_0) &&
4942  m_caster->HasAura(data, EFFECT_1) &&
4943  m_caster->HasAura(data, EFFECT_2))
4944  return SPELL_FAILED_BAD_TARGETS;
4945  }
4946  break;
4947  case SDC_QUEST_TAKEN:
4950  break;
4951  case SDC_QUEST_REWARDED:
4952  if (!m_caster->ToPlayer() || !m_caster->ToPlayer()->GetQuestRewardStatus(data))
4954  break;
4955  case SDC_HAS_SPELL:
4956  if (!m_caster->ToPlayer() || !m_caster->ToPlayer()->HasSpell(data))
4958  break;
4959  case SDC_ACTIVE_EVENT:
4960  if (!sGameEventMgr.IsActiveEvent(data))
4962  break;
4963  case SDC_TEAM:
4964  if (!m_caster->ToPlayer() || m_caster->ToPlayer()->GetTeam() != (data ? HORDE : ALLIANCE))
4966  break;
4967  case SDC_CASTER_HP_PCT:
4968  {
4969  bool below = data < 0;
4970  float pct = float(labs(data)) / 100.f;
4971 
4972  if (below)
4973  {
4974  if (m_caster->GetHealth() > m_caster->GetMaxHealth()*pct)
4975  return SPELL_FAILED_BAD_TARGETS;
4976  }
4977  else
4978  {
4979  if (m_caster->GetHealth() < m_caster->GetMaxHealth()*pct)
4980  return SPELL_FAILED_BAD_TARGETS;
4981  }
4982  break;
4983  }
4984  case SDC_TARGET_HP_PCT:
4985  {
4986  if (!unitTarget)
4988 
4989  bool below = data < 0;
4990 
4991  if (below)
4992  {
4993  if (unitTarget->GetHealthPct() <= data)
4994  return SPELL_FAILED_BAD_TARGETS;
4995