OregonCore  revision fb2a440-git
Your Favourite TBC server
Spell.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "Common.h"
19 #include "Database/DatabaseEnv.h"
20 #include "WorldPacket.h"
21 #include "WorldSession.h"
22 #include "GridNotifiers.h"
23 #include "GridNotifiersImpl.h"
24 #include "Opcodes.h"
25 #include "Log.h"
26 #include "UpdateMask.h"
27 #include "World.h"
28 #include "ObjectMgr.h"
29 #include "SpellMgr.h"
30 #include "Player.h"
31 #include "Pet.h"
32 #include "Unit.h"
33 #include "Spell.h"
34 #include "DynamicObject.h"
35 #include "SpellAuras.h"
36 #include "UpdateData.h"
37 #include "ObjectAccessor.h"
38 #include "CellImpl.h"
39 #include "SharedDefines.h"
40 #include "LootMgr.h"
41 #include "VMapFactory.h"
42 #include "Battleground.h"
43 #include "Utilities/Util.h"
44 #include "TemporarySummon.h"
45 #include "GameEventMgr.h"
46 #include "DisableMgr.h"
47 #include "ConditionMgr.h"
48 
49 #define SPELL_CHANNEL_UPDATE_INTERVAL (1*IN_MILLISECONDS)
50 
52 
53 bool IsQuestTameSpell(uint32 spellId)
54 {
55  SpellEntry const* spellproto = sSpellStore.LookupEntry(spellId);
56  if (!spellproto) return false;
57 
58  return spellproto->Effect[0] == SPELL_EFFECT_THREAT
59  && spellproto->Effect[1] == SPELL_EFFECT_APPLY_AURA && spellproto->EffectApplyAuraName[1] == SPELL_AURA_DUMMY;
60 }
61 
63 {
64  m_unitTarget = NULL;
65  m_itemTarget = NULL;
66  m_GOTarget = NULL;
67 
68  m_unitTargetGUID = 0;
69  m_GOTargetGUID = 0;
71  m_itemTargetGUID = 0;
73 
74  m_srcPos.Relocate(0, 0, 0, 0);
75  m_strTarget = "";
76  m_targetMask = 0;
77 }
78 
80 {
81 }
82 
84 {
85  if (!target)
86  return;
87 
88  m_unitTarget = target;
89  m_unitTargetGUID = target->GetGUID();
91 }
92 
93 void SpellCastTargets::setSrc(float x, float y, float z)
94 {
95  m_srcPos.Relocate(x, y, z);
97 }
98 
100 {
101  if (pos)
102  {
103  m_srcPos.Relocate(pos);
105  }
106 }
107 
108 void SpellCastTargets::setDst(float x, float y, float z, float orientation, uint32 mapId)
109 {
110  m_dstPos.Relocate(x, y, z, orientation);
112  if (mapId != MAPID_INVALID)
113  m_dstPos.m_mapId = mapId;
114 }
115 
117 {
118  if (pos)
119  {
120  m_dstPos.Relocate(pos);
122  }
123 }
124 
126 {
127  m_GOTarget = target;
128  m_GOTargetGUID = target->GetGUID();
129  // m_targetMask |= TARGET_FLAG_OBJECT;
130 }
131 
133 {
134  if (!item)
135  return;
136 
137  m_itemTarget = item;
138  m_itemTargetGUID = item->GetGUID();
139  m_itemTargetEntry = item->GetEntry();
141 }
142 
144 {
145  m_CorpseTargetGUID = corpse->GetGUID();
146 }
147 
149 {
153  NULL;
154 
155  m_itemTarget = NULL;
156  if (caster->GetTypeId() == TYPEID_PLAYER)
157  {
161  {
162  // here it is not guid but slot. Also prevent hacking slots
163  Player* pTrader = caster->ToPlayer()->GetTrader();
164  if (pTrader && m_itemTargetGUID.GetRawValue() < TRADE_SLOT_COUNT)
166  }
167  if (m_itemTarget)
169  }
170 }
171 
173 {
174  data >> m_targetMask;
175 
176  if (m_targetMask == TARGET_FLAG_SELF)
177  return;
178 
179  // TARGET_FLAG_UNK2 is used for non-combat pets, maybe other?
180  if (m_targetMask & (TARGET_FLAG_UNIT | TARGET_FLAG_UNK2))
181  data >> m_unitTargetGUID.ReadAsPacked();
182 
184  data >> m_GOTargetGUID.ReadAsPacked();
185 
186  if ((m_targetMask & (TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM)) && caster->GetTypeId() == TYPEID_PLAYER)
187  data >> m_itemTargetGUID.ReadAsPacked();
188 
189  if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION)
190  {
192  if (!m_srcPos.IsPositionValid())
193  throw ByteBufferException(false, data.rpos(), 0, data.size());
194  }
195 
196  if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
197  {
199  if (!m_dstPos.IsPositionValid())
200  throw ByteBufferException(false, data.rpos(), 0, data.size());
201  }
202 
203  if (m_targetMask & TARGET_FLAG_STRING)
204  data >> m_strTarget;
205 
206  if (m_targetMask & (TARGET_FLAG_CORPSE | TARGET_FLAG_PVP_CORPSE))
208 
209  // find real units/GOs
210  Update(caster);
211 }
212 
214 {
215  data << uint32(m_targetMask);
216 
218  {
220  {
221  if (m_unitTarget)
222  data << m_unitTarget->GetPackGUID();
223  else
224  data << uint8(0);
225  }
227  {
228  if (m_GOTarget)
229  data << m_GOTarget->GetPackGUID();
230  else
231  data << uint8(0);
232  }
235  else
236  data << uint8(0);
237  }
238 
240  {
241  if (m_itemTarget)
242  data << m_itemTarget->GetPackGUID();
243  else
244  data << uint8(0);
245  }
246 
249 
252 
254  data << m_strTarget;
255 }
256 
257 Spell::Spell(Unit* Caster, SpellEntry const* info, bool triggered, uint64 originalCasterGUID, Spell** triggeringContainer, bool skipCheck)
258  : m_spellInfo(info)
259  , m_caster(Caster)
260  , m_spellValue(new SpellValue(m_spellInfo))
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 }
360 
362 {
363  m_destroyed = true;
364 
365  delete m_spellValue;
366 }
367 
368 void ResizeUnitListByDistance(std::list<Unit*> &_list, WorldObject* source, uint32 _size, bool _keepnearest)
369 {
370  float d;
371  std::list<Unit*>::iterator _i;
372  ASSERT(_size >= 0);
373  while(_list.size() > _size)
374  {
375  d = source->GetDistance((*_list.begin()));
376  _i = _list.begin();
377  for(std::list<Unit*>::iterator itr = _list.begin(); itr != _list.end(); itr++)
378  {
379  if((_keepnearest && source->GetDistance(*itr) > d) || (!_keepnearest && source->GetDistance(*itr) < d))
380  {
381  d = source->GetDistance(*itr);
382  _i = itr;
383  }
384  }
385  _list.erase(_i);
386  }
387 }
388 
390 {
391  for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
392  {
393  // not call for empty effect.
394  // Also some spells use not used effect targets for store targets for dummy effect in triggered spells
395  if (!m_spellInfo->Effect[i])
396  continue;
397 
398  uint32 effectTargetType = sSpellMgr.EffectTargetType[m_spellInfo->Effect[i]];
399 
400  // is it possible that areaaura is not applied to caster?
401  if (effectTargetType == SPELL_REQUIRE_NONE)
402  continue;
403 
406 
407  if (targetA)
408  SetTargetMap(i, targetA);
409  if (targetB) // In very rare case !A && B
410  SetTargetMap(i, targetB);
411 
412  if (effectTargetType != SPELL_REQUIRE_UNIT)
413  {
414  if (effectTargetType == SPELL_REQUIRE_CASTER)
416  else if (effectTargetType == SPELL_REQUIRE_ITEM)
417  {
418  if (m_targets.getItemTarget())
420  }
421  continue;
422  }
423 
424  if (!targetA && !targetB)
425  {
426  // add here custom effects that need default target.
427  // FOR EVERY TARGET TYPE THERE IS A DIFFERENT FILL!!
428  switch (m_spellInfo->Effect[i])
429  {
430  case SPELL_EFFECT_DUMMY:
431  {
432  switch (m_spellInfo->Id)
433  {
434  case 20577: // Cannibalize
435  {
436  // non-standard target selection
437  SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
438  float max_range = GetSpellMaxRange(srange);
439  WorldObject* result = NULL;
440 
441  Oregon::CannibalizeObjectCheck u_check(m_caster, max_range);
443  m_caster->VisitNearbyGridObject(max_range, searcher);
444  if (!result)
445  m_caster->VisitNearbyWorldObject(max_range, searcher);
446 
447 
448  if (result)
449  {
450  switch (result->GetTypeId())
451  {
452  case TYPEID_UNIT:
453  case TYPEID_PLAYER:
454  AddUnitTarget((Unit*)result, i);
455  break;
456  case TYPEID_CORPSE:
457  m_targets.setCorpseTarget((Corpse*)result);
458  if (Player* owner = ObjectAccessor::FindPlayer(((Corpse*)result)->GetOwnerGUID()))
459  AddUnitTarget(owner, i);
460  break;
461  }
462  }
463  else
464  {
465  // clear cooldown at fail
466  if (m_caster->GetTypeId() == TYPEID_PLAYER)
469  finish(false);
470  }
471  break;
472  }
473  default:
474  if (m_targets.getUnitTarget())
476  break;
477  }
478  break;
479  }
480  case SPELL_EFFECT_BIND:
488  if (m_targets.getUnitTarget())
490  else
492  break;
495  {
496  Player* target = sObjectMgr.GetPlayer(m_caster->ToPlayer()->GetSelection());
497  if (target)
498  AddUnitTarget(target, i);
499  }
500  break;
502  if (m_targets.getUnitTarget())
505  {
507  if (corpse)
508  {
509  Player* owner = ObjectAccessor::FindPlayer(corpse->GetOwnerGUID());
510  if (owner)
511  AddUnitTarget(owner, i);
512  }
513  }
514  break;
517  case SPELL_EFFECT_STUCK:
520  break;
522  if (Guardian* pet = m_caster->GetGuardianPet())
523  AddUnitTarget(pet, i);
524  break;
525  /*case SPELL_EFFECT_ENCHANT_ITEM:
526  case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY:
527  case SPELL_EFFECT_DISENCHANT:
528  case SPELL_EFFECT_FEED_PET:
529  case SPELL_EFFECT_PROSPECTING:
530  if (m_targets.getItemTarget())
531  AddItemTarget(m_targets.getItemTarget(), i);
532  break;*/
535  break;
537  // AreaAura
538  if (m_spellInfo->Attributes == 0x9050000 || m_spellInfo->Attributes == 0x10000)
540  break;
542  if (m_targets.getUnitTarget())
544  else if (m_targets.getCorpseTargetGUID())
545  {
547  if (corpse)
548  {
549  Player* owner = ObjectAccessor::FindPlayer(corpse->GetOwnerGUID());
550  if (owner)
551  AddUnitTarget(owner, i);
552  }
553  }
554  break;
556  if (!m_caster->ToPlayer())
557  break;
558 
559  // Special message for this Spell (if not ready)
561  {
563  finish(false);
564  return;
565  }
566 
567  if (sObjectMgr.GetRAFLinkedBuddyForPlayer(m_caster->ToPlayer()))
569  break;
570  default:
571  break;
572  }
573  }
574  }
575 
576  if (m_targets.HasDst())
577  {
578  if (m_spellInfo->speed > 0.0f)
579  {
580  float dist = m_caster->GetDistance(m_targets.m_dstPos);
581  if (dist < 5.0f) dist = 5.0f;
582  m_delayMoment = (uint64) floor(dist / m_spellInfo->speed * 1000.0f);
583  }
584  }
585 
586  // m_targets is originally sent by client and its values are used
587  // in single target casts. It may occur that we have set implicit
588  // targets but we need to change m_targets too for those checks
589 
590  if (!m_targets.getUnitTarget() && m_UniqueTargetInfo.size())
591  if (uint64 targetGUID = (*m_UniqueTargetInfo.begin()).targetGUID)
592  if (Unit* target = m_caster->GetGUID() == targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetGUID))
593  m_targets.setUnitTarget(target);
594 
595  if (!m_targets.getGOTarget() && m_UniqueGOTargetInfo.size())
596  if (uint64 targetGUID = (*m_UniqueGOTargetInfo.begin()).targetGUID)
597  if (GameObject* target = m_caster->GetMap()->GetGameObject(targetGUID))
598  m_targets.setGOTarget(target);
599 
600  if (!m_targets.getItemTarget() && m_UniqueItemInfo.size())
601  if (Item* target = (*m_UniqueItemInfo.begin()).item)
602  m_targets.setItemTarget(target);
603 }
604 
606 {
607  //==========================================================================================
608  // Now fill data for trigger system, need know:
609  // can spell trigger another or not (m_canTrigger)
610  // Create base triggers flags for Attacker and Victim (m_procAttacker and m_procVictim)
611  //==========================================================================================
612 
613  // Fill flag can spell trigger or not
614  if (!m_IsTriggeredSpell)
615  m_canTrigger = true; // Normal cast - can trigger
616  else if (!m_triggeredByAuraSpell)
617  m_canTrigger = true; // Triggered from SPELL_EFFECT_TRIGGER_SPELL - can trigger
618  else // Exceptions (some periodic triggers)
619  {
620  m_canTrigger = false; // Triggered spells can`t trigger another
621  switch (m_spellInfo->SpellFamilyName)
622  {
623  case SPELLFAMILY_MAGE: // Arcane Missles / Blizzard / Molten Armor triggers need do it
624  if (m_spellInfo->SpellFamilyFlags & 0x0000000800200080LL) m_canTrigger = true;
625  break;
626  case SPELLFAMILY_WARLOCK: // For Hellfire Effect / Rain of Fire / Soul Fire triggers need do it
627  if (m_spellInfo->SpellFamilyFlags & 0x0000800000000060LL) m_canTrigger = true;
628  if (m_spellInfo->SpellFamilyFlags & 0x0000008000000060LL)
629  {
632  m_canTrigger = true;
633  }
634  break;
635  case SPELLFAMILY_HUNTER: // Hunter Explosive Trap Effect/Immolation Trap Effect/Frost Trap Aura/Snake Trap Effect
636  if (m_spellInfo->SpellFamilyFlags & 0x0000200000000014LL) m_canTrigger = true;
637  break;
638  case SPELLFAMILY_PALADIN: // For Holy Shock, SoC and SoB triggers need to do it
639  if (m_spellInfo->SpellFamilyFlags & 0x0001040002200000LL) m_canTrigger = true;
640  break;
641  case SPELLFAMILY_ROGUE: // mutilate mainhand + offhand
642  if (m_spellInfo->SpellFamilyFlags & 0x600000000LL) m_canTrigger = true;
643  break;
644  case SPELLFAMILY_SHAMAN:
645  // Lightning Shield
646  if (m_spellInfo->SpellFamilyFlags & 0x0000000000000400LL) m_canTrigger = true;
647  break;
648  }
649  }
650 
652  m_canTrigger = false; // Do not trigger from item cast spell(except potions)
653 
655  // Get data for type of attack and fill base info for trigger
656  switch (m_spellInfo->DmgClass)
657  {
660  if (m_attackType == OFF_ATTACK)
662  else
665  break;
667  // Auto attack
669  {
672  }
673  else // Ranged spell attack
674  {
677  }
678  break;
679  default:
680  if (IsPositiveSpell(m_spellInfo->Id)) // Check for positive spell
681  {
684  }
685  else if (m_spellInfo->AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG) // Wands auto attack
686  {
689  }
690  else // Negative spell
691  {
694  }
695  break;
696  }
697 
700  m_canTrigger = true;
701 
703  m_canTrigger = false;
704 
705  // Hunter traps spells (for Entrapment trigger)
706  // Gives your Immolation Trap, Frost Trap, Explosive Trap, and Snake Trap ....
709 }
710 
712 {
713  // m_UniqueTargetInfo.clear();
714  // m_UniqueGOTargetInfo.clear();
715 
716  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
717  ihit->deleted = true;
718 
719  for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
720  ihit->deleted = true;
721 
722  m_UniqueItemInfo.clear();
723  m_countOfHit = 0;
724  m_countOfMiss = 0;
725  m_delayMoment = 0;
726 }
727 
728 void Spell::AddUnitTarget(Unit* pVictim, uint32 effIndex)
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 }
761 
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);
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
823 
824  if (target.reflectResult == SPELL_MISS_REFLECT) // Impossible reflect again, so simply deflect spell
826 
827  // Increase time interval for reflected spells by 1.5
828  target.timeDelay += target.timeDelay >> 1;
829  }
830  else
832  }
833 }
834 
835 void Spell::AddUnitTarget(uint64 unitGUID, uint32 effIndex)
836 {
837  Unit* unit = m_caster->GetGUID() == unitGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, unitGUID);
838  if (unit)
839  AddUnitTarget(unit, effIndex);
840 }
841 
842 void Spell::AddGOTarget(GameObject* pVictim, uint32 effIndex)
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 }
889 
890 void Spell::AddGOTarget(uint64 goGUID, uint32 effIndex)
891 {
892  GameObject* go = m_caster->GetMap()->GetGameObject(goGUID);
893  if (go)
894  AddGOTarget(go, effIndex);
895 }
896 
897 void Spell::AddItemTarget(Item* pitem, uint32 effIndex)
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 }
919 
921 {
922  if (!target || target == (TargetInfo*)0x10 || target->processed || m_spellInfo->Id > MAX_SPELL_ID) // Check target
923  return;
924 
925  target->processed = true; // Target checked in apply effects procedure
926 
927  // Get mask of effects for target
928  uint8 mask = target->effectMask;
929 
930  Unit* unit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
931 
932  if (!unit)
933  {
934  uint8 farMask = 0;
935  // create far target mask
936  for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
938  if ((1 << i) & mask)
939  farMask |= (1 << i);
940 
941  if (!farMask)
942  return;
943  // find unit in world
944  unit = ObjectAccessor::FindUnit(target->targetGUID);
945  if (!unit)
946  return;
947 
948  // do far effects on the unit
949  // can't use default call because of threading, do stuff as fast as possible
950  for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
951  if (farMask & (1 << i))
952  HandleEffects(unit, NULL, NULL, i);
953  return;
954  }
955 
957  return; // No missinfo in that case
958 
959  // Get original caster (if exist) and calculate damage/healing from him data
961 
962  // Skip if m_originalCaster not avaiable
963  if (!caster)
964  return;
965 
966  SpellMissInfo missInfo = target->missCondition;
967 
968  // Need init unitTarget by default unit (can changed in code on reflect)
969  // Or on missInfo != SPELL_MISS_NONE unitTarget undefined (but need in trigger subsystem)
970  unitTarget = unit;
971 
972  // Reset damage/healing counter
973  m_damage = target->damage;
974  m_healing = -target->damage;
975 
976  // Fill base trigger info
977  uint32 procAttacker = m_procAttacker;
978  uint32 procVictim = m_procVictim;
979  uint32 procEx = PROC_EX_NONE;
980 
981  if (missInfo == SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
982  DoSpellHitOnUnit(unit, mask);
983  else if (missInfo == SPELL_MISS_REFLECT) // In case spell reflect from target, do all effect on caster (if hit)
984  {
985  if (target->reflectResult == SPELL_MISS_NONE) // If reflected spell hit caster -> do all effect on him
986  {
987  DoSpellHitOnUnit(m_caster, mask);
988  caster = unit;
989  }
990  }
991 
992  // Do not take combo points on dodge and miss
994  if (missInfo != SPELL_MISS_NONE)
995  m_needComboPoints = false;
996 
997  // All calculated do it!
998  // Do healing and triggers
999  if (m_healing > 0)
1000  {
1001  bool crit = caster->isSpellCrit(NULL, m_spellInfo, m_spellSchoolMask);
1002  uint32 addhealth = m_healing;
1003  if (crit)
1004  {
1005  procEx |= PROC_EX_CRITICAL_HIT;
1006  addhealth = caster->SpellCriticalBonus(m_spellInfo, addhealth, NULL);
1007  }
1008  else
1009  procEx |= PROC_EX_NORMAL_HIT;
1010 
1011  caster->SendHealSpellLog(unitTarget, m_spellInfo->Id, addhealth, crit);
1012 
1013  // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
1014  if (missInfo != SPELL_MISS_REFLECT)
1015  caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_canTrigger);
1016 
1017  int32 gain = unitTarget->ModifyHealth(int32(addhealth));
1018  if (m_IsTriggeredSpell)
1019  /* @todo: Test me
1020  spells like earth shield and prayer of mending
1021  should give threat to the target they were casted on */
1022  unitTarget->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
1023  else
1024  caster->getHostileRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
1025 
1026  if (caster->GetTypeId() == TYPEID_PLAYER)
1027  if (Battleground* bg = caster->ToPlayer()->GetBattleground())
1028  bg->UpdatePlayerScore(caster->ToPlayer(), SCORE_HEALING_DONE, gain);
1029 
1030  }
1031  // Do damage and triggers
1032  else if (m_damage > 0)
1033  {
1034  // Fill base damage struct (unitTarget - is real spell target)
1036 
1037  // Add bonuses and fill damageInfo struct
1038  caster->CalculateSpellDamageTaken(&damageInfo, m_damage, m_spellInfo, m_attackType, target->crit);
1039 
1040  // Send log damage message to client
1041  caster->SendSpellNonMeleeDamageLog(&damageInfo);
1042 
1043  procEx = createProcExtendMask(&damageInfo, missInfo);
1044  procVictim |= PROC_FLAG_TAKEN_DAMAGE;
1045 
1046  caster->DealSpellDamage(&damageInfo, true);
1047 
1048  // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
1049  if (missInfo != SPELL_MISS_REFLECT)
1050  {
1051  caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, damageInfo.damage, m_attackType, m_spellInfo, m_canTrigger);
1053  caster->ToPlayer()->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx, m_spellInfo);
1054  }
1055 
1056  // Judgement of Blood
1058  {
1059  int32 damagePoint = damageInfo.damage * 33 / 100;
1060  m_caster->CastCustomSpell(m_caster, 32220, &damagePoint, NULL, NULL, true);
1061  }
1062  // Bloodthirst
1063  else if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellInfo->SpellFamilyFlags & 0x40000000000LL)
1064  {
1065  uint32 BTAura = 0;
1066  switch (m_spellInfo->Id)
1067  {
1068  case 23881:
1069  BTAura = 23885;
1070  break;
1071  case 23892:
1072  BTAura = 23886;
1073  break;
1074  case 23893:
1075  BTAura = 23887;
1076  break;
1077  case 23894:
1078  BTAura = 23888;
1079  break;
1080  case 25251:
1081  BTAura = 25252;
1082  break;
1083  case 30335:
1084  BTAura = 30339;
1085  break;
1086  default:
1087  sLog.outError("Spell::EffectSchoolDMG: Spell %u not handled in BTAura", m_spellInfo->Id);
1088  break;
1089  }
1090  if (BTAura)
1091  m_caster->CastSpell(m_caster, BTAura, true);
1092  }
1093  }
1094  // Passive spell hits/misses or active spells only misses (only triggers)
1095  else
1096  {
1097  // Fill base damage struct (unitTarget - is real spell target)
1099  procEx = createProcExtendMask(&damageInfo, missInfo);
1100  // Do triggers for unit (reflect triggers passed on hit phase for correct drop charge)
1101  if (missInfo != SPELL_MISS_REFLECT)
1102  caster->ProcDamageAndSpell(unit, procAttacker, procVictim, procEx, 0, m_attackType, m_spellInfo, m_canTrigger);
1103 
1104  // Failed Pickpocket, reveal rogue
1106  {
1110  }
1111  }
1112 
1113  // Call scripted function for AI if this spell is casted upon a creature (except pets)
1114  if (IS_CREATURE_GUID(target->targetGUID))
1115  {
1116  // cast at creature (or GO) quest objectives update at successful cast finished (+channel finished)
1117  // ignore autorepeat/melee casts for speed (not exist quest for spells (hm...)
1120  }
1121 
1122  if (missInfo != SPELL_MISS_EVADE && missInfo != SPELL_MISS_REFLECT
1123  && m_caster && !m_caster->IsFriendlyTo(unit) &&
1125  {
1127 
1129  if (!unit->IsStandState())
1131  }
1132 
1133  if (unit->IsPvP() && m_caster->GetTypeId() == TYPEID_PLAYER && (unit->GetTypeId() == TYPEID_PLAYER || unit->IsInCombat()))
1134  m_caster->ToPlayer()->UpdatePvP(true);
1135 }
1136 
1137 void Spell::DoSpellHitOnUnit(Unit* unit, const uint32 effectMask)
1138 {
1139  if (!unit || !effectMask)
1140  return;
1141 
1142  // Recheck immune (only for delayed spells)
1143  if (m_spellInfo->speed &&
1145  && (unit->IsImmunedToDamage(GetSpellSchoolMask(m_spellInfo), true) ||
1146  unit->IsImmuneToSpell(m_spellInfo, true)))
1147  {
1149  m_damage = 0;
1150  return;
1151  }
1152 
1153  if (m_caster != unit)
1154  {
1155  if (unit->GetCharmerOrOwnerGUID() != m_caster->GetGUID())
1156  {
1158  {
1159  if (! (sSpellMgr.GetSpellCustomAttr(m_spellInfo->Id) & SPELL_ATTR_CU_ANY_TARGET))
1160  {
1162  m_damage = 0;
1163  return;
1164  }
1165  }
1166  }
1167  if (m_caster->IsValidAttackTarget(unit))
1168  {
1172  }
1173  else if (m_caster->IsFriendlyTo(unit))
1174  {
1175  // for delayed spells ignore negative spells (after duel end) for friendly targets
1176  // @todo this cause soul transfer bugged
1177  if (m_spellInfo->speed > 0.0f && unit->GetTypeId() == TYPEID_PLAYER && !IsPositiveSpell(m_spellInfo->Id))
1178  {
1180  m_damage = 0;
1181  return;
1182  }
1183 
1184  // assisting case, healing and resurrection
1186  {
1188  if (m_caster->GetTypeId() == TYPEID_PLAYER)
1189  m_caster->ToPlayer()->UpdatePvP(true);
1190  }
1192  {
1193  m_caster->SetInCombatState(unit->IsInPvPCombat(), unit);
1195  }
1196  }
1197  }
1198 
1199  uint8 aura_effmask = 0;
1200  for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1201  if (effectMask & (1 << i) && m_spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA)
1202  aura_effmask |= 1 << i;
1203 
1204  // Get Data Needed for Diminishing Returns, some effects may have multiple auras, so this must be done on spell hit, not aura add
1206  if (m_diminishGroup && aura_effmask)
1207  {
1209  // send immunity message if target is immune
1211  {
1213  return;
1214  }
1215 
1217  // Increase Diminishing on unit, current informations for actually casts will use values above
1218  if ((type == DRTYPE_PLAYER && (unit->GetTypeId() == TYPEID_PLAYER || unit->IsPet() || unit->ToCreature()->isPossessedByPlayer())) || type == DRTYPE_ALL)
1220  }
1221 
1222  for (uint32 effectNumber = 0; effectNumber < 3; effectNumber++)
1223  if (effectMask & (1 << effectNumber))
1224  HandleEffects(unit, NULL, NULL, effectNumber);
1225 
1226  if (unit->GetTypeId() == TYPEID_UNIT && unit->ToCreature()->IsAIEnabled)
1227  unit->ToCreature()->AI()->SpellHit(m_caster, m_spellInfo);
1228 
1231 
1232  // trigger only for first effect targets
1233  if (m_ChanceTriggerSpells.size() && (effectMask & 0x1))
1234  {
1235  int _duration = 0;
1236  for (ChanceTriggerSpells::const_iterator i = m_ChanceTriggerSpells.begin(); i != m_ChanceTriggerSpells.end(); ++i)
1237  {
1238  if (roll_chance_i(i->second))
1239  {
1240  m_caster->CastSpell(unit, i->first, true);
1241  // SPELL_AURA_ADD_TARGET_TRIGGER auras shouldn't trigger auras without duration
1242  // set duration equal to triggering spell
1243  if (GetSpellDuration(i->first) == -1)
1244  {
1245  // get duration from aura-only once
1246  if (!_duration)
1247  {
1249  _duration = aur ? aur->GetAuraDuration() : -1;
1250  }
1251  unit->SetAurasDurationByCasterSpell(i->first->Id, m_caster->GetGUID(), _duration);
1252  }
1253  }
1254  }
1255  }
1256 
1258  {
1259  if (const std::vector<int32>* spell_triggered = sSpellMgr.GetSpellLinked(m_spellInfo->Id + SPELL_LINK_HIT))
1260  {
1261  for (std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
1262  if (*i < 0)
1263  unit->RemoveAurasDueToSpell(-(*i));
1264  else
1265  unit->CastSpell(unit, *i, true, 0, 0, m_caster->GetGUID());
1266  }
1267  }
1268 }
1269 
1271 {
1272  if (!target || target == (GOTargetInfo*)0x10 || target->processed || m_spellInfo->Id > MAX_SPELL_ID) // Check target
1273  return;
1274 
1275  target->processed = true; // Target checked in apply effects procedure
1276 
1277  uint32 effectMask = target->effectMask;
1278  if (!effectMask)
1279  return;
1280 
1281  GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
1282  if (!go)
1283  return;
1284 
1285  for (uint32 effectNumber = 0; effectNumber < 3; effectNumber++)
1286  if (effectMask & (1 << effectNumber))
1287  HandleEffects(NULL, NULL, go, effectNumber);
1288 
1289  sLog.outString("CASTED %u on GUID: " UI64FMTD ", entry: %u", m_spellInfo->Id, go->GetGUID(), go->GetGOInfo()->id);
1290 
1291  // cast at creature (or GO) quest objectives update at successful cast finished (+channel finished)
1292  // ignore autorepeat/melee casts for speed (not exist quest for spells (hm...)
1295 }
1296 
1298 {
1299  uint32 effectMask = target->effectMask;
1300  if (!target->item || !effectMask)
1301  return;
1302 
1303  for (uint32 effectNumber = 0; effectNumber < 3; effectNumber++)
1304  if (effectMask & (1 << effectNumber))
1305  HandleEffects(NULL, target->item, NULL, effectNumber);
1306 }
1307 
1309 {
1310  // Not need check return true
1311  if (m_needAliveTargetMask == 0)
1312  return true;
1313 
1314  uint8 needAliveTargetMask = m_needAliveTargetMask;
1315 
1316  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
1317  {
1318  if (ihit->deleted)
1319  continue;
1320 
1321  if (ihit->missCondition == SPELL_MISS_NONE && (needAliveTargetMask & ihit->effectMask))
1322  {
1323  Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
1324 
1325  if (unit && unit->IsAlive())
1326  needAliveTargetMask &= ~ihit->effectMask; // remove from need alive mask effect that have alive target
1327  }
1328  }
1329 
1330  // is all effects from m_needAliveTargetMask have alive targets
1331  return needAliveTargetMask == 0;
1332 }
1333 
1334 // Helper for Chain Healing
1335 // Spell target first
1336 // Raidmates then descending by injury suffered (MaxHealth - Health)
1337 // Other players/mobs then descending by injury suffered (MaxHealth - Health)
1338 struct ChainHealingOrder : public std::binary_function<const Unit*, const Unit*, bool>
1339 {
1341  ChainHealingOrder(Unit const* Target) : MainTarget(Target) {};
1342  // functor for operator ">"
1343  bool operator()(Unit const* _Left, Unit const* _Right) const
1344  {
1345  return (ChainHealingHash(_Left) < ChainHealingHash(_Right));
1346  }
1347 
1349  {
1350  /*if (Target == MainTarget)
1351  return 0;
1352  else*/ if (Target->GetTypeId() == TYPEID_PLAYER && MainTarget->GetTypeId() == TYPEID_PLAYER &&
1353  Target->ToPlayer()->IsInSameRaidWith((Player const*)MainTarget))
1354  {
1355  if (Target->GetHealth() == Target->GetMaxHealth())
1356  return 40000;
1357  else
1358  return 20000 - Target->GetMaxHealth() + Target->GetHealth();
1359  }
1360  else
1361  return 40000 - Target->GetMaxHealth() + Target->GetHealth();
1362  }
1363 };
1364 
1365 // Helper for targets nearest to the spell target
1366 // The spell target is always first unless there is a target at _completely_ the same position (unbelievable case)
1367 struct TargetDistanceOrder : public std::binary_function<const Unit, const Unit, bool>
1368 {
1370  TargetDistanceOrder(const Unit* Target) : MainTarget(Target) {};
1371  // functor for operator ">"
1372  bool operator()(const Unit* _Left, const Unit* _Right) const
1373  {
1374  return (MainTarget->GetDistance(_Left) < MainTarget->GetDistance(_Right));
1375  }
1376 };
1377 
1378 void Spell::SearchChainTarget(std::list<Unit*>& TagUnitMap, float max_range, uint32 num, SpellTargets TargetType)
1379 {
1380  Unit* cur = m_targets.getUnitTarget();
1381  if (!cur)
1382  return;
1383 
1384  //FIXME: This very like horrible hack and wrong for most spells
1386  max_range += num * CHAIN_SPELL_JUMP_RADIUS;
1387 
1388  std::list<Unit*> tempUnitMap;
1389  if (TargetType == SPELL_TARGETS_CHAINHEAL)
1390  {
1391  SearchAreaTarget(tempUnitMap, max_range, PUSH_CHAIN, SPELL_TARGETS_ALLY);
1392  tempUnitMap.sort(ChainHealingOrder(m_caster));
1393  //if (cur->GetHealth() == cur->GetMaxHealth() && tempUnitMap.size())
1394  // cur = tempUnitMap.front();
1395  }
1396  else
1397  SearchAreaTarget(tempUnitMap, max_range, PUSH_CHAIN, TargetType);
1398  tempUnitMap.remove(cur);
1399 
1400  while (num)
1401  {
1402  TagUnitMap.push_back(cur);
1403  --num;
1404 
1405  if (tempUnitMap.empty())
1406  break;
1407 
1408  std::list<Unit*>::iterator next;
1409 
1410  if (TargetType == SPELL_TARGETS_CHAINHEAL)
1411  {
1412  next = tempUnitMap.begin();
1413  while (cur->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS
1414  || !cur->IsWithinLOSInMap(*next))
1415  {
1416  ++next;
1417  if (next == tempUnitMap.end())
1418  return;
1419  }
1420  }
1421  else
1422  {
1423  tempUnitMap.sort(TargetDistanceOrder(cur));
1424  next = tempUnitMap.begin();
1425 
1426  if (cur->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS)
1427  break;
1429  && !m_caster->isInFrontInMap(*next, max_range))
1430  || !m_caster->CanSeeOrDetect(*next)
1431  || !cur->IsWithinLOSInMap(*next))
1432  {
1433  ++next;
1434  if (next == tempUnitMap.end() || cur->GetDistance(*next) > CHAIN_SPELL_JUMP_RADIUS)
1435  return;
1436  }
1437  }
1438 
1439  cur = *next;
1440  tempUnitMap.erase(next);
1441  }
1442 }
1443 
1444 void Spell::SearchAreaTarget(std::list<Unit*>& TagUnitMap, float radius, const uint32 type, SpellTargets TargetType, uint32 entry)
1445 {
1446  Position* pos;
1447  switch (type)
1448  {
1449  case PUSH_DST_CENTER:
1450  CheckDst();
1451  pos = &m_targets.m_dstPos;
1452  break;
1453  case PUSH_SRC_CENTER:
1454  CheckSrc();
1455  pos = &m_targets.m_srcPos;
1456  break;
1457  case PUSH_CHAIN:
1458  {
1459  Unit* target = m_targets.getUnitTarget();
1460  if (!target)
1461  {
1462  sLog.outError("SPELL: cannot find unit target for spell ID %u\n", m_spellInfo->Id);
1463  return;
1464  }
1465  pos = target;
1466  break;
1467  }
1468  default:
1469  pos = m_caster;
1470  break;
1471  }
1472 
1473  Oregon::SpellNotifierCreatureAndPlayer notifier(*this, TagUnitMap, radius, type, TargetType, pos, entry);
1474  if ((m_spellInfo->AttributesEx3 & SPELL_ATTR3_PLAYERS_ONLY) || (TargetType == SPELL_TARGETS_ENTRY && !entry))
1475  {
1476  m_caster->GetMap()->VisitWorld(pos->m_positionX, pos->m_positionY, radius, notifier);
1477  TagUnitMap.remove_if(Oregon::ObjectTypeIdCheck(TYPEID_PLAYER, false)); // above line will select also pets and totems, remove them
1478  }
1479  else
1480  m_caster->GetMap()->VisitAll(pos->m_positionX, pos->m_positionY, radius, notifier);
1481 }
1482 
1484 {
1485  switch (TargetType)
1486  {
1487  case SPELL_TARGETS_ENTRY:
1488  {
1489  ConditionList conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET, m_spellInfo->Id);
1490  if (conditions.empty())
1491  {
1492  sLog.outDebug("Spell (ID: %u) (caster Entry: %u) does not have record in `conditions` for spell script target (ConditionSourceType 13)", m_spellInfo->Id, m_caster->GetEntry());
1494  return SearchNearbyTarget(range, SPELL_TARGETS_ALLY);
1495  else
1496  return SearchNearbyTarget(range, SPELL_TARGETS_ENEMY);
1497  }
1498 
1499  Creature* creatureScriptTarget = NULL;
1500  GameObject* goScriptTarget = NULL;
1501 
1502  for (ConditionList::const_iterator i_spellST = conditions.begin(); i_spellST != conditions.end(); ++i_spellST)
1503  {
1504  if ((*i_spellST)->Type != CONDITION_SPELL_SCRIPT_TARGET)
1505  continue;
1506  switch((*i_spellST)->ConditionValue1)
1507  {
1509  if ((*i_spellST)->ConditionValue2)
1510  {
1511  if (GameObject *go = m_caster->FindNearestGameObject((*i_spellST)->ConditionValue2, range))
1512  {
1513  // remember found target and range, next attempt will find more near target with another entry
1514  goScriptTarget = go;
1515  creatureScriptTarget = NULL;
1516  range = m_caster->GetDistance(goScriptTarget);
1517  }
1518  }
1519  else if (focusObject) //Focus Object
1520  {
1521  float frange = m_caster->GetDistance(focusObject);
1522  if (range >= frange)
1523  {
1524  creatureScriptTarget = NULL;
1525  goScriptTarget = focusObject;
1526  range = frange;
1527  }
1528  }
1529  break;
1532  default:
1533  if (Creature *cre = m_caster->FindNearestCreature((*i_spellST)->ConditionValue2, range, (*i_spellST)->ConditionValue1 != SPELL_TARGET_TYPE_DEAD))
1534  {
1535  creatureScriptTarget = cre;
1536  goScriptTarget = NULL;
1537  range = m_caster->GetDistance(creatureScriptTarget);
1538  }
1539  break;
1540  }
1541  }
1542 
1543  if (creatureScriptTarget)
1544  return creatureScriptTarget;
1545  else
1546  return goScriptTarget;
1547  }
1548  default:
1549  case SPELL_TARGETS_ENEMY:
1550  {
1551  Unit* target = NULL;
1554  m_caster->VisitNearbyObject(range, searcher);
1555  return target;
1556  }
1557  case SPELL_TARGETS_ALLY:
1558  {
1559  Unit* target = NULL;
1562  m_caster->VisitNearbyObject(range, searcher);
1563  return target;
1564  }
1565  }
1566 }
1567 
1569 {
1570  SpellNotifyPushType pushType = PUSH_NONE;
1571  Player* modOwner = NULL;
1572  if (m_originalCaster)
1573  modOwner = m_originalCaster->GetSpellModOwner();
1574 
1575  switch (sSpellMgr.SpellTargetType[cur])
1576  {
1578  {
1579  switch (cur)
1580  {
1581  case TARGET_NONE:
1582  case TARGET_UNIT_CASTER:
1583  AddUnitTarget(m_caster, i);
1584  break;
1586  {
1587  float min_dis = GetSpellMinRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
1588  float max_dis = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
1589  float dis = rand_norm() * (max_dis - min_dis) + min_dis;
1590  float x, y, z, angle;
1591  angle = (float)rand_norm() * static_cast<float>(M_PI * 35.0f / 180.0f) - static_cast<float>(M_PI * 17.5f / 180.0f);
1592  m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE, dis, angle);
1593 
1594  float ground = z;
1595  float liquidLevel = m_caster->GetMap()->GetWaterOrGroundLevel(x, y, z, &ground);
1596  if (liquidLevel <= ground) // When there is no liquid Map::GetWaterOrGroundLevel returns ground level
1597  {
1599  SendChannelUpdate(0);
1600  finish(false);
1601  return;
1602  }
1603 
1604  if (ground + 0.75 > liquidLevel)
1605  {
1607  SendChannelUpdate(0);
1608  finish(false);
1609  return;
1610  }
1611 
1612  m_targets.setDst(x, y, liquidLevel, m_caster->GetOrientation());
1613 
1614  break;
1615  }
1616  case TARGET_UNIT_MASTER:
1617  if (Unit* owner = m_caster->GetCharmerOrOwner())
1618  AddUnitTarget(owner, i);
1619  break;
1620  case TARGET_UNIT_PET:
1621  if (Player* plr = m_caster->ToPlayer())
1622  {
1623  if (Pet* pet = plr->GetPet())
1624  {
1625  AddUnitTarget(pet, i);
1626  break;
1627  }
1628  }
1629 
1630  if (Guardian* pet = m_caster->GetGuardianPet())
1631  AddUnitTarget(pet, i);
1632  break;
1635  pushType = PUSH_CASTER_CENTER;
1636  break;
1637  }
1638  break;
1639  }
1640 
1642  {
1643  Unit* target = m_targets.getUnitTarget();
1644  if (!target)
1645  {
1646  if (Player* player = m_caster->ToPlayer())
1647  target = ObjectAccessor::GetUnit(*player, player->GetSelection());
1648  else
1649  target = m_caster->GetVictim();
1650 
1651  if (target)
1652  m_targets.setUnitTarget(target);
1653  else
1654  {
1655  sLog.outError("SPELL: no unit target for spell ID %u", m_spellInfo->Id);
1656  break;
1657  }
1658  }
1659 
1660  switch (cur)
1661  {
1663  if ((m_spellInfo->AttributesEx & (0x8 | 0x80)) == 0)
1664  {
1665  // try to select magnet target first
1667  // if not found (target is not changed) search for SPELL_AURA_ADD_CASTER_HIT_TRIGGER
1669  }
1670  case TARGET_UNIT_CHAINHEAL:
1671  pushType = PUSH_CHAIN;
1672  break;
1674  AddUnitTarget(target, i);
1675  break;
1677  case TARGET_UNIT_TARGET_ANY: // SelectMagnetTarget()?
1680  if (IsValidSingleTargetSpell(target))
1681  AddUnitTarget(target, i);
1682  break;
1685  pushType = PUSH_CASTER_CENTER; // not real
1686  break;
1687  }
1688  break;
1689  }
1690 
1692  {
1693  float range = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
1694  if (modOwner)
1695  modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
1696 
1697  WorldObject* target = NULL;
1698 
1699  switch (cur)
1700  {
1702  target = SearchNearbyTarget(range, SPELL_TARGETS_ENEMY);
1703  break;
1705  case TARGET_UNIT_NEARBY_PARTY: // TODO: fix party/raid targets
1707  target = SearchNearbyTarget(range, SPELL_TARGETS_ALLY);
1708  break;
1710  target = SearchNearbyTarget(range, SPELL_TARGETS_ENTRY);
1711  break;
1712  }
1713 
1714  if (!target)
1715  return;
1716  else if (target->GetTypeId() == TYPEID_UNIT || target->GetTypeId() == TYPEID_PLAYER)
1717  {
1718  pushType = PUSH_CHAIN;
1719  m_targets.setUnitTarget((Unit*)target);
1720  }
1721  else if (target->GetTypeId() == TYPEID_GAMEOBJECT)
1722  AddGOTarget((GameObject*)target, i);
1723 
1724  break;
1725  }
1726 
1727  case TARGET_TYPE_AREA_SRC:
1728  pushType = PUSH_SRC_CENTER;
1729  break;
1730 
1731  case TARGET_TYPE_AREA_DST:
1732  pushType = PUSH_DST_CENTER;
1733  break;
1734 
1735  case TARGET_TYPE_AREA_CONE:
1737  pushType = PUSH_IN_BACK;
1739  pushType = PUSH_IN_LINE;
1740  else
1741  pushType = PUSH_IN_FRONT;
1742  break;
1743 
1744  case TARGET_TYPE_DEST_CASTER: //4+8+2
1745  {
1746  if (cur == TARGET_SRC_CASTER)
1747  {
1749  break;
1750  }
1751  else if (cur == TARGET_DST_CASTER)
1752  {
1754  break;
1755  }
1756 
1757  float angle, dist;
1758 
1759  float objSize = m_caster->GetObjectSize();
1760  dist = GetSpellRadius(m_spellInfo, i, true);
1761  if (dist < objSize)
1762  dist = objSize;
1763  else if (cur == TARGET_DEST_CASTER_RANDOM)
1764  dist = objSize + (dist - objSize) * rand_norm();
1765 
1766  switch (cur)
1767  {
1769  angle = static_cast<float>(-M_PI / 4);
1770  break;
1772  angle = static_cast<float>(-3 * M_PI / 4);
1773  break;
1775  angle = static_cast<float>(3 * M_PI / 4);
1776  break;
1778  angle = static_cast<float>(M_PI / 4);
1779  break;
1780  case TARGET_MINION:
1783  angle = 0.0f;
1784  break;
1786  angle = static_cast<float>(M_PI);
1787  break;
1789  angle = static_cast<float>(-M_PI / 2);
1790  break;
1792  angle = static_cast<float>(M_PI / 2);
1793  break;
1794  default:
1795  angle = (float)rand_norm() * static_cast<float>(2 * M_PI);
1796  break;
1797  }
1798 
1799  Position pos;
1800  switch (cur)
1801  {
1807  pos = m_caster->GetFirstCollisionPosition(dist, angle);
1808  break;
1809  default:
1810  pos = m_caster->GetNearPosition(dist, angle);
1811  break;
1812  }
1813  m_targets.setDst(&pos); // also flag
1814  break;
1815  }
1816 
1817  case TARGET_TYPE_DEST_TARGET: //2+8+2
1818  {
1819  Unit* target = m_targets.getUnitTarget();
1820  if (!target)
1821  {
1822  sLog.outError("SPELL: no unit target for spell ID %u\n", m_spellInfo->Id);
1823  break;
1824  }
1825 
1826  if (cur == TARGET_DST_TARGET_ENEMY || cur == TARGET_DEST_TARGET_ANY)
1827  {
1828  m_targets.setDst(target);
1829  break;
1830  }
1831 
1832  float angle, dist;
1833 
1834  float objSize = target->GetObjectSize();
1835  dist = GetSpellRadius(m_spellInfo, i, false);
1836  if (dist < objSize)
1837  dist = objSize;
1838  else if (cur == TARGET_DEST_CASTER_RANDOM)
1839  dist = objSize + (dist - objSize) * rand_norm();
1840 
1841  switch (cur)
1842  {
1844  angle = 0.0f;
1845  break;
1847  angle = M_PI;
1848  break;
1850  angle = M_PI / 2;
1851  break;
1853  angle = -M_PI / 2;
1854  break;
1856  angle = -M_PI / 4;
1857  break;
1859  angle = -3 * M_PI / 4;
1860  break;
1862  angle = 3 * M_PI / 4;
1863  break;
1865  angle = M_PI / 4;
1866  break;
1867  default:
1868  angle = rand_norm() * 2 * M_PI;
1869  break;
1870  }
1871 
1872  Position pos;
1873  switch (cur)
1874  {
1883  {
1884  target->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ, dist);
1885  pos = target->GetFirstCollisionPosition(dist, angle);
1886  }
1887  break;
1888  default:
1889  pos = target->GetNearPosition(dist, angle);
1890  break;
1891  }
1892  m_targets.setDst(&pos);
1893  break;
1894  }
1895 
1896  case TARGET_TYPE_DEST_DEST: //5+8+1
1897  {
1898  if (!m_targets.HasDst())
1899  {
1900  sLog.outError("SPELL: no destination for spell ID %u\n", m_spellInfo->Id);
1901  break;
1902  }
1903 
1904  float angle;
1905  switch (cur)
1906  {
1910  case TARGET_DEST_DEST:
1911  case TARGET_DEST_TRAJ:
1912  return;
1914  angle = 0.0f;
1915  break;
1916  case TARGET_DEST_DEST_BACK:
1917  angle = M_PI;
1918  break;
1920  angle = M_PI / 2;
1921  break;
1922  case TARGET_DEST_DEST_LEFT:
1923  angle = -M_PI / 2;
1924  break;
1926  angle = -M_PI / 4;
1927  break;
1929  angle = -3 * M_PI / 4;
1930  break;
1932  angle = 3 * M_PI / 4;
1933  break;
1935  angle = float(M_PI) / 4;
1936  break;
1937  default:
1938  angle = rand_norm() * 2 * M_PI;
1939  break;
1940  }
1941 
1942  float dist;
1943  dist = GetSpellRadius(m_spellInfo, i, true);
1944  if (cur == TARGET_DEST_DEST_RANDOM)
1945  dist *= rand_norm();
1946 
1947  // must has dst, no need to set flag
1949  break;
1950  }
1951 
1953  {
1954  switch (cur)
1955  {
1956  case TARGET_DST_DB:
1957  if (SpellTargetPosition const* st = sSpellMgr.GetSpellTargetPosition(m_spellInfo->Id))
1958  {
1960  m_targets.setDst(st->target_X, st->target_Y, st->target_Z, st->target_Orientation, (int32)st->target_mapId);
1961  else if (st->target_mapId == m_caster->GetMapId())
1962  m_targets.setDst(st->target_X, st->target_Y, st->target_Z, st->target_Orientation);
1963  }
1964  else
1965  sLog.outError("SPELL: unknown target coordinates for spell ID %u\n", m_spellInfo->Id);
1966  break;
1967  case TARGET_DST_HOME:
1968  if (m_caster->GetTypeId() == TYPEID_PLAYER)
1970  break;
1972  {
1973  float range = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
1974  if (modOwner)
1975  modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
1976 
1977  if (WorldObject* target = SearchNearbyTarget(range, SPELL_TARGETS_ENTRY))
1978  m_targets.setDst(target);
1979  break;
1980  }
1981  }
1982  break;
1983  }
1984 
1985  case TARGET_TYPE_CHANNEL:
1986  {
1988  {
1989  sLog.outDebug("SPELL: no current channeled spell for spell ID %u - spell triggering this spell was interrupted.", m_spellInfo->Id);
1990  break;
1991  }
1992 
1993  switch (cur)
1994  {
1995  case TARGET_UNIT_CHANNEL:
1997  AddUnitTarget(target, i);
1998  else
1999  sLog.outError("SPELL: cannot find channel spell target for spell ID %u", m_spellInfo->Id);
2000  break;
2001  case TARGET_DEST_CHANNEL:
2004  else
2005  sLog.outError("SPELL: cannot find channel spell destination for spell ID %u", m_spellInfo->Id);
2006  break;
2007  }
2008  break;
2009  }
2010 
2011  default:
2012  {
2013  switch (cur)
2014  {
2015  case TARGET_GAMEOBJECT:
2017  if (m_targets.getGOTarget())
2019  else
2020  {
2022  {
2023  if (obj->GetTypeId() != TYPEID_GAMEOBJECT)
2024  break;
2025  AddGOTarget(obj->ToGameObject(), i);
2026  }
2027  }
2028  break;
2030  if (m_targets.getGOTargetGUID())
2032  else if (m_targets.getItemTarget())
2034  break;
2035  default:
2036  sLog.outError("SPELL (caster[type: %u; guidlow: %u], spell: %u): unhandled spell target (%u)",
2038  break;
2039  }
2040  break;
2041  }
2042  }
2043 
2044  if (pushType == PUSH_CHAIN) // Chain
2045  {
2046  Unit* target = m_targets.getUnitTarget();
2047  if (!target)
2048  {
2049  sLog.outError("SPELL: no chain unit target for spell ID %u", m_spellInfo->Id);
2050  return;
2051  }
2052 
2053  //Chain: 2, 6, 22, 25, 45, 77
2054  uint32 maxTargets = m_spellInfo->EffectChainTarget[i];
2055  if (modOwner)
2056  modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this);
2057 
2058  if (maxTargets > 1)
2059  {
2060  //otherwise, this multiplier is used for something else
2061  m_damageMultipliers[i] = 1.0f;
2062  m_applyMultiplierMask |= 1 << i;
2063 
2064  float range = GetSpellMaxRange(sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex));
2065  if (modOwner)
2066  modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this);
2067 
2068  std::list<Unit*> unitList;
2069 
2070  switch (cur)
2071  {
2074  case TARGET_UNIT_NEARBY_ENTRY: // fix me
2075  SearchChainTarget(unitList, range, maxTargets, SPELL_TARGETS_ENEMY);
2076  break;
2077  case TARGET_UNIT_CHAINHEAL:
2078  case TARGET_UNIT_NEARBY_ALLY: // fix me
2081  SearchChainTarget(unitList, range, maxTargets, SPELL_TARGETS_CHAINHEAL);
2082  break;
2083  }
2084 
2085  for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); ++itr)
2086  AddUnitTarget(*itr, i);
2087  }
2088  else
2089  AddUnitTarget(target, i);
2090  }
2091  else if (pushType)
2092  {
2093  // Dummy, just for client
2094  if (sSpellMgr.EffectTargetType[m_spellInfo->Effect[i]] == SPELL_REQUIRE_DEST)
2095  return;
2096 
2097  float radius = GetSpellRadius(m_spellInfo, i, true);
2098  if (modOwner)
2099  modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius, this);
2100 
2101  std::list<Unit*> unitList;
2102 
2103  switch (cur)
2104  {
2109  SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENEMY);
2110  radius = GetSpellRadius(m_spellInfo, i, false);
2111  break;
2114  case TARGET_UNIT_CONE_ALLY:
2115  SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ALLY);
2116  break;
2119  m_caster->GetPartyMember(unitList, radius); //fix me
2120  break;
2121  case TARGET_GAMEOBJECT_SRC_AREA: // fix me
2123  break;
2126  case TARGET_UNIT_CONE_ENTRY: // fix me
2127  {
2128  ConditionList conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET, m_spellInfo->Id);
2130  if (conditions.empty())
2131  {
2132  sLog.outErrorDb("Spell (ID: %u) (caster Entry: %u) does not have record in spell_script_target", m_spellInfo->Id, m_caster->GetEntry());
2133 
2134  if (IsPositiveEffect(m_spellInfo->Id, i))
2135  SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ALLY);
2136  else
2137  SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENEMY);
2138  }
2139  // let it be done in one check?
2140  else
2141  {
2142  for (ConditionList::const_iterator i_spellST = conditions.begin(); i_spellST != conditions.end(); ++i_spellST)
2143  {
2144  if ((*i_spellST)->Type != CONDITION_SPELL_SCRIPT_TARGET)
2145  continue;
2146  if ((*i_spellST)->ConditionValue1 == SPELL_TARGET_TYPE_CREATURE)
2147  SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENTRY, (*i_spellST)->ConditionValue2);
2148  }
2149  }
2150  break;
2151  }
2153  m_targets.getUnitTarget()->GetPartyMember(unitList, radius);
2154  break;
2156  m_caster->GetPartyMember(unitList, radius);
2157  break;
2159  m_caster->GetRaidMember(unitList, radius);
2160  break;
2162  {
2164  ? m_targets.getUnitTarget()->ToPlayer() : NULL;
2165 
2166  Group* pGroup = targetPlayer ? targetPlayer->GetGroup() : NULL;
2167  if (pGroup)
2168  {
2169  for (GroupReference* itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
2170  {
2171  Player* Target = itr->GetSource();
2172 
2173  // IsHostileTo check duel and controlled by enemy
2174  if (Target && targetPlayer->IsWithinDistInMap(Target, radius) &&
2175  targetPlayer->getClass() == Target->getClass() &&
2176  !m_caster->IsHostileTo(Target))
2177  AddUnitTarget(Target, i);
2178  }
2179  }
2180  else if (m_targets.getUnitTarget())
2182  break;
2183  }
2184  }
2185 
2186  if (!unitList.empty())
2187  {
2189  {
2190  if (m_spellInfo->Id == 5246) //Intimidating Shout
2191  unitList.remove(m_targets.getUnitTarget());
2192 
2193  if(sSpellMgr.SpellTargetType[cur] == TARGET_TYPE_AREA_CONE)
2195  else
2197  }
2198  else if (m_spellInfo->Id == 27285) // Seed of Corruption proc spell
2199  unitList.remove(m_targets.getUnitTarget());
2200 
2201  bool massbuff = IsPositiveSpell(m_spellInfo->Id) && sSpellMgr.IsNoStackSpellDueToSpell(m_spellInfo->Id, m_spellInfo->Id, false);
2202 
2203  for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); )
2204  {
2205  // for mass-buffs skip targets that have higher ranks already applied.on them
2206  if (*itr != m_caster && massbuff)
2207  {
2208  if ((*itr)->HasHigherRankOfAura(m_spellInfo->Id, i))
2209  {
2210  itr = unitList.erase(itr);
2211  continue;
2212  }
2213  }
2214 
2215  AddUnitTarget(*itr, i);
2216  ++itr;
2217  }
2218  }
2219  }
2220 }
2221 
2222 void Spell::prepare(SpellCastTargets* targets, Aura* triggeredByAura)
2223 {
2224  if (m_CastItem)
2226  else
2227  m_castItemGUID = 0;
2228 
2229  m_targets = *targets;
2230 
2232 
2235 
2236  if (triggeredByAura)
2237  m_triggeredByAuraSpell = triggeredByAura->GetSpellProto();
2238 
2239  // create and add update event for this spell
2240  SpellEvent* Event = new SpellEvent(this);
2242 
2243  //Prevent casting at cast another spell (ServerSide check)
2244  if (!m_IsTriggeredSpell && m_caster->IsNonMeleeSpellCast(false, true, true) && m_cast_count)
2245  {
2247  finish(false);
2248  return;
2249  }
2250 
2251  if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, m_caster))
2252  {
2254  finish(false);
2255  return;
2256  }
2257 
2258  // Fill cost data (not use power for item casts)
2260 
2261  FillTargetMap();
2262 
2263  SpellCastResult result = CheckCast(true);
2264  if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
2265  {
2266  if (triggeredByAura && !triggeredByAura->IsPassive() && !IsPassiveSpell(m_spellInfo))
2267  {
2268  SendChannelUpdate(0);
2269  triggeredByAura->SetAuraDuration(0);
2270  }
2271 
2272  SendCastResult(result);
2273 
2274  finish(false);
2275  return;
2276  }
2277 
2278  // Prepare data for triggers
2280 
2281  // Set combo point requirement
2283  m_needComboPoints = false;
2284 
2285  // calculate cast time (calculated after first CanCast check to prevent charge counting for first CanCast fail)
2287 
2288  // don't allow channeled spells / spells with cast time to be casted while moving
2289  // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
2291  {
2293  finish(false);
2294  return;
2295  }
2296 
2297  // Set cast time to 0 if .cheat casttime is enabled.
2298  if (m_caster->GetTypeId() == TYPEID_PLAYER)
2299  {
2301  m_casttime = 0;
2302  }
2303 
2304  // set timer base at cast time
2305  ReSetTimer();
2306 
2307  if (m_IsTriggeredSpell)
2308  cast(true);
2309  else
2310  {
2311  // stealth must be removed at cast starting (at show channel bar)
2312  // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
2315 
2317  SendSpellStart();
2318 
2319  if (m_caster->GetTypeId() == TYPEID_PLAYER)
2321 
2322  // item: first cast may destroy item and second cast causes crash
2324  cast(true);
2325  }
2326 }
2327 
2328 void Spell::cancel(bool sendInterrupt)
2329 {
2331  return;
2332 
2333  uint32 oldState = m_spellState;
2335 
2336  m_autoRepeat = false;
2337  switch (oldState)
2338  {
2339  case SPELL_STATE_PREPARING:
2340  case SPELL_STATE_DELAYED:
2341  {
2342  SendInterrupted(0);
2343  if (sendInterrupt)
2345  }
2346  break;
2347 
2348  case SPELL_STATE_CASTING:
2349  {
2350  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2351  {
2352  if (ihit->deleted)
2353  continue;
2354 
2355  if (ihit->missCondition == SPELL_MISS_NONE)
2356  {
2357  Unit* unit = m_caster->GetGUID() == (*ihit).targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
2358  if (unit && unit->IsAlive())
2360  }
2361  }
2362 
2364  SendChannelUpdate(0);
2365 
2366  // Do not send interrupt for channeling spells to avoid a visual bug
2367  // that happens when a caster recasts the spell before the channeling ended
2369  {
2370  SendInterrupted(0);
2371  if (sendInterrupt)
2373  }
2374  }
2375  break;
2376  default:
2377  {
2378  } break;
2379  }
2380 
2381  SetReferencedFromCurrent(false);
2382  if (m_selfContainer && *m_selfContainer == this)
2383  *m_selfContainer = nullptr;
2384 
2386  if (IsChanneledSpell(m_spellInfo)) // if not channeled then the object for the current cast wasn't summoned yet
2387  {
2389 
2390  // reset cooldown state for disabled while active spells
2391  if (m_caster->GetTypeId() == TYPEID_PLAYER)
2392  {
2395  }
2396  }
2397 
2398  //set state back so finish will be processed
2399  m_spellState = oldState;
2400 
2401  finish(false);
2402 }
2403 
2404 void Spell::cast(bool skipCheck)
2405 {
2406  if (m_spellInfo->Id > MAX_SPELL_ID)
2407  return;
2408 
2409  // update pointers base at GUIDs to prevent access to non-existed already object
2410  UpdatePointers();
2411 
2412  // cancel at lost main target unit
2414  {
2415  cancel();
2416  return;
2417  }
2418 
2419  SetExecutedCurrently(true);
2420  SpellCastResult castResult = SPELL_CAST_OK;
2421 
2424 
2425  if (!m_IsTriggeredSpell)
2426  {
2427  castResult = CheckPower();
2428  if (castResult != SPELL_CAST_OK)
2429  {
2430  SendCastResult(castResult);
2431  finish(false);
2432  SetExecutedCurrently(false);
2433  return;
2434  }
2435  }
2436 
2437  // triggered cast called from Spell::prepare where it was already checked
2438  if (!skipCheck)
2439  {
2440  FillTargetMap();
2441 
2442  castResult = CheckCast(false);
2443  if (castResult != SPELL_CAST_OK)
2444  {
2445  SendCastResult(castResult);
2446  SendInterrupted(0);
2447  finish(false);
2448  SetExecutedCurrently(false);
2449  return;
2450  }
2451  }
2452  // Check if some auras need to be interrupted when casting combat auto-repeating spells
2455 
2456  if (m_spellState == SPELL_STATE_FINISHED) // stop cast if spell marked as finish somewhere in Take*/FillTargetMap
2457  {
2458  SendInterrupted(0);
2459  finish(false);
2460  SetExecutedCurrently(false);
2461  return;
2462  }
2463 
2466  pet->DespawnOrUnsummon();
2467 
2468  // traded items have trade slot instead of guid in m_itemTargetGUID
2469  // set to real guid to be sent later to the client
2471 
2472  if (!m_IsTriggeredSpell)
2473  TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
2474 
2475  // CAST SPELL
2477 
2478  // calc miss, reflect, parry, etc.
2480 
2481  SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
2482 
2483  //handle SPELL_AURA_ADD_TARGET_TRIGGER auras
2484  //are there any spells need to be triggered after hit?
2486  for (Unit::AuraList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
2487  {
2488  SpellEntry const* auraSpellInfo = (*i)->GetSpellProto();
2489  uint32 auraSpellIdx = (*i)->GetEffIndex();
2490  if (IsAffectedBy(auraSpellInfo, auraSpellIdx))
2491  {
2492  if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(auraSpellInfo->EffectTriggerSpell[auraSpellIdx]))
2493  {
2494  // Calculate chance at that moment (can be depend for example from combo points)
2495  int32 chance = m_caster->CalculateSpellDamage(auraSpellInfo, auraSpellIdx, (*i)->GetBasePoints(), NULL);
2496  m_ChanceTriggerSpells.push_back(std::make_pair(spellInfo, chance * (*i)->GetStackAmount()));
2497  }
2498  }
2499  }
2500 
2503 
2504  // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
2505  // @TODO: Find similarities for spells such as Ruthlessness and run the proper check here
2506  if ((m_spellInfo->speed > 0.0f && !IsChanneledSpell(m_spellInfo)) || m_spellInfo->Id == 14157)
2507  {
2508  // Okay, maps created, now prepare flags
2509  m_immediateHandled = false;
2511  SetDelayStart(0);
2512 
2513  if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !m_caster->IsNonMeleeSpellCast(false, false, true))
2515  }
2516  else
2517  {
2518  // Immediate spell, no big deal
2519  handle_immediate();
2520  }
2521 
2522  // combo points should not be taken before SPELL_AURA_ADD_TARGET_TRIGGER auras are handled
2523  if (!m_IsTriggeredSpell)
2524  TakePower();
2525 
2527  {
2528  if (const std::vector<int32>* spell_triggered = sSpellMgr.GetSpellLinked(m_spellInfo->Id))
2529  {
2530  for (std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
2531  if (*i < 0)
2533  else
2535  }
2536  }
2537 
2538  // Clear spell cooldowns after every spell is cast if .cheat cooldown is enabled.
2539  if (m_caster->GetTypeId() == TYPEID_PLAYER)
2540  {
2543  }
2544 
2545  SetExecutedCurrently(false);
2546 }
2547 
2549 {
2550  if (m_spellInfo->Id > MAX_SPELL_ID)
2551  return;
2552 
2553  // start channeling if applicable
2555  {
2556  int32 duration = GetSpellDuration(m_spellInfo);
2558  duration = m_spellValue->Duration;
2559  if (duration > 0)
2560  {
2561  if (m_targets.getUnitTarget())
2562  {
2565  }
2566 
2567  // Apply duration mod
2568  if (Player* modOwner = m_caster->GetSpellModOwner())
2569  modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2570 
2571  // Apply haste mods
2572  m_caster->ModSpellDurationTime(m_spellInfo, duration, this);
2573 
2576  SendChannelStart(duration);
2577  }
2578  else if (duration == -1)
2579  {
2582  SendChannelStart(duration);
2583  }
2584 
2585  // Interrupt movement at channeled spells for creature case
2587  m_caster->StopMoving();
2588  }
2589 
2590  // process immediate effects (items, ground, etc.) also initialize some variables
2592 
2593  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2594  {
2595  if (m_destroyed || ihit == m_UniqueTargetInfo.end() || m_UniqueTargetInfo.size() == 0)
2596  break;
2597 
2598  if (ihit->deleted)
2599  continue;
2600 
2601  DoAllEffectOnTarget(&(*ihit));
2602  }
2603 
2604  for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2605  {
2606  if (m_destroyed || ihit == m_UniqueGOTargetInfo.end() || m_UniqueGOTargetInfo.size() == 0)
2607  break;
2608 
2609  if (ihit->deleted)
2610  continue;
2611 
2612  DoAllEffectOnTarget(&(*ihit));
2613  }
2614 
2615  // spell is finished, perform some last features of the spell here
2617 
2619  finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
2620 }
2621 
2623 {
2624  UpdatePointers();
2625  uint64 next_time = 0;
2626 
2627  if (!m_immediateHandled)
2628  {
2630  m_immediateHandled = true;
2631  }
2632 
2633  bool single_missile = (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION);
2634 
2635  // now recheck units targeting correctness (need before any effects apply to prevent adding immunity at first effect not allow apply second spell effect and similar cases)
2636  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2637  {
2638  if (ihit->deleted)
2639  continue;
2640 
2641  if (ihit->processed == false)
2642  {
2643  if (single_missile || ihit->timeDelay <= t_offset)
2644  {
2645  ihit->timeDelay = t_offset;
2646  DoAllEffectOnTarget(&(*ihit));
2647  }
2648  else if (next_time == 0 || ihit->timeDelay < next_time)
2649  next_time = ihit->timeDelay;
2650  }
2651  }
2652 
2653  // now recheck gameobject targeting correctness
2654  for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
2655  {
2656  if (ighit->deleted)
2657  continue;
2658 
2659  if (!ighit->processed)
2660  {
2661  if (single_missile || ighit->timeDelay <= t_offset)
2662  DoAllEffectOnTarget(&(*ighit));
2663  else if (next_time == 0 || ighit->timeDelay < next_time)
2664  next_time = ighit->timeDelay;
2665  }
2666  }
2667  // All targets passed - need finish phase
2668  if (next_time == 0)
2669  {
2670  // spell is finished, perform some last features of the spell here
2672 
2673  finish(true); // successfully finish spell cast
2674 
2675  // return zero, spell is finished now
2676  return 0;
2677  }
2678  else
2679  {
2680  // spell is unfinished, return next execution time
2681  return next_time;
2682  }
2683 }
2684 
2686 {
2687  // handle some immediate features of the spell here
2688 
2691 
2693  TakeCastItem();
2694 
2696  for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2697  {
2698  if (m_spellInfo->Effect[j] == 0)
2699  continue;
2700 
2701  // apply Send Event effect to ground in case empty target lists
2703  {
2704  HandleEffects(NULL, NULL, NULL, j);
2705  continue;
2706  }
2707 
2708  // Don't do spell log, if is school damage spell
2710  m_needSpellLog = false;
2711  }
2712 
2713  // initialize Diminishing Returns Data
2716 
2717  // process items
2718  for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2719  DoAllEffectOnTarget(&(*ihit));
2720 
2721  if (!m_originalCaster)
2722  return;
2723  // process ground
2724  for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2725  {
2726  if (sSpellMgr.EffectTargetType[m_spellInfo->Effect[j]] == SPELL_REQUIRE_DEST)
2727  {
2728  if (!m_targets.HasDst()) // FIXME: this will ignore dest set in effect
2730  HandleEffects(m_originalCaster, NULL, NULL, j);
2731  }
2732  else if (sSpellMgr.EffectTargetType[m_spellInfo->Effect[j]] == SPELL_REQUIRE_NONE)
2733  HandleEffects(m_originalCaster, NULL, NULL, j);
2734  }
2735 }
2736 
2738 {
2739  // Take for real after all targets are processed
2740  if (m_needComboPoints)
2741  if (Player* player = m_caster->ToPlayer())
2742  player->ClearComboPoints();
2743 
2744  // spell log
2745  if (m_needSpellLog)
2746  SendLogExecute();
2747 }
2748 
2750 {
2751  if (m_caster->GetTypeId() != TYPEID_PLAYER)
2752  return;
2753 
2754  Player* _player = m_caster->ToPlayer();
2755  // Add cooldown for max (disable spell)
2756  // Cooldown started on SendCooldownEvent call
2758  return;
2759 
2760  // init cooldown values
2761  uint32 cat = 0;
2762  int32 rec = -1;
2763  int32 catrec = -1;
2764 
2765  // some special item spells without correct cooldown in SpellInfo
2766  // cooldown information stored in item prototype
2767  // This used in same way in WorldSession::HandleItemQuerySingleOpcode data sending to client.
2768 
2769  if (m_CastItem)
2770  {
2771  ItemTemplate const* proto = m_CastItem->GetProto();
2772  if (proto)
2773  {
2774  for (int idx = 0; idx < 5; ++idx)
2775  {
2776  if (proto->Spells[idx].SpellId == m_spellInfo->Id)
2777  {
2778  cat = proto->Spells[idx].SpellCategory;
2779  rec = proto->Spells[idx].SpellCooldown;
2780  catrec = proto->Spells[idx].SpellCategoryCooldown;
2781  break;
2782  }
2783  }
2784  }
2785  }
2786 
2787  // if no cooldown found above then base at DBC data
2788  if (rec < 0 && catrec < 0)
2789  {
2790  cat = m_spellInfo->Category;
2791  rec = m_spellInfo->RecoveryTime;
2793  }
2794 
2795  // shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK)
2796  // prevent 0 cooldowns set by another way
2797  if (rec <= 0 && catrec <= 0 && (cat == 76 || cat == 351))
2798  rec = _player->GetAttackTime(RANGED_ATTACK);
2799 
2800  // Now we have cooldown data (if found any), time to apply mods
2801  if (rec > 0)
2802  _player->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COOLDOWN, rec, this);
2803 
2804  if (catrec > 0)
2805  _player->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COOLDOWN, catrec, this);
2806 
2807  // replace negative cooldowns by 0
2808  if (rec < 0) rec = 0;
2809  if (catrec < 0) catrec = 0;
2810 
2811  // no cooldown after applying spell mods
2812  if (rec == 0 && catrec == 0)
2813  return;
2814 
2815  time_t curTime = time(NULL);
2816 
2817  time_t catrecTime = catrec ? curTime + catrec / IN_MILLISECONDS : 0; // in secs
2818  time_t recTime = rec ? curTime + rec / IN_MILLISECONDS : catrecTime; // in secs
2819 
2820  // self spell cooldown
2821  if (recTime > 0)
2822  _player->AddSpellCooldown(m_spellInfo->Id, m_CastItem ? m_CastItem->GetEntry() : 0, recTime);
2823 
2824  // category spells
2825  if (catrec > 0)
2826  {
2827  SpellCategoryStore::const_iterator i_scstore = sSpellCategoryStore.find(cat);
2828  if (i_scstore != sSpellCategoryStore.end())
2829  {
2830  for (SpellCategorySet::const_iterator i_scset = i_scstore->second.begin(); i_scset != i_scstore->second.end(); ++i_scset)
2831  {
2832  if (*i_scset == m_spellInfo->Id) // skip main spell, already handled above
2833  continue;
2834 
2835  _player->AddSpellCooldown(*i_scset, m_CastItem ? m_CastItem->GetEntry() : 0, catrecTime);
2836  }
2837  }
2838  }
2839 }
2840 
2841 void Spell::update(uint32 difftime)
2842 {
2843  // update pointers based at it's GUIDs
2844  UpdatePointers();
2845 
2847  {
2848  cancel();
2849  return;
2850  }
2851 
2852  // check if the player or unit caster has moved before the spell finished (exclude casting on vehicles)
2853  if (((m_caster->GetTypeId() == TYPEID_PLAYER || m_caster->GetTypeId() == TYPEID_UNIT) && m_timer != 0) &&
2856  {
2857  // always cancel for channeled spells
2859  cancel();
2860  // don't cancel for melee, autorepeat, triggered and instant spells
2862  cancel();
2863  }
2864 
2865  switch (m_spellState)
2866  {
2867  case SPELL_STATE_PREPARING:
2868  {
2869  if (m_timer > 0)
2870  {
2871  if (difftime >= (uint32)m_timer)
2872  m_timer = 0;
2873  else
2874  m_timer -= difftime;
2875  }
2876 
2877  if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
2879  }
2880  break;
2881  case SPELL_STATE_CASTING:
2882  {
2883  if (m_timer)
2884  {
2886  {
2887  // check if player has jumped before the channeling finished
2889  cancel();
2890 
2891  // check for incapacitating player states
2893  cancel();
2894  }
2895 
2896  // check if there are alive targets left
2898  {
2899  SendChannelUpdate(0);
2900  finish();
2901  }
2902 
2903  if (m_timer > 0)
2904  {
2905  if (difftime >= (uint32)m_timer)
2906  m_timer = 0;
2907  else
2908  m_timer -= difftime;
2909  }
2910  }
2911 
2912  if (m_timer == 0)
2913  {
2914  SendChannelUpdate(0);
2915 
2916  // channeled spell processed independently for quest targeting
2917  // cast at creature (or GO) quest objectives update at successful cast channel finished
2918  // ignore autorepeat/melee casts for speed (not exist quest for spells (hm...)
2920  {
2921  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2922  {
2923  if (ihit->deleted)
2924  continue;
2925 
2926  TargetInfo* target = &*ihit;
2927 
2928  if (!IS_CREATURE_GUID(target->targetGUID))
2929  continue;
2930 
2931  Unit* unit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2932  if (unit == NULL)
2933  continue;
2934 
2936  }
2937 
2938  for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2939  {
2940  if (ihit->deleted)
2941  continue;
2942 
2943  GOTargetInfo* target = &*ihit;
2944 
2945  GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
2946  if (!go)
2947  continue;
2948 
2950  }
2951  }
2952 
2953  finish();
2954  }
2955  }
2956  break;
2957  default:
2958  {
2959  } break;
2960  }
2961 }
2962 
2963 void Spell::finish(bool ok)
2964 {
2965  if (!m_caster)
2966  return;
2967 
2969  return;
2971 
2974 
2975  if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !m_caster->IsNonMeleeSpellCast(false, false, true))
2977 
2978  if (!ok)
2979  {
2980  //restore spell mods
2981  if (m_caster->GetTypeId() == TYPEID_PLAYER)
2983 
2984  // Spell has failed so the combat is no longer being initiated
2985  // Do this only if the unit is initiating combat
2987  m_caster->SetInitiatingCombat(false);
2988 
2989  return;
2990  }
2991  // other code related only to successfully finished spells
2992 
2993  //remove spell mods
2994  if (Player* modOwner = m_caster->GetSpellModOwner())
2995  {
2996  // Take mods after trigger spell
2997  // mods are taken only on succesfull cast and independantly from targets of the spell
2998  modOwner->RemoveSpellMods(this);
2999  }
3000 
3001  // Okay to remove extra attacks
3003  m_caster->m_extraAttacks = 0;
3004 
3005  // Heal caster for all health leech from all targets
3006  if (m_healthLeech)
3007  {
3010  }
3011 
3012  if (IsAutoActionResetSpell())
3013  {
3015  {
3018  if (m_caster->haveOffhandWeapon())
3020  }
3021  }
3022 
3023  // call triggered spell only at successful cast (after clear combo points -> for add some if need)
3024  // I assume what he means is that some triggered spells may add combo points
3025  if (!m_TriggerSpells.empty())
3026  TriggerSpell();
3027 
3028  // Stop Attack for some spells
3030  m_caster->AttackStop();
3031 }
3032 
3034 {
3035  if (m_caster->GetTypeId() != TYPEID_PLAYER)
3036  return;
3037 
3038  if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
3039  return;
3040 
3041  if (result != SPELL_CAST_OK)
3042  {
3043  WorldPacket data(SMSG_CAST_FAILED, (4 + 1 + 1));
3044  data << uint32(m_spellInfo->Id);
3045  data << uint8(!IsPassiveSpell(m_spellInfo) ? result : SPELL_FAILED_DONT_REPORT); // do not report failed passive spells
3046  data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
3047  switch (result)
3048  {
3051  break;
3053  // hardcode areas limitation case
3054  switch (m_spellInfo->Id)
3055  {
3056  case 41617: // Cenarion Mana Salve
3057  case 41619: // Cenarion Healing Salve
3058  data << uint32(3905);
3059  break;
3060  case 41618: // Bottled Nethergon Energy
3061  case 41620: // Bottled Nethergon Vapor
3062  data << uint32(3842);
3063  break;
3064  case 45373: // Bloodberry Elixir
3065  data << uint32(4075);
3066  break;
3067  case 32307: // Warmaul Ogre Banner
3068  data << uint32(3637);
3069  break;
3070  default: // default case
3071  data << uint32(m_spellInfo->AreaId);
3072  break;
3073  }
3074  break;
3075  case SPELL_FAILED_TOTEMS:
3076  if (m_spellInfo->Totem[0])
3077  data << uint32(m_spellInfo->Totem[0]);
3078  if (m_spellInfo->Totem[1])
3079  data << uint32(m_spellInfo->Totem[1]);
3080  break;
3082  if (m_spellInfo->TotemCategory[0])
3083  data << uint32(m_spellInfo->TotemCategory[0]);
3084  if (m_spellInfo->TotemCategory[1])
3085  data << uint32(m_spellInfo->TotemCategory[1]);
3086  break;
3093  break;
3094  default:
3095  break;
3096  }
3097  m_caster->ToPlayer()->GetSession()->SendPacket(&data);
3098  }
3099  else
3100  {
3101  WorldPacket data(SMSG_CLEAR_EXTRA_AURA_INFO, (8 + 4));
3102  data << m_caster->GetPackGUID();
3103  data << uint32(m_spellInfo->Id);
3104  m_caster->ToPlayer()->GetSession()->SendPacket(&data);
3105  }
3106 }
3107 
3109 {
3110  if (!m_isNeedSendToClient)
3111  return;
3112 
3113  DEBUG_LOG("Sending SMSG_SPELL_START id=%u", m_spellInfo->Id);
3114 
3115  uint32 castFlags = CAST_FLAG_UNKNOWN1;
3116  if (IsRangedSpell())
3117  castFlags |= CAST_FLAG_AMMO;
3118 
3119  //Unit* target = m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster;
3120 
3121  WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
3122  if (m_CastItem)
3123  data << m_CastItem->GetPackGUID();
3124  else
3125  data << m_caster->GetPackGUID();
3126 
3127  data << m_caster->GetPackGUID();
3128  data << uint32(m_spellInfo->Id);; // spellId
3129  data << uint8(m_cast_count); // pending spell cast?
3130  data << uint16(castFlags); // cast flags
3131  data << int32(m_timer); // delay?
3132  data << m_targets;
3133 
3134  if (castFlags & CAST_FLAG_AMMO)
3135  WriteAmmoToPacket(&data);
3136 
3137  m_caster->SendMessageToSet(&data, true);
3138 }
3139 
3141 {
3142  // not send invisible spell casting
3143  if (!m_isNeedSendToClient)
3144  return;
3145 
3146  DEBUG_LOG("Sending SMSG_SPELL_GO id=%u", m_spellInfo->Id);
3147 
3148  //Unit* target = m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster;
3149 
3150  uint32 castFlags = CAST_FLAG_UNKNOWN3;
3151 
3152  // triggered spells with spell visual != 0 and not auto shot
3154  castFlags |= CAST_FLAG_PENDING;
3155 
3156  if (IsRangedSpell())
3157  castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual
3158 
3159  WorldPacket data(SMSG_SPELL_GO, 50); // guess size
3160 
3161  if (m_CastItem)
3162  data << m_CastItem->GetPackGUID();
3163  else
3164  data << m_caster->GetPackGUID();
3165 
3166  data << m_caster->GetPackGUID();
3167  data << uint32(m_spellInfo->Id); // spellId
3168  data << uint16(castFlags); // cast flags
3169  data << uint32(getMSTime()); // timestamp
3170 
3171  WriteSpellGoTargets(&data);
3172 
3173  data << m_targets;
3174 
3175  if (castFlags & CAST_FLAG_AMMO)
3176  WriteAmmoToPacket(&data);
3177 
3178  m_caster->SendMessageToSet(&data, true);
3179 }
3180 
3182 {
3183  uint32 ammoInventoryType = 0;
3184  uint32 ammoDisplayID = 0;
3185 
3186  if (m_caster->GetTypeId() == TYPEID_PLAYER)
3187  {
3189  if (pItem)
3190  {
3191  ammoInventoryType = pItem->GetProto()->InventoryType;
3192  if (ammoInventoryType == INVTYPE_THROWN)
3193  ammoDisplayID = pItem->GetProto()->DisplayInfoID;
3194  else
3195  {
3197  if (ammoID)
3198  {
3199  ItemTemplate const* pProto = sObjectMgr.GetItemTemplate(ammoID);
3200  if (pProto)
3201  {
3202  ammoDisplayID = pProto->DisplayInfoID;
3203  ammoInventoryType = pProto->InventoryType;
3204  }
3205  }
3206  else if (m_caster->HasAura(46699)) // Requires No Ammo
3207  {
3208  ammoDisplayID = 5996; // normal arrow
3209  ammoInventoryType = INVTYPE_AMMO;
3210  }
3211  }
3212  }
3213  }
3214  else
3215  {
3216  for (uint8 i = 0; i < 3; ++i)
3217  {
3219  {
3220  if (ItemTemplate const* pProto = sObjectMgr.GetItemTemplate(item_id))
3221  {
3222  if (pProto->Class == ITEM_CLASS_WEAPON)
3223  {
3224  switch (pProto->SubClass)
3225  {
3227  ammoDisplayID = pProto->DisplayInfoID;
3228  ammoInventoryType = pProto->InventoryType;
3229  break;
3232  ammoDisplayID = 5996; // is this need fixing?
3233  ammoInventoryType = INVTYPE_AMMO;
3234  break;
3236  ammoDisplayID = 5998; // is this need fixing?
3237  ammoInventoryType = INVTYPE_AMMO;
3238  break;
3239  }
3240 
3241  if (ammoDisplayID)
3242  break;
3243  }
3244  }
3245  }
3246  }
3247  }
3248 
3249  *data << uint32(ammoDisplayID);
3250  *data << uint32(ammoInventoryType);
3251 }
3252 
3254 {
3255  *data << (uint8)m_countOfHit;
3256  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3257  {
3258  if (ihit->deleted)
3259  continue;
3260 
3261  if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
3262  *data << uint64(ihit->targetGUID);
3263  }
3264 
3265  for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
3266  {
3267  if (ighit->deleted)
3268  continue;
3269 
3270  *data << uint64(ighit->targetGUID); // Always hits
3271  }
3272 
3273  *data << (uint8)m_countOfMiss;
3274  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3275  {
3276  if (ihit->deleted)
3277  continue;
3278 
3279  if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
3280  {
3281  *data << uint64(ihit->targetGUID);
3282  *data << uint8(ihit->missCondition);
3283  if (ihit->missCondition == SPELL_MISS_REFLECT)
3284  *data << uint8(ihit->reflectResult);
3285  }
3286  }
3287 }
3288 
3290 {
3292 
3293  WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
3294 
3295  if (m_caster->GetTypeId() == TYPEID_PLAYER)
3296  data << m_caster->GetPackGUID();
3297  else
3298  data << target->GetPackGUID();
3299 
3300  data << uint32(m_spellInfo->Id);
3301  uint32 count1 = 1;
3302  data << uint32(count1); // count1 (effect count?)
3303  for (uint32 i = 0; i < count1; ++i)
3304  {
3305  data << uint32(m_spellInfo->Effect[0]); // spell effect
3306  uint32 count2 = 1;
3307  data << uint32(count2); // count2 (target count?)
3308  for (uint32 j = 0; j < count2; ++j)
3309  {
3310  switch (m_spellInfo->Effect[0])
3311  {
3313  if (Unit* unit = m_targets.getUnitTarget())
3314  data << unit->GetPackGUID();
3315  else
3316  data << uint8(0);
3317  data << uint32(0);
3318  data << uint32(0);
3319  data << float(0);
3320  break;
3322  if (Unit* unit = m_targets.getUnitTarget())
3323  data << unit->GetPackGUID();
3324  else
3325  data << uint8(0);
3326  data << uint32(m_caster->m_extraAttacks);
3327  break;
3329  if (Unit* unit = m_targets.getUnitTarget())
3330  data << unit->GetPackGUID();
3331  else
3332  data << uint8(0);
3333  data << uint32(0); // spellid
3334  break;
3336  if (Unit* unit = m_targets.getUnitTarget())
3337  data << unit->GetPackGUID();
3338  else
3339  data << uint8(0);
3340  data << uint32(0);
3341  data << uint32(0);
3342  break;
3345  if (Item* item = m_targets.getItemTarget())
3346  data << item->GetPackGUID();
3347  else
3348  data << uint8(0);
3349  break;
3351  data << uint32(m_spellInfo->EffectItemType[0]);
3352  break;
3353  case SPELL_EFFECT_SUMMON:
3358  case SPELL_EFFECT_DUEL:
3363  if (Unit* unit = m_targets.getUnitTarget())
3364  data << unit->GetPackGUID();
3365  else if (m_targets.getItemTargetGUID())
3367  else if (GameObject* go = m_targets.getGOTarget())
3368  data << go->GetPackGUID();
3369  else
3370  data << uint8(0); // guid
3371  break;
3372  case SPELL_EFFECT_FEED_PET:
3373  data << uint32(m_targets.getItemTargetEntry());
3374  break;
3376  if (Unit* unit = m_targets.getUnitTarget())
3377  data << unit->GetPackGUID();
3378  else
3379  data << uint8(0);
3380  break;
3381  default:
3382  return;
3383  }
3384  }
3385  }
3386 
3387  m_caster->SendMessageToSet(&data, true);
3388 }
3389 
3391 {
3392  WorldPacket data(SMSG_SPELL_FAILURE, (8 + 4 + 1));
3393  data << m_caster->GetPackGUID();
3394  data << m_spellInfo->Id;
3395  data << result;
3396  m_caster->SendMessageToSet(&data, true);
3397 
3398  data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 4));
3399  data << m_caster->GetPackGUID();
3400  data << m_spellInfo->Id;
3401  m_caster->SendMessageToSet(&data, true);
3402 }
3403 
3405 {
3406  if (time == 0)
3407  {
3410  }
3411 
3412  WorldPacket data(MSG_CHANNEL_UPDATE, 8 + 4);
3413  data << m_caster->GetPackGUID();
3414  data << uint32(time);
3415 
3416  m_caster->SendMessageToSet(&data, true);
3417 }
3418 
3420 {
3421  uint64 channelTarget = 0;
3423  channelTarget = m_targets.getUnitTargetGUID();
3424  else if (m_targets.getGOTargetGUID())
3425  channelTarget = m_targets.getGOTargetGUID();
3426  else if (m_targets.getCorpseTargetGUID())
3427  channelTarget = m_targets.getCorpseTargetGUID();
3428 
3429 
3430  m_timer = duration;
3431  if (channelTarget)
3433 
3435 
3436  if (!m_isNeedSendToClient)
3437  return;
3438 
3439  WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
3440  data << m_caster->GetPackGUID();
3441  data << uint32(m_spellInfo->Id);
3442  data << uint32(duration);
3443  m_caster->SendMessageToSet(&data, true);
3444 }
3445 
3447 {
3448  WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + 2 + 4));
3449  data << m_caster->GetGUID();
3450  data << uint32(1) << uint16(0) << uint32(1);
3451 
3452  target->GetSession()->SendPacket(&data);
3453 }
3454 
3456 {
3457  if (m_caster->GetTypeId() != TYPEID_PLAYER)
3458  return;
3459 
3461  data << uint64(m_caster->GetGUID());
3462  data << uint32(SpellID); // spell visual id?
3463  m_caster->ToPlayer()->GetSession()->SendPacket(&data);
3464 }
3465 
3467 {
3469  return;
3470 
3471  // not remove cast item at triggered spell (equipping, weapon damage, etc)
3472  if (m_IsTriggeredSpell)
3473  return;
3474 
3475  ItemTemplate const* proto = m_CastItem->GetProto();
3476 
3477  if (!proto)
3478  {
3479  // This code is to avoid a crash
3480  // I'm not sure, if this is really an error, but I guess every item needs a prototype
3481  sLog.outError("Cast item has no item prototype highId=%d, lowId=%d", m_CastItem->GetGUIDHigh(), m_CastItem->GetGUIDLow());
3482  return;
3483  }
3484 
3485  bool expendable = false;
3486  bool withoutCharges = false;
3487 
3488  for (int i = 0; i < 5; i++)
3489  {
3490  if (proto->Spells[i].SpellId)
3491  {
3492  // item has limited charges
3493  if (proto->Spells[i].SpellCharges)
3494  {
3495  if (proto->Spells[i].SpellCharges < 0)
3496  expendable = true;
3497 
3498  int32 charges = m_CastItem->GetSpellCharges(i);
3499 
3500  // item has charges left
3501  if (charges)
3502  {
3503  (charges > 0) ? --charges : ++charges; // abs(charges) less at 1 after use
3504  if (proto->Stackable < 2)
3505  m_CastItem->SetSpellCharges(i, charges);
3507  }
3508 
3509  // all charges used
3510  withoutCharges = (charges == 0);
3511  }
3512  }
3513  }
3514 
3515  if (expendable && withoutCharges)
3516  {
3517  uint32 count = 1;
3518  m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
3519 
3520  // prevent crash at access to deleted m_targets.getItemTarget
3522  m_targets.setItemTarget(NULL);
3523 
3524  m_CastItem = NULL;
3525  }
3526 }
3527 
3529 {
3531  return;
3532 
3533  //Don't take power if the spell is cast while .cheat power is enabled.
3534  if (m_caster->GetTypeId() == TYPEID_PLAYER)
3535  {
3537  return;
3538  }
3539 
3540  bool hit = true;
3541  if (m_caster->GetTypeId() == TYPEID_PLAYER)
3542  {
3544  if (uint64 targetGUID = m_targets.getUnitTargetGUID())
3545  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3546  {
3547  if (ihit->deleted)
3548  continue;
3549 
3550  if (ihit->targetGUID == targetGUID)
3551  {
3552  if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_MISS/* && ihit->targetGUID != m_caster->GetGUID()*/)
3553  hit = false;
3554  break;
3555  }
3556  }
3557  }
3558 
3559  if (!m_powerCost)
3560  return;
3561 
3562  // health as power used
3564  {
3566  return;
3567  }
3568 
3570  {
3571  sLog.outError("Spell::TakePower: Unknown power type '%d'", m_spellInfo->powerType);
3572  return;
3573  }
3574 
3575  Powers powerType = Powers(m_spellInfo->powerType);
3576 
3577  m_caster->ModifyPower(powerType, -m_powerCost);
3578 
3579  // Set the five second timer
3580  if (powerType == POWER_MANA && m_powerCost > 0)
3582 }
3583 
3585 {
3586  if (m_IsTriggeredSpell) // reagents used in triggered spell removed by original spell or don't must be removed.
3587  return;
3588 
3589  if (m_caster->GetTypeId() != TYPEID_PLAYER)
3590  return;
3591 
3592  ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetProto() : NULL;
3593 
3594  // do not take reagents for these item casts
3595  if (castItemTemplate && castItemTemplate->Flags & ITEM_PROTO_FLAG_TRIGGERED_CAST)
3596  return;
3597 
3598  Player* p_caster = m_caster->ToPlayer();
3599  if (p_caster->CanCastNoReagents(m_spellInfo))
3600  return;
3601 
3602  for (uint32 x = 0; x < 8; x++)
3603  {
3604  if (m_spellInfo->Reagent[x] <= 0)
3605  continue;
3606 
3607  uint32 itemid = m_spellInfo->Reagent[x];
3608  uint32 itemcount = m_spellInfo->ReagentCount[x];
3609 
3610  // if CastItem is also spell reagent
3611  if (m_CastItem)
3612  {
3613  ItemTemplate const* proto = m_CastItem->GetProto();
3614  if (proto && proto->ItemId == itemid)
3615  {
3616  for (int s = 0; s < 5; s++)
3617  {
3618  // CastItem will be used up and does not count as reagent
3619  int32 charges = m_CastItem->GetSpellCharges(s);
3620  if (proto->Spells[s].SpellCharges < 0 && abs(charges) < 2)
3621  {
3622  ++itemcount;
3623  break;
3624  }
3625  }
3626 
3627  m_CastItem = NULL;
3628  }
3629  }
3630 
3631  // if getItemTarget is also spell reagent
3632  if (m_targets.getItemTargetEntry() == itemid)
3633  m_targets.setItemTarget(NULL);
3634 
3635  p_caster->DestroyItemCount(itemid, itemcount, true);
3636  }
3637 }
3638 
3640 {
3641  if (m_UniqueTargetInfo.empty())
3642  return;
3643 
3646  return;
3647 
3648  float threat = 0.0f;
3649  if (SpellThreatEntry const* threatEntry = sSpellMgr.GetSpellThreatEntry(m_spellInfo->Id))
3650  {
3651  if (threatEntry->apPctMod != 0.0f)
3652  threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
3653 
3654  threat += threatEntry->flatMod;
3655  }
3656  else
3657  threat += m_spellInfo->spellLevel;
3658 
3659  if (threat == 0.0f)
3660  return;
3661 
3662  // since 2.0.1 threat from positive effects also is distributed among all targets, so the overall caused threat is at most the defined bonus
3663  threat /= m_UniqueTargetInfo.size();
3664 
3665  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3666  {
3667  float threatToAdd = threat;
3668  if (ihit->missCondition != SPELL_MISS_NONE)
3669  threatToAdd = 0.0f;
3670 
3671  Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3672  if (!target)
3673  continue;
3674 
3675  // positive spells distribute threat among all units that are in combat with target, like healing
3677  target->AddAssistThreat(m_caster, threatToAdd, m_spellInfo);
3678  // for negative spells threat gets distributed among affected targets
3679  else
3680  if (!target->IsFriendlyTo(m_caster))
3681  target->AddThreat(m_caster, threatToAdd, GetSpellSchoolMask(m_spellInfo), m_spellInfo);
3682  }
3683 
3684  sLog.outDebug("Spell %u, added an additional %f threat for %s %u target(s)", m_spellInfo->Id, threat, IsPositiveSpell(m_spellInfo->Id) ? "assisting" : "harming", uint32(m_UniqueTargetInfo.size()));
3685 }
3686 
3687 void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, float /*DamageMultiplier*/)
3688 {
3689  unitTarget = pUnitTarget;
3690  itemTarget = pItemTarget;
3691  gameObjTarget = pGOTarget;
3692 
3693  uint8 eff = m_spellInfo->Effect[i];
3694 
3695  DEBUG_LOG("Spell: Effect : %u", eff);
3696 
3697  //we do not need DamageMultiplier here.
3698  damage = CalculateDamage(i, NULL);
3699 
3700  if (eff < TOTAL_SPELL_EFFECTS)
3701  {
3702  //sLog.outDebug("WORLD: Spell FX %d < TOTAL_SPELL_EFFECTS ", eff);
3703  (*this.*SpellEffects[eff])((SpellEffIndex)i);
3704  }
3705  /*
3706  else
3707  {
3708  sLog.outDebug("WORLD: Spell FX %d > TOTAL_SPELL_EFFECTS ", eff);
3709  if (m_CastItem)
3710  EffectEnchantItemTmp(i);
3711  else
3712  {
3713  sLog.outError("SPELL: unknown effect %u spell id %u\n",
3714  eff, m_spellInfo->Id);
3715  }
3716  }
3717  */
3718 }
3719 
3721 {
3722  for (TriggerSpells::iterator si = m_TriggerSpells.begin(); si != m_TriggerSpells.end(); ++si)
3723  {
3724  Spell* spell = new Spell(m_caster, (*si), true, m_originalCasterGUID, m_selfContainer, true);
3725  spell->prepare(&m_targets); // use original spell original targets
3726  }
3727 }
3728 
3730 {
3731  // check death state
3733  return SPELL_FAILED_CASTER_DEAD;
3734 
3735  // check cooldowns to prevent cheating
3736  if (!m_IsTriggeredSpell)
3737  if (Player* plr = m_caster->ToPlayer())
3738  if (plr->HasSpellCooldown(m_spellInfo->Id) || (strict && plr->HasGlobalCooldown(m_spellInfo)))
3739  return SPELL_FAILED_NOT_READY;
3740 
3741  // only triggered spells can be processed an ended battleground
3744  if (bg->GetStatus() == STATUS_WAIT_LEAVE)
3745  return SPELL_FAILED_DONT_REPORT;
3746 
3748  {
3752 
3756  }
3757 
3758  // only check at first call, Stealth auras are already removed at second call
3759  // for now, ignore triggered spells
3760  if (strict && !m_IsTriggeredSpell)
3761  {
3762  // Cannot be used in this stance/form
3764  if (shapeError != SPELL_CAST_OK)
3765  return shapeError;
3766 
3769  }
3770 
3771  // caster state requirements
3776 
3777  // cancel autorepeat spells if cast start when moving
3778  // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
3780  {
3781  // skip stuck spell to allow use it in falling case and apply spell limitations at movement
3784  return SPELL_FAILED_MOVING;
3785  }
3786 
3787  // check spell cast conditions from database
3788  {
3790  condInfo.mConditionTargets[1] = m_targets.getUnitTarget();
3791  ConditionList conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
3792  if (!conditions.empty() && !sConditionMgr.IsObjectMeetToConditions(condInfo, conditions))
3793  {
3794  // mLastFailedCondition can be NULL if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
3795  if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
3797 
3798  if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
3800 
3801  return SPELL_FAILED_BAD_TARGETS;
3802  }
3803  }
3804 
3807 
3808  Unit* target = m_targets.getUnitTarget();
3809 
3810  if (target)
3811  {
3812  // target state requirements (not allowed state), apply to self also
3815 
3818 
3819  // @todo Find a way to check for form instead of checking byte flag, probably no problem either way
3820  // Not allow casting on Spirit of Redemption form, includes the priest IN redemption form, except for triggered spells
3822  return SPELL_FAILED_BAD_TARGETS;
3823 
3824  if (target != m_caster)
3825  {
3826  // target state requirements (apply to non-self only), to allow cast affects to self like Dirty Deeds
3829 
3830  // Not allow casting on flying player
3831  if (target->IsInFlight())
3832  return SPELL_FAILED_BAD_TARGETS;
3833 
3834  // Must be behind the target.
3835  if (m_spellInfo->AttributesEx2 == 0x100000 && (m_spellInfo->AttributesEx & 0x200) == 0x200 && target->HasInArc(static_cast<float>(M_PI), m_caster)
3836  && (m_spellInfo->SpellFamilyName != SPELLFAMILY_DRUID || m_spellInfo->SpellFamilyFlags != 0x0000000000020000LL))
3837  return SPELL_FAILED_NOT_BEHIND;
3838 
3839  // Target must be facing you.
3840  if ((m_spellInfo->Attributes == 0x150010) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
3841  return SPELL_FAILED_NOT_INFRONT;
3842 
3843  // Do not allow these spells to target creatures not tapped by us (Banish, Polymorph, many quest spells)
3845  if (Creature const* targetCreature = target->ToCreature())
3846  if (targetCreature->hasLootRecipient() && !targetCreature->isTappedBy(m_caster->ToPlayer()))
3848 
3850  return SPELL_FAILED_BAD_TARGETS;
3851 
3852  bool isTrigger = (target->ToCreature() && target->ToCreature()->IsTrigger());
3853  if (!isTrigger)
3854  {
3855  WorldObject* losTarget = target;
3858  losTarget = dynObj;
3859 
3862  }
3863 
3864  // auto selection spell rank implemented in WorldSession::HandleCastSpellOpcode
3865  // this case can be triggered if rank not found (too low-level target for first rank)
3867  {
3868  for (int i = 0; i < 3; i++)
3869  {
3871  if (target->getLevel() + 10 < m_spellInfo->spellLevel)
3872  return SPELL_FAILED_LOWLEVEL;
3873  }
3874  }
3875  }
3876 
3877  // check pet presence
3878  for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3879  {
3881  {
3882  target = m_caster->GetGuardianPet();
3883  if (!target)
3884  {
3885  if (m_triggeredByAuraSpell) // not report pet not existence for triggered spells
3886  return SPELL_FAILED_DONT_REPORT;
3887  else
3888  return SPELL_FAILED_NO_PET;
3889  }
3890  else if (!target->IsAlive())
3892  break;
3893  }
3894  }
3895 
3896  //check creature type
3897  //ignore self casts (including area casts when caster selected as target)
3898  if (target != m_caster)
3899  {
3900  if (!CheckTargetCreatureType(target))
3901  {
3902  if (target->GetTypeId() == TYPEID_PLAYER)
3904  else
3905  return SPELL_FAILED_BAD_TARGETS;
3906  }
3907  }
3908 
3909  // @todo this check can be applied and for player to prevent cheating when IsPositiveSpell will return always correct result.
3910  // check target for pet/charmed casts (not self targeted), self targeted cast used for area effects and etc
3912  {
3913  // check correctness positive/negative cast target (pet cast real check and cheating check)
3915  {
3916  //dispel positivity is dependant on target, don't check it
3917  if (m_caster->IsHostileTo(target) && !IsDispel(m_spellInfo))
3918  return SPELL_FAILED_BAD_TARGETS;
3919  }
3920  else
3921  {
3922  if (m_caster->IsFriendlyTo(target))
3923  return SPELL_FAILED_BAD_TARGETS;
3924  }
3925  }
3926 
3927  // spells cannot be cast if player is in fake combat also
3930  }
3931 
3932  // Spell casted only in battleground
3934  if (!m_caster->ToPlayer()->InBattleground())
3936 
3937  // do not allow spells to be cast in arenas
3938  // - with greater than 15 min CD without SPELL_ATTR4_USABLE_IN_ARENA flag
3939  // - with SPELL_ATTR4_NOT_USABLE_IN_ARENA flag
3942  if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
3943  if (mapEntry->IsBattleArena())
3945 
3946  // zone check
3947  if (m_caster->GetTypeId() == TYPEID_PLAYER)
3948  {
3950  if (locRes != SPELL_CAST_OK)
3951  return locRes;
3952  }
3953 
3954  // not let players cast spells at mount (and let do it to creatures)
3957  {
3958  if (m_caster->IsInFlight())
3959  return SPELL_FAILED_NOT_FLYING;
3960  else
3961  return SPELL_FAILED_NOT_MOUNTED;
3962  }
3963 
3966 
3967  SpellCastResult castResult = SPELL_CAST_OK;
3968 
3969  // always (except passive spells) check items (focus object can be required for any type casts)
3970  if (!IsPassiveSpell(m_spellInfo->Id))
3971  {
3972  castResult = CheckItems();
3973  if (castResult != SPELL_CAST_OK)
3974  return castResult;
3975  }
3976 
3977  if (!m_IsTriggeredSpell)
3978  {
3980  {
3981  castResult = CheckRange(strict);
3982  if (castResult != SPELL_CAST_OK)
3983  return castResult;
3984  }
3985  }
3986 
3987  // ImpliciteTargetA-B = 38, If fact there is 0 Spell with ImpliciteTargetB=38
3988  if (m_UniqueTargetInfo.empty()) // skip second canCast apply (for delayed spells for example)
3989  {
3990  for (uint8 j = 0; j < MAX_SPELL_EFFECTS; j++)
3991  {
3996  {
3997  ConditionList conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET, m_spellInfo->Id);
3998  if (conditions.empty())
3999  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);
4000 
4001  SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
4002  float range = GetSpellMaxRange(srange);
4003 
4004  Creature* creatureScriptTarget = NULL;
4005  GameObject* goScriptTarget = NULL;
4006 
4007  for (ConditionList::const_iterator i_spellST = conditions.begin(); i_spellST != conditions.end(); ++i_spellST)
4008  {
4009  if ((*i_spellST)->Type != CONDITION_SPELL_SCRIPT_TARGET)
4010  continue;
4011  switch((*i_spellST)->ConditionValue1)
4012  {
4014  {
4015  GameObject* p_GameObject = NULL;
4016 
4017  if ((*i_spellST)->ConditionValue2)
4018  {
4020  Cell cell(p);
4021 
4022  Oregon::NearestGameObjectEntryInObjectRangeCheck go_check(*m_caster, (*i_spellST)->ConditionValue2, range);
4024 
4026  cell.Visit(p, object_checker, *m_caster->GetMap(), *m_caster, range);
4027 
4028  if (p_GameObject)
4029  {
4030  // remember found target and range, next attempt will find more near target with another entry
4031  creatureScriptTarget = NULL;
4032  goScriptTarget = p_GameObject;
4033  range = go_check.GetLastRange();
4034  }
4035  }
4036  else if (focusObject) //Focus Object
4037  {
4038  float frange = m_caster->GetDistance(focusObject);
4039  if (range >= frange)
4040  {
4041  creatureScriptTarget = NULL;
4042  goScriptTarget = focusObject;
4043  range = frange;
4044  }
4045  }
4046  break;
4047  }
4050  default:
4051  {
4052  Creature* p_Creature = NULL;
4053 
4055  Cell cell(p);
4056  cell.SetNoCreate(); // Really don't know what is that???
4057 
4058  Oregon::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster, (*i_spellST)->ConditionValue2, (*i_spellST)->ConditionValue1 != SPELL_TARGET_TYPE_DEAD, range);
4060 
4062 
4063  cell.Visit(p, grid_creature_searcher, *m_caster->GetMap(), *m_caster, range);
4064 
4065  if (p_Creature)
4066  {
4067  creatureScriptTarget = p_Creature;
4068  goScriptTarget = NULL;
4069  range = u_check.GetLastRange();
4070  }
4071  break;
4072  }
4073  }
4074  }
4075 
4076  if (creatureScriptTarget)
4077  {
4078  // store coordinates for TARGET_DST_NEARBY_ENTRY
4081  {
4082  m_targets.setDst(creatureScriptTarget->GetPositionX(), creatureScriptTarget->GetPositionY(), creatureScriptTarget->GetPositionZ(), creatureScriptTarget->GetOrientation());
4083 
4085  AddUnitTarget(creatureScriptTarget, j);
4086  }
4087  // store explicit target for TARGET_UNIT_NEARBY_ENTRY
4088  else
4089  AddUnitTarget(creatureScriptTarget, j);
4090  }
4091  else if (goScriptTarget)
4092  {
4093  // store coordinates for TARGET_DST_NEARBY_ENTRY
4096  {
4097  m_targets.setDst(goScriptTarget->GetPositionX(), goScriptTarget->GetPositionY(), goScriptTarget->GetPositionZ(), goScriptTarget->GetOrientation());
4098 
4100  AddGOTarget(goScriptTarget, j);
4101  }
4102  // store explicit target for TARGET_UNIT_NEARBY_ENTRY
4103  else
4104  AddGOTarget(goScriptTarget, j);
4105  }
4106  //Missing DB Entry or targets for this spellEffect.
4107  else
4108  {
4109  // not report target not existence for triggered spells
4111  return SPELL_FAILED_DONT_REPORT;
4112  else
4113  return SPELL_FAILED_BAD_TARGETS;
4114  }
4115  }
4116  }
4117  }
4118 
4119  if (!m_IsTriggeredSpell)
4120  {
4121  SpellCastResult castResult;
4122 
4123  castResult = CheckRange(strict);
4124  if (castResult != SPELL_CAST_OK)
4125  return castResult;
4126 
4127  castResult = CheckPower();
4128  if (castResult != SPELL_CAST_OK)
4129  return castResult;
4130 
4131  castResult = CheckCasterAuras();
4132  if (castResult != SPELL_CAST_OK)
4133  return castResult;
4134  }
4135 
4136  // check for effect-specific restrictions
4137  for (uint32 i = 0; i < MAX_SPELL_EFFECTS; i++)
4138  {
4139  // for effects of spells that have only one target
4140  switch (m_spellInfo->Effect[i])
4141  {
4142  case SPELL_EFFECT_DUMMY:
4143  {
4144  if (SpellCastResult result = CheckDummyCast(i))
4145  if (result != SPELL_CAST_OK)
4146  return result;
4147  break;
4148  }
4150  {
4151  // Hammer of Wrath
4152  if (m_spellInfo->SpellVisual == 7250)
4153  {
4154  if (!m_targets.getUnitTarget())
4156 
4158  return SPELL_FAILED_BAD_TARGETS;
4159  }
4160  break;
4161  }
4163  {
4164  // report single-target "buff degrading" (dont report for triggered spells)
4165  // also works only for positive spells and the buffed is always able to degrade
4166  // his own buffs
4167  if (strict && target != m_caster && target)
4170  if (sSpellMgr.IsNoStackSpellDueToSpell(m_spellInfo->Id, m_spellInfo->Id, false))
4171  if (target->HasHigherRankOfAura(m_spellInfo->Id, i))
4173 
4174  switch(m_spellInfo->EffectApplyAuraName[i])
4175  {
4176  case SPELL_AURA_BIND_SIGHT:
4177  {
4178  // Cannot bind sight across instances/continents.
4179  // Does not affect the same instance/continent, no matter the range.
4180  if(target == m_caster)
4181  return SPELL_FAILED_BAD_TARGETS;
4182  break;
4183  }
4184  }
4185  break;
4186  }
4188  {
4189  if (m_caster->GetTypeId() != TYPEID_PLAYER)
4190  return SPELL_FAILED_BAD_TARGETS;
4191 
4193  break;
4194 
4195  Pet* pet = m_caster->ToPlayer()->GetPet();
4196 
4197  if (!pet)
4198  return SPELL_FAILED_NO_PET;
4199 
4200  SpellEntry const* learn_spellproto = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[i]);
4201 
4202  if (!learn_spellproto)
4203  return SPELL_FAILED_NOT_KNOWN;
4204 
4205  if (!pet->CanTakeMoreActiveSpells(learn_spellproto->Id))
4207 
4208  if (m_spellInfo->spellLevel > pet->getLevel())
4209  return SPELL_FAILED_LOWLEVEL;
4210 
4211  if (!pet->HasTPForSpell(learn_spellproto->Id))
4213 
4214  break;
4215  }
4216  case SPELL_EFFECT_TRIGGER_SPELL_2: // Only Ritual of Summoning
4217  {
4220  break;
4221  }
4223  {
4224  if (m_caster->GetTypeId() != TYPEID_PLAYER)
4225  return SPELL_FAILED_BAD_TARGETS;
4226 
4227  Pet* pet = m_caster->ToPlayer()->GetPet();
4228  if (!pet)
4229  return SPELL_FAILED_NO_PET;
4230 
4231  SpellEntry const* learn_spellproto = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[i]);
4232 
4233  if (!learn_spellproto)
4234  return SPELL_FAILED_NOT_KNOWN;
4235 
4236  if (!pet->CanTakeMoreActiveSpells(learn_spellproto->Id))
4238 
4239  if (m_spellInfo->spellLevel > pet->getLevel())
4240  return SPELL_FAILED_LOWLEVEL;
4241 
4242  if (!pet->HasTPForSpell(learn_spellproto->Id))
4244 
4245  break;
4246  }
4247  case SPELL_EFFECT_FEED_PET:
4248  {
4250  return SPELL_FAILED_BAD_TARGETS;
4251 
4252  Pet* pet = m_caster->ToPlayer()->GetPet();
4253 
4254  if (!pet)
4255  return SPELL_FAILED_NO_PET;
4256 
4257  if (!pet->HaveInDiet(m_targets.getItemTarget()->GetProto()))
4259 
4262 
4263  if (m_caster->IsInCombat() || pet->IsInCombat())
4265 
4266  break;
4267  }
4270  {
4271  // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
4272  if (m_caster->GetTypeId() == TYPEID_PLAYER)
4273  if (Unit* target = m_targets.getUnitTarget())
4274  if (target != m_caster && target->getPowerType() != uint32(m_spellInfo->EffectMiscValue[i]))
4275  if (!(target->ToCreature() && target->ToCreature()->ToPet() && m_spellInfo->EffectMiscValue[i] == POWER_HAPPINESS))
4276  return SPELL_FAILED_BAD_TARGETS;
4277  break;
4278  }
4279  case SPELL_EFFECT_CHARGE:
4280  {
4282  return SPELL_FAILED_ROOTED;
4283 
4284  break;
4285  }
4286  case SPELL_EFFECT_SKINNING:
4287  {
4289  return SPELL_FAILED_BAD_TARGETS;
4290 
4293 
4294  Creature* creature = m_targets.getUnitTarget()->ToCreature();
4295  if (!creature->IsCritter() && !creature->loot.isLooted())
4297 
4298  uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4299 
4300  int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
4301  int32 TargetLevel = m_targets.getUnitTarget()->getLevel();
4302  int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
4303  if (ReqValue > skillValue)
4305 
4306  // chance for fail at orange skinning attempt
4307  if ((m_selfContainer && (*m_selfContainer) == this) &&
4308  skillValue < sWorld.GetConfigMaxSkillValue() &&
4309  (ReqValue < 0 ? 0 : ReqValue) > irand(skillValue - 25, skillValue + 37))
4310  return SPELL_FAILED_TRY_AGAIN;
4311 
4312  break;
4313  }
4316  {
4319  break;
4320 
4321  // we need a go target in case of TARGET_GAMEOBJECT
4323  return SPELL_FAILED_BAD_TARGETS;
4324 
4325  Item* pTempItem = nullptr;
4328 
4329  // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
4331  !m_targets.getGOTarget() &&
4332  (!pTempItem || !pTempItem->GetProto()->LockID || !pTempItem->IsLocked()))
4333  return SPELL_FAILED_BAD_TARGETS;
4334 
4335  if (m_spellInfo->Id != 1842 || (m_targets.getGOTarget() &&
4337  if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners
4339  return SPELL_FAILED_TRY_AGAIN;
4340 
4341  // get the lock entry
4342  uint32 lockId = 0;
4343  if (GameObject* go = m_targets.getGOTarget())
4344  {
4345  lockId = go->GetGOInfo()->GetLockId();
4346  if (!lockId)
4347  return SPELL_FAILED_BAD_TARGETS;
4348  }
4349  else if (Item* itm = m_targets.getItemTarget())
4350  lockId = itm->GetProto()->LockID;
4351 
4352  SkillType skillId = SKILL_NONE;
4353  int32 reqSkillValue = 0;
4354  int32 skillValue = 0;
4355 
4356  // check lock compatibility
4357  SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
4358  if (res != SPELL_CAST_OK)
4359  return res;
4360 
4361  // chance for fail at lockpicking attempt
4362  // second check prevent fail at rechecks
4363  if (skillId != SKILL_NONE && (!m_selfContainer || ((*m_selfContainer) != this)))
4364  {
4365  bool canFailAtMax = skillId == SKILL_LOCKPICKING;
4366 
4367  // chance for failure in orange lockpick
4368  if ((canFailAtMax || skillValue < sWorld.GetConfigMaxSkillValue()) && reqSkillValue > irand(skillValue - 25, skillValue + 37))
4369  return SPELL_FAILED_TRY_AGAIN;
4370  }
4371  break;
4372  }
4373  // Bring the pet back to the land of the living
4375  {
4376  Creature* pet = m_caster->GetGuardianPet();
4377  if (pet && pet->IsAlive())
4379 
4380  // Do not revive dismissed pets, they are not dead
4383 
4384  // Attempting to revive a non existing pet?
4385  if (m_caster->IsPlayer() && !m_caster->ToPlayer()->doesOwnPet())
4386  return SPELL_FAILED_NO_PET;
4387 
4388  break;
4389  }
4390  // Called when we start channeling 'Dismiss pet' spell
4392  {
4393  // Don't start dismissing the pet if it's dead!
4394  Pet* pet = m_caster->ToPlayer()->GetPet();
4395  if (!pet || !pet->IsAlive())
4397 
4398  break;
4399  }
4400  // This is generic summon effect
4401  case SPELL_EFFECT_SUMMON:
4402  {
4403  SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]);
4404  if (!SummonProperties)
4405  break;
4406  switch (SummonProperties->Category)
4407  {
4408  case SUMMON_CATEGORY_PET:
4411  // intentional missing break, check both GetPetGUID() and GetCharmGUID for SUMMON_CATEGORY_PET
4413  if (m_caster->GetCharmGUID())
4415  break;
4416  }
4417  break;
4418  }
4420  {
4421  // Check these things only for player hunters
4423  {
4424  // Player should not be able to call the pet if he doesn't own one...
4425  if (!m_caster->ToPlayer()->doesOwnPet())
4426  return SPELL_FAILED_NO_PET;
4427 
4428  // ... or the pet is dead ...
4431  }
4432  if (m_caster->GetPetGUID()) // let warlock do a replacement summon
4433  {
4434  if (m_caster->IsPlayer())
4435  {
4436  if (strict) // starting cast, trigger pet stun (cast by pet so it doesn't attack player)
4437  if (Pet* pet = m_caster->ToPlayer()->GetPet())
4438  pet->CastSpell(pet, 32752, true, NULL, NULL, pet->GetGUID());
4439  }
4442  }
4443 
4444  if (m_caster->GetCharmGUID())
4446 
4447  break;
4448  }
4450  {
4451  if (m_caster->GetTypeId() != TYPEID_PLAYER)
4452  return SPELL_FAILED_BAD_TARGETS;
4453  if (!m_caster->ToPlayer()->GetSelection())
4454  return SPELL_FAILED_BAD_TARGETS;
4455 
4456  Player* target = sObjectMgr.GetPlayer(m_caster->ToPlayer()->GetSelection());
4457  if (!target || m_caster->ToPlayer() == target || !target->IsInSameRaidWith(m_caster->ToPlayer()))
4458  return SPELL_FAILED_BAD_TARGETS;
4459 
4460  // check if our map is dungeon
4461  MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
4462 
4463  if (map->IsDungeon())
4464  {
4465  uint32 mapId = m_caster->GetMap()->GetId();
4466  DungeonDifficulty difficulty = m_caster->GetMap()->GetDifficulty();
4467  if (map->IsRaid())
4468  if (InstancePlayerBind* targetBind = target->GetBoundInstance(mapId, difficulty))
4469  if (InstancePlayerBind* casterBind = m_caster->ToPlayer()->GetBoundInstance(mapId, difficulty))
4470  if (targetBind->perm && targetBind->save != casterBind->save)
4472 
4473  InstanceTemplate const* instance = ObjectMgr::GetInstanceTemplate(mapId);
4474  if (!instance)