OregonCore  revision be9e804-git
Your Favourite TBC server
SpellMgr.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 "Unit.h"
19 #include "SpellMgr.h"
20 #include "ObjectMgr.h"
21 #include "SpellAuraDefines.h"
22 #include "DBCStores.h"
23 #include "Chat.h"
24 #include "Spell.h"
25 #include "CreatureAI.h"
26 #include "BattlegroundMgr.h"
27 
29 
31 {
32  for (int i = 0; i < TOTAL_SPELL_EFFECTS; ++i)
33  {
34  switch (i)
35  {
37  case SPELL_EFFECT_SUMMON: //28
39  case SPELL_EFFECT_TRANS_DOOR: //50 summon object
40  case SPELL_EFFECT_SUMMON_PET: //56
41  case SPELL_EFFECT_ADD_FARSIGHT: //72
48  case SPELL_EFFECT_TRIGGER_SPELL_2: //151 ritual of summon
50  break;
51  case SPELL_EFFECT_PARRY: // 0
52  case SPELL_EFFECT_BLOCK: // 0
53  case SPELL_EFFECT_SKILL: // always with dummy 3 as A
54  //case SPELL_EFFECT_LEARN_SPELL: // 0 may be 5 pet
55  case SPELL_EFFECT_TRADE_SKILL: // 0 or 1
56  case SPELL_EFFECT_PROFICIENCY: // 0
58  break;
65  break;
66  //caster must be pushed otherwise no sound
73  break;
74  default:
76  break;
77  }
78  }
79 
80  for (int i = 0; i < TOTAL_SPELL_TARGETS; ++i)
81  {
82  switch (i)
83  {
84  case TARGET_UNIT_CASTER:
86  case TARGET_UNIT_MASTER:
87  case TARGET_UNIT_PET:
91  break;
102  break;
109  break;
116  break;
123  break;
129  break;
130  case TARGET_DST_CASTER:
131  case TARGET_SRC_CASTER:
132  case TARGET_MINION:
145  break;
159  break;
163  case TARGET_DEST_DEST:
164  case TARGET_DEST_TRAJ:
175  break;
176  case TARGET_DST_DB:
177  case TARGET_DST_HOME:
180  break;
181  case TARGET_UNIT_CHANNEL:
182  case TARGET_DEST_CHANNEL:
184  break;
185  default:
187  }
188  }
189 
190  for (int i = 0; i < TOTAL_SPELL_TARGETS; ++i)
191  {
192  switch (i)
193  {
208  IsAreaEffectTarget[i] = true;
209  break;
210  default:
211  IsAreaEffectTarget[i] = false;
212  break;
213  }
214  }
215 }
216 
218 {
220 }
221 
223 {
224  static SpellMgr spellMgr;
225  return spellMgr;
226 }
227 
229 {
230  if (!spellInfo)
231  return 0;
232  SpellDurationEntry const* du = sSpellDurationStore.LookupEntry(spellInfo->DurationIndex);
233  if (!du)
234  return 0;
235  return (du->Duration[0] == -1) ? -1 : abs(du->Duration[0]);
236 }
237 
239 {
240  if (!spellInfo)
241  return 0;
242  SpellDurationEntry const* du = sSpellDurationStore.LookupEntry(spellInfo->DurationIndex);
243  if (!du)
244  return 0;
245  return (du->Duration[2] == -1) ? -1 : abs(du->Duration[2]);
246 }
247 
248 uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell const* spell)
249 {
250  SpellCastTimesEntry const* spellCastTimeEntry = sSpellCastTimesStore.LookupEntry(spellInfo->CastingTimeIndex);
251 
252  // not all spells have cast time index and this is all is pasiive abilities
253  if (!spellCastTimeEntry)
254  return 0;
255 
256  int32 castTime = spellCastTimeEntry->CastTime;
257 
258  if (spell)
259  {
260  if (Player* modOwner = spell->GetCaster()->GetSpellModOwner())
261  modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CASTING_TIME, castTime, spell);
262 
263  if (!(spellInfo->Attributes & (SPELL_ATTR0_ABILITY | SPELL_ATTR0_TRADESPELL)))
264  castTime = int32(castTime * spell->GetCaster()->GetFloatValue(UNIT_MOD_CAST_SPEED));
265  else
266  {
267  if (spell->IsRangedSpell() && !spell->IsAutoRepeat())
268  castTime = int32(castTime * spell->GetCaster()->m_modAttackSpeedPct[RANGED_ATTACK]);
269  }
270  }
271 
272  if (spellInfo->Attributes & SPELL_ATTR0_RANGED && (!spell || !spell->IsAutoRepeat()))
273  castTime += 500;
274 
275  return (castTime > 0) ? uint32(castTime) : 0;
276 }
277 
278 bool IsPassiveSpell(uint32 spellId)
279 {
280  SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
281  if (!spellInfo)
282  return false;
283  return IsPassiveSpell(spellInfo);
284 }
285 
286 bool IsPassiveSpell(SpellEntry const* spellInfo)
287 {
288  return (spellInfo->Attributes & SPELL_ATTR0_PASSIVE) != 0;
289 }
290 
292 {
293  SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
294  if (!spellInfo)
295  return false;
296  if (spellInfo->Attributes & SPELL_ATTR0_PASSIVE)
297  return false;
299  return false;
300  return true;
301 }
302 
303 uint32 CalculatePowerCost(SpellEntry const* spellInfo, Unit const* caster, SpellSchoolMask schoolMask)
304 {
305  // Spell drain all exist power on cast (Only paladin lay of Hands)
306  if (spellInfo->AttributesEx & SPELL_ATTR1_DRAIN_ALL_POWER)
307  {
308  // If power type - health drain all
309  if (spellInfo->powerType == POWER_HEALTH)
310  return caster->GetHealth();
311  // Else drain all power
312  if (spellInfo->powerType < MAX_POWERS)
313  return caster->GetPower(Powers(spellInfo->powerType));
314  sLog.outError("CalculateManaCost: Unknown power type '%d' in spell %d", spellInfo->powerType, spellInfo->Id);
315  return 0;
316  }
317 
318  // Base powerCost
319  int32 powerCost = spellInfo->manaCost;
320  // PCT cost from total amount
321  if (spellInfo->ManaCostPercentage)
322  {
323  switch (spellInfo->powerType)
324  {
325  // health as power used
326  case POWER_HEALTH:
327  powerCost += spellInfo->ManaCostPercentage * caster->GetCreateHealth() / 100;
328  break;
329  case POWER_MANA:
330  powerCost += spellInfo->ManaCostPercentage * caster->GetCreateMana() / 100;
331  break;
332  case POWER_RAGE:
333  case POWER_FOCUS:
334  case POWER_ENERGY:
335  case POWER_HAPPINESS:
336  powerCost += spellInfo->ManaCostPercentage * caster->GetMaxPower(Powers(spellInfo->powerType)) / 100;
337  break;
338  default:
339  sLog.outError("CalculateManaCost: Unknown power type '%d' in spell %d", spellInfo->powerType, spellInfo->Id);
340  return 0;
341  }
342  }
343  SpellSchools school = GetFirstSchoolInMask(schoolMask);
344  // Flat mod from caster auras by spell school
345  powerCost += caster->GetInt32Value(UNIT_FIELD_POWER_COST_MODIFIER + school);
346  // Shiv - costs 20 + weaponSpeed*10 energy (apply only to non-triggered spell with energy cost)
348  powerCost += caster->GetAttackTime(OFF_ATTACK) / 100;
349  // Apply cost mod by spell
350  if (Player* modOwner = caster->GetSpellModOwner())
351  modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COST, powerCost);
352 
354  {
355  GtNPCManaCostScalerEntry const* spellScaler = sGtNPCManaCostScalerStore.LookupEntry(spellInfo->spellLevel - 1);
356  GtNPCManaCostScalerEntry const* casterScaler = sGtNPCManaCostScalerStore.LookupEntry(caster->getLevel() - 1);
357  if (spellScaler && casterScaler)
358  powerCost *= casterScaler->ratio / spellScaler->ratio;
359  }
360 
361  // PCT mod from user auras by school
362  powerCost = int32(powerCost * (1.0f + caster->GetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER + school)));
363  if (powerCost < 0)
364  powerCost = 0;
365  return powerCost;
366 }
367 
368 /*bool IsNoStackAuraDueToAura(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2)
369 {
370  SpellEntry const *spellInfo_1 = sSpellStore.LookupEntry(spellId_1);
371  SpellEntry const *spellInfo_2 = sSpellStore.LookupEntry(spellId_2);
372  if (!spellInfo_1 || !spellInfo_2) return false;
373  if (spellInfo_1->Id == spellId_2) return false;
374 
375  if (spellInfo_1->Effect[effIndex_1] != spellInfo_2->Effect[effIndex_2] ||
376  spellInfo_1->EffectItemType[effIndex_1] != spellInfo_2->EffectItemType[effIndex_2] ||
377  spellInfo_1->EffectMiscValue[effIndex_1] != spellInfo_2->EffectMiscValue[effIndex_2] ||
378  spellInfo_1->EffectApplyAuraName[effIndex_1] != spellInfo_2->EffectApplyAuraName[effIndex_2])
379  return false;
380 
381  return true;
382 }*/
383 
384 int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2)
385 {
386  SpellEntry const* spellInfo_1 = sSpellStore.LookupEntry(spellId_1);
387  SpellEntry const* spellInfo_2 = sSpellStore.LookupEntry(spellId_2);
388  if (!spellInfo_1 || !spellInfo_2) return 0;
389  if (spellId_1 == spellId_2) return 0;
390 
391  int32 diff = spellInfo_1->EffectBasePoints[effIndex_1] - spellInfo_2->EffectBasePoints[effIndex_2];
392  if (spellInfo_1->EffectBasePoints[effIndex_1] + 1 < 0 && spellInfo_2->EffectBasePoints[effIndex_2] + 1 < 0) return -diff;
393  else return diff;
394 }
395 
397 {
398  SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
399  if (!spellInfo)
400  return SPELL_SPECIFIC_NORMAL;
401 
402  switch (spellInfo->SpellFamilyName)
403  {
404  case SPELLFAMILY_GENERIC:
405  {
406  // Food / Drinks (mostly)
408  {
409  for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
410  {
411  if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_POWER_REGEN)
412  return SPELL_SPECIFIC_DRINK;
413 
414  if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_REGEN ||
416  return SPELL_SPECIFIC_FOOD;
417  }
418  }
419 
420  switch (spellInfo->Id)
421  {
422  case 12880: // warrior's Enrage rank 1
423  case 14201: // Enrage rank 2
424  case 14202: // Enrage rank 3
425  case 14203: // Enrage rank 4
426  case 14204: // Enrage rank 5
427  case 12292: // Death Wish
429  break;
430  default:
431  break;
432  }
433  break;
434  }
435  case SPELLFAMILY_MAGE:
436  {
437  // family flags 18(Molten), 25(Frost/Ice), 28(Mage)
438  if (spellInfo->SpellFamilyFlags & 0x12040000)
440 
441  if ((spellInfo->SpellFamilyFlags & 0x1000000) && spellInfo->EffectApplyAuraName[0] == SPELL_AURA_MOD_CONFUSE)
443 
444  break;
445  }
446  case SPELLFAMILY_WARRIOR:
447  {
448  // Sunder Armor (vs Expose Armor)
449  if (spellInfo->SpellFamilyFlags & 0x00000000004000LL)
451 
452  break;
453  }
454  case SPELLFAMILY_WARLOCK:
455  {
456  // only warlock curses have this
457  if (spellInfo->Dispel == DISPEL_CURSE)
458  return SPELL_SPECIFIC_CURSE;
459 
460  // family flag 37 (only part spells have family name)
461  if (spellInfo->SpellFamilyFlags & 0x2000000000LL)
463 
464  //seed of corruption and corruption
465  if (spellInfo->SpellFamilyFlags & 0x1000000002LL)
467  break;
468  }
469  case SPELLFAMILY_HUNTER:
470  {
471  // only hunter stings have this
472  if (spellInfo->Dispel == DISPEL_POISON)
473  return SPELL_SPECIFIC_STING;
474 
475  break;
476  }
477  case SPELLFAMILY_PALADIN:
478  {
479  if (IsSealSpell(spellInfo))
480  return SPELL_SPECIFIC_SEAL;
481 
482  if ((spellInfo->SpellFamilyFlags & 0x00000820180400LL) && (spellInfo->AttributesEx3 & 0x200))
484 
485  for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
486  {
487  // only paladin auras have this
488  if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY)
489  return SPELL_SPECIFIC_AURA;
490  }
491  break;
492  }
493  case SPELLFAMILY_SHAMAN:
494  {
495  if (IsElementalShield(spellInfo))
497 
498  break;
499  }
500  case SPELLFAMILY_ROGUE:
501  {
502  // Expose Armor (vs Sunder Armor)
503  if (spellInfo->SpellFamilyFlags & 0x00000000080000LL)
505  break;
506  }
507  }
508 
509  // only warlock armor/skin have this (in additional to family cases)
510  if (spellInfo->SpellVisual == 130 && spellInfo->SpellIconID == 89)
512 
513  // only hunter aspects have this (but not all aspects in hunter family)
514  if (spellInfo->activeIconID == 122 && (GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_NATURE) &&
515  (spellInfo->Attributes & 0x50000) != 0 && (spellInfo->Attributes & 0x9000010) == 0)
516  return SPELL_SPECIFIC_ASPECT;
517 
518  for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
519  {
520  if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA)
521  {
522  switch (spellInfo->EffectApplyAuraName[i])
523  {
527  return SPELL_SPECIFIC_CHARM;
531  return SPELL_SPECIFIC_TRACKER;
532  }
533  }
534  }
535 
536  return SPELL_SPECIFIC_NORMAL;
537 }
538 
539 bool IsPositiveTarget(uint32 targetA, uint32 targetB)
540 {
541  // non-positive targets
542  switch (targetA)
543  {
551  case TARGET_UNIT_CHANNEL:
552  return false;
553  default:
554  break;
555  }
556  if (targetB)
557  return IsPositiveTarget(targetB, 0);
558  return true;
559 }
560 
561 bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
562 {
563  SpellEntry const* spellproto = sSpellStore.LookupEntry(spellId);
564  if (!spellproto)
565  return false;
566 
567  // not found a single positive spell with this attribute
568  if (spellproto->Attributes & SPELL_ATTR0_NEGATIVE_1)
569  return false;
570 
571  switch (spellproto->SpellFamilyName)
572  {
573  case SPELLFAMILY_GENERIC:
574  switch (spellproto->Id)
575  {
576  case 6716: // Test of Faith
577  case 23333: // Warsong Flag
578  case 23335: // Silverwing Flag
579  case 34976: // Netherstorm Flag
580  return true;
581  case 1852: // Silenced (GM)
582  case 46392: // Focused Assault
583  case 46393: // Brutal Assault
584  case 43437: // Paralyzed
585  case 28441: // AB Effect 000
586  case 37675: // Chaos Blast
587  case 41519: // Mark of Stormrage
588  case 34877: // Custodian of Time
589  case 34700: // Allergic Reaction
590  case 31719: // Suspension
591  case 43501: // Siphon Soul (Hexlord Spell)
592  case 30457: // Complete vulnerability
593  case 30529: // Recently In Game - Chess Event
594  case 37465: // Rain of Fire
595  case 45661: // Encapsulate (Felmyst - Sunwell Plateau)
596  case 45662:
597  case 45665:
598  return false;
599  default:
600  break;
601  }
602  break;
603  case SPELLFAMILY_MAGE:
604  {
605  // Amplify Magic, Dampen Magic
606  if (spellproto->SpellFamilyFlags == 0x00002000)
607  return true;
608 
609  switch (spellproto->Id)
610  {
611  case 31579: // Arcane Empowerment Rank1 talent aura with one positive and one negative (check not needed in wotlk)
612  case 31582: // Arcane Empowerment Rank2
613  case 31583: // Arcane Empowerment Rank3
614  return true;
615  default:
616  break;
617  }
618  }
619  break;
620  default:
621  break;
622  }
623 
624  switch (spellproto->Mechanic)
625  {
627  return true;
628  default:
629  break;
630  }
631 
632  switch (spellproto->Effect[effIndex])
633  {
634  // always positive effects (check before target checks that provided non-positive result in some case for positive effects)
635  case SPELL_EFFECT_HEAL:
640  return true;
642  return false;
643 
644  // non-positive aura use
647  {
648  switch (spellproto->EffectApplyAuraName[effIndex])
649  {
650  case SPELL_AURA_MOD_DAMAGE_DONE: // dependent from bas point sign (negative -> negative)
651  case SPELL_AURA_MOD_STAT:
657  if (spellproto->EffectBasePoints[effIndex] + int32(spellproto->EffectBaseDice[effIndex]) < 0)
658  return false;
659  break;
660  case SPELL_AURA_MOD_DAMAGE_TAKEN: // dependent from bas point sign (positive -> negative)
661  if (spellproto->EffectBasePoints[effIndex] + int32(spellproto->EffectBaseDice[effIndex]) > 0)
662  return false;
663  break;
665  if (spellproto->EffectBasePoints[effIndex] + int32(spellproto->EffectBaseDice[effIndex]) > 0)
666  return true; // some expected positive spells have SPELL_ATTR1_NEGATIVE
667  break;
669  return true;
672  if (spellId != spellproto->EffectTriggerSpell[effIndex])
673  {
674  uint32 spellTriggeredId = spellproto->EffectTriggerSpell[effIndex];
675  SpellEntry const* spellTriggeredProto = sSpellStore.LookupEntry(spellTriggeredId);
676 
677  if (spellTriggeredProto)
678  {
679  // non-positive targets of main spell return early
680  for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
681  {
682  // if non-positive trigger cast targeted to positive target this main cast is non-positive
683  // this will place this spell auras as debuffs
684  if (!IsPositiveTarget(spellTriggeredProto->EffectImplicitTargetA[i], spellTriggeredProto->EffectImplicitTargetB[i]) && !IsPositiveEffect(spellTriggeredId, i))
685  return false;
686  }
687  }
688  }
689  break;
691  // many positive auras have negative triggered spells at damage for example and this not make it negative (it can be canceled for example)
692  break;
693  case SPELL_AURA_MOD_STUN: //have positive and negative spells, we can't sort its correctly at this moment.
694  if (effIndex == 0 && spellproto->Effect[1] == 0 && spellproto->Effect[2] == 0)
695  return false; // but all single stun aura spells is negative
696  break;
698  if (spellproto->Id == 24740) // Wisp Costume
699  return true;
700  return false;
701  case SPELL_AURA_MOD_ROOT:
703  case SPELL_AURA_GHOST:
707  return false;
708  case SPELL_AURA_PERIODIC_DAMAGE: // used in positive spells also.
709  // part of negative spell if casted at self (prevent cancel)
710  if (spellproto->EffectImplicitTargetA[effIndex] == TARGET_UNIT_CASTER)
711  return false;
712  break;
713  case SPELL_AURA_MOD_DECREASE_SPEED: // used in positive spells also
714  // part of positive spell if casted at self
715  if (spellproto->EffectImplicitTargetA[effIndex] != TARGET_UNIT_CASTER)
716  return false;
717  // but not this if this first effect (didn't find better check)
718  if (spellproto->Attributes & SPELL_ATTR0_NEGATIVE_1 && effIndex == 0)
719  return false;
720  break;
722  {
723  // non-positive immunities
724  switch (spellproto->EffectMiscValue[effIndex])
725  {
726  case MECHANIC_BANDAGE:
727  case MECHANIC_SHIELD:
728  case MECHANIC_MOUNT:
730  return false;
731  default:
732  break;
733  }
734  break;
735  }
736  case SPELL_AURA_ADD_FLAT_MODIFIER: // mods
738  {
739  // non-positive mods
740  switch (spellproto->EffectMiscValue[effIndex])
741  {
742  case SPELLMOD_COST: // dependent from bas point sign (negative -> positive)
743  if (spellproto->EffectBasePoints[effIndex] + int32(spellproto->EffectBaseDice[effIndex]) > 0)
744  {
745  if (spellproto->Id == 12042) // Arcane Power is a positive spell
746  return true;
747 
748  return false;
749  }
750  break;
751  default:
752  break;
753  }
754  break;
755  }
756  default:
757  break;
758  }
759  break;
760  }
761  default:
762  break;
763  }
764 
765  // non-positive targets
766  if (!IsPositiveTarget(spellproto->EffectImplicitTargetA[effIndex], spellproto->EffectImplicitTargetB[effIndex]))
767  return false;
768 
769  // ok, positive
770  return true;
771 }
772 
773 bool IsPositiveSpell(uint32 spellId)
774 {
775  // spells with at least one negative effect are considered negative
776  // some self-applied spells have negative effects but in self casting case negative check ignored.
777  for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
778  if (!IsPositiveEffect(spellId, i))
779  return false;
780  return true;
781 }
782 
783 bool IsSingleTargetSpell(SpellEntry const* spellInfo)
784 {
785  // all other single target spells have if it has AttributesEx5
787  return true;
788 
789  // TODO - need found Judgements rule
790  switch (GetSpellSpecific(spellInfo->Id))
791  {
793  return true;
794  default:
795  break;
796  }
797 
798  // single target triggered spell.
799  // Not real client side single target spell, but it' not triggered until prev. aura expired.
800  // This is allow store it in single target spells list for caster for spell proc checking
801  if (spellInfo->Id == 38324) // Regeneration (triggered by 38299 (HoTs on Heals))
802  return true;
803 
804  return false;
805 }
806 
807 bool IsSingleTargetSpells(SpellEntry const* spellInfo1, SpellEntry const* spellInfo2)
808 {
809  // TODO - need better check
810  // Equal icon and spellfamily
811  if (spellInfo1->SpellFamilyName == spellInfo2->SpellFamilyName &&
812  spellInfo1->SpellIconID == spellInfo2->SpellIconID)
813  return true;
814 
815  // TODO - need found Judgements rule
816  SpellSpecific spec1 = GetSpellSpecific(spellInfo1->Id);
817  // spell with single target specific types
818  switch (spec1)
819  {
822  if (GetSpellSpecific(spellInfo2->Id) == spec1)
823  return true;
824  default:
825  break;
826  }
827 
828  return false;
829 }
830 
831 bool IsAuraAddedBySpell(uint32 auraType, uint32 spellId)
832 {
833  SpellEntry const* spellproto = sSpellStore.LookupEntry(spellId);
834  if (!spellproto) return false;
835 
836  for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
837  if (spellproto->EffectApplyAuraName[i] == auraType)
838  return true;
839  return false;
840 }
841 
843 {
844  // talents that learn spells can have stance requirements that need ignore
845  // (this requirement only for client-side stance show in talent description)
846  if (GetTalentSpellCost(spellInfo->Id) > 0 &&
847  (spellInfo->Effect[0] == SPELL_EFFECT_LEARN_SPELL || spellInfo->Effect[1] == SPELL_EFFECT_LEARN_SPELL || spellInfo->Effect[2] == SPELL_EFFECT_LEARN_SPELL))
848  return SPELL_CAST_OK;
849 
850  uint32 stanceMask = (form ? 1 << (form - 1) : 0);
851 
852  if (stanceMask & spellInfo->StancesNot) // can explicitly not be casted in this stance
854 
855  if (stanceMask & spellInfo->Stances) // can explicitly be casted in this stance
856  return SPELL_CAST_OK;
857 
858  bool actAsShifted = false;
859  if (form > 0)
860  {
861  SpellShapeshiftEntry const* shapeInfo = sSpellShapeshiftStore.LookupEntry(form);
862  if (!shapeInfo)
863  {
864  sLog.outError("GetErrorAtShapeshiftedCast: unknown shapeshift %u", form);
865  return SPELL_CAST_OK;
866  }
867  actAsShifted = !(shapeInfo->flags1 & 1); // shapeshift acts as normal form for spells
868  }
869 
870  if (actAsShifted)
871  {
872  if (spellInfo->Attributes & SPELL_ATTR0_NOT_SHAPESHIFT) // not while shapeshifted
874  else if (spellInfo->Stances != 0) // needs other shapeshift
876  }
877  else
878  {
879  // needs shapeshift
880  if (!(spellInfo->AttributesEx2 & SPELL_ATTR2_NOT_NEED_SHAPESHIFT) && spellInfo->Stances != 0)
882  }
883 
884  return SPELL_CAST_OK;
885 }
886 
888 {
889  mSpellTargetPositions.clear(); // need for reload case
890 
891  uint32 count = 0;
892 
893  // 0 1 2 3 4 5
894  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT id, target_map, target_position_x, target_position_y, target_position_z, target_orientation FROM spell_target_position");
895  if (!result)
896  {
897 
898 
899 
900  sLog.outString(">> Loaded %u spell target coordinates", count);
901  return;
902  }
903 
904 
905  do
906  {
907  Field* fields = result->Fetch();
908 
909 
910  uint32 Spell_ID = fields[0].GetUInt32();
911 
913 
914  st.target_mapId = fields[1].GetUInt32();
915  st.target_X = fields[2].GetFloat();
916  st.target_Y = fields[3].GetFloat();
917  st.target_Z = fields[4].GetFloat();
918  st.target_Orientation = fields[5].GetFloat();
919 
920  MapEntry const* mapEntry = sMapStore.LookupEntry(st.target_mapId);
921  if (!mapEntry)
922  {
923  sLog.outErrorDb("Spell (ID:%u) target map (ID: %u) does not exist in Map.dbc.", Spell_ID, st.target_mapId);
924  continue;
925  }
926 
927  if (st.target_X == 0 && st.target_Y == 0 && st.target_Z == 0)
928  {
929  sLog.outErrorDb("Spell (ID:%u) target coordinates not provided.", Spell_ID);
930  continue;
931  }
932 
933  SpellEntry const* spellInfo = sSpellStore.LookupEntry(Spell_ID);
934  if (!spellInfo)
935  {
936  sLog.outErrorDb("Spell (ID:%u) listed in spell_target_position does not exist.", Spell_ID);
937  continue;
938  }
939 
940  bool found = false;
941  for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
942  {
943  if (spellInfo->EffectImplicitTargetA[i] == TARGET_DST_DB || spellInfo->EffectImplicitTargetB[i] == TARGET_DST_DB)
944  {
945  found = true;
946  break;
947  }
948  }
949  if (!found)
950  {
951  sLog.outErrorDb("Spell (Id: %u) listed in spell_target_position does not have target TARGET_DST_DB (17).", Spell_ID);
952  continue;
953  }
954 
955  mSpellTargetPositions[Spell_ID] = st;
956  ++count;
957 
958  }
959  while (result->NextRow());
960 
961  sLog.outString(">> Loaded %u spell teleport coordinates", count);
962 }
963 
965 {
966  mSpellAffectMap.clear(); // need for reload case
967 
968  uint32 count = 0;
969 
970  // 0 1 2
971  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT entry, effectId, SpellFamilyMask FROM spell_affect");
972  if (!result)
973  {
974  sLog.outString(">> Loaded %u spell affect definitions", count);
975  return;
976  }
977 
978  do
979  {
980  Field* fields = result->Fetch();
981 
982  uint16 entry = fields[0].GetUInt16();
983  uint8 effectId = fields[1].GetUInt8();
984 
985  SpellEntry const* spellInfo = sSpellStore.LookupEntry(entry);
986 
987  if (!spellInfo)
988  {
989  sLog.outErrorDb("Spell %u listed in spell_affect does not exist", entry);
990  continue;
991  }
992 
993  if (effectId >= 3)
994  {
995  sLog.outErrorDb("Spell %u listed in spell_affect has invalid effect index (%u)", entry, effectId);
996  continue;
997  }
998 
999  if ((spellInfo->Effect[effectId] != SPELL_EFFECT_APPLY_AURA) ||
1000  (spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_DUMMY &&
1001  spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_FLAT_MODIFIER &&
1002  spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_PCT_MODIFIER &&
1003  spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_TARGET_TRIGGER))
1004  {
1005  sLog.outErrorDb("Spell %u listed in spell_affect does not have SPELL_AURA_ADD_FLAT_MODIFIER (%u) or SPELL_AURA_ADD_PCT_MODIFIER (%u) or SPELL_AURA_ADD_TARGET_TRIGGER (%u) for effect index (%u)", entry, SPELL_AURA_ADD_FLAT_MODIFIER, SPELL_AURA_ADD_PCT_MODIFIER, SPELL_AURA_ADD_TARGET_TRIGGER, effectId);
1006  continue;
1007  }
1008 
1009  uint64 spellAffectMask = fields[2].GetUInt64();
1010 
1011  // Spell.dbc have own data for low part of SpellFamilyMask
1012  if (spellInfo->EffectItemType[effectId])
1013  {
1014  if (spellInfo->EffectItemType[effectId] == spellAffectMask)
1015  {
1016  sLog.outErrorDb("Spell %u listed in spell_affect has redundant (same with EffectItemType%d) data for effect index (%u), skipped.", entry, effectId + 1, effectId);
1017  continue;
1018  }
1019  }
1020 
1021  mSpellAffectMap.insert(SpellAffectMap::value_type((entry << 8) + effectId, spellAffectMask));
1022 
1023  ++count;
1024  }
1025  while (result->NextRow());
1026 
1027  sLog.outString(">> Loaded %u spell affect definitions", count);
1028 
1029  for (uint32 id = 0; id < sSpellStore.GetNumRows(); ++id)
1030  {
1031  SpellEntry const* spellInfo = sSpellStore.LookupEntry(id);
1032  if (!spellInfo)
1033  continue;
1034 
1035  for (int effectId = 0; effectId < MAX_SPELL_EFFECTS; ++effectId)
1036  {
1037  if (spellInfo->Effect[effectId] != SPELL_EFFECT_APPLY_AURA ||
1038  (spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_FLAT_MODIFIER &&
1039  spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_PCT_MODIFIER &&
1040  spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_TARGET_TRIGGER))
1041  continue;
1042 
1043  if (spellInfo->EffectItemType[effectId] != 0)
1044  continue;
1045 
1046  if (mSpellAffectMap.find((id << 8) + effectId) != mSpellAffectMap.end())
1047  continue;
1048 
1049  sLog.outErrorDb("Spell %u (%s) misses spell_affect for effect %u", id, spellInfo->SpellName[sWorld.GetDefaultDbcLocale()], effectId);
1050  }
1051  }
1052 }
1053 
1054 bool SpellMgr::IsAffectedBySpell(SpellEntry const* spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const
1055 {
1056  // false for spellInfo == NULL
1057  if (!spellInfo)
1058  return false;
1059 
1060  SpellEntry const* affect_spell = sSpellStore.LookupEntry(spellId);
1061  // false for affect_spell == NULL
1062  if (!affect_spell)
1063  return false;
1064 
1065  // False if spellFamily not equal
1066  if (affect_spell->SpellFamilyName != spellInfo->SpellFamilyName)
1067  return false;
1068 
1069  // If familyFlags == 0
1070  if (!familyFlags)
1071  {
1072  // Get it from spellAffect table
1073  familyFlags = GetSpellAffectMask(spellId, effectId);
1074  // false if familyFlags == 0
1075  if (!familyFlags)
1076  return false;
1077  }
1078 
1079  // true
1080  if (familyFlags & spellInfo->SpellFamilyFlags)
1081  return true;
1082 
1083  return false;
1084 }
1085 
1087 {
1088  mSpellProcEventMap.clear(); // need for reload case
1089 
1090  uint32 count = 0;
1091 
1092  // 0 1 2 3 4 5 6 7 8
1093  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT entry, SchoolMask, SpellFamilyName, SpellFamilyMask, procFlags, procEx, ppmRate, CustomChance, Cooldown FROM spell_proc_event");
1094  if (!result)
1095  {
1096  sLog.outString(">> Loaded %u spell proc event conditions", count);
1097  return;
1098  }
1099 
1100  uint32 customProc = 0;
1101  do
1102  {
1103  Field* fields = result->Fetch();
1104 
1105  uint16 entry = fields[0].GetUInt16();
1106 
1107  const SpellEntry* spell = sSpellStore.LookupEntry(entry);
1108  if (!spell)
1109  {
1110  sLog.outErrorDb("Spell %u listed in spell_proc_event does not exist", entry);
1111  continue;
1112  }
1113 
1114  SpellProcEventEntry spe;
1115 
1116  spe.schoolMask = fields[1].GetUInt32();
1117  spe.spellFamilyName = fields[2].GetUInt32();
1118  spe.spellFamilyMask = fields[3].GetUInt64();
1119  spe.procFlags = fields[4].GetUInt32();
1120  spe.procEx = fields[5].GetUInt32();
1121  spe.ppmRate = fields[6].GetFloat();
1122  spe.customChance = fields[7].GetFloat();
1123  spe.cooldown = fields[8].GetUInt32();
1124 
1125  mSpellProcEventMap[entry] = spe;
1126 
1127  if (spell->procFlags == 0)
1128  {
1129  if (spe.procFlags == 0)
1130  {
1131  sLog.outErrorDb("Spell %u listed in spell_proc_event probally not triggered spell", entry);
1132  continue;
1133  }
1134  customProc++;
1135  }
1136  ++count;
1137  }
1138  while (result->NextRow());
1139 
1140  if (customProc)
1141  sLog.outString(">> Loaded %u custom spell proc event conditions +%u custom", count, customProc);
1142  else
1143  sLog.outString(">> Loaded %u spell proc event conditions", count);
1144 }
1145 
1146 
1147 bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellProcEvent, uint32 EventProcFlag, SpellEntry const* procSpell, uint32 procFlags, uint32 procExtra, bool active)
1148 {
1149  // No extra req need
1150  uint32 procEvent_procEx = PROC_EX_NONE;
1151 
1152  // check prockFlags for condition
1153  if ((procFlags & EventProcFlag) == 0)
1154  return false;
1155 
1156  /* Check Periodic Auras
1157 
1158  * Both hots and dots can trigger if spell has no PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
1159  nor PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
1160 
1161  * Only Hots can trigger if spell has PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
1162 
1163  * Only dots can trigger if spell has both positivity flags or PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG
1164 
1165  */
1166 
1167  if (procFlags & PROC_FLAG_DONE_PERIODIC)
1168  {
1169  if (EventProcFlag & PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG)
1170  {
1171  if (!(procExtra & PROC_EX_INTERNAL_DOT))
1172  return false;
1173  }
1174  else if (EventProcFlag & PROC_FLAG_DONE_SPELL_MAGIC_DMG_CLASS_POS
1175  && !(procExtra & PROC_EX_INTERNAL_HOT))
1176  return false;
1177  }
1178 
1179  if (procFlags & PROC_FLAG_TAKEN_PERIODIC)
1180  {
1181  if (EventProcFlag & PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_NEG)
1182  {
1183  if (!(procExtra & PROC_EX_INTERNAL_DOT))
1184  return false;
1185  }
1186  else if (EventProcFlag & PROC_FLAG_TAKEN_SPELL_MAGIC_DMG_CLASS_POS
1187  && !(procExtra & PROC_EX_INTERNAL_HOT))
1188  return false;
1189  }
1190 
1191  // Always trigger for this
1193  return true;
1194 
1195  if (spellProcEvent) // Exist event data
1196  {
1197  // Store extra req
1198  procEvent_procEx = spellProcEvent->procEx;
1199 
1200  // For melee triggers
1201  if (procSpell == NULL)
1202  {
1203  // Check (if set) for school (melee attack have Normal school)
1204  if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0)
1205  return false;
1206  }
1207  else // For spells need check school/spell family/family mask
1208  {
1209  // Potions can trigger only if spellfamily given
1210  if (procSpell->SpellFamilyName == SPELLFAMILY_POTION)
1211  {
1212  if (procSpell->SpellFamilyName == spellProcEvent->spellFamilyName)
1213  return true;
1214  return false;
1215  }
1216 
1217  // Check (if set) for school
1218  if (spellProcEvent->schoolMask && (spellProcEvent->schoolMask & procSpell->SchoolMask) == 0)
1219  return false;
1220 
1221  // Check (if set) for spellFamilyName
1222  if (spellProcEvent->spellFamilyName && (spellProcEvent->spellFamilyName != procSpell->SpellFamilyName))
1223  return false;
1224 
1225  // spellFamilyName is Ok need check for spellFamilyMask if present
1226  if (spellProcEvent->spellFamilyMask)
1227  {
1228  if ((spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags) == 0)
1229  return false;
1230  active = true; // Spell added manualy -> so its active spell
1231  }
1232  }
1233  }
1234  // potions can trigger only if have spell_proc entry
1235  else if (procSpell && procSpell->SpellFamilyName == SPELLFAMILY_POTION)
1236  return false;
1237 
1238  // Check for extra req (if none) and hit/crit
1239  if (procEvent_procEx == PROC_EX_NONE)
1240  {
1241  // No extra req, so can trigger only for active (damage/healing present) and hit/crit
1242  if ((procExtra & (PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT)) && active)
1243  return true;
1244  }
1245  else // Passive spells hits here only if resist/reflect/immune/evade
1246  {
1247  // Exist req for PROC_EX_EX_TRIGGER_ALWAYS
1248  if (procEvent_procEx & PROC_EX_EX_TRIGGER_ALWAYS)
1249  return true;
1250  // Passive spells cant trigger if need hit
1251  if ((procEvent_procEx & PROC_EX_NORMAL_HIT) && !active)
1252  return false;
1253  // Check Extra Requirement like (hit/crit/miss/resist/parry/dodge/block/immune/reflect/absorb and other)
1254  if (procEvent_procEx & procExtra)
1255  return true;
1256  }
1257  return false;
1258 }
1259 
1261 {
1262  mSpellSpellGroup.clear(); // need for reload case
1263  mSpellGroupSpell.clear();
1264 
1265  uint32 count = 0;
1266 
1267  // 0 1
1268  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT id, spell_id FROM spell_group");
1269  if ( !result )
1270  {
1271  sLog.outString( ">> Loaded %u spell group definitions", count );
1272  return;
1273  }
1274 
1275  std::set<uint32> groups;
1276 
1277  do
1278  {
1279  Field* fields = result->Fetch();
1280 
1281  uint32 group_id = fields[0].GetUInt32();
1282  if (group_id <= SPELL_GROUP_DB_RANGE_MIN && group_id >= SPELL_GROUP_CORE_RANGE_MAX)
1283  {
1284  sLog.outErrorDb("SpellGroup id %u listed in `spell_groups` is in core range, but is not defined in core!", group_id);
1285  continue;
1286  }
1287  int32 spell_id = fields[1].GetInt32();
1288 
1289  groups.insert(std::set<uint32>::value_type(group_id));
1290  mSpellGroupSpell.insert(SpellGroupSpellMap::value_type((SpellGroup)group_id, spell_id));
1291 
1292  }
1293  while ( result->NextRow() );
1294 
1295  for (SpellGroupSpellMap::iterator itr = mSpellGroupSpell.begin(); itr != mSpellGroupSpell.end() ; )
1296  {
1297  if (itr->second < 0)
1298  {
1299  if (groups.find(abs(itr->second)) == groups.end())
1300  {
1301  sLog.outErrorDb("SpellGroup id %u listed in `spell_groups` does not exist", abs(itr->second));
1302  mSpellGroupSpell.erase(itr++);
1303  }
1304  else
1305  ++itr;
1306  }
1307  else
1308  {
1309  SpellEntry const* spellInfo = sSpellStore.LookupEntry(itr->second);
1310 
1311  if (!spellInfo)
1312  {
1313  sLog.outErrorDb("Spell %u listed in `spell_group` does not exist", itr->second);
1314  mSpellGroupSpell.erase(itr++);
1315  }
1316  else if (GetSpellRank(itr->second) > 1)
1317  {
1318  sLog.outErrorDb("Spell %u listed in `spell_group` is not first rank of spell", itr->second);
1319  mSpellGroupSpell.erase(itr++);
1320  }
1321  else
1322  ++itr;
1323  }
1324  }
1325 
1326  for (std::set<uint32>::iterator groupItr = groups.begin() ; groupItr != groups.end() ; ++groupItr)
1327  {
1328  std::set<uint32> spells;
1329  GetSetOfSpellsInSpellGroup(SpellGroup(*groupItr), spells);
1330 
1331  for (std::set<uint32>::iterator spellItr = spells.begin() ; spellItr != spells.end() ; ++spellItr)
1332  {
1333  ++count;
1334  mSpellSpellGroup.insert(SpellSpellGroupMap::value_type(*spellItr, SpellGroup(*groupItr)));
1335  }
1336  }
1337 
1338  sLog.outString( ">> Loaded %u spell group definitions", count );
1339 }
1340 
1342 {
1343  mSpellGroupStack.clear(); // need for reload case
1344 
1345  uint32 count = 0;
1346 
1347  // 0 1
1348  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT group_id, stack_rule FROM spell_group_stack_rules");
1349  if ( !result )
1350  {
1351  sLog.outString( ">> Loaded %u spell group stack rules", count );
1352  return;
1353  }
1354 
1355  do
1356  {
1357  Field* fields = result->Fetch();
1358 
1359  uint32 group_id = fields[0].GetUInt32();
1360  uint8 stack_rule = fields[1].GetUInt32();
1361  if (stack_rule >= SPELL_GROUP_STACK_RULE_MAX)
1362  {
1363  sLog.outErrorDb("SpellGroupStackRule %u listed in `spell_group_stack_rules` does not exist", stack_rule);
1364  continue;
1365  }
1366 
1368 
1369  if (spellGroup.first == spellGroup.second)
1370  {
1371  sLog.outErrorDb("SpellGroup id %u listed in `spell_group_stack_rules` does not exist", group_id);
1372  continue;
1373  }
1374 
1375  mSpellGroupStack[(SpellGroup)group_id] = (SpellGroupStackRule)stack_rule;
1376 
1377  ++count;
1378  }
1379  while ( result->NextRow() );
1380 
1381  sLog.outString( ">> Loaded %u spell group stack rules", count );
1382 }
1383 
1385 {
1386  mSpellThreatMap.clear(); // need for reload case
1387 
1388  uint32 count = 0;
1389 
1390  // 0 1 2 3
1391  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT entry, flatMod, pctMod, apPctMod FROM spell_threat");
1392 
1393  if (!result)
1394  {
1395  sLog.outString( ">> Loaded %u aggro generating spells", count);
1396  return;
1397  }
1398 
1399  do
1400  {
1401  Field* fields = result->Fetch();
1402 
1403  uint32 entry = fields[0].GetUInt32();
1404 
1405  if (!sSpellStore.LookupEntry(entry))
1406  {
1407  sLog.outErrorDb("Spell %u listed in `spell_threat` does not exist", entry);
1408  continue;
1409  }
1410 
1411  SpellThreatEntry ste;
1412  ste.flatMod = fields[1].GetInt16();
1413  ste.pctMod = fields[2].GetFloat();
1414  ste.apPctMod = fields[3].GetFloat();
1415 
1416  mSpellThreatMap[entry] = ste;
1417  count++;
1418  }
1419  while (result->NextRow());
1420 
1421  sLog.outString(">> Loaded %u SpellThreatEntries.", count);
1422 }
1423 
1425 {
1426  mSpellEnchantProcEventMap.clear(); // need for reload case
1427 
1428  uint32 count = 0;
1429 
1430  // 0 1 2 3
1431  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT entry, customChance, PPMChance, procEx FROM spell_enchant_proc_data");
1432  if (!result)
1433  {
1434  sLog.outString(">> Loaded %u spell enchant proc event conditions", count);
1435  return;
1436  }
1437 
1438  do
1439  {
1440  Field* fields = result->Fetch();
1441 
1442  uint32 enchantId = fields[0].GetUInt32();
1443 
1444  SpellItemEnchantmentEntry const* ench = sSpellItemEnchantmentStore.LookupEntry(enchantId);
1445  if (!ench)
1446  {
1447  sLog.outErrorDb("Enchancment %u listed in spell_enchant_proc_data does not exist", enchantId);
1448  continue;
1449  }
1450 
1452 
1453  spe.customChance = fields[1].GetUInt32();
1454  spe.PPMChance = fields[2].GetFloat();
1455  spe.procEx = fields[3].GetUInt32();
1456 
1457  mSpellEnchantProcEventMap[enchantId] = spe;
1458 
1459  ++count;
1460  }
1461  while (result->NextRow());
1462 
1463  sLog.outString(">> Loaded %u enchant proc data definitions", count);
1464 }
1465 
1467 {
1468  // 0 1 2 3 4 5 6 7 8 9 10 11 12
1469  if (QueryResult_AutoPtr result = WorldDatabase.PQuery("SELECT entry, effIndex, bitMaskCondition, condition0, data0, condition1, data1, condition2, data2, condition3, data3, condition4, data4 FROM spell_dummy_condition ORDER BY entry ASC"))
1470  {
1471  Field* field;
1472  SpellDummyConditionEntry sdcEntry;
1473 
1474  do
1475  {
1476  field = result->Fetch();
1477 
1478  sdcEntry.entry = field[0].GetUInt32();
1479  sdcEntry.effIndex = SpellEffIndex(field[1].GetUInt32());
1480  sdcEntry.bitMaskCondition = field[2].GetUInt32();
1481 
1482  for (uint32 i = 0; i < 5; i++) // 5 condition - data pairs
1483  {
1484  sdcEntry.conditions[i].condition = static_cast<SpellDummyCondition>(field[3 + i * 2].GetUInt32());
1485  sdcEntry.conditions[i].data = field[4 + i * 2].GetInt32();
1486  }
1487 
1488  mSpellDummyConditionMap.insert( std::pair<uint32, SpellDummyConditionEntry>(sdcEntry.entry, sdcEntry) );
1489  }
1490  while (result->NextRow());
1491 
1492  sLog.outString(">> Loaded %llu spell dummy conditions", result->GetRowCount());
1493  return;
1494  }
1495 
1496  sLog.outString(">> Loaded 0 spell dummy conditions");
1497 }
1498 
1499 bool SpellMgr::IsRankSpellDueToSpell(SpellEntry const* spellInfo_1, uint32 spellId_2) const
1500 {
1501  SpellEntry const* spellInfo_2 = sSpellStore.LookupEntry(spellId_2);
1502  if (!spellInfo_1 || !spellInfo_2) return false;
1503  if (spellInfo_1->Id == spellId_2) return false;
1504 
1505  return GetFirstSpellInChain(spellInfo_1->Id) == GetFirstSpellInChain(spellId_2);
1506 }
1507 
1515 {
1516  if (spellInfo->powerType != POWER_MANA && spellInfo->powerType != POWER_HEALTH)
1517  {
1518  // These spells do not cost energy/rage/focus and their cost does not
1519  // change between ranks so we will allow only the highest rank in spellbook
1520 
1521  // One exception - Faerie Fire (feral) need to stack in order to properly show
1522  // up in talent tree otherwise on higher rank it will be seen as not used
1523  if (spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && spellInfo->SpellFamilyFlags & 0x400)
1524  return true;
1525 
1526  return false;
1527  }
1528 
1529  if (IsProfessionSpell(spellInfo->Id))
1530  return false;
1531 
1532  // All stance spells. if any better way, change it.
1533  for (int i = 0; i < MAX_SPELL_EFFECTS; i++)
1534  {
1535  // Paladin aura Spell
1536  if (spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN
1537  && spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY)
1538  return false;
1539  // Druid form Spell
1540  if (spellInfo->SpellFamilyName == SPELLFAMILY_DRUID
1541  && spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA
1542  && spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
1543  return false;
1544  // Rogue Stealth
1545  if (spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE
1546  && spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA
1547  && spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_SHAPESHIFT)
1548  return false;
1549  }
1550  return true;
1551 }
1552 
1560 bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool sameCaster) const
1561 {
1562  SpellEntry const* spellInfo_1 = sSpellStore.LookupEntry(spellId_1);
1563  SpellEntry const* spellInfo_2 = sSpellStore.LookupEntry(spellId_2);
1564 
1565  if (!spellInfo_1 || !spellInfo_2)
1566  return false;
1567 
1568  SpellGroupStackRule stackRule = CheckSpellGroupStackRules(spellInfo_1->Id, spellInfo_2->Id);
1569  if (stackRule)
1570  {
1571  if (stackRule == SPELL_GROUP_STACK_RULE_EXCLUSIVE)
1572  return true;
1573  if (sameCaster && stackRule == SPELL_GROUP_STACK_RULE_EXCLUSIVE_FROM_SAME_CASTER)
1574  return true;
1575  if (stackRule != SPELL_GROUP_STACK_RULE_DEFAULT)
1576  return false;
1577  }
1578 
1579  if (spellInfo_1->SpellFamilyName != spellInfo_2->SpellFamilyName)
1580  return false;
1581 
1582  if (!sameCaster)
1583  {
1584  // Iterate through effects
1585  for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1586  if (spellInfo_1->Effect[i] == SPELL_EFFECT_APPLY_AURA
1587  || spellInfo_1->Effect[i] == SPELL_EFFECT_PERSISTENT_AREA_AURA)
1588  // not area auras (shaman totem)
1589  switch (spellInfo_1->EffectApplyAuraName[i])
1590  {
1591  // DOT or HOT from different casters will stack
1602  return false;
1603  default:
1604  break;
1605  }
1606  }
1607 
1608  // Iterate through specifics
1609  SpellSpecific spellSpec = GetSpellSpecific(spellId_1);
1610  switch (spellSpec)
1611  {
1612  case SPELL_SPECIFIC_STING:
1613  case SPELL_SPECIFIC_CURSE:
1614  case SPELL_SPECIFIC_ASPECT:
1617  return sameCaster == (spellSpec == GetSpellSpecific(spellId_2));
1618  default:
1619  break;
1620  }
1621 
1622  if (spellInfo_1->SpellFamilyName == SPELLFAMILY_GENERIC)
1623  {
1624  if (spellInfo_1->HasAttribute(SPELL_ATTR0_PASSIVE) && spellInfo_1->SpellIconID == 1)
1625  return false;
1626 
1627  if (spellInfo_1->SpellIconID == spellInfo_2->SpellIconID)
1628  return true;
1629 
1630  if (spellInfo_1->EffectApplyAuraName[0] == SPELL_AURA_MOUNTED && spellInfo_2->EffectApplyAuraName[0] == SPELL_AURA_MOUNTED)
1631  return true;
1632 
1633  if (!(spellInfo_1->EffectApplyAuraName[0] == SPELL_AURA_MOD_POWER_REGEN &&
1634  spellInfo_1->EffectApplyAuraName[1] == SPELL_AURA_PERIODIC_DUMMY))
1635  return false;
1636  }
1637 
1638  // check for class spells
1639  else
1640  {
1641  if (spellInfo_1->SpellFamilyFlags != spellInfo_2->SpellFamilyFlags)
1642  return false;
1643  }
1644 
1645  //use data of highest rank spell(needed for spells which ranks have different effects)
1646  spellInfo_1 = sSpellStore.LookupEntry(GetLastSpellInChain(spellId_1));
1647  spellInfo_2 = sSpellStore.LookupEntry(GetLastSpellInChain(spellId_2));
1648 
1649  //if spells have exactly the same effect they cannot stack
1650  for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1651  if (spellInfo_1->Effect[i] != spellInfo_2->Effect[i]
1652  || spellInfo_1->EffectApplyAuraName[i] != spellInfo_2->EffectApplyAuraName[i]
1653  || spellInfo_1->EffectMiscValue[i] != spellInfo_2->EffectMiscValue[i]) // paladin resist aura
1654  return false; // need itemtype check? need an example to add that check
1655 
1656  return true;
1657 }
1658 
1660 {
1661  spell_id = GetFirstSpellInChain(spell_id);
1662  return mSpellSpellGroup.equal_range(spell_id);
1663 }
1664 
1666 {
1668  for (SpellSpellGroupMap::const_iterator itr = spellGroup.first; itr != spellGroup.second; ++itr)
1669  {
1670  if (itr->second == groupid)
1671  return true;
1672  }
1673  return false;
1674 }
1675 
1677 {
1678  return mSpellGroupSpell.equal_range(group_id);
1679 }
1680 
1681 void SpellMgr::GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set<uint32>& foundSpells) const
1682 {
1683  std::set<SpellGroup> usedGroups;
1684  GetSetOfSpellsInSpellGroup(group_id, foundSpells, usedGroups);
1685 }
1686 
1687 void SpellMgr::GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set<uint32>& foundSpells, std::set<SpellGroup>& usedGroups) const
1688 {
1689  if (usedGroups.find(group_id) != usedGroups.end())
1690  return;
1691  usedGroups.insert(group_id);
1692 
1694  for (SpellGroupSpellMap::const_iterator itr = groupSpell.first; itr != groupSpell.second; ++itr)
1695  {
1696  if (itr->second < 0)
1697  {
1698  SpellGroup currGroup = (SpellGroup)abs(itr->second);
1699  GetSetOfSpellsInSpellGroup(currGroup, foundSpells, usedGroups);
1700  }
1701  else
1702  {
1703  foundSpells.insert(itr->second);
1704  }
1705  }
1706 }
1707 
1709 {
1710  spellid_1 = GetFirstSpellInChain(spellid_1);
1711  spellid_2 = GetFirstSpellInChain(spellid_2);
1712  if (spellid_1 == spellid_2)
1714  // find SpellGroups which are common for both spells
1715  SpellSpellGroupMapBounds spellGroup1 = GetSpellSpellGroupMapBounds(spellid_1);
1716  std::set<SpellGroup> groups;
1717  for (SpellSpellGroupMap::const_iterator itr = spellGroup1.first; itr != spellGroup1.second; ++itr)
1718  {
1719  if (IsSpellMemberOfSpellGroup(spellid_2, itr->second))
1720  {
1721  bool add = true;
1722  SpellGroupSpellMapBounds groupSpell = GetSpellGroupSpellMapBounds(itr->second);
1723  for (SpellGroupSpellMap::const_iterator itr2 = groupSpell.first; itr2 != groupSpell.second; ++itr2)
1724  {
1725  if (itr2->second < 0)
1726  {
1727  SpellGroup currGroup = (SpellGroup)abs(itr2->second);
1728  if (IsSpellMemberOfSpellGroup(spellid_1, currGroup) && IsSpellMemberOfSpellGroup(spellid_2, currGroup))
1729  {
1730  add = false;
1731  break;
1732  }
1733  }
1734  }
1735  if (add)
1736  groups.insert(itr->second);
1737  }
1738  }
1739 
1741 
1742  for (std::set<SpellGroup>::iterator itr = groups.begin(); itr!= groups.end(); ++itr)
1743  {
1744  SpellGroupStackMap::const_iterator found = mSpellGroupStack.find(*itr);
1745  if (found != mSpellGroupStack.end())
1746  rule = found->second;
1747  if (rule)
1748  break;
1749  }
1750  return rule;
1751 }
1752 
1754 {
1755  SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
1756  if (!spellInfo)
1757  return false;
1758 
1759  if (spellInfo->Effect[1] != SPELL_EFFECT_SKILL)
1760  return false;
1761 
1762  uint32 skill = spellInfo->EffectMiscValue[1];
1763 
1764  return IsProfessionSkill(skill);
1765 }
1766 
1768 {
1769  SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
1770  if (!spellInfo)
1771  return false;
1772 
1773  if (spellInfo->Effect[1] != SPELL_EFFECT_SKILL)
1774  return false;
1775 
1776  uint32 skill = spellInfo->EffectMiscValue[1];
1777 
1778  return IsPrimaryProfessionSkill(skill);
1779 }
1780 
1782 {
1783  return IsPrimaryProfessionSpell(spellId) && GetSpellRank(spellId) == 1;
1784 }
1785 
1786 SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const
1787 {
1788  // ignore passive spells
1789  if (IsPassiveSpell(spellInfo->Id))
1790  return spellInfo;
1791 
1792  bool needRankSelection = false;
1793  for (int i = 0; i < 3; i++)
1794  {
1795  if (IsPositiveEffect(spellInfo->Id, i) && (
1796  spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA ||
1798  ))
1799  {
1800  needRankSelection = true;
1801  break;
1802  }
1803  }
1804 
1805  // not required
1806  if (!needRankSelection)
1807  return spellInfo;
1808 
1809  for (uint32 nextSpellId = spellInfo->Id; nextSpellId != 0; nextSpellId = GetPrevSpellInChain(nextSpellId))
1810  {
1811  SpellEntry const* nextSpellInfo = sSpellStore.LookupEntry(nextSpellId);
1812  if (!nextSpellInfo)
1813  break;
1814 
1815  // if found appropriate level
1816  if (playerLevel + 10 >= nextSpellInfo->spellLevel)
1817  return nextSpellInfo;
1818 
1819  // one rank less then
1820  }
1821 
1822  // not found
1823  return NULL;
1824 }
1825 
1827 {
1828  mSpellsReqSpell.clear(); // need for reload case
1829  mSpellReq.clear(); // need for reload case
1830 
1831  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT spell_id, req_spell from spell_required");
1832 
1833  if (!result)
1834  {
1835  sLog.outString(">> Loaded 0 spell required records");
1836  sLog.outErrorDb("spell_required table is empty!");
1837  return;
1838  }
1839  uint32 rows = 0;
1840 
1841  do
1842  {
1843  Field* fields = result->Fetch();
1844 
1845  uint32 spell_id = fields[0].GetUInt32();
1846  uint32 spell_req = fields[1].GetUInt32();
1847 
1848  mSpellsReqSpell.insert (std::pair<uint32, uint32>(spell_req, spell_id));
1849  mSpellReq[spell_id] = spell_req;
1850  ++rows;
1851  }
1852  while (result->NextRow());
1853 
1854  sLog.outString(">> Loaded %u spell required records", rows);
1855 }
1856 
1858 {
1860  char const* SpellName;
1868 
1869  bool operator()(const SpellRankEntry& _Left, const SpellRankEntry& _Right)const
1870  {
1871  return (_Left.SkillId != _Right.SkillId ? _Left.SkillId < _Right.SkillId
1872  : _Left.SpellName != _Right.SpellName ? _Left.SpellName < _Right.SpellName
1873  : _Left.ProcFlags != _Right.ProcFlags ? _Left.ProcFlags < _Right.ProcFlags
1874  : _Left.SpellFamilyFlags != _Right.SpellFamilyFlags ? _Left.SpellFamilyFlags < _Right.SpellFamilyFlags
1875  : (_Left.SpellVisual != _Right.SpellVisual) && (!_Left.SpellVisual || !_Right.SpellVisual) ? _Left.SpellVisual < _Right.SpellVisual
1876  : (_Left.ManaCost != _Right.ManaCost) && (!_Left.ManaCost || !_Right.ManaCost) ? _Left.ManaCost < _Right.ManaCost
1877  : (_Left.DurationIndex != _Right.DurationIndex) && (!_Left.DurationIndex || !_Right.DurationIndex) ? _Left.DurationIndex < _Right.DurationIndex
1878  : (_Left.RangeIndex != _Right.RangeIndex) && (!_Left.RangeIndex || !_Right.RangeIndex || _Left.RangeIndex == 1 || !_Right.RangeIndex == 1) ? _Left.RangeIndex < _Right.RangeIndex
1879  : _Left.TargetAuraState < _Right.TargetAuraState
1880  );
1881  }
1882 };
1883 
1885 {
1887  char const* Rank;
1888 };
1889 
1891 {
1892  mSpellChains.clear(); // need for reload case
1893 
1894  std::vector<uint32> ChainedSpells;
1895  for (uint32 ability_id = 0; ability_id < sSkillLineAbilityStore.GetNumRows(); ability_id++)
1896  {
1897  SkillLineAbilityEntry const* AbilityInfo = sSkillLineAbilityStore.LookupEntry(ability_id);
1898  if (!AbilityInfo)
1899  continue;
1900  if (AbilityInfo->spellId == 20154) //exception to these rules (not needed in 3.0.3)
1901  continue;
1902  if (!AbilityInfo->forward_spellid)
1903  continue;
1904  ChainedSpells.push_back(AbilityInfo->forward_spellid);
1905  }
1906 
1907  std::multimap<SpellRankEntry, SpellRankValue, SpellRankEntry> RankMap;
1908 
1909  for (uint32 ability_id = 0; ability_id < sSkillLineAbilityStore.GetNumRows(); ability_id++)
1910  {
1911  SkillLineAbilityEntry const* AbilityInfo = sSkillLineAbilityStore.LookupEntry(ability_id);
1912  if (!AbilityInfo)
1913  continue;
1914 
1915  //get only spell with lowest ability_id to prevent doubles
1916  uint32 spell_id = AbilityInfo->spellId;
1917  if (spell_id == 20154) //exception to these rules (not needed in 3.0.3)
1918  continue;
1919  bool found = false;
1920  for (uint32 i = 0; i < ChainedSpells.size(); i++)
1921  {
1922  if (ChainedSpells.at(i) == spell_id)
1923  found = true;
1924  }
1925  if (found)
1926  continue;
1927 
1928  if (mSkillLineAbilityMap.lower_bound(spell_id)->second->id != ability_id)
1929  continue;
1930  SpellEntry const* SpellInfo = sSpellStore.LookupEntry(spell_id);
1931  if (!SpellInfo)
1932  continue;
1933  std::string sRank = SpellInfo->Rank[sWorld.GetDefaultDbcLocale()];
1934  if (sRank.empty())
1935  continue;
1936  //exception to polymorph spells-make pig and turtle other chain than sheep
1937  if ((SpellInfo->SpellFamilyName == SPELLFAMILY_MAGE) && (SpellInfo->SpellFamilyFlags & 0x1000000) && (SpellInfo->SpellIconID != 82))
1938  continue;
1939 
1940  SpellRankEntry entry;
1942  entry.SkillId = AbilityInfo->skillId;
1943  entry.SpellName = SpellInfo->SpellName[sWorld.GetDefaultDbcLocale()];
1944  entry.DurationIndex = SpellInfo->DurationIndex;
1945  entry.RangeIndex = SpellInfo->rangeIndex;
1946  entry.ProcFlags = SpellInfo->procFlags;
1947  entry.SpellFamilyFlags = SpellInfo->SpellFamilyFlags;
1948  entry.TargetAuraState = SpellInfo->TargetAuraState;
1949  entry.SpellVisual = SpellInfo->SpellVisual;
1950  entry.ManaCost = SpellInfo->manaCost;
1951 
1952  for (;;)
1953  {
1954  AbilityInfo = mSkillLineAbilityMap.lower_bound(spell_id)->second;
1955  value.Id = spell_id;
1956  value.Rank = SpellInfo->Rank[sWorld.GetDefaultDbcLocale()];
1957  RankMap.insert(std::pair<SpellRankEntry, SpellRankValue>(entry, value));
1958  spell_id = AbilityInfo->forward_spellid;
1959  SpellInfo = sSpellStore.LookupEntry(spell_id);
1960  if (!SpellInfo)
1961  break;
1962  }
1963  }
1964 
1965 
1966  uint32 count = 0;
1967 
1968  for (std::multimap<SpellRankEntry, SpellRankValue, SpellRankEntry>::iterator itr = RankMap.begin(); itr != RankMap.end();)
1969  {
1970  SpellRankEntry entry = itr->first;
1971  //trac errors in extracted data
1972  std::multimap<char const*, std::multimap<SpellRankEntry, SpellRankValue, SpellRankEntry>::iterator> RankErrorMap;
1973  for (std::multimap<SpellRankEntry, SpellRankValue, SpellRankEntry>::iterator itr2 = RankMap.lower_bound(entry); itr2 != RankMap.upper_bound(entry); itr2++)
1974  RankErrorMap.insert(std::pair<char const*, std::multimap<SpellRankEntry, SpellRankValue, SpellRankEntry>::iterator>(itr2->second.Rank, itr2));
1975  for (std::multimap<char const*, std::multimap<SpellRankEntry, SpellRankValue, SpellRankEntry>::iterator>::iterator itr2 = RankErrorMap.begin(); itr2 != RankErrorMap.end();)
1976  {
1977  char const* err_entry = itr2->first;
1978  uint32 rank_count = RankErrorMap.count(itr2->first);
1979  if (rank_count > 1)
1980  for (itr2 = RankErrorMap.lower_bound(err_entry); itr2 != RankErrorMap.upper_bound(err_entry); itr2++)
1981  {
1982  sLog.outDebug("There is a duplicate rank entry (%s) for spell: %u", itr2->first, itr2->second->second.Id);
1983  sLog.outDebug("Spell %u removed from chain data.", itr2->second->second.Id);
1984  RankMap.erase(itr2->second);
1985  itr = RankMap.lower_bound(entry);
1986  }
1987  else
1988  itr2++;
1989  }
1990  //do not proceed for spells with less than 2 ranks
1991  uint32 spell_max_rank = RankMap.count(entry);
1992  if (spell_max_rank < 2)
1993  {
1994  itr = RankMap.upper_bound(entry);
1995  continue;
1996  }
1997 
1998  itr = RankMap.upper_bound(entry);
1999 
2000  //order spells by spells by spellLevel
2001  std::list<uint32> RankedSpells;
2002  uint32 min_spell_lvl = 0;
2003  std::multimap<SpellRankEntry, SpellRankValue, SpellRankEntry>::iterator min_itr;
2004  for (; RankMap.count(entry);)
2005  {
2006  for (std::multimap<SpellRankEntry, SpellRankValue, SpellRankEntry>::iterator itr2 = RankMap.lower_bound(entry); itr2 != RankMap.upper_bound(entry); itr2++)
2007  {
2008  SpellEntry const* SpellInfo = sSpellStore.LookupEntry(itr2->second.Id);
2009  if (SpellInfo->spellLevel < min_spell_lvl || itr2 == RankMap.lower_bound(entry))
2010  {
2011  min_spell_lvl = SpellInfo->spellLevel;
2012  min_itr = itr2;
2013  }
2014  }
2015  RankedSpells.push_back(min_itr->second.Id);
2016  RankMap.erase(min_itr);
2017  }
2018 
2019  //use data from talent.dbc
2020  uint16 talent_id = 0;
2021  for (std::list<uint32>::iterator itr2 = RankedSpells.begin(); itr2 != RankedSpells.end();)
2022  {
2023  if (TalentSpellPos const* TalentPos = GetTalentSpellPos(*itr2))
2024  {
2025  talent_id = TalentPos->talent_id;
2026  RankedSpells.erase(itr2);
2027  itr2 = RankedSpells.begin();
2028  }
2029  else
2030  itr2++;
2031  }
2032  if (talent_id)
2033  {
2034  TalentEntry const* TalentInfo = sTalentStore.LookupEntry(talent_id);
2035  for (uint8 rank = 5; rank; rank--)
2036  {
2037  if (TalentInfo->RankID[rank - 1])
2038  RankedSpells.push_front(TalentInfo->RankID[rank - 1]);
2039  }
2040  }
2041 
2042  count++;
2043 
2044  itr = RankMap.upper_bound(entry);
2045  uint32 spell_rank = 1;
2046  for (std::list<uint32>::iterator itr2 = RankedSpells.begin(); itr2 != RankedSpells.end(); spell_rank++)
2047  {
2048  uint32 spell_id = *itr2;
2049  mSpellChains[spell_id].rank = spell_rank;
2050  mSpellChains[spell_id].first = RankedSpells.front();
2051  mSpellChains[spell_id].last = RankedSpells.back();
2052 
2053  itr2++;
2054 
2055  if (spell_rank < 2)
2056  mSpellChains[spell_id].prev = 0;
2057 
2058  if (spell_id == RankedSpells.back())
2059  mSpellChains[spell_id].next = 0;
2060  else
2061  {
2062  mSpellChains[*itr2].prev = spell_id;
2063  mSpellChains[spell_id].next = *itr2;
2064  }
2065  }
2066  }
2067 
2068  //uncomment these two lines to print yourself list of spell_chains on startup
2069  // for (UNORDERED_MAP<uint32, SpellChainNode>::iterator itr=mSpellChains.begin();itr != mSpellChains.end();itr++)
2070  // sLog.outString("Id: %u, Rank: %d , %s",itr->first,itr->second.rank, sSpellStore.LookupEntry(itr->first)->Rank[sWorld.GetDefaultDbcLocale()]);
2071 
2072  sLog.outString(">> Loaded %u spell chains", count);
2073 }
2074 
2076 {
2077  mSpellLearnSkills.clear(); // need for reload case
2078 
2079  // search auto-learned skills and add its to map also for use in unlearn spells/talents
2080  uint32 dbc_count = 0;
2081  for (uint32 spell = 0; spell < sSpellStore.GetNumRows(); ++spell)
2082  {
2083  SpellEntry const* entry = sSpellStore.LookupEntry(spell);
2084 
2085  if (!entry)
2086  continue;
2087 
2088  for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
2089  {
2090  if (entry->Effect[i] == SPELL_EFFECT_SKILL)
2091  {
2092  SpellLearnSkillNode dbc_node;
2093  dbc_node.skill = entry->EffectMiscValue[i];
2094  if (dbc_node.skill != SKILL_RIDING)
2095  dbc_node.value = 1;
2096  else
2097  dbc_node.value = (entry->EffectBasePoints[i] + 1) * 75;
2098  dbc_node.maxvalue = (entry->EffectBasePoints[i] + 1) * 75;
2099 
2100  mSpellLearnSkills[spell] = dbc_node;
2101  ++dbc_count;
2102  break;
2103  }
2104  }
2105  }
2106 
2107  sLog.outString(">> Loaded %u Spell Learn Skills from DBC", dbc_count);
2108 }
2109 
2111 {
2112  mSpellLearnSpells.clear(); // need for reload case
2113 
2114  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT entry, SpellID FROM spell_learn_spell");
2115  if (!result)
2116  {
2117 
2118  sLog.outString(">> Loaded 0 spell learn spells");
2119  sLog.outErrorDb("spell_learn_spell table is empty!");
2120  return;
2121  }
2122 
2123  uint32 count = 0;
2124 
2125  do
2126  {
2127  Field* fields = result->Fetch();
2128 
2129  uint32 spell_id = fields[0].GetUInt32();
2130 
2131  SpellLearnSpellNode node;
2132  node.spell = fields[1].GetUInt32();
2133  node.autoLearned = false;
2134 
2135  if (!sSpellStore.LookupEntry(spell_id))
2136  {
2137  sLog.outErrorDb("Spell %u listed in spell_learn_spell does not exist", spell_id);
2138  continue;
2139  }
2140 
2141  if (!sSpellStore.LookupEntry(node.spell))
2142  {
2143  sLog.outErrorDb("Spell %u listed in spell_learn_spell does not exist", node.spell);
2144  continue;
2145  }
2146 
2147  mSpellLearnSpells.insert(SpellLearnSpellMap::value_type(spell_id, node));
2148 
2149  ++count;
2150  }
2151  while (result->NextRow());
2152 
2153  // search auto-learned spells and add its to map also for use in unlearn spells/talents
2154  uint32 dbc_count = 0;
2155  for (uint32 spell = 0; spell < sSpellStore.GetNumRows(); ++spell)
2156  {
2157  SpellEntry const* entry = sSpellStore.LookupEntry(spell);
2158 
2159  if (!entry)
2160  continue;
2161 
2162  for (int i = 0; i < MAX_SPELL_EFFECTS; ++i)
2163  {
2164  if (entry->Effect[i] == SPELL_EFFECT_LEARN_SPELL)
2165  {
2166  SpellLearnSpellNode dbc_node;
2167  dbc_node.spell = entry->EffectTriggerSpell[i];
2168  dbc_node.autoLearned = true;
2169 
2170  SpellLearnSpellMap::const_iterator db_node_begin = GetBeginSpellLearnSpell(spell);
2171  SpellLearnSpellMap::const_iterator db_node_end = GetEndSpellLearnSpell(spell);
2172 
2173  bool found = false;
2174  for (SpellLearnSpellMap::const_iterator itr = db_node_begin; itr != db_node_end; ++itr)
2175  {
2176  if (itr->second.spell == dbc_node.spell)
2177  {
2178  sLog.outErrorDb("Spell %u auto-learn spell %u in spell.dbc then the record in spell_learn_spell is redundant, please fix DB.",
2179  spell, dbc_node.spell);
2180  found = true;
2181  break;
2182  }
2183  }
2184 
2185  if (!found) // add new spell-spell pair if not found
2186  {
2187  mSpellLearnSpells.insert(SpellLearnSpellMap::value_type(spell, dbc_node));
2188  ++dbc_count;
2189  }
2190  }
2191  }
2192  }
2193 
2194  sLog.outString(">> Loaded %u spell learn spells + %u found in DBC", count, dbc_count);
2195 }
2196 
2198 {
2199  mSpellPetAuraMap.clear(); // need for reload case
2200 
2201  uint32 count = 0;
2202 
2203  // 0 1 2
2204  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT spell, pet, aura FROM spell_pet_auras");
2205  if (!result)
2206  {
2207  sLog.outString(">> Loaded %u spell pet auras", count);
2208  return;
2209  }
2210 
2211 
2212  do
2213  {
2214  Field* fields = result->Fetch();
2215 
2216  uint16 spell = fields[0].GetUInt16();
2217  uint16 pet = fields[1].GetUInt16();
2218  uint16 aura = fields[2].GetUInt16();
2219 
2220  SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find(spell);
2221  if (itr != mSpellPetAuraMap.end())
2222  itr->second.AddAura(pet, aura);
2223  else
2224  {
2225  SpellEntry const* spellInfo = sSpellStore.LookupEntry(spell);
2226  if (!spellInfo)
2227  {
2228  sLog.outErrorDb("Spell %u listed in spell_pet_auras does not exist", spell);
2229  continue;
2230  }
2231  int i = 0;
2232  for (; i < MAX_SPELL_EFFECTS; ++i)
2233  if ((spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA &&
2234  spellInfo->EffectApplyAuraName[i] == SPELL_AURA_DUMMY) ||
2235  spellInfo->Effect[i] == SPELL_EFFECT_DUMMY)
2236  break;
2237 
2238  if (i == 3)
2239  {
2240  sLog.outError("Spell %u listed in spell_pet_auras does not have dummy aura or dummy effect", spell);
2241  continue;
2242  }
2243 
2244  SpellEntry const* spellInfo2 = sSpellStore.LookupEntry(aura);
2245  if (!spellInfo2)
2246  {
2247  sLog.outErrorDb("Aura %u listed in spell_pet_auras does not exist", aura);
2248  continue;
2249  }
2250 
2251  PetAura pa(pet, aura, spellInfo->EffectImplicitTargetA[i] == TARGET_UNIT_PET, spellInfo->EffectBasePoints[i] + spellInfo->EffectBaseDice[i]);
2252  mSpellPetAuraMap[spell] = pa;
2253  }
2254 
2255  ++count;
2256  }
2257  while (result->NextRow());
2258 
2259  sLog.outString(">> Loaded %u spell pet auras", count);
2260 }
2261 
2262 // set data in core for now
2264 {
2265  mSpellCustomAttr.resize(GetSpellStore()->GetNumRows());
2266 
2267  SpellEntry* spellInfo;
2268  for (uint32 i = 0; i < GetSpellStore()->GetNumRows(); ++i)
2269  {
2270  mSpellCustomAttr[i] = 0;
2271  spellInfo = (SpellEntry*)GetSpellStore()->LookupEntry(i);
2272  if (!spellInfo)
2273  continue;
2274 
2275  bool auraSpell = true;
2276  for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2277  {
2278  if (spellInfo->Effect[j])
2279  if (spellInfo->Effect[j] != SPELL_EFFECT_APPLY_AURA
2281  //ignore target party for now
2282  {
2283  auraSpell = false;
2284  break;
2285  }
2286  }
2287  if (auraSpell)
2289 
2290  for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2291  {
2292  switch (spellInfo->EffectApplyAuraName[j])
2293  {
2298  break;
2302  break;
2303  case SPELL_AURA_MOD_ROOT:
2306  break;
2307  default:
2308  break;
2309  }
2310 
2311  switch (spellInfo->Effect[j])
2312  {
2318  case SPELL_EFFECT_HEAL:
2320  break;
2321  case SPELL_EFFECT_CHARGE:
2322  if (!spellInfo->speed && !spellInfo->SpellFamilyName)
2323  spellInfo->speed = SPEED_CHARGE;
2325  break;
2328  break;
2330  if (IsPositionTarget(spellInfo->EffectImplicitTargetA[j]) ||
2332  spellInfo->Effect[j] = SPELL_EFFECT_TRIGGER_MISSILE;
2333  break;
2335  // Self-Ressurect spells shouldn't be usable in arenas
2337  break;
2338  }
2339  }
2340 
2341  for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
2342  {
2343  switch (spellInfo->EffectApplyAuraName[j])
2344  {
2347  case SPELL_AURA_MOD_CHARM:
2348  case SPELL_AURA_MOD_FEAR:
2349  case SPELL_AURA_MOD_STUN:
2352  break;
2353  }
2354  }
2355 
2356  for (uint32 j = 0; j < 16; j++)
2357  {
2358  if (spellInfo->ToolTip[j] && *spellInfo->ToolTip[j])
2359  {
2361  break;
2362  }
2363  }
2364 
2365  if (spellInfo->SpellVisual == 3879)
2367 
2368  // Natural Shapeshifter
2369  if (spellInfo->Id == 16834 || spellInfo->Id == 16835)
2370  {
2371  SpellEntry const* baseInfo = sSpellStore.LookupEntry(16833);
2372  spellInfo->DurationIndex = baseInfo->DurationIndex;
2373  }
2374 
2375  switch (spellInfo->Category)
2376  {
2378  // these spells have 2min shared cooldown, But the time doesn't seem to be in dbcs.
2379  // I have really no idea from where client gets the data, perhaps hardcoded like this?
2380  spellInfo->RecoveryTime = 2 * 60 * IN_MILLISECONDS;
2381  spellInfo->StartRecoveryTime = 2 * 60 * IN_MILLISECONDS;
2382  spellInfo->StartRecoveryCategory = 2 * 60 * IN_MILLISECONDS;
2383  break;
2384  }
2385 
2386  switch (i)
2387  {
2388  case 26029: // dark glare
2389  case 37433: // spout
2390  case 43140:
2391  case 43215: // flame breath
2393  break;
2394  case 24340:
2395  case 26558:
2396  case 28884: // Meteor
2397  case 36837:
2398  case 38903:
2399  case 41276: // Meteor
2400  case 26789: // Shard of the Fallen Star
2401  case 31436: // Malevolent Cleave
2402  case 35181: // Dive Bomb
2403  case 40810:
2404  case 43267:
2405  case 43268: // Saber Lash
2406  case 42384: // Brutal Swipe
2407  case 45150: // Meteor Slash
2409  switch (i) // Saber Lash Targets
2410  {
2411  case 40810:
2412  spellInfo->MaxAffectedTargets = 3;
2413  break;
2414  case 43267:
2415  case 43268:
2416  spellInfo->MaxAffectedTargets = 2;
2417  break;
2418  }
2419  break;
2420  case 44978:
2421  case 45001:
2422  case 45002: // Wild Magic
2423  case 45004:
2424  case 45006:
2425  case 45010: // Wild Magic
2426  case 31347: // Doom
2427  case 41635: // Prayer of Mending
2428  case 44869: // Spectral Blast
2429  case 45027: // Revitalize
2430  case 45976: // Muru Portal Channel
2431  case 39365: // Thundering Storm
2432  case 41071: // Raise Dead
2433  case 41172: // Rapid Shot
2434  case 40834: // Agonizing Flames
2435  spellInfo->MaxAffectedTargets = 1;
2436  break;
2437  case 36384: // Skartax Purple Beam
2438  spellInfo->MaxAffectedTargets = 2;
2439  break;
2440  case 41357: // L1 Acane Charge
2441  case 41376: // Spite
2442  case 39992: // Needle Spine
2443  case 29576: // Multi-Shot
2444  case 37790: // Spread Shot
2445  case 45248: // Shadow Blades
2446  case 41303: // Soul Drain
2447  spellInfo->MaxAffectedTargets = 3;
2448  break;
2449  case 38310: // Multi-Shot
2450  spellInfo->MaxAffectedTargets = 4;
2451  break;
2452  case 32205: // Place Burning Blade Pyre
2453  spellInfo->AttributesEx2 |= SPELL_ATTR2_IGNORE_LOS;
2454  break;
2455  case 42005: // Bloodboil
2456  case 38296: // Spitfire Totem
2457  case 37676: // Insidious Whisper
2458  case 46008: // Negative Energy
2459  case 45641: // Fire Bloom
2460  case 5484: // Howl Of Terror
2461  case 46771: // Flame Sear
2462  spellInfo->MaxAffectedTargets = 5;
2463  break;
2464  case 15286: // Vampiric Embrace
2465  case 34914: // Vampiric Touch
2466  spellInfo->Attributes |= SPELL_ATTR0_NOT_SHAPESHIFT;
2468  spellInfo->Stances = FORM_SHADOW;
2469  break;
2470  case 40827: // Sinful Beam
2471  case 40859: // Sinister Beam
2472  case 40860: // Vile Beam
2473  case 40861: // Wicked Beam
2474  spellInfo->MaxAffectedTargets = 10;
2475  break;
2476  case 46841: // Escape to the Isle of Quel'Denas
2477  spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_CASTER;
2478  break;
2479  case 8122:
2480  case 8124:
2481  case 10888:
2482  case 10890: // Psychic Scream
2483  case 12494: // Frostbite
2485  break;
2486  case 38794:
2487  case 33711: //Murmur's Touch
2488  spellInfo->MaxAffectedTargets = 1;
2489  spellInfo->EffectTriggerSpell[0] = 33760;
2490  break;
2491  case 36350: //They Must Burn Bomb Aura (self)
2492  spellInfo->EffectTriggerSpell[0] = 36325; // They Must Burn Bomb Drop (DND)
2493  break;
2494  case 44949: // Whirlwind's offhand attack - @todo remove this (50% weapon damage effect)
2495  spellInfo->Effect[1] = 0;
2496  break;
2497  case 12723: // Sweeping Strikes proc
2500  break;
2501  case 24905: // Moonkin form -> elune's touch
2502  spellInfo->EffectImplicitTargetA[2] = TARGET_UNIT_CASTER;
2503  break;
2504  case 7922: // Charge stun
2505  case 25274: // Intercept stun
2506  case 2094: // Blind
2507  case 20424: // Seal of Command Trigger
2508  spellInfo->speed = 590.0f; // Minor delay
2509  break;
2510  case 32220: // Judgement of Blood
2511  spellInfo->speed = 5.0f; // Minor delay
2512  break;
2513  case 1833: // Cheap Shot
2514  spellInfo->speed = 1230.0f; // Tiny delay
2515  break;
2516  case 26679: // Deadly Throw
2517  spellInfo->speed = 0; // Instant
2518  break;
2519  case 41013: // Parasitic Shadowfiend Passive
2520  spellInfo->EffectApplyAuraName[0] = 4; // proc debuff, and summon infinite fiends
2521  break;
2522  case 1543: // Flare
2523  spellInfo->speed = 0;
2524  break;
2525  case 27892: // To Anchor 1
2526  case 27928: // To Anchor 1
2527  case 27935: // To Anchor 1
2528  case 27915: // Anchor to Skulls
2529  case 27931: // Anchor to Skulls
2530  case 27937: // Anchor to Skulls
2531  spellInfo->rangeIndex = 13;
2532  break;
2533  case 34580:
2535  break;
2536  case 39384:
2537  spellInfo->Effect[1] = 0; //Delete this effect, could be fixed also by implementing script_targets for each spell effect..
2538  spellInfo->rangeIndex = 16;//1y, don't know why, but with 5y (dbc value) all fields around are effected too, so somethings wrong in range check for those spells propably..
2539  break;
2540  case 6774:
2541  spellInfo->AttributesEx3 |= SPELL_ATTR3_NO_INITIAL_AGGRO; // slice and dice no longer gives combat or remove stealth
2543  break;
2544  case 29200: // Purify Helboar Meat
2545  spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER;
2546  spellInfo->EffectImplicitTargetB[0] = 0;
2547  break;
2548  case 35460: // Fury of the Dreghood Elders
2550  break;
2551  case 4073: // Mechanical Dragonling
2552  case 19804: // Arcanite Dragonling
2553  case 12749: // Mithril Mechanical Dragonling
2554  case 13258: // Summon Goblin Bomb
2555  case 13166: // Battle Chicken
2557  break;
2558  case 13279: // Gnomish Death Ray (Dummy Target)
2561  break;
2562  case 31828: // Blessed Life (Rank 1)
2563  case 31829: // Blessed Life (Rank 2)
2564  case 31830: // Blessed Life (Rank 3)
2566  break;
2567  case 39095: // Amplify Damage (Prince Malchaazar)
2569  spellInfo->EffectImplicitTargetB[0] = 0;
2570  break;
2571  case 42389: // Nalorakk's Mangle
2573  spellInfo->EffectImplicitTargetB[1] = 0;
2574  break;
2575  case 29955: // "Arcane Missiles implict correctly target"
2576  spellInfo->EffectImplicitTargetA[0] = TARGET_UNIT_CASTER;
2577  break;
2578  case 33206: // "Pain Suppression dispel resistance"
2580  break;
2581  case 19970: // Entangling Roots (Rank 6) -- Nature's Grasp Proc
2582  case 19971: // Entangling Roots (Rank 5) -- Nature's Grasp Proc
2583  case 19972: // Entangling Roots (Rank 4) -- Nature's Grasp Proc
2584  case 19973: // Entangling Roots (Rank 3) -- Nature's Grasp Proc
2585  case 19974: // Entangling Roots (Rank 2) -- Nature's Grasp Proc
2586  case 19975: // Entangling Roots (Rank 1) -- Nature's Grasp Proc
2587  case 27010: // Entangling Roots (Rank 7) -- Nature's Grasp Proc
2588  spellInfo->CastingTimeIndex = 1;
2589  break;
2590  case 19596: // Bestial Swiftness - append additional aura
2592  break;
2593  case 1206: // "REUSE" - we turn it into 30% outdoor movement speed bonus (for Bestial Swiftness)
2594  spellInfo->Effect[0] = SPELL_EFFECT_APPLY_AURA;
2596  spellInfo->EffectBasePoints[0] = 29; // all spells claiming they increase speed by 30% increase it just by 29%
2598  break;
2599  case 31789: // Righteous Defense
2600  spellInfo->EffectTriggerSpell[1] = 31790;
2601  break;
2602  case 47129: // Totemic Beacon
2603  spellInfo->EffectImplicitTargetA[1] = TARGET_NONE;
2604  break;
2605  case 40255: // Molten Flame
2606  // Molten Fire triggers itself, resulting in infinite cycling,
2607  // memory eating and a non-avoidable crash
2608  spellInfo->Effect[1] = 0;
2609  break;
2610  // Explosive Trap - fix initial dmg and proc
2611  case 13812: // rank 1
2612  case 14314: // rank 2
2613  case 14315: // rank 3
2614  case 27026: // rank 4
2616  break;
2617  // Frost Trap & Snake Trap - fix proc
2618  case 13810:
2619  case 45145:
2620  spellInfo->Effect[2] = SPELL_EFFECT_DUMMY;
2622  break;
2623  case 33778: // Lifebloom (rank 1)
2624  case 379: // Earth Shield
2625  case 38395: // Siphon Essence
2626  case 34299: // Improved Leader of the Pack (heal)
2627  case 27813: // Blessed Recovery rank 1
2628  case 27817: // Blessed Recovery rank 2
2629  case 27818: // Blessed Recovery rank 3
2630  case 28880: // Gift of Narru
2632  break;
2633  case 35372: // Protectorate Igniter
2636  break;
2637  case 30298: // Tree Disguise
2639  break;
2640  case 45391: // Vapor Select
2641  spellInfo->AttributesEx3 |= SPELL_ATTR3_CANT_MISS;
2642  spellInfo->MaxAffectedTargets = 1;
2643  break;
2644  case 45399: // Demonic Vapor Trail Periodic
2645  spellInfo->rangeIndex = 2;
2646  break;
2647  case 28730: // Arcane Torrent (mana)
2648  spellInfo->EffectImplicitTargetA[1] = TARGET_UNIT_CASTER;
2649  break;
2650  case 25046: // Arcane Torrent (energy)
2651  spellInfo->Effect[1] = SPELL_EFFECT_DUMMY;
2652  spellInfo->EffectImplicitTargetA[1] = TARGET_UNIT_CASTER;
2653  break;
2654  case 23505: // Berserking
2655  case 23451: // Speed
2656  spellInfo->Attributes |= SPELL_ATTR0_NEGATIVE_1;
2657  break;
2658  default:
2659  break;
2660  }
2661 
2662  switch (spellInfo->SpellFamilyName)
2663  {
2664  case SPELLFAMILY_WARRIOR:
2665  // Shout
2666  if (spellInfo->SpellFamilyFlags & 0x0000000000020000LL)
2668  break;
2669  case SPELLFAMILY_DRUID:
2670  // Roar
2671  if (spellInfo->SpellFamilyFlags & 0x0000000800000000LL)
2673  // Rake
2674  else if (spellInfo->SpellFamilyFlags & 0x1000LL)
2676  break;
2677  }
2678  }
2679 
2680  /* Fix some weird values in SpellItemEnchantment */
2681  for (uint32 i = 0; i <= 3340; i++)
2682  {
2683  if (SpellItemEnchantmentEntry* ench = const_cast<SpellItemEnchantmentEntry*>(sSpellItemEnchantmentStore.LookupEntry(i)))
2684  {
2685  switch (ench->ID)
2686  {
2687  // Flametongue Weapon
2688  case 5:
2689  ench->type[0] = ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL;
2690  ench->spellid[0] = 8026;
2691  break; // rank 1
2692  case 4:
2693  ench->type[0] = ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL;
2694  ench->spellid[0] = 8028;
2695  break; // rank 2
2696  case 3:
2697  ench->type[0] = ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL;
2698  ench->spellid[0] = 8029;
2699  break; // rank 3
2700  case 523:
2701  ench->type[0] = ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL;
2702  ench->spellid[0] = 10445;
2703  break; // rank 4
2704  case 1665:
2705  ench->type[0] = ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL;
2706  ench->spellid[0] = 16343;
2707  break; // rank 5
2708  case 1666:
2709  ench->type[0] = ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL;
2710  ench->spellid[0] = 16344;
2711  break; // rank 6
2712  case 2634:
2713  ench->type[0] = ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL;
2714  ench->spellid[0] = 25488;
2715  break; // rank 7
2716  }
2717  }
2718  }
2719 
2721 }
2722 
2724 {
2725  uint32 count = 0;
2726  SpellEntry* spellInfo;
2727 
2728  // 0 1
2729  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT spellid, cooldown FROM spell_cooldown");
2730  if (!result)
2731  {
2732  sLog.outString(">> Loaded %u custom spell cooldowns", count);
2733  return;
2734  }
2735 
2736  do
2737  {
2738  Field* fields = result->Fetch();
2739 
2740  int32 spellid = fields[0].GetInt32();
2741  uint32 cooldown = fields[1].GetUInt32();
2742 
2743  spellInfo = (SpellEntry*)GetSpellStore()->LookupEntry(spellid);
2744  if (!spellInfo)
2745  {
2746  sLog.outErrorDb("Spell %i listed in spell_cooldown does not exist", spellid);
2747  continue;
2748  }
2749 
2750  if (spellid > 0 && cooldown > 0)
2751  spellInfo->RecoveryTime = cooldown;
2752 
2753  ++count;
2754  }
2755  while (result->NextRow());
2756 
2757  sLog.outString(">> Loaded %u custom spell cooldowns", count);
2758 }
2759 
2761 {
2762  mSpellLinkedMap.clear(); // need for reload case
2763  uint32 count = 0;
2764 
2765  // 0 1 2
2766  QueryResult_AutoPtr result = WorldDatabase.Query("SELECT spell_trigger, spell_effect, type FROM spell_linked_spell");
2767  if (!result)
2768  {
2769  sLog.outString(">> Loaded %u linked spells", count);
2770  return;
2771  }
2772 
2773  do
2774  {
2775  Field* fields = result->Fetch();
2776 
2777  int32 trigger = fields[0].GetInt32();
2778  int32 effect = fields[1].GetInt32();
2779  int32 type = fields[2].GetInt32();
2780 
2781  SpellEntry const* spellInfo = sSpellStore.LookupEntry(abs(trigger));
2782  if (!spellInfo)
2783  {
2784  sLog.outErrorDb("Spell Trigger %i listed in spell_linked_spell does not exist", trigger);
2785  continue;
2786  }
2787  spellInfo = sSpellStore.LookupEntry(abs(effect));
2788  if (!spellInfo)
2789  {
2790  sLog.outErrorDb("Spell Effect %i listed in spell_linked_spell does not exist", effect);
2791  continue;
2792  }
2793 
2794  if (trigger > 0)
2795  {
2796  switch (type)
2797  {
2798  case 0:
2800  break;
2801  case 1:
2803  break;
2804  case 2:
2806  break;
2807  }
2808  }
2809  else
2811 
2812  if (type) //we will find a better way when more types are needed
2813  {
2814  if (trigger > 0)
2815  trigger += SPELL_LINKED_MAX_SPELLS * type;
2816  else
2817  trigger -= SPELL_LINKED_MAX_SPELLS * type;
2818  }
2819  mSpellLinkedMap[trigger].push_back(effect);
2820 
2821  ++count;
2822  }
2823  while (result->NextRow());
2824 
2825  sLog.outString(">> Loaded %u linked spells", count);
2826 }
2827 
2828 // Some checks for spells, to prevent adding depricated/broken spells for trainers, spell book, etc
2829 bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg)
2830 {
2831  // not exist
2832  if (!spellInfo)
2833  return false;
2834 
2835  bool need_check_reagents = false;
2836 
2837  // check effects
2838  for (int i = 0; i < 3; ++i)
2839  {
2840  switch (spellInfo->Effect[i])
2841  {
2842  case 0:
2843  continue;
2844 
2845  // craft spell for crafting non-existed item (break client recipes list show)
2847  {
2848  if (!ObjectMgr::GetItemTemplate(spellInfo->EffectItemType[i]))
2849  {
2850  if (msg)
2851  {
2852  if (pl)
2853  ChatHandler(pl).PSendSysMessage("Craft spell %u create not-exist in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->EffectItemType[i]);
2854  else
2855  sLog.outErrorDb("Craft spell %u create not-exist in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->EffectItemType[i]);
2856  }
2857  return false;
2858  }
2859 
2860  need_check_reagents = true;
2861  break;
2862  }
2864  {
2865  SpellEntry const* spellInfo2 = sSpellStore.LookupEntry(spellInfo->EffectTriggerSpell[i]);
2866  if (!IsSpellValid(spellInfo2, pl, msg))
2867  {
2868  if (msg)
2869  {
2870  if (pl)
2871  ChatHandler(pl).PSendSysMessage("Spell %u learn to broken spell %u, and then...", spellInfo->Id, spellInfo->EffectTriggerSpell[i]);
2872  else
2873  sLog.outErrorDb("Spell %u learn to invalid spell %u, and then...", spellInfo->Id, spellInfo->EffectTriggerSpell[i]);
2874  }
2875  return false;
2876  }
2877  break;
2878  }
2879  }
2880  }
2881 
2882  if (need_check_reagents)
2883  {
2884  for (int j = 0; j < 8; ++j)
2885  {
2886  if (spellInfo->Reagent[j] > 0 && !ObjectMgr::GetItemTemplate(spellInfo->Reagent[j]))
2887  {
2888  if (msg)
2889  {
2890  if (pl)
2891  ChatHandler(pl).PSendSysMessage("Craft spell %u has invalid reagent in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Reagent[j]);
2892  else
2893  sLog.outErrorDb("Craft spell %u has invalid reagent in DB item (Entry: %u) and then...", spellInfo->Id, spellInfo->Reagent[j]);
2894  }
2895  return false;
2896  }
2897  }
2898  }
2899 
2900  return true;
2901 }
2902 
2904 {
2905  // normal case
2906  if (spellInfo->AreaId && spellInfo->AreaId != zone_id && spellInfo->AreaId != area_id)
2908 
2909  // continent limitation (virtual continent)
2911  {
2912  uint32 v_map = GetVirtualMapForMapAndZone(map_id, zone_id);
2913  MapEntry const* mapEntry = sMapStore.LookupEntry(v_map);
2914  if (!mapEntry || mapEntry->addon < 1 || !mapEntry->IsContinent())
2916  }
2917 
2918  // raid instance limitation
2920  {
2921  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2922  if (!mapEntry || mapEntry->IsRaid())
2924  }
2925 
2926  // special cases zone check (maps checked by multimap common id)
2927  switch (spellInfo->Id)
2928  {
2929  case 46838: // Shattrath Flask of Pure Death
2930  case 41607: // Shattrath Flask of Fortification
2931  case 41605: // Shattrath Flask of Mighty Restoration
2932  case 41604: // Shattrath Flask of Supreme Power
2933  case 41606: // Shattrath Flask of Relentless Assault
2934  case 46840: // Shattrath Flask of Blinding Light
2935  {
2936  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2937  if (!mapEntry)
2939 
2940  // Tempest Keep // Black Temple // Serpentshrine Cavern // Sunwell // Mount Hyjal
2941  if (mapEntry->multimap_id == 206 || mapEntry->MapID == 564 || mapEntry->MapID == 548 || mapEntry->MapID == 580 || mapEntry->MapID == 534)
2942  return SPELL_CAST_OK;
2943  else
2944  return SPELL_FAILED_DONT_REPORT;
2945  }
2946  case 23333: // Warsong Flag
2947  case 23335: // Silverwing Flag
2948  case 46392: // Focused Assault
2949  case 46393: // Brutal Assault
2950  {
2951  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2952  if (!mapEntry)
2954 
2955  if (!mapEntry->IsBattleground())
2957 
2958  if (zone_id == 3277)
2959  return SPELL_CAST_OK;
2960 
2962  }
2963  case 34976: // Netherstorm Flag
2964  {
2965  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2966  if (!mapEntry)
2968 
2969  if (!mapEntry->IsBattleground())
2971 
2972  if (zone_id == 3820)
2973  return SPELL_CAST_OK;
2974 
2976  }
2977  case 32724: // Gold Team (Alliance)
2978  case 32725: // Green Team (Alliance)
2979  case 32727: // Arena Preparation
2980  case 35774: // Gold Team (Horde)
2981  case 35775: // Green Team (Horde)
2982  {
2983  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
2984  if (!mapEntry)
2986 
2987  //the follow code doesn't work.
2988  //if (!mapEntry->IsBattleArena())
2989  // return false;
2990 
2991  //this is the working code, HACK
2992  if (zone_id == 3702 || zone_id == 3968 || zone_id == 3698)
2993  return SPELL_CAST_OK;
2994 
2996  }
2997  case 41618: // Bottled Nethergon Energy
2998  case 41620: // Bottled Nethergon Vapor
2999  {
3000  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
3001  if (!mapEntry)
3003 
3004  return mapEntry->multimap_id == 206 ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
3005  }
3006  case 41617: // Cenarion Mana Salve
3007  case 41619: // Cenarion Healing Salve
3008  {
3009  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
3010  if (!mapEntry)
3012 
3013  return mapEntry->multimap_id == 207 ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
3014  }
3015  case 40216: // Dragonmaw Illusion
3016  case 42016: // Dragonmaw Illusion
3017  return (area_id == 3759 || area_id == 3966 || area_id == 3939) ? SPELL_CAST_OK : SPELL_FAILED_REQUIRES_AREA;
3018  case 2584: // Waiting to Resurrect
3019  case 22011: // Spirit Heal Channel
3020  case 22012: // Spirit Heal
3021  case 24171: // Resurrection Impact Visual
3022  case 42792: // Recently Dropped Flag
3023  case 43681: // Inactive
3024  case 44535: // Spirit Heal (mana)
3025  case 44521: // Preparation
3026  {
3027  MapEntry const* mapEntry = sMapStore.LookupEntry(map_id);
3028  if (!mapEntry)
3030 
3031  if (!mapEntry->IsBattleground())
3033  }
3034  }
3035 
3036  return SPELL_CAST_OK;
3037 }
3038 
3040 {
3041  mSkillLineAbilityMap.clear();
3042 
3043  uint32 count = 0;
3044 
3045  for (uint32 i = 0; i < sSkillLineAbilityStore.GetNumRows(); i++)
3046  {
3047  SkillLineAbilityEntry const* SkillInfo = sSkillLineAbilityStore.LookupEntry(i);
3048  if (!SkillInfo)
3049  continue;
3050 
3051  mSkillLineAbilityMap.insert(SkillLineAbilityMap::value_type(SkillInfo->spellId, SkillInfo));
3052  ++count;
3053  }
3054 
3055  sLog.outString(">> Loaded %u SkillLineAbility MultiMap", count);
3056 }
3057 
3059 {
3060  if (!spellproto || IsPositiveSpell(spellproto->Id))
3061  return DIMINISHING_NONE;
3062 
3063  // Explicit Diminishing Groups
3064  switch (spellproto->SpellFamilyName)
3065  {
3066  // Event + General spells
3067  case SPELLFAMILY_UNK1:
3068  return DIMINISHING_NONE;
3069  case SPELLFAMILY_MAGE:
3070  {
3071  // Item "Magic Dust" shouldn't be limited in PvP and
3072  // does not share DR with other sleep mechanics.
3073  if (spellproto->SpellIconID == 44)
3074  return DIMINISHING_NONE;
3075  break;
3076  // Frost Nova / Freeze (Water Elemental)
3077  if (spellproto->SpellIconID == 193)
3079  break;
3080  }
3081  case SPELLFAMILY_WARRIOR:
3082  {
3083  // Hamstring - limit duration to 10s in PvP
3084  if (spellproto->SpellFamilyFlags & 0x00000000002LL)
3085  return DIMINISHING_LIMITONLY;
3086  break;
3087  }
3088  case SPELLFAMILY_WARLOCK:
3089  {
3090  // Death Coil
3091  if (spellproto->SpellFamilyFlags & 0x00000080000LL)
3092  return DIMINISHING_HORROR;
3093  // Seduction
3094  else if (spellproto->SpellFamilyFlags & 0x00040000000LL)
3095  return DIMINISHING_FEAR;
3096  // Curses/etc
3097  else if (spellproto->SpellFamilyFlags & 0x00080000000LL)
3098  return DIMINISHING_LIMITONLY;
3099  // Unstable affliction dispel silence
3100  else if (spellproto->Id == 31117)
3101  return DIMINISHING_SILENCE;
3102  break;
3103  }
3104  case SPELLFAMILY_DRUID:
3105  {
3106  // Cyclone
3107  if (spellproto->SpellFamilyFlags & 0x02000000000LL)
3109  // Nature's Grasp trigger
3110  if (spellproto->SpellFamilyFlags & 0x00000000200LL && spellproto->Attributes == 0x49010000)
3112  break;
3113  }
3114  case SPELLFAMILY_ROGUE:
3115  {
3116  // Kidney Shot
3117  if (spellproto->SpellFamilyFlags & 0x00000200000LL)
3118  return DIMINISHING_KIDNEYSHOT;
3119  // Gouge
3120  else if (spellproto->SpellFamilyFlags & 0x00000000008LL)
3121  return DIMINISHING_DISORIENT;
3122  // Blind
3123  else if (spellproto->SpellFamilyFlags & 0x00001000000LL)
3125  break;
3126  }
3127  case SPELLFAMILY_HUNTER:
3128  {
3129  // Freezing trap
3130  if (spellproto->SpellFamilyFlags & 0x00000000008LL)
3131  return DIMINISHING_FREEZE;
3132  // Intimidation
3133  else if (spellproto->Id == 24394)
3135  // Entrapment (own diminishing)
3136  else if (spellproto->SpellVisual == 7484 && spellproto->SpellIconID == 20)
3137  return DIMINISHING_ENTRAPMENT;
3138  break;
3139  }
3140  case SPELLFAMILY_PALADIN:
3141  {
3142  // Turn Evil shared diminishing with fear
3143  if (spellproto->Id == 10326)
3144  return DIMINISHING_FEAR;
3145  break;
3146  }
3147  default:
3148  {
3149  if (spellproto->Id == 12494) // frostbite
3150  return DIMINISHING_ROOT;
3151  break;
3152  }
3153  }
3154 
3155  // Lastly - Set diminishing depending on mechanic
3156  uint32 mechanic = spellproto->GetAllEffectsMechanicMask();
3157  if (mechanic & (1 << MECHANIC_CHARM))
3158  return DIMINISHING_MIND_CONTROL;
3159  if (mechanic & (1 << MECHANIC_SLEEP))
3160  return DIMINISHING_SLEEP;
3161  if (mechanic & ((1 << MECHANIC_SAPPED) | (1 << MECHANIC_POLYMORPH) | (1 << MECHANIC_SHACKLE)))
3162  return DIMINISHING_DISORIENT;
3163  if (mechanic & (1 << MECHANIC_KNOCKOUT))
3164  return DIMINISHING_DISORIENT;
3165  if (mechanic & (1 << MECHANIC_DISARM))
3166  return DIMINISHING_DISARM;
3167  if (mechanic & (1 << MECHANIC_FEAR))
3168  return DIMINISHING_FEAR;
3169  if (mechanic & (1 << MECHANIC_STUN))
3170  return triggered ? DIMINISHING_STUN : DIMINISHING_CONTROLLED_STUN;
3171  if (mechanic & (1 << MECHANIC_BANISH))
3172  return DIMINISHING_BANISH;
3173  if (mechanic & (1 << MECHANIC_ROOT))
3174  return triggered ? DIMINISHING_ROOT : DIMINISHING_CONTROLLED_ROOT;
3175  if (mechanic & (1 << MECHANIC_FREEZE))
3176  return DIMINISHING_FREEZE;
3177  if (mechanic & (1 << MECHANIC_HORROR))
3178  return DIMINISHING_HORROR;
3179 
3180  return DIMINISHING_NONE;
3181 }
3182 
3184 {
3185  switch (group)
3186  {
3188  case DIMINISHING_STUN:
3190  case DIMINISHING_SLEEP:
3192  case DIMINISHING_ROOT:
3193  case DIMINISHING_FEAR:
3196  case DIMINISHING_DISORIENT:
3197  case DIMINISHING_FREEZE:
3199  case DIMINISHING_BANISH:
3200  case DIMINISHING_LIMITONLY:
3201  return true;
3202  default:
3203  break;
3204  }
3205  return false;
3206 }
3207 
3209 {
3210  switch (group)
3211  {
3214  case DIMINISHING_STUN:
3216  return DRTYPE_ALL;
3217  case DIMINISHING_SLEEP:
3219  case DIMINISHING_ROOT:
3220  case DIMINISHING_FEAR:
3222  case DIMINISHING_DISORIENT:
3223  case DIMINISHING_DISARM:
3224  case DIMINISHING_HORROR:
3225  case DIMINISHING_FREEZE:
3226  case DIMINISHING_BANISH:
3228  case DIMINISHING_SILENCE:
3229  return DRTYPE_PLAYER;
3230  default:
3231  break;
3232  }
3233 
3234  return DRTYPE_NONE;
3235 }
bool IsProfessionSkill(uint32 skill)
Definition: SpellMgr.h:825
uint32 AuraInterruptFlags
Definition: DBCStructure.h:700
SpellPetAuraMap mSpellPetAuraMap
Definition: SpellMgr.h:1231
uint32 GetLastSpellInChain(uint32 spell_id) const
Definition: SpellMgr.h:1061
void LoadSpellLearnSkills()
Definition: SpellMgr.cpp:2075
uint32 GetCreateMana() const
Definition: Unit.h:1558
uint32 Category
Definition: DBCStructure.h:675
uint32 spellLevel
Definition: DBCStructure.h:707
SpellSchools GetFirstSchoolInMask(SpellSchoolMask mask)
uint32 AttributesEx
Definition: DBCStructure.h:680
DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const *spellproto, bool triggered)
Definition: SpellMgr.cpp:3058
bool IsPrimaryProfessionFirstRankSpell(uint32 spellId) const
Definition: SpellMgr.cpp:1781
DBCStorage< SpellEntry > const * GetSpellStore()
Definition: DBCStores.cpp:776
uint32 CalculatePowerCost(SpellEntry const *spellInfo, Unit const *caster, SpellSchoolMask schoolMask)
Definition: SpellMgr.cpp:303
bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellInfo2)
Definition: SpellMgr.cpp:807
#define SPELL_GROUP_STACK_RULE_MAX
Definition: SpellMgr.h:685
uint32 SpellVisual
Definition: SpellMgr.cpp:1863
bool IsRangedSpell() const
Definition: Spell.h:465
uint32 MaxAffectedTargets
Definition: DBCStructure.h:762
uint32 spellFamilyName
Definition: SpellMgr.h:639
SpellProcEventMap mSpellProcEventMap
Definition: SpellMgr.h:1229
uint32 EffectTriggerSpell[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:741
uint32 GetPrevSpellInChain(uint32 spell_id) const
Definition: SpellMgr.h:1037
static bool canStackSpellRanks(SpellEntry const *spellInfo)
Definition: SpellMgr.cpp:1514
uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId)
Definition: DBCStores.cpp:652
uint32 MapID
Definition: DBCStructure.h:514
bool IsSingleTargetSpell(SpellEntry const *spellInfo)
Definition: SpellMgr.cpp:783
static void ClearAISpellInfo()
Definition: UnitAI.cpp:325
DatabaseType WorldDatabase
Accessor to the world database.
Definition: Main.cpp:53
bool IsPassiveSpell(uint32 spellId)
Definition: SpellMgr.cpp:278
char const * SpellName
Definition: SpellMgr.cpp:1860
bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group)
Definition: SpellMgr.cpp:3183
uint32 RangeIndex
Definition: SpellMgr.cpp:1862
SpellSchoolMask
uint32 SpellVisual
Definition: DBCStructure.h:743
DBCStorage< SpellCastTimesEntry > sSpellCastTimesStore(SpellCastTimefmt)
bool IsControlledByPlayer() const
Definition: Unit.h:1383
uint32 Stances
Definition: DBCStructure.h:686
Unit * GetCaster() const
Definition: Spell.h:509
static bool IsPrimaryProfessionSpell(uint32 spellId)
Definition: SpellMgr.cpp:1767
void LoadSpellProcEvents()
Definition: SpellMgr.cpp:1086
SpellGroupSpellMapBounds GetSpellGroupSpellMapBounds(SpellGroup group_id) const
Definition: SpellMgr.cpp:1676
QueryResult_AutoPtr PQuery(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:400
SpellSpellGroupMap mSpellSpellGroup
Definition: SpellMgr.h:1227
SpellSchools
SpellSpecific
Definition: SpellMgr.h:95
Definition: Field.h:24
SpellRequiredMap mSpellReq
Definition: SpellMgr.h:1221
void LoadSpellPetAuras()
Definition: SpellMgr.cpp:2197
void LoadSpellTargetPositions()
Definition: SpellMgr.cpp:887
SpellEnchantProcEventMap mSpellEnchantProcEventMap
Definition: SpellMgr.h:1235
bool IsAreaEffectTarget[TOTAL_SPELL_TARGETS]
Definition: SpellMgr.cpp:28
DBCStorage< GtNPCManaCostScalerEntry > sGtNPCManaCostScalerStore(GtNPCManaCostScalerfmt)
int32 EffectBaseDice[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:726
bool IsContinent() const
Definition: DBCStructure.h:583
uint32 AttributesEx2
Definition: DBCStructure.h:681
uint32 InterruptFlags
Definition: DBCStructure.h:699
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition: SpellMgr.cpp:3208
bool IsAutoRepeat() const
Definition: Spell.h:449
#define sLog
Log class singleton.
Definition: Log.h:187
DiminishingGroup
SpellSelectTargetTypes SpellTargetType[TOTAL_SPELL_TARGETS]
Definition: SpellMgr.h:1181
SpellLearnSpellMap::const_iterator GetBeginSpellLearnSpell(uint32 spell_id) const
Definition: SpellMgr.h:1104
std::pair< SpellGroupSpellMap::const_iterator, SpellGroupSpellMap::const_iterator > SpellGroupSpellMapBounds
Definition: SpellMgr.h:676
int32 GetSpellMaxDuration(SpellEntry const *spellInfo)
Definition: SpellMgr.cpp:238
SpellGroupStackRule CheckSpellGroupStackRules(uint32 spellInfo1, uint32 spellInfo2) const
Definition: SpellMgr.cpp:1708
void LoadSpellRequired()
Definition: SpellMgr.cpp:1826
ACE_INT32 int32
Definition: Define.h:67
QueryResult_AutoPtr Query(const char *sql)
Definition: Database.cpp:383
uint32 powerType
Definition: DBCStructure.h:709
void LoadSpellCustomCooldowns()
Definition: SpellMgr.cpp:2723
SkillLineAbilityMap mSkillLineAbilityMap
Definition: SpellMgr.h:1230
SpellTargetPositionMap mSpellTargetPositions
Definition: SpellMgr.h:1224
uint32 GetSpellCastTime(SpellEntry const *spellInfo, Spell const *spell)
Definition: SpellMgr.cpp:248
uint32 addon
Definition: DBCStructure.h:542
uint32 Effect[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:724
void LoadSpellEnchantProcData()
Definition: SpellMgr.cpp:1424
static SpellMgr & Instance()
Definition: SpellMgr.cpp:222
int32 EffectBasePoints[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:729
#define MAX_POWERS
static ItemTemplate const * GetItemTemplate(uint32 id)
Definition: ObjectMgr.h:648
char * Rank[16]
Definition: DBCStructure.h:750
void LoadSpellLinked()
Definition: SpellMgr.cpp:2760
DBCStorage< MapEntry > sMapStore(MapEntryfmt)
DBCStorage< SpellEntry > sSpellStore(SpellEntryfmt)
uint32 EffectApplyAuraName[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:734
uint32 rangeIndex
Definition: DBCStructure.h:714
void LoadSpellLearnSpells()
Definition: SpellMgr.cpp:2110
uint32 procFlags
Definition: DBCStructure.h:702
uint32 GetPower(Powers power) const
Definition: Unit.h:1096
uint32 multimap_id
Definition: DBCStructure.h:528
Spell is Pickpocket.
Definition: SpellMgr.h:851
uint8 getLevel() const
Definition: Unit.h:1057
uint32 GetAttackTime(WeaponAttackType att) const
Definition: Unit.h:1104
SpellSchoolMask GetSpellSchoolMask(SpellEntry const *spellInfo)
Definition: SpellMgr.h:481
uint32 CastingTimeIndex
Definition: DBCStructure.h:696
must ignore armor
Definition: SpellMgr.h:847
uint32 Attributes
Definition: DBCStructure.h:679
DBCStorage< TalentEntry > sTalentStore(TalentEntryfmt)
SpellGroup
Definition: SpellMgr.h:659
bool HasAttribute(SpellAttributes attribute) const
Definition: DBCStructure.h:774
bool IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2, bool sameCaster) const
Definition: SpellMgr.cpp:1560
uint32 Dispel
Definition: DBCStructure.h:677
char * SpellName[16]
Definition: DBCStructure.h:748
ACE_UINT8 uint8
Definition: Define.h:73
Powers
uint32 GetMaxPower(Powers power) const
Definition: Unit.h:1097
bool IsPrimaryProfessionSkill(uint32 skill)
Definition: SpellMgr.h:813
std::pair< SpellSpellGroupMap::const_iterator, SpellSpellGroupMap::const_iterator > SpellSpellGroupMapBounds
Definition: SpellMgr.h:672
uint32 AttributesEx3
Definition: DBCStructure.h:682
void LoadSpellChains()
Definition: SpellMgr.cpp:1890
uint32 TargetAuraState
Definition: SpellMgr.cpp:1866
#define TOTAL_SPELL_TARGETS
uint32 AttributesEx4
Definition: DBCStructure.h:683
bool IsBattleground() const
Definition: DBCStructure.h:562
void PSendSysMessage(const char *format,...) ATTR_PRINTF(2
Definition: Chat.cpp:858
bool IsPositiveEffect(uint32 spellId, uint32 effIndex)
Definition: SpellMgr.cpp:561
SpellDummyConditionMap mSpellDummyConditionMap
Definition: SpellMgr.h:1236
uint32 StancesNot
Definition: DBCStructure.h:687
uint8 GetSpellRank(uint32 spell_id) const
Definition: SpellMgr.h:1053
SpellEffIndex effIndex
Definition: SpellMgr.h:911
bool IsAffectedBySpell(SpellEntry const *spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const
Definition: SpellMgr.cpp:1054
void LoadSpellGroupStackRules()
Definition: SpellMgr.cpp:1341
TalentSpellPos const * GetTalentSpellPos(uint32 spellId)
Definition: DBCStores.cpp:589
uint32 GetFirstSpellInChain(uint32 spell_id) const
Definition: SpellMgr.h:1020
char const * Rank
Definition: SpellMgr.cpp:1887
uint32 Targets
Definition: DBCStructure.h:688
uint64 spellFamilyMask
Definition: SpellMgr.h:640
char * ToolTip[16]
Definition: DBCStructure.h:754
uint32 EffectImplicitTargetB[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:732
uint32 ProcFlags
Definition: SpellMgr.cpp:1864
SpellEffIndex
Definition: SharedDefines.h:24
etc mysql my cnf *Then change max_allowed_packet to a bigger value
SpellCustomAttribute mSpellCustomAttr
Definition: SpellMgr.h:1232
bool IsRankSpellDueToSpell(SpellEntry const *spellInfo_1, uint32 spellId_2) const
Definition: SpellMgr.cpp:1499
uint64 SpellFamilyFlags
Definition: DBCStructure.h:761
SpellLinkedMap mSpellLinkedMap
Definition: SpellMgr.h:1233
float m_modAttackSpeedPct[3]
Definition: Unit.h:1631
uint32 SpellIconID
Definition: DBCStructure.h:745
uint32 EffectImplicitTargetA[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:731
DBCStorage< SpellItemEnchantmentEntry > sSpellItemEnchantmentStore(SpellItemEnchantmentfmt)
void GetSetOfSpellsInSpellGroup(SpellGroup group_id, std::set< uint32 > &foundSpells) const
Definition: SpellMgr.cpp:1681
uint32 EffectItemType[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:738
SpellAffectMap mSpellAffectMap
Definition: SpellMgr.h:1226
SpellCastResult GetErrorAtShapeshiftedCast(SpellEntry const *spellInfo, uint32 form)
Definition: SpellMgr.cpp:842
DiminishingReturnsType
void LoadSpellAffects()
Definition: SpellMgr.cpp:964
bool IsAutocastableSpell(uint32 spellId)
Definition: SpellMgr.cpp:291
int32 Reagent[8]
Definition: DBCStructure.h:719
uint32 SchoolMask
Definition: DBCStructure.h:772
SpellLearnSpellMap mSpellLearnSpells
Definition: SpellMgr.h:1223
SpellLearnSkillMap mSpellLearnSkills
Definition: SpellMgr.h:1222
SpellLearnSpellMap::const_iterator GetEndSpellLearnSpell(uint32 spell_id) const
Definition: SpellMgr.h:1109
static void FillAISpellInfo()
Definition: UnitAI.cpp:272
int32 EffectMiscValue[MAX_SPELL_EFFECTS]
Definition: DBCStructure.h:739
bool IsSpellMemberOfSpellGroup(uint32 spellid, SpellGroup groupid) const
Definition: SpellMgr.cpp:1665
static bool IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const *spellProcEvent, uint32 EventProcFlag, SpellEntry const *procSpell, uint32 procFlags, uint32 procExtra, bool active)
Definition: SpellMgr.cpp:1147
SpellGroupStackRule
Definition: SpellMgr.h:678
int32 CompareAuraRanks(uint32 spellId_1, uint32 effIndex_1, uint32 spellId_2, uint32 effIndex_2)
Definition: SpellMgr.cpp:384
bool IsRaid() const
Definition: DBCStructure.h:558
bool IsPositiveSpell(uint32 spellId)
Definition: SpellMgr.cpp:773
uint64 GetSpellAffectMask(uint16 spellId, uint8 effectId) const
Definition: SpellMgr.h:934
bool IsSealSpell(SpellEntry const *spellInfo)
Definition: SpellMgr.h:215
SpellGroupStackMap mSpellGroupStack
Definition: SpellMgr.h:1234
SpellDummyCondition
Definition: SpellMgr.h:888
uint32 DurationIndex
Definition: DBCStructure.h:708
approves cast on any target, even when its non-attackable
Definition: SpellMgr.h:850
void LoadSkillLineAbilityMap()
Definition: SpellMgr.cpp:3039
uint32 TargetAuraState
Definition: DBCStructure.h:693
SpellGroupSpellMap mSpellGroupSpell
Definition: SpellMgr.h:1228
void LoadSpellThreats()
Definition: SpellMgr.cpp:1384
bool IsAuraAddedBySpell(uint32 auraType, uint32 spellId)
Definition: SpellMgr.cpp:831
ACE_UINT64 uint64
Definition: Define.h:70
DBCStorage< SpellDurationEntry > sSpellDurationStore(SpellDurationfmt)
float target_Orientation
Definition: SpellMgr.h:722
uint32 GetAllEffectsMechanicMask() const
Definition: DBCStructure.h:807
SpellThreatMap mSpellThreatMap
Definition: SpellMgr.h:1225
uint32 RankID[5]
Definition: DBCStructure.h:934
SpellsRequiringSpellMap mSpellsReqSpell
Definition: SpellMgr.h:1220
void LoadSpellGroups()
Definition: SpellMgr.cpp:1260
uint32 RecoveryTime
Definition: DBCStructure.h:697
Player * GetSpellModOwner() const
Definition: Unit.cpp:11862
bool IsElementalShield(SpellEntry const *spellInfo)
Definition: SpellMgr.h:223
ACE_Refcounted_Auto_Ptr< QueryResult, ACE_Null_Mutex > QueryResult_AutoPtr
Definition: QueryResult.h:113
uint32 AreaId
Definition: DBCStructure.h:771
SpellCastResult IsSpellAllowedInLocation(SpellEntry const *spellInfo, uint32 map_id, uint32 zone_id, uint32 area_id)
Definition: SpellMgr.cpp:2903
ignore bonus healing/damage
Definition: SpellMgr.h:849
uint32 SpellFamilyName
Definition: DBCStructure.h:760
uint32 DurationIndex
Definition: SpellMgr.cpp:1861
SpellEntry const * SelectAuraRankForPlayerLevel(SpellEntry const *spellInfo, uint32 playerLevel) const
Definition: SpellMgr.cpp:1786
uint32 GetCreateHealth() const
Definition: Unit.h:1550
static bool IsProfessionSpell(uint32 spellId)
Definition: SpellMgr.cpp:1753
#define SPEED_CHARGE
Definition: MotionMaster.h:80
bool IsPositionTarget(uint32 target)
Definition: SpellMgr.h:944
uint32 Mechanic
Definition: DBCStructure.h:678
bool operator()(const SpellRankEntry &_Left, const SpellRankEntry &_Right) const
Definition: SpellMgr.cpp:1869
SpellChainMap mSpellChains
Definition: SpellMgr.h:1219
uint32 GetTalentSpellCost(uint32 spellId)
Definition: DBCStores.cpp:598
#define MAX_SPELL_EFFECTS
Definition: DBCStructure.h:670
void LoadSpellCustomAttr()
Definition: SpellMgr.cpp:2263
SpellCastResult
const int32 & GetInt32Value(uint16 index) const
Definition: Object.h:204
related to movement impiaring effects
Definition: SpellMgr.h:846
uint32 StartRecoveryTime
Definition: DBCStructure.h:758
#define sWorld
Definition: World.h:860
SpellSpellGroupMapBounds GetSpellSpellGroupMapBounds(uint32 spell_id) const
Definition: SpellMgr.cpp:1659
uint32 ManaCostPercentage
Definition: DBCStructure.h:756
ACE_UINT16 uint16
Definition: Define.h:72
bool IsPositiveTarget(uint32 targetA, uint32 targetB)
Definition: SpellMgr.cpp:539
ACE_UINT32 uint32
Definition: Define.h:71
uint32 activeIconID
Definition: DBCStructure.h:746
must be cast from item, never directly
Definition: SpellMgr.h:848
SpellEffectTargetTypes EffectTargetType[TOTAL_SPELL_EFFECTS]
Definition: SpellMgr.h:1180
struct SpellDummyConditionEntry::@257 conditions[5]
uint32 GetHealth() const
Definition: Unit.h:1074
uint32 AttributesEx5
Definition: DBCStructure.h:684
void LoadSpellDummyCondition()
Definition: SpellMgr.cpp:1466
Definition: Unit.h:908
#define SPELL_LINKED_MAX_SPELLS
Definition: SpellMgr.h:117
Definition: Player.h:923
static bool IsSpellValid(SpellEntry const *spellInfo, Player *pl=NULL, bool msg=true)
Definition: SpellMgr.cpp:2829
DBCStorage< SpellShapeshiftEntry > sSpellShapeshiftStore(SpellShapeshiftfmt)
uint64 SpellFamilyFlags
Definition: SpellMgr.cpp:1865
int32 GetSpellDuration(SpellEntry const *spellInfo)
Definition: SpellMgr.cpp:228
SpellDummyCondition condition
Definition: SpellMgr.h:916
uint32 manaCost
Definition: DBCStructure.h:710
SpellMgr()
Definition: SpellMgr.cpp:30
DBCStorage< SkillLineAbilityEntry > sSkillLineAbilityStore(SkillLineAbilityfmt)
SpellSpecific GetSpellSpecific(uint32 spellId)
Definition: SpellMgr.cpp:396
uint32 StartRecoveryCategory
Definition: DBCStructure.h:757
const float & GetFloatValue(uint16 index) const
Definition: Object.h:222
Definition: Spell.h:249