OregonCore  revision be9e804-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 <https://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;
1591  float 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 
2204  unitList.remove(m_caster);
2205 
2206  for (std::list<Unit*>::iterator itr = unitList.begin(); itr != unitList.end(); )
2207  {
2209  {
2210  if ((*itr)->HasBreakableByDamageCrowdControlAura())
2211  {
2212  itr = unitList.erase(itr);
2213  continue;
2214  }
2215  }
2216 
2217  // for mass-buffs skip targets that have higher ranks already applied.on them
2218  if (*itr != m_caster && massbuff)
2219  {
2220  if ((*itr)->HasHigherRankOfAura(m_spellInfo->Id, i))
2221  {
2222  itr = unitList.erase(itr);
2223  continue;
2224  }
2225  }
2226 
2227  AddUnitTarget(*itr, i);
2228  ++itr;
2229  }
2230  }
2231  }
2232 }
2233 
2234 void Spell::prepare(SpellCastTargets* targets, Aura* triggeredByAura)
2235 {
2236  if (m_CastItem)
2238  else
2239  m_castItemGUID = 0;
2240 
2241  m_targets = *targets;
2242 
2244 
2247 
2248  if (triggeredByAura)
2249  m_triggeredByAuraSpell = triggeredByAura->GetSpellProto();
2250 
2251  // create and add update event for this spell
2252  SpellEvent* Event = new SpellEvent(this);
2254 
2255  //Prevent casting at cast another spell (ServerSide check)
2256  if (!m_IsTriggeredSpell && m_caster->IsNonMeleeSpellCast(false, true, true) && m_cast_count)
2257  {
2259  finish(false);
2260  return;
2261  }
2262 
2263  if (sDisableMgr.IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, m_caster))
2264  {
2266  finish(false);
2267  return;
2268  }
2269 
2270  // Fill cost data (not use power for item casts)
2272 
2273  FillTargetMap();
2274 
2275  SpellCastResult result = CheckCast(true);
2276  if (result != SPELL_CAST_OK && !IsAutoRepeat()) //always cast autorepeat dummy for triggering
2277  {
2278  if (triggeredByAura && !triggeredByAura->IsPassive() && !IsPassiveSpell(m_spellInfo))
2279  {
2280  SendChannelUpdate(0);
2281  triggeredByAura->SetAuraDuration(0);
2282  }
2283 
2284  SendCastResult(result);
2285 
2286  finish(false);
2287  return;
2288  }
2289 
2290  // Prepare data for triggers
2292 
2293  // Set combo point requirement
2295  m_needComboPoints = false;
2296 
2297  // calculate cast time (calculated after first CanCast check to prevent charge counting for first CanCast fail)
2299 
2300  // don't allow channeled spells / spells with cast time to be casted while moving
2301  // (even if they are interrupted on moving, spells with almost immediate effect get to have their effect processed before movement interrupter kicks in)
2303  {
2305  finish(false);
2306  return;
2307  }
2308 
2309  // Set cast time to 0 if .cheat casttime is enabled.
2310  if (m_caster->GetTypeId() == TYPEID_PLAYER)
2311  {
2313  m_casttime = 0;
2314  }
2315 
2316  // set timer base at cast time
2317  ReSetTimer();
2318 
2319  if (m_IsTriggeredSpell)
2320  cast(true);
2321  else
2322  {
2323  // stealth must be removed at cast starting (at show channel bar)
2324  // skip triggered spell (item equip spell casting and other not explicit character casts/item uses)
2327 
2329  SendSpellStart();
2330 
2331  if (m_caster->GetTypeId() == TYPEID_PLAYER)
2333 
2334  // item: first cast may destroy item and second cast causes crash
2336  cast(true);
2337  }
2338 }
2339 
2340 void Spell::cancel(bool sendInterrupt)
2341 {
2343  return;
2344 
2345  uint32 oldState = m_spellState;
2347 
2348  m_autoRepeat = false;
2349  switch (oldState)
2350  {
2351  case SPELL_STATE_PREPARING:
2352  case SPELL_STATE_DELAYED:
2353  {
2354  SendInterrupted(0);
2355  if (sendInterrupt)
2357  }
2358  break;
2359 
2360  case SPELL_STATE_CASTING:
2361  {
2362  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2363  {
2364  if (ihit->deleted)
2365  continue;
2366 
2367  if (ihit->missCondition == SPELL_MISS_NONE)
2368  {
2369  Unit* unit = m_caster->GetGUID() == (*ihit).targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
2370  if (unit && unit->IsAlive())
2372  }
2373  }
2374 
2376  SendChannelUpdate(0);
2377 
2378  // Do not send interrupt for channeling spells to avoid a visual bug
2379  // that happens when a caster recasts the spell before the channeling ended
2381  {
2382  SendInterrupted(0);
2383  if (sendInterrupt)
2385  }
2386  }
2387  break;
2388  default:
2389  {
2390  } break;
2391  }
2392 
2393  SetReferencedFromCurrent(false);
2394  if (m_selfContainer && *m_selfContainer == this)
2395  *m_selfContainer = nullptr;
2396 
2398  if (IsChanneledSpell(m_spellInfo)) // if not channeled then the object for the current cast wasn't summoned yet
2399  {
2401 
2402  // reset cooldown state for disabled while active spells
2403  if (m_caster->GetTypeId() == TYPEID_PLAYER)
2404  {
2407  }
2408  }
2409 
2410  //set state back so finish will be processed
2411  m_spellState = oldState;
2412 
2413  finish(false);
2414 }
2415 
2416 void Spell::cast(bool skipCheck)
2417 {
2418  if (m_spellInfo->Id > MAX_SPELL_ID)
2419  return;
2420 
2421  // update pointers base at GUIDs to prevent access to non-existed already object
2422  UpdatePointers();
2423 
2424  // cancel at lost main target unit
2426  {
2427  cancel();
2428  return;
2429  }
2430 
2431  SetExecutedCurrently(true);
2432  SpellCastResult castResult = SPELL_CAST_OK;
2433 
2436 
2437  if (!m_IsTriggeredSpell)
2438  {
2439  castResult = CheckPower();
2440  if (castResult != SPELL_CAST_OK)
2441  {
2442  SendCastResult(castResult);
2443  finish(false);
2444  SetExecutedCurrently(false);
2445  return;
2446  }
2447  }
2448 
2449  // triggered cast called from Spell::prepare where it was already checked
2450  if (!skipCheck)
2451  {
2452  FillTargetMap();
2453 
2454  castResult = CheckCast(false);
2455  if (castResult != SPELL_CAST_OK)
2456  {
2457  SendCastResult(castResult);
2458  SendInterrupted(0);
2459  finish(false);
2460  SetExecutedCurrently(false);
2461  return;
2462  }
2463  }
2464  // Check if some auras need to be interrupted when casting combat auto-repeating spells
2467 
2468  if (m_spellState == SPELL_STATE_FINISHED) // stop cast if spell marked as finish somewhere in Take*/FillTargetMap
2469  {
2470  SendInterrupted(0);
2471  finish(false);
2472  SetExecutedCurrently(false);
2473  return;
2474  }
2475 
2478  pet->DespawnOrUnsummon();
2479 
2480  // traded items have trade slot instead of guid in m_itemTargetGUID
2481  // set to real guid to be sent later to the client
2483 
2484  if (!m_IsTriggeredSpell)
2485  TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot
2486 
2487  // CAST SPELL
2489 
2490  // calc miss, reflect, parry, etc.
2492 
2493  SendSpellGo(); // we must send smsg_spell_go packet before m_castItem delete in TakeCastItem()...
2494 
2495  //handle SPELL_AURA_ADD_TARGET_TRIGGER auras
2496  //are there any spells need to be triggered after hit?
2498  for (Unit::AuraList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
2499  {
2500  SpellEntry const* auraSpellInfo = (*i)->GetSpellProto();
2501  uint32 auraSpellIdx = (*i)->GetEffIndex();
2502  if (IsAffectedBy(auraSpellInfo, auraSpellIdx))
2503  {
2504  if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(auraSpellInfo->EffectTriggerSpell[auraSpellIdx]))
2505  {
2506  // Calculate chance at that moment (can be depend for example from combo points)
2507  int32 chance = m_caster->CalculateSpellDamage(auraSpellInfo, auraSpellIdx, (*i)->GetBasePoints(), NULL);
2508  m_ChanceTriggerSpells.push_back(std::make_pair(spellInfo, chance * (*i)->GetStackAmount()));
2509  }
2510  }
2511  }
2512 
2515 
2516  // Okay, everything is prepared. Now we need to distinguish between immediate and evented delayed spells
2517  // @TODO: Find similarities for spells such as Ruthlessness and run the proper check here
2518  if ((m_spellInfo->speed > 0.0f && !IsChanneledSpell(m_spellInfo)) || m_spellInfo->Id == 14157)
2519  {
2520  // Okay, maps created, now prepare flags
2521  m_immediateHandled = false;
2523  SetDelayStart(0);
2524 
2525  if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !m_caster->IsNonMeleeSpellCast(false, false, true))
2527  }
2528  else
2529  {
2530  // Immediate spell, no big deal
2531  handle_immediate();
2532  }
2533 
2534  // combo points should not be taken before SPELL_AURA_ADD_TARGET_TRIGGER auras are handled
2535  if (!m_IsTriggeredSpell)
2536  TakePower();
2537 
2539  {
2540  if (const std::vector<int32>* spell_triggered = sSpellMgr.GetSpellLinked(m_spellInfo->Id))
2541  {
2542  for (std::vector<int32>::const_iterator i = spell_triggered->begin(); i != spell_triggered->end(); ++i)
2543  if (*i < 0)
2545  else
2547  }
2548  }
2549 
2550  // Clear spell cooldowns after every spell is cast if .cheat cooldown is enabled.
2551  if (m_caster->GetTypeId() == TYPEID_PLAYER)
2552  {
2555  }
2556 
2557  SetExecutedCurrently(false);
2558 }
2559 
2561 {
2562  if (m_spellInfo->Id > MAX_SPELL_ID)
2563  return;
2564 
2565  // start channeling if applicable
2567  {
2568  int32 duration = GetSpellDuration(m_spellInfo);
2570  duration = m_spellValue->Duration;
2571  if (duration > 0)
2572  {
2573  if (m_targets.getUnitTarget())
2574  {
2577  }
2578 
2579  // Apply duration mod
2580  if (Player* modOwner = m_caster->GetSpellModOwner())
2581  modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration);
2582 
2583  // Apply haste mods
2584  m_caster->ModSpellDurationTime(m_spellInfo, duration, this);
2585 
2588  SendChannelStart(duration);
2589  }
2590  else if (duration == -1)
2591  {
2594  SendChannelStart(duration);
2595  }
2596 
2597  // Interrupt movement at channeled spells for creature case
2599  m_caster->StopMoving();
2600  }
2601 
2602  // process immediate effects (items, ground, etc.) also initialize some variables
2604 
2605  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2606  {
2607  if (m_destroyed || ihit == m_UniqueTargetInfo.end() || m_UniqueTargetInfo.size() == 0)
2608  break;
2609 
2610  if (ihit->deleted)
2611  continue;
2612 
2613  DoAllEffectOnTarget(&(*ihit));
2614  }
2615 
2616  for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2617  {
2618  if (m_destroyed || ihit == m_UniqueGOTargetInfo.end() || m_UniqueGOTargetInfo.size() == 0)
2619  break;
2620 
2621  if (ihit->deleted)
2622  continue;
2623 
2624  DoAllEffectOnTarget(&(*ihit));
2625  }
2626 
2627  // spell is finished, perform some last features of the spell here
2629 
2631  finish(true); // successfully finish spell cast (not last in case autorepeat or channel spell)
2632 }
2633 
2635 {
2636  UpdatePointers();
2637  uint64 next_time = 0;
2638 
2639  if (!m_immediateHandled)
2640  {
2642  m_immediateHandled = true;
2643  }
2644 
2645  bool single_missile = (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION);
2646 
2647  // 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)
2648  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2649  {
2650  if (ihit->deleted)
2651  continue;
2652 
2653  if (ihit->processed == false)
2654  {
2655  if (single_missile || ihit->timeDelay <= t_offset)
2656  {
2657  ihit->timeDelay = t_offset;
2658  DoAllEffectOnTarget(&(*ihit));
2659  }
2660  else if (next_time == 0 || ihit->timeDelay < next_time)
2661  next_time = ihit->timeDelay;
2662  }
2663  }
2664 
2665  // now recheck gameobject targeting correctness
2666  for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
2667  {
2668  if (ighit->deleted)
2669  continue;
2670 
2671  if (!ighit->processed)
2672  {
2673  if (single_missile || ighit->timeDelay <= t_offset)
2674  DoAllEffectOnTarget(&(*ighit));
2675  else if (next_time == 0 || ighit->timeDelay < next_time)
2676  next_time = ighit->timeDelay;
2677  }
2678  }
2679  // All targets passed - need finish phase
2680  if (next_time == 0)
2681  {
2682  // spell is finished, perform some last features of the spell here
2684 
2685  finish(true); // successfully finish spell cast
2686 
2687  // return zero, spell is finished now
2688  return 0;
2689  }
2690  else
2691  {
2692  // spell is unfinished, return next execution time
2693  return next_time;
2694  }
2695 }
2696 
2698 {
2699  // handle some immediate features of the spell here
2700 
2703 
2705  TakeCastItem();
2706 
2708 
2709  // initialize Diminishing Returns Data
2712 
2713  // process items
2714  for (std::list<ItemTargetInfo>::iterator ihit = m_UniqueItemInfo.begin(); ihit != m_UniqueItemInfo.end(); ++ihit)
2715  DoAllEffectOnTarget(&(*ihit));
2716 
2717  if (!m_originalCaster)
2718  return;
2719 
2720  // handle effects with SPELL_EFFECT_HANDLE_HIT mode
2721  for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2722  {
2723  // don't do anything for empty effect
2724  if (m_spellInfo->Effect[j] == 0)
2725  continue;
2726 
2727  // call effect handlers to handle destination hit
2728  if (sSpellMgr.EffectTargetType[m_spellInfo->Effect[j]] == SPELL_REQUIRE_DEST)
2729  {
2730  if (!m_targets.HasDst()) // FIXME: this will ignore dest set in effect
2732  HandleEffects(m_originalCaster, nullptr, nullptr, j);
2733  }
2734  else if (sSpellMgr.EffectTargetType[m_spellInfo->Effect[j]] == SPELL_REQUIRE_NONE)
2735  HandleEffects(m_originalCaster, nullptr, nullptr, j);
2736 
2737  // Don't do spell log, if is school damage spell
2739  m_needSpellLog = false;
2740  }
2741 }
2742 
2744 {
2745  // Take for real after all targets are processed
2746  if (m_needComboPoints)
2747  if (Player* player = m_caster->ToPlayer())
2748  player->ClearComboPoints();
2749 
2750  // spell log
2751  if (m_needSpellLog)
2752  SendLogExecute();
2753 }
2754 
2756 {
2757  if (m_caster->GetTypeId() != TYPEID_PLAYER)
2758  return;
2759 
2760  Player* _player = m_caster->ToPlayer();
2761  // Add cooldown for max (disable spell)
2762  // Cooldown started on SendCooldownEvent call
2764  return;
2765 
2766  // init cooldown values
2767  uint32 cat = 0;
2768  int32 rec = -1;
2769  int32 catrec = -1;
2770 
2771  // some special item spells without correct cooldown in SpellInfo
2772  // cooldown information stored in item prototype
2773  // This used in same way in WorldSession::HandleItemQuerySingleOpcode data sending to client.
2774 
2775  if (m_CastItem)
2776  {
2777  ItemTemplate const* proto = m_CastItem->GetProto();
2778  if (proto)
2779  {
2780  for (int idx = 0; idx < 5; ++idx)
2781  {
2782  if (proto->Spells[idx].SpellId == m_spellInfo->Id)
2783  {
2784  cat = proto->Spells[idx].SpellCategory;
2785  rec = proto->Spells[idx].SpellCooldown;
2786  catrec = proto->Spells[idx].SpellCategoryCooldown;
2787  break;
2788  }
2789  }
2790  }
2791  }
2792 
2793  // if no cooldown found above then base at DBC data
2794  if (rec < 0 && catrec < 0)
2795  {
2796  cat = m_spellInfo->Category;
2797  rec = m_spellInfo->RecoveryTime;
2799  }
2800 
2801  // shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK)
2802  // prevent 0 cooldowns set by another way
2803  if (rec <= 0 && catrec <= 0 && (cat == 76 || cat == 351))
2804  rec = _player->GetAttackTime(RANGED_ATTACK);
2805 
2806  // Now we have cooldown data (if found any), time to apply mods
2807  if (rec > 0)
2808  _player->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COOLDOWN, rec, this);
2809 
2810  if (catrec > 0)
2811  _player->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COOLDOWN, catrec, this);
2812 
2813  // replace negative cooldowns by 0
2814  if (rec < 0) rec = 0;
2815  if (catrec < 0) catrec = 0;
2816 
2817  // no cooldown after applying spell mods
2818  if (rec == 0 && catrec == 0)
2819  return;
2820 
2821  time_t curTime = time(NULL);
2822 
2823  time_t catrecTime = catrec ? curTime + catrec / IN_MILLISECONDS : 0; // in secs
2824  time_t recTime = rec ? curTime + rec / IN_MILLISECONDS : catrecTime; // in secs
2825 
2826  // self spell cooldown
2827  if (recTime > 0)
2828  _player->AddSpellCooldown(m_spellInfo->Id, m_CastItem ? m_CastItem->GetEntry() : 0, recTime);
2829 
2830  // category spells
2831  if (catrec > 0)
2832  {
2833  SpellCategoryStore::const_iterator i_scstore = sSpellCategoryStore.find(cat);
2834  if (i_scstore != sSpellCategoryStore.end())
2835  {
2836  for (SpellCategorySet::const_iterator i_scset = i_scstore->second.begin(); i_scset != i_scstore->second.end(); ++i_scset)
2837  {
2838  if (*i_scset == m_spellInfo->Id) // skip main spell, already handled above
2839  continue;
2840 
2841  _player->AddSpellCooldown(*i_scset, m_CastItem ? m_CastItem->GetEntry() : 0, catrecTime);
2842  }
2843  }
2844  }
2845 }
2846 
2847 void Spell::update(uint32 difftime)
2848 {
2849  // update pointers based at it's GUIDs
2850  UpdatePointers();
2851 
2853  {
2854  cancel();
2855  return;
2856  }
2857 
2858  // check if the player or unit caster has moved before the spell finished (exclude casting on vehicles)
2859  if (((m_caster->GetTypeId() == TYPEID_PLAYER || m_caster->GetTypeId() == TYPEID_UNIT) && m_timer != 0) &&
2862  {
2863  // always cancel for channeled spells
2865  cancel();
2866  // don't cancel for melee, autorepeat, triggered and instant spells
2868  cancel();
2869  }
2870 
2871  switch (m_spellState)
2872  {
2873  case SPELL_STATE_PREPARING:
2874  {
2875  if (m_timer > 0)
2876  {
2877  if (difftime >= (uint32)m_timer)
2878  m_timer = 0;
2879  else
2880  m_timer -= difftime;
2881  }
2882 
2883  if (m_timer == 0 && !IsNextMeleeSwingSpell() && !IsAutoRepeat())
2885  }
2886  break;
2887  case SPELL_STATE_CASTING:
2888  {
2889  if (m_timer)
2890  {
2892  {
2893  // check if player has jumped before the channeling finished
2895  cancel();
2896 
2897  // check for incapacitating player states
2899  cancel();
2900  }
2901 
2902  // check if there are alive targets left
2904  {
2905  SendChannelUpdate(0);
2906  finish();
2907  }
2908 
2909  if (m_timer > 0)
2910  {
2911  if (difftime >= (uint32)m_timer)
2912  m_timer = 0;
2913  else
2914  m_timer -= difftime;
2915  }
2916  }
2917 
2918  if (m_timer == 0)
2919  {
2920  SendChannelUpdate(0);
2921 
2922  // channeled spell processed independently for quest targeting
2923  // cast at creature (or GO) quest objectives update at successful cast channel finished
2924  // ignore autorepeat/melee casts for speed (not exist quest for spells (hm...)
2926  {
2927  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
2928  {
2929  if (ihit->deleted)
2930  continue;
2931 
2932  TargetInfo* target = &*ihit;
2933 
2934  if (!IS_CREATURE_GUID(target->targetGUID))
2935  continue;
2936 
2937  Unit* unit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID);
2938  if (unit == NULL)
2939  continue;
2940 
2942  }
2943 
2944  for (std::list<GOTargetInfo>::iterator ihit = m_UniqueGOTargetInfo.begin(); ihit != m_UniqueGOTargetInfo.end(); ++ihit)
2945  {
2946  if (ihit->deleted)
2947  continue;
2948 
2949  GOTargetInfo* target = &*ihit;
2950 
2951  GameObject* go = m_caster->GetMap()->GetGameObject(target->targetGUID);
2952  if (!go)
2953  continue;
2954 
2956  }
2957  }
2958 
2959  finish();
2960  }
2961  }
2962  break;
2963  default:
2964  {
2965  } break;
2966  }
2967 }
2968 
2969 void Spell::finish(bool ok)
2970 {
2971  if (!m_caster)
2972  return;
2973 
2975  return;
2977 
2980 
2981  if (m_caster->HasUnitState(UNIT_STATE_CASTING) && !m_caster->IsNonMeleeSpellCast(false, false, true))
2983 
2984  if (!ok)
2985  {
2986  //restore spell mods
2987  if (m_caster->GetTypeId() == TYPEID_PLAYER)
2989 
2990  // Spell has failed so the combat is no longer being initiated
2991  // Do this only if the unit is initiating combat
2993  m_caster->SetInitiatingCombat(false);
2994 
2995  return;
2996  }
2997  // other code related only to successfully finished spells
2998 
2999  //remove spell mods
3000  if (Player* modOwner = m_caster->GetSpellModOwner())
3001  {
3002  // Take mods after trigger spell
3003  // mods are taken only on succesfull cast and independantly from targets of the spell
3004  modOwner->RemoveSpellMods(this);
3005  }
3006 
3007  // Okay to remove extra attacks
3009  m_caster->m_extraAttacks = 0;
3010 
3011  // Heal caster for all health leech from all targets
3012  if (m_healthLeech)
3013  {
3016  }
3017 
3018  if (IsAutoActionResetSpell())
3019  {
3021  {
3024  if (m_caster->haveOffhandWeapon())
3026  }
3027  }
3028 
3029  // call triggered spell only at successful cast (after clear combo points -> for add some if need)
3030  // I assume what he means is that some triggered spells may add combo points
3031  if (!m_TriggerSpells.empty())
3032  TriggerSpell();
3033 
3034  // Stop Attack for some spells
3036  m_caster->AttackStop();
3037 }
3038 
3040 {
3041  if (m_caster->GetTypeId() != TYPEID_PLAYER)
3042  return;
3043 
3044  if (m_caster->ToPlayer()->GetSession()->PlayerLoading()) // don't send cast results at loading time
3045  return;
3046 
3047  if (result != SPELL_CAST_OK)
3048  {
3049  WorldPacket data(SMSG_CAST_FAILED, (4 + 1 + 1));
3050  data << uint32(m_spellInfo->Id);
3051  data << uint8(!IsPassiveSpell(m_spellInfo) ? result : SPELL_FAILED_DONT_REPORT); // do not report failed passive spells
3052  data << uint8(m_cast_count); // single cast or multi 2.3 (0/1)
3053  switch (result)
3054  {
3057  break;
3059  // hardcode areas limitation case
3060  switch (m_spellInfo->Id)
3061  {
3062  case 41617: // Cenarion Mana Salve
3063  case 41619: // Cenarion Healing Salve
3064  data << uint32(3905);
3065  break;
3066  case 41618: // Bottled Nethergon Energy
3067  case 41620: // Bottled Nethergon Vapor
3068  data << uint32(3842);
3069  break;
3070  case 45373: // Bloodberry Elixir
3071  data << uint32(4075);
3072  break;
3073  case 32307: // Warmaul Ogre Banner
3074  data << uint32(3637);
3075  break;
3076  default: // default case
3077  data << uint32(m_spellInfo->AreaId);
3078  break;
3079  }
3080  break;
3081  case SPELL_FAILED_TOTEMS:
3082  if (m_spellInfo->Totem[0])
3083  data << uint32(m_spellInfo->Totem[0]);
3084  if (m_spellInfo->Totem[1])
3085  data << uint32(m_spellInfo->Totem[1]);
3086  break;
3088  if (m_spellInfo->TotemCategory[0])
3089  data << uint32(m_spellInfo->TotemCategory[0]);
3090  if (m_spellInfo->TotemCategory[1])
3091  data << uint32(m_spellInfo->TotemCategory[1]);
3092  break;
3099  break;
3100  default:
3101  break;
3102  }
3103  m_caster->ToPlayer()->GetSession()->SendPacket(&data);
3104  }
3105  else
3106  {
3107  WorldPacket data(SMSG_CLEAR_EXTRA_AURA_INFO, (8 + 4));
3108  data << m_caster->GetPackGUID();
3109  data << uint32(m_spellInfo->Id);
3110  m_caster->ToPlayer()->GetSession()->SendPacket(&data);
3111  }
3112 }
3113 
3115 {
3116  if (!m_isNeedSendToClient)
3117  return;
3118 
3119  DEBUG_LOG("Sending SMSG_SPELL_START id=%u", m_spellInfo->Id);
3120 
3121  uint32 castFlags = CAST_FLAG_UNKNOWN1;
3122  if (IsRangedSpell())
3123  castFlags |= CAST_FLAG_AMMO;
3124 
3125  //Unit* target = m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster;
3126 
3127  WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
3128  if (m_CastItem)
3129  data << m_CastItem->GetPackGUID();
3130  else
3131  data << m_caster->GetPackGUID();
3132 
3133  data << m_caster->GetPackGUID();
3134  data << uint32(m_spellInfo->Id);; // spellId
3135  data << uint8(m_cast_count); // pending spell cast?
3136  data << uint16(castFlags); // cast flags
3137  data << int32(m_timer); // delay?
3138  data << m_targets;
3139 
3140  if (castFlags & CAST_FLAG_AMMO)
3141  WriteAmmoToPacket(&data);
3142 
3143  m_caster->SendMessageToSet(&data, true);
3144 }
3145 
3147 {
3148  // not send invisible spell casting
3149  if (!m_isNeedSendToClient)
3150  return;
3151 
3152  DEBUG_LOG("Sending SMSG_SPELL_GO id=%u", m_spellInfo->Id);
3153 
3154  //Unit* target = m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster;
3155 
3156  uint32 castFlags = CAST_FLAG_UNKNOWN3;
3157 
3158  // triggered spells with spell visual != 0 and not auto shot
3160  castFlags |= CAST_FLAG_PENDING;
3161 
3162  if (IsRangedSpell())
3163  castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual
3164 
3165  WorldPacket data(SMSG_SPELL_GO, 50); // guess size
3166 
3167  if (m_CastItem)
3168  data << m_CastItem->GetPackGUID();
3169  else
3170  data << m_caster->GetPackGUID();
3171 
3172  data << m_caster->GetPackGUID();
3173  data << uint32(m_spellInfo->Id); // spellId
3174  data << uint16(castFlags); // cast flags
3175  data << uint32(getMSTime()); // timestamp
3176 
3177  WriteSpellGoTargets(&data);
3178 
3179  data << m_targets;
3180 
3181  if (castFlags & CAST_FLAG_AMMO)
3182  WriteAmmoToPacket(&data);
3183 
3184  m_caster->SendMessageToSet(&data, true);
3185 }
3186 
3188 {
3189  uint32 ammoInventoryType = 0;
3190  uint32 ammoDisplayID = 0;
3191 
3192  if (m_caster->GetTypeId() == TYPEID_PLAYER)
3193  {
3195  if (pItem)
3196  {
3197  ammoInventoryType = pItem->GetProto()->InventoryType;
3198  if (ammoInventoryType == INVTYPE_THROWN)
3199  ammoDisplayID = pItem->GetProto()->DisplayInfoID;
3200  else
3201  {
3203  if (ammoID)
3204  {
3205  ItemTemplate const* pProto = sObjectMgr.GetItemTemplate(ammoID);
3206  if (pProto)
3207  {
3208  ammoDisplayID = pProto->DisplayInfoID;
3209  ammoInventoryType = pProto->InventoryType;
3210  }
3211  }
3212  else if (m_caster->HasAura(46699)) // Requires No Ammo
3213  {
3214  ammoDisplayID = 5996; // normal arrow
3215  ammoInventoryType = INVTYPE_AMMO;
3216  }
3217  }
3218  }
3219  }
3220  else
3221  {
3222  for (uint8 i = 0; i < 3; ++i)
3223  {
3225  {
3226  if (ItemTemplate const* pProto = sObjectMgr.GetItemTemplate(item_id))
3227  {
3228  if (pProto->Class == ITEM_CLASS_WEAPON)
3229  {
3230  switch (pProto->SubClass)
3231  {
3233  ammoDisplayID = pProto->DisplayInfoID;
3234  ammoInventoryType = pProto->InventoryType;
3235  break;
3238  ammoDisplayID = 5996; // is this need fixing?
3239  ammoInventoryType = INVTYPE_AMMO;
3240  break;
3242  ammoDisplayID = 5998; // is this need fixing?
3243  ammoInventoryType = INVTYPE_AMMO;
3244  break;
3245  }
3246 
3247  if (ammoDisplayID)
3248  break;
3249  }
3250  }
3251  }
3252  }
3253  }
3254 
3255  *data << uint32(ammoDisplayID);
3256  *data << uint32(ammoInventoryType);
3257 }
3258 
3260 {
3261  *data << (uint8)m_countOfHit;
3262  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3263  {
3264  if (ihit->deleted)
3265  continue;
3266 
3267  if ((*ihit).missCondition == SPELL_MISS_NONE) // Add only hits
3268  *data << uint64(ihit->targetGUID);
3269  }
3270 
3271  for (std::list<GOTargetInfo>::iterator ighit = m_UniqueGOTargetInfo.begin(); ighit != m_UniqueGOTargetInfo.end(); ++ighit)
3272  {
3273  if (ighit->deleted)
3274  continue;
3275 
3276  *data << uint64(ighit->targetGUID); // Always hits
3277  }
3278 
3279  *data << (uint8)m_countOfMiss;
3280  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3281  {
3282  if (ihit->deleted)
3283  continue;
3284 
3285  if (ihit->missCondition != SPELL_MISS_NONE) // Add only miss
3286  {
3287  *data << uint64(ihit->targetGUID);
3288  *data << uint8(ihit->missCondition);
3289  if (ihit->missCondition == SPELL_MISS_REFLECT)
3290  *data << uint8(ihit->reflectResult);
3291  }
3292  }
3293 }
3294 
3296 {
3298 
3299  WorldPacket data(SMSG_SPELLLOGEXECUTE, (8 + 4 + 4 + 4 + 4 + 8));
3300 
3301  if (m_caster->GetTypeId() == TYPEID_PLAYER)
3302  data << m_caster->GetPackGUID();
3303  else
3304  data << target->GetPackGUID();
3305 
3306  data << uint32(m_spellInfo->Id);
3307  uint32 count1 = 1;
3308  data << uint32(count1); // count1 (effect count?)
3309  for (uint32 i = 0; i < count1; ++i)
3310  {
3311  data << uint32(m_spellInfo->Effect[0]); // spell effect
3312  uint32 count2 = 1;
3313  data << uint32(count2); // count2 (target count?)
3314  for (uint32 j = 0; j < count2; ++j)
3315  {
3316  switch (m_spellInfo->Effect[0])
3317  {
3319  if (Unit* unit = m_targets.getUnitTarget())
3320  data << unit->GetPackGUID();
3321  else
3322  data << uint8(0);
3323  data << uint32(0);
3324  data << uint32(0);
3325  data << float(0);
3326  break;
3328  if (Unit* unit = m_targets.getUnitTarget())
3329  data << unit->GetPackGUID();
3330  else
3331  data << uint8(0);
3332  data << uint32(m_caster->m_extraAttacks);
3333  break;
3335  if (Unit* unit = m_targets.getUnitTarget())
3336  data << unit->GetPackGUID();
3337  else
3338  data << uint8(0);
3339  data << uint32(0); // spellid
3340  break;
3342  if (Unit* unit = m_targets.getUnitTarget())
3343  data << unit->GetPackGUID();
3344  else
3345  data << uint8(0);
3346  data << uint32(0);
3347  data << uint32(0);
3348  break;
3351  if (Item* item = m_targets.getItemTarget())
3352  data << item->GetPackGUID();
3353  else
3354  data << uint8(0);
3355  break;
3357  data << uint32(m_spellInfo->EffectItemType[0]);
3358  break;
3359  case SPELL_EFFECT_SUMMON:
3364  case SPELL_EFFECT_DUEL:
3369  if (Unit* unit = m_targets.getUnitTarget())
3370  data << unit->GetPackGUID();
3371  else if (m_targets.getItemTargetGUID())
3373  else if (GameObject* go = m_targets.getGOTarget())
3374  data << go->GetPackGUID();
3375  else
3376  data << uint8(0); // guid
3377  break;
3378  case SPELL_EFFECT_FEED_PET:
3379  data << uint32(m_targets.getItemTargetEntry());
3380  break;
3382  if (Unit* unit = m_targets.getUnitTarget())
3383  data << unit->GetPackGUID();
3384  else
3385  data << uint8(0);
3386  break;
3387  default:
3388  return;
3389  }
3390  }
3391  }
3392 
3393  m_caster->SendMessageToSet(&data, true);
3394 }
3395 
3397 {
3398  WorldPacket data(SMSG_SPELL_FAILURE, (8 + 4 + 1));
3399  data << m_caster->GetPackGUID();
3400  data << m_spellInfo->Id;
3401  data << result;
3402  m_caster->SendMessageToSet(&data, true);
3403 
3404  data.Initialize(SMSG_SPELL_FAILED_OTHER, (8 + 4));
3405  data << m_caster->GetPackGUID();
3406  data << m_spellInfo->Id;
3407  m_caster->SendMessageToSet(&data, true);
3408 }
3409 
3411 {
3412  if (time == 0)
3413  {
3416  }
3417 
3418  WorldPacket data(MSG_CHANNEL_UPDATE, 8 + 4);
3419  data << m_caster->GetPackGUID();
3420  data << uint32(time);
3421 
3422  m_caster->SendMessageToSet(&data, true);
3423 }
3424 
3426 {
3427  uint64 channelTarget = 0;
3429  channelTarget = m_targets.getUnitTargetGUID();
3430  else if (m_targets.getGOTargetGUID())
3431  channelTarget = m_targets.getGOTargetGUID();
3432  else if (m_targets.getCorpseTargetGUID())
3433  channelTarget = m_targets.getCorpseTargetGUID();
3434 
3435 
3436  m_timer = duration;
3437  if (channelTarget)
3439 
3441 
3442  if (!m_isNeedSendToClient)
3443  return;
3444 
3445  WorldPacket data(MSG_CHANNEL_START, (8 + 4 + 4));
3446  data << m_caster->GetPackGUID();
3447  data << uint32(m_spellInfo->Id);
3448  data << uint32(duration);
3449  m_caster->SendMessageToSet(&data, true);
3450 }
3451 
3453 {
3454  WorldPacket data(SMSG_RESURRECT_REQUEST, (8 + 4 + 2 + 4));
3455  data << m_caster->GetGUID();
3456  data << uint32(1) << uint16(0) << uint32(1);
3457 
3458  target->GetSession()->SendPacket(&data);
3459 }
3460 
3462 {
3463  if (m_caster->GetTypeId() != TYPEID_PLAYER)
3464  return;
3465 
3467  data << uint64(m_caster->GetGUID());
3468  data << uint32(SpellID); // spell visual id?
3469  m_caster->ToPlayer()->GetSession()->SendPacket(&data);
3470 }
3471 
3473 {
3475  return;
3476 
3477  // not remove cast item at triggered spell (equipping, weapon damage, etc)
3478  if (m_IsTriggeredSpell)
3479  return;
3480 
3481  ItemTemplate const* proto = m_CastItem->GetProto();
3482 
3483  if (!proto)
3484  {
3485  // This code is to avoid a crash
3486  // I'm not sure, if this is really an error, but I guess every item needs a prototype
3487  sLog.outError("Cast item has no item prototype highId=%d, lowId=%d", m_CastItem->GetGUIDHigh(), m_CastItem->GetGUIDLow());
3488  return;
3489  }
3490 
3491  bool expendable = false;
3492  bool withoutCharges = false;
3493 
3494  for (int i = 0; i < 5; i++)
3495  {
3496  if (proto->Spells[i].SpellId)
3497  {
3498  // item has limited charges
3499  if (proto->Spells[i].SpellCharges)
3500  {
3501  if (proto->Spells[i].SpellCharges < 0)
3502  expendable = true;
3503 
3504  int32 charges = m_CastItem->GetSpellCharges(i);
3505 
3506  // item has charges left
3507  if (charges)
3508  {
3509  (charges > 0) ? --charges : ++charges; // abs(charges) less at 1 after use
3510  if (proto->Stackable < 2)
3511  m_CastItem->SetSpellCharges(i, charges);
3513  }
3514 
3515  // all charges used
3516  withoutCharges = (charges == 0);
3517  }
3518  }
3519  }
3520 
3521  if (expendable && withoutCharges)
3522  {
3523  uint32 count = 1;
3524  m_caster->ToPlayer()->DestroyItemCount(m_CastItem, count, true);
3525 
3526  // prevent crash at access to deleted m_targets.getItemTarget
3528  m_targets.setItemTarget(NULL);
3529 
3530  m_CastItem = NULL;
3531  }
3532 }
3533 
3535 {
3537  return;
3538 
3539  //Don't take power if the spell is cast while .cheat power is enabled.
3540  if (m_caster->GetTypeId() == TYPEID_PLAYER)
3541  {
3543  return;
3544  }
3545 
3546  bool hit = true;
3547  if (m_caster->GetTypeId() == TYPEID_PLAYER)
3548  {
3550  if (uint64 targetGUID = m_targets.getUnitTargetGUID())
3551  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3552  {
3553  if (ihit->deleted)
3554  continue;
3555 
3556  if (ihit->targetGUID == targetGUID)
3557  {
3558  if (ihit->missCondition != SPELL_MISS_NONE && ihit->missCondition != SPELL_MISS_MISS/* && ihit->targetGUID != m_caster->GetGUID()*/)
3559  hit = false;
3560  break;
3561  }
3562  }
3563  }
3564 
3565  if (!m_powerCost)
3566  return;
3567 
3568  // health as power used
3570  {
3572  return;
3573  }
3574 
3576  {
3577  sLog.outError("Spell::TakePower: Unknown power type '%d'", m_spellInfo->powerType);
3578  return;
3579  }
3580 
3581  Powers powerType = Powers(m_spellInfo->powerType);
3582 
3583  m_caster->ModifyPower(powerType, -m_powerCost);
3584 
3585  // Set the five second timer
3586  if (powerType == POWER_MANA && m_powerCost > 0)
3588 }
3589 
3591 {
3592  if (m_IsTriggeredSpell) // reagents used in triggered spell removed by original spell or don't must be removed.
3593  return;
3594 
3595  if (m_caster->GetTypeId() != TYPEID_PLAYER)
3596  return;
3597 
3598  ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetProto() : NULL;
3599 
3600  // do not take reagents for these item casts
3601  if (castItemTemplate && castItemTemplate->Flags & ITEM_PROTO_FLAG_TRIGGERED_CAST)
3602  return;
3603 
3604  Player* p_caster = m_caster->ToPlayer();
3605  if (p_caster->CanCastNoReagents(m_spellInfo))
3606  return;
3607 
3608  for (uint32 x = 0; x < 8; x++)
3609  {
3610  if (m_spellInfo->Reagent[x] <= 0)
3611  continue;
3612 
3613  uint32 itemid = m_spellInfo->Reagent[x];
3614  uint32 itemcount = m_spellInfo->ReagentCount[x];
3615 
3616  // if CastItem is also spell reagent
3617  if (m_CastItem)
3618  {
3619  ItemTemplate const* proto = m_CastItem->GetProto();
3620  if (proto && proto->ItemId == itemid)
3621  {
3622  for (int s = 0; s < 5; s++)
3623  {
3624  // CastItem will be used up and does not count as reagent
3625  int32 charges = m_CastItem->GetSpellCharges(s);
3626  if (proto->Spells[s].SpellCharges < 0 && abs(charges) < 2)
3627  {
3628  ++itemcount;
3629  break;
3630  }
3631  }
3632 
3633  m_CastItem = NULL;
3634  }
3635  }
3636 
3637  // if getItemTarget is also spell reagent
3638  if (m_targets.getItemTargetEntry() == itemid)
3639  m_targets.setItemTarget(NULL);
3640 
3641  p_caster->DestroyItemCount(itemid, itemcount, true);
3642  }
3643 }
3644 
3646 {
3647  if (m_UniqueTargetInfo.empty())
3648  return;
3649 
3652  return;
3653 
3654  float threat = 0.0f;
3655  if (SpellThreatEntry const* threatEntry = sSpellMgr.GetSpellThreatEntry(m_spellInfo->Id))
3656  {
3657  if (threatEntry->apPctMod != 0.0f)
3658  threat += threatEntry->apPctMod * m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
3659 
3660  threat += threatEntry->flatMod;
3661  }
3662  else
3663  threat += m_spellInfo->spellLevel;
3664 
3665  if (threat == 0.0f)
3666  return;
3667 
3668  // 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
3669  threat /= m_UniqueTargetInfo.size();
3670 
3671  for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
3672  {
3673  float threatToAdd = threat;
3674  if (ihit->missCondition != SPELL_MISS_NONE)
3675  threatToAdd = 0.0f;
3676 
3677  Unit* target = ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID);
3678  if (!target)
3679  continue;
3680 
3681  // positive spells distribute threat among all units that are in combat with target, like healing
3683  target->AddAssistThreat(m_caster, threatToAdd, m_spellInfo);
3684  // for negative spells threat gets distributed among affected targets
3685  else
3686  if (!target->IsFriendlyTo(m_caster))
3687  target->AddThreat(m_caster, threatToAdd, GetSpellSchoolMask(m_spellInfo), m_spellInfo);
3688  }
3689 
3690  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()));
3691 }
3692 
3693 void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, float /*DamageMultiplier*/)
3694 {
3695  unitTarget = pUnitTarget;
3696  itemTarget = pItemTarget;
3697  gameObjTarget = pGOTarget;
3698 
3699  uint8 eff = m_spellInfo->Effect[i];
3700 
3701  DEBUG_LOG("Spell: Effect : %u", eff);
3702 
3703  //we do not need DamageMultiplier here.
3704  damage = CalculateDamage(i, NULL);
3705 
3706  if (eff < TOTAL_SPELL_EFFECTS)
3707  {
3708  //sLog.outDebug("WORLD: Spell FX %d < TOTAL_SPELL_EFFECTS ", eff);
3709  (*this.*SpellEffects[eff])((SpellEffIndex)i);
3710  }
3711  /*
3712  else
3713  {
3714  sLog.outDebug("WORLD: Spell FX %d > TOTAL_SPELL_EFFECTS ", eff);
3715  if (m_CastItem)
3716  EffectEnchantItemTmp(i);
3717  else
3718  {
3719  sLog.outError("SPELL: unknown effect %u spell id %u\n",
3720  eff, m_spellInfo->Id);
3721  }
3722  }
3723  */
3724 }
3725 
3727 {
3728  for (TriggerSpells::iterator si = m_TriggerSpells.begin(); si != m_TriggerSpells.end(); ++si)
3729  {
3730  Spell* spell = new Spell(m_caster, (*si), true, m_originalCasterGUID, m_selfContainer, true);
3731  spell->prepare(&m_targets); // use original spell original targets
3732  }
3733 }
3734 
3736 {
3737  // check death state
3739  return SPELL_FAILED_CASTER_DEAD;
3740 
3741  // check cooldowns to prevent cheating
3742  if (!m_IsTriggeredSpell)
3743  if (Player* plr = m_caster->ToPlayer())
3744  if (plr->HasSpellCooldown(m_spellInfo->Id) || (strict && plr->HasGlobalCooldown(m_spellInfo)))
3745  return SPELL_FAILED_NOT_READY;
3746 
3747  // only triggered spells can be processed an ended battleground
3750  if (bg->GetStatus() == STATUS_WAIT_LEAVE)
3751  return SPELL_FAILED_DONT_REPORT;
3752 
3754  {
3758 
3762  }
3763 
3764  // only check at first call, Stealth auras are already removed at second call
3765  // for now, ignore triggered spells
3766  if (strict && !m_IsTriggeredSpell)
3767  {
3768  // Cannot be used in this stance/form
3770  if (shapeError != SPELL_CAST_OK)
3771  return shapeError;
3772 
3775  }
3776 
3777  // caster state requirements
3782 
3783  // cancel autorepeat spells if cast start when moving
3784  // (not wand currently autorepeat cast delayed to moving stop anyway in spell update code)
3786  {
3787  // skip stuck spell to allow use it in falling case and apply spell limitations at movement
3790  return SPELL_FAILED_MOVING;
3791  }
3792 
3793  // check spell cast conditions from database
3794  {
3796  condInfo.mConditionTargets[1] = m_targets.getUnitTarget();
3797  ConditionList conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL, m_spellInfo->Id);
3798  if (!conditions.empty() && !sConditionMgr.IsObjectMeetToConditions(condInfo, conditions))
3799  {
3800  // mLastFailedCondition can be NULL if there was an error processing the condition in Condition::Meets (i.e. wrong data for ConditionTarget or others)
3801  if (condInfo.mLastFailedCondition && condInfo.mLastFailedCondition->ErrorType)
3803 
3804  if (!condInfo.mLastFailedCondition || !condInfo.mLastFailedCondition->ConditionTarget)
3806 
3807  return SPELL_FAILED_BAD_TARGETS;
3808  }
3809  }
3810 
3813 
3814  Unit* target = m_targets.getUnitTarget();
3815 
3816  if (target)
3817  {
3818  // target state requirements (not allowed state), apply to self also
3821 
3824 
3825  // @todo Find a way to check for form instead of checking byte flag, probably no problem either way
3826  // Not allow casting on Spirit of Redemption form, includes the priest IN redemption form, except for triggered spells
3828  return SPELL_FAILED_BAD_TARGETS;
3829 
3830  if (target != m_caster)
3831  {
3832  // target state requirements (apply to non-self only), to allow cast affects to self like Dirty Deeds
3835 
3836  // Not allow casting on flying player
3837  if (target->IsInFlight())
3838  return SPELL_FAILED_BAD_TARGETS;
3839 
3840  // Must be behind the target.
3841  if (m_spellInfo->AttributesEx2 == 0x100000 && (m_spellInfo->AttributesEx & 0x200) == 0x200 && target->HasInArc(static_cast<float>(M_PI), m_caster)
3842  && (m_spellInfo->SpellFamilyName != SPELLFAMILY_DRUID || m_spellInfo->SpellFamilyFlags != 0x0000000000020000LL))
3843  return SPELL_FAILED_NOT_BEHIND;
3844 
3845  // Target must be facing you.
3846  if ((m_spellInfo->Attributes == 0x150010) && !target->HasInArc(static_cast<float>(M_PI), m_caster))
3847  return SPELL_FAILED_NOT_INFRONT;
3848 
3849  // Do not allow these spells to target creatures not tapped by us (Banish, Polymorph, many quest spells)
3851  if (Creature const* targetCreature = target->ToCreature())
3852  if (targetCreature->hasLootRecipient() && !targetCreature->isTappedBy(m_caster->ToPlayer()))
3854 
3856  return SPELL_FAILED_BAD_TARGETS;
3857 
3858  bool isTrigger = (target->ToCreature() && target->ToCreature()->IsTrigger());
3859  if (!isTrigger)
3860  {
3861  WorldObject* losTarget = target;
3864  losTarget = dynObj;
3865 
3868  }
3869 
3870  // auto selection spell rank implemented in WorldSession::HandleCastSpellOpcode
3871  // this case can be triggered if rank not found (too low-level target for first rank)
3873  {
3874  for (int i = 0; i < 3; i++)
3875  {
3877  if (target->getLevel() + 10 < m_spellInfo->spellLevel)
3878  return SPELL_FAILED_LOWLEVEL;
3879  }
3880  }
3881  }
3882 
3883  // check pet presence
3884  for (int j = 0; j < MAX_SPELL_EFFECTS; ++j)
3885  {
3887  {
3888  target = m_caster->GetGuardianPet();
3889  if (!target)
3890  {
3891  if (m_triggeredByAuraSpell) // not report pet not existence for triggered spells
3892  return SPELL_FAILED_DONT_REPORT;
3893  else
3894  return SPELL_FAILED_NO_PET;
3895  }
3896  else if (!target->IsAlive())
3898  break;
3899  }
3900  }
3901 
3902  //check creature type
3903  //ignore self casts (including area casts when caster selected as target)
3904  if (target != m_caster)
3905  {
3906  if (!CheckTargetCreatureType(target))
3907  {
3908  if (target->GetTypeId() == TYPEID_PLAYER)
3910  else
3911  return SPELL_FAILED_BAD_TARGETS;
3912  }
3913  }
3914 
3915  // @todo this check can be applied and for player to prevent cheating when IsPositiveSpell will return always correct result.
3916  // check target for pet/charmed casts (not self targeted), self targeted cast used for area effects and etc
3918  {
3919  // check correctness positive/negative cast target (pet cast real check and cheating check)
3921  {
3922  //dispel positivity is dependant on target, don't check it
3923  if (m_caster->IsHostileTo(target) && !IsDispel(m_spellInfo))
3924  return SPELL_FAILED_BAD_TARGETS;
3925  }
3926  else
3927  {
3928  if (m_caster->IsFriendlyTo(target))
3929  return SPELL_FAILED_BAD_TARGETS;
3930  }
3931  }
3932 
3933  // spells cannot be cast if player is in fake combat also
3936  }
3937 
3938  // Spell casted only in battleground
3940  if (!m_caster->ToPlayer()->InBattleground())
3942 
3943  // do not allow spells to be cast in arenas
3944  // - with greater than 15 min CD without SPELL_ATTR4_USABLE_IN_ARENA flag
3945  // - with SPELL_ATTR4_NOT_USABLE_IN_ARENA flag
3948  if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId()))
3949  if (mapEntry->IsBattleArena())
3951 
3952  // zone check
3953  if (m_caster->GetTypeId() == TYPEID_PLAYER)
3954  {
3956  if (locRes != SPELL_CAST_OK)
3957  return locRes;
3958  }
3959 
3960  // not let players cast spells at mount (and let do it to creatures)
3963  {
3964  if (m_caster->IsInFlight())
3965  return SPELL_FAILED_NOT_FLYING;
3966  else
3967  return SPELL_FAILED_NOT_MOUNTED;
3968  }
3969 
3972 
3973  SpellCastResult castResult = SPELL_CAST_OK;
3974 
3975  // always (except passive spells) check items (focus object can be required for any type casts)
3976  if (!IsPassiveSpell(m_spellInfo->Id))
3977  {
3978  castResult = CheckItems();
3979  if (castResult != SPELL_CAST_OK)
3980  return castResult;
3981  }
3982 
3983  if (!m_IsTriggeredSpell)
3984  {
3986  {
3987  castResult = CheckRange(strict);
3988  if (castResult != SPELL_CAST_OK)
3989  return castResult;
3990  }
3991  }
3992 
3993  // ImpliciteTargetA-B = 38, If fact there is 0 Spell with ImpliciteTargetB=38
3994  if (m_UniqueTargetInfo.empty()) // skip second canCast apply (for delayed spells for example)
3995  {
3996  for (uint8 j = 0; j < MAX_SPELL_EFFECTS; j++)
3997  {
4002  {
4003  ConditionList conditions = sConditionMgr.GetConditionsForNotGroupedEntry(CONDITION_SOURCE_TYPE_SPELL_SCRIPT_TARGET, m_spellInfo->Id);
4004  if (conditions.empty())
4005  sLog.outErrorDb("Spell (ID: %u) has effect EffectImplicitTargetA/EffectImplicitTargetB = TARGET_UNIT_NEARBY_ENTRY or TARGET_DST_NEARBY_ENTRY, but does not have record in conditions.", m_spellInfo->Id);
4006 
4007  SpellRangeEntry const* srange = sSpellRangeStore.LookupEntry(m_spellInfo->rangeIndex);
4008  float range = GetSpellMaxRange(srange);
4009 
4010  Creature* creatureScriptTarget = NULL;
4011  GameObject* goScriptTarget = NULL;
4012 
4013  for (ConditionList::const_iterator i_spellST = conditions.begin(); i_spellST != conditions.end(); ++i_spellST)
4014  {
4015  if ((*i_spellST)->Type != CONDITION_SPELL_SCRIPT_TARGET)
4016  continue;
4017  switch((*i_spellST)->ConditionValue1)
4018  {
4020  {
4021  GameObject* p_GameObject = NULL;
4022 
4023  if ((*i_spellST)->ConditionValue2)
4024  {
4026  Cell cell(p);
4027 
4028  Oregon::NearestGameObjectEntryInObjectRangeCheck go_check(*m_caster, (*i_spellST)->ConditionValue2, range);
4030 
4032  cell.Visit(p, object_checker, *m_caster->GetMap(), *m_caster, range);
4033 
4034  if (p_GameObject)
4035  {
4036  // remember found target and range, next attempt will find more near target with another entry
4037  creatureScriptTarget = NULL;
4038  goScriptTarget = p_GameObject;
4039  range = go_check.GetLastRange();
4040  }
4041  }
4042  else if (focusObject) //Focus Object
4043  {
4044  float frange = m_caster->GetDistance(focusObject);
4045  if (range >= frange)
4046  {
4047  creatureScriptTarget = NULL;
4048  goScriptTarget = focusObject;
4049  range = frange;
4050  }
4051  }
4052  break;
4053  }
4056  default:
4057  {
4058  Creature* p_Creature = NULL;
4059 
4061  Cell cell(p);
4062  cell.SetNoCreate(); // Really don't know what is that???
4063 
4064  Oregon::NearestCreatureEntryWithLiveStateInObjectRangeCheck u_check(*m_caster, (*i_spellST)->ConditionValue2, (*i_spellST)->ConditionValue1 != SPELL_TARGET_TYPE_DEAD, range);
4066 
4068 
4069  cell.Visit(p, grid_creature_searcher, *m_caster->GetMap(), *m_caster, range);
4070 
4071  if (p_Creature)
4072  {
4073  creatureScriptTarget = p_Creature;
4074  goScriptTarget = NULL;
4075  range = u_check.GetLastRange();
4076  }
4077  break;
4078  }
4079  }
4080  }
4081 
4082  if (creatureScriptTarget)
4083  {
4084  // store coordinates for TARGET_DST_NEARBY_ENTRY
4087  {
4088  m_targets.setDst(creatureScriptTarget->GetPositionX(), creatureScriptTarget->GetPositionY(), creatureScriptTarget->GetPositionZ(), creatureScriptTarget->GetOrientation());
4089 
4091  AddUnitTarget(creatureScriptTarget, j);
4092  }
4093  // store explicit target for TARGET_UNIT_NEARBY_ENTRY
4094  else
4095  AddUnitTarget(creatureScriptTarget, j);
4096  }
4097  else if (goScriptTarget)
4098  {
4099  // store coordinates for TARGET_DST_NEARBY_ENTRY
4102  {
4103  m_targets.setDst(goScriptTarget->GetPositionX(), goScriptTarget->GetPositionY(), goScriptTarget->GetPositionZ(), goScriptTarget->GetOrientation());
4104 
4106  AddGOTarget(goScriptTarget, j);
4107  }
4108  // store explicit target for TARGET_UNIT_NEARBY_ENTRY
4109  else
4110  AddGOTarget(goScriptTarget, j);
4111  }
4112  //Missing DB Entry or targets for this spellEffect.
4113  else
4114  {
4115  // not report target not existence for triggered spells
4117  return SPELL_FAILED_DONT_REPORT;
4118  else
4119  return SPELL_FAILED_BAD_TARGETS;
4120  }
4121  }
4122  }
4123  }
4124 
4125  if (!m_IsTriggeredSpell)
4126  {
4127  SpellCastResult castResult;
4128 
4129  castResult = CheckRange(strict);
4130  if (castResult != SPELL_CAST_OK)
4131  return castResult;
4132 
4133  castResult = CheckPower();
4134  if (castResult != SPELL_CAST_OK)
4135  return castResult;
4136 
4137  castResult = CheckCasterAuras();
4138  if (castResult != SPELL_CAST_OK)
4139  return castResult;
4140  }
4141 
4142  // check for effect-specific restrictions
4143  for (uint32 i = 0; i < MAX_SPELL_EFFECTS; i++)
4144  {
4145  // for effects of spells that have only one target
4146  switch (m_spellInfo->Effect[i])
4147  {
4148  case SPELL_EFFECT_DUMMY:
4149  {
4150  if (SpellCastResult result = CheckDummyCast(i))
4151  if (result != SPELL_CAST_OK)
4152  return result;
4153  break;
4154  }
4156  {
4157  // Hammer of Wrath
4158  if (m_spellInfo->SpellVisual == 7250)
4159  {
4160  if (!m_targets.getUnitTarget())
4162 
4164  return SPELL_FAILED_BAD_TARGETS;
4165  }
4166  break;
4167  }
4169  {
4170  // report single-target "buff degrading" (dont report for triggered spells)
4171  // also works only for positive spells and the buffed is always able to degrade
4172  // his own buffs
4173  if (strict && target != m_caster && target)
4176  if (sSpellMgr.IsNoStackSpellDueToSpell(m_spellInfo->Id, m_spellInfo->Id, false))
4177  if (target->HasHigherRankOfAura(m_spellInfo->Id, i))
4179 
4180  switch(m_spellInfo->EffectApplyAuraName[i])
4181  {
4182  case SPELL_AURA_BIND_SIGHT:
4183  {
4184  // Cannot bind sight across instances/continents.
4185  // Does not affect the same instance/continent, no matter the range.
4186  if(target == m_caster)
4187  return SPELL_FAILED_BAD_TARGETS;
4188  break;
4189  }
4190  }
4191  break;
4192  }
4194  {
4195  if (m_caster->GetTypeId() != TYPEID_PLAYER)
4196  return SPELL_FAILED_BAD_TARGETS;
4197 
4199  break;
4200 
4201  Pet* pet = m_caster->ToPlayer()->GetPet();
4202 
4203  if (!pet)
4204  return SPELL_FAILED_NO_PET;
4205 
4206  SpellEntry const* learn_spellproto = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[i]);
4207 
4208  if (!learn_spellproto)
4209  return SPELL_FAILED_NOT_KNOWN;
4210 
4211  if (!pet->CanTakeMoreActiveSpells(learn_spellproto->Id))
4213 
4214  if (m_spellInfo->spellLevel > pet->getLevel())
4215  return SPELL_FAILED_LOWLEVEL;
4216 
4217  if (!pet->HasTPForSpell(learn_spellproto->Id))
4219 
4220  break;
4221  }
4222  case SPELL_EFFECT_TRIGGER_SPELL_2: // Only Ritual of Summoning
4223  {
4226  break;
4227  }
4229  {
4230  if (m_caster->GetTypeId() != TYPEID_PLAYER)
4231  return SPELL_FAILED_BAD_TARGETS;
4232 
4233  Pet* pet = m_caster->ToPlayer()->GetPet();
4234  if (!pet)
4235  return SPELL_FAILED_NO_PET;
4236 
4237  SpellEntry const* learn_spellproto = sSpellStore.LookupEntry(m_spellInfo->EffectTriggerSpell[i]);
4238 
4239  if (!learn_spellproto)
4240  return SPELL_FAILED_NOT_KNOWN;
4241 
4242  if (!pet->CanTakeMoreActiveSpells(learn_spellproto->Id))
4244 
4245  if (m_spellInfo->spellLevel > pet->getLevel())
4246  return SPELL_FAILED_LOWLEVEL;
4247 
4248  if (!pet->HasTPForSpell(learn_spellproto->Id))
4250 
4251  break;
4252  }
4253  case SPELL_EFFECT_FEED_PET:
4254  {
4256  return SPELL_FAILED_BAD_TARGETS;
4257 
4258  Pet* pet = m_caster->ToPlayer()->GetPet();
4259 
4260  if (!pet)
4261  return SPELL_FAILED_NO_PET;
4262 
4263  if (!pet->HaveInDiet(m_targets.getItemTarget()->GetProto()))
4265 
4268 
4269  if (m_caster->IsInCombat() || pet->IsInCombat())
4271 
4272  break;
4273  }
4276  {
4277  // Can be area effect, Check only for players and not check if target - caster (spell can have multiply drain/burn effects)
4278  if (m_caster->GetTypeId() == TYPEID_PLAYER)
4279  if (Unit* target = m_targets.getUnitTarget())
4280  if (target != m_caster)
4281  {
4282  // Targets have power type mana even if they're not mana
4283  // users, so if it's mana we need to check max is >= 1
4284  bool hasPower = int32(target->getPowerType()) == m_spellInfo->EffectMiscValue[i];
4285 
4286  if (!hasPower ||
4287  (target->getPowerType() == POWER_MANA &&
4288  target->GetMaxPower(POWER_MANA) == 0))
4289  return SPELL_FAILED_BAD_TARGETS;
4290  }
4291  break;
4292  }
4293  case SPELL_EFFECT_CHARGE:
4294  {
4295  if (Unit* target = m_targets.getUnitTarget())
4296  if (!target->IsAlive())
4297  return SPELL_FAILED_BAD_TARGETS;
4298 
4300  return SPELL_FAILED_ROOTED;
4301 
4302  break;
4303  }
4304  case SPELL_EFFECT_SKINNING:
4305  {
4307  return SPELL_FAILED_BAD_TARGETS;
4308 
4311 
4312  Creature* creature = m_targets.getUnitTarget()->ToCreature();
4313  if (!creature->IsCritter() && !creature->loot.isLooted())
4315 
4316  uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
4317 
4318  int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
4319  int32 TargetLevel = m_targets.getUnitTarget()->getLevel();
4320  int32 ReqValue = (skillValue < 100 ? (TargetLevel - 10) * 10 : TargetLevel * 5);
4321  if (ReqValue > skillValue)
4323 
4324  // chance for fail at orange skinning attempt
4325  if ((m_selfContainer && (*m_selfContainer) == this) &&
4326  skillValue < sWorld.GetConfigMaxSkillValue() &&
4327  (ReqValue < 0 ? 0 : ReqValue) > irand(skillValue - 25, skillValue + 37))
4328  return SPELL_FAILED_TRY_AGAIN;
4329 
4330  break;
4331  }
4334  {
4337  break;
4338 
4339  // we need a go target in case of TARGET_GAMEOBJECT
4341  return SPELL_FAILED_BAD_TARGETS;
4342 
4343  Item* pTempItem = nullptr;
4346 
4347  // we need a go target, or an openable item target in case of TARGET_GAMEOBJECT_ITEM_TARGET
4349  !m_targets.getGOTarget() &&
4350  (!pTempItem || !pTempItem->GetProto()->LockID || !pTempItem->IsLocked()))
4351  return SPELL_FAILED_BAD_TARGETS;
4352 
4353  if (m_spellInfo->Id != 1842 || (m_targets.getGOTarget() &&
4355  if (m_caster->ToPlayer()->InBattleground() && // In Battleground players can use only flags and banners
4357  return SPELL_FAILED_TRY_AGAIN;
4358 
4359  // get the lock entry
4360  uint32 lockId = 0;
4361  if (GameObject* go = m_targets.getGOTarget())
4362  {
4363  lockId = go->GetGOInfo()->GetLockId();
4364  if (!lockId)
4365  return SPELL_FAILED_BAD_TARGETS;
4366  }
4367  else if (Item* itm = m_targets.getItemTarget())
4368  lockId = itm->GetProto()->LockID;
4369 
4370  SkillType skillId = SKILL_NONE;
4371  int32 reqSkillValue = 0;
4372  int32 skillValue = 0;
4373 
4374  // check lock compatibility
4375  SpellCastResult res = CanOpenLock(i, lockId, skillId, reqSkillValue, skillValue);
4376  if (res != SPELL_CAST_OK)
4377  return res;
4378 
4379  // chance for fail at lockpicking attempt
4380  // second check prevent fail at rechecks
4381  if (skillId != SKILL_NONE && (!m_selfContainer || ((*m_selfContainer) != this)))
4382  {
4383  bool canFailAtMax = skillId == SKILL_LOCKPICKING;
4384 
4385  // chance for failure in orange lockpick
4386  if ((canFailAtMax || skillValue < sWorld.GetConfigMaxSkillValue()) && reqSkillValue > irand(skillValue - 25, skillValue + 37))
4387  return SPELL_FAILED_TRY_AGAIN;
4388  }
4389  break;
4390  }
4391  // Bring the pet back to the land of the living
4393  {
4394  Creature* pet = m_caster->GetGuardianPet();
4395  if (pet && pet->IsAlive())
4397 
4398  // Do not revive dismissed pets, they are not dead
4401 
4402  // Attempting to revive a non existing pet?
4403  if (m_caster->IsPlayer() && !m_caster->ToPlayer()->doesOwnPet())
4404  return SPELL_FAILED_NO_PET;
4405 
4406  break;
4407  }
4408  // Called when we start channeling 'Dismiss pet' spell
4410  {
4411  // Don't start dismissing the pet if it's dead!
4412  Pet* pet = m_caster->ToPlayer()->GetPet();
4413  if (!pet || !pet->IsAlive())
4415 
4416  break;
4417  }
4418  // This is generic summon effect
4419  case SPELL_EFFECT_SUMMON:
4420  {
4421  SummonPropertiesEntry const* SummonProperties = sSummonPropertiesStore.LookupEntry(m_spellInfo->EffectMiscValueB[i]);
4422  if (!SummonProperties)
4423  break;
4424  switch (SummonProperties->Category)
4425  {
4426  case SUMMON_CATEGORY_PET:
4429  // intentional missing break, check both GetPetGUID() and GetCharmGUID for SUMMON_CATEGORY_PET
4431  if (m_caster->GetCharmGUID())
4433  break;
4434  }
4435  break;
4436  }
4438  {
4439  // Check these things only for player hunters
4441  {
4442  // Player should not be able to call the pet if he doesn't own one...
4443  if (!m_caster->ToPlayer()->doesOwnPet())
4444  return SPELL_FAILED_NO_PET;
4445 
4446  // ... or the pet is dead ...
4449  }
4450  if (m_caster->GetPetGUID()) // let warlock do a replacement summon
4451  {
4452  if (m_caster->IsPlayer())
4453  {
4454  if (strict) // starting cast, trigger pet stun (cast by pet so it doesn't attack player)
4455  if (Pet* pet = m_caster->ToPlayer()->GetPet())
4456  pet->CastSpell(pet, 32752, true, NULL, NULL, pet->GetGUID());
4457  }
4460  }
4461 
4462  if (m_caster->GetCharmGUID())
4464 
4465  break;
4466  }
4468  {
4469  if (m_caster->GetTypeId() != TYPEID_PLAYER)
4470  return SPELL_FAILED_BAD_TARGETS;
4471  if (!m_caster->ToPlayer()->GetSelection())
4472  return SPELL_FAILED_BAD_TARGETS;
4473 
4474  Player* target = sObjectMgr.GetPlayer(m_caster->ToPlayer()->GetSelection());
4475  if (!target || m_caster->ToPlayer() == target || !target->IsInSameRaidWith(m_caster->ToPlayer()))
4476  return SPELL_FAILED_BAD_TARGETS;
4477 
4478  // check if our map is dungeon
4479  MapEntry const* map = sMapStore.LookupEntry(m_caster->GetMapId());
4480 
4481  if (map->IsDungeon())
4482  {
4483  uint32 mapId = m_caster->GetMap()->GetId();
4484  DungeonDifficulty difficulty = m_caster->GetMap()->GetDifficulty();
4485