TrinityCore
PlayerAI.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "PlayerAI.h"
19#include "Creature.h"
20#include "Item.h"
21#include "Map.h"
22#include "MotionMaster.h"
23#include "ObjectAccessor.h"
24#include "Player.h"
25#include "Spell.h"
26#include "SpellAuras.h"
27#include "SpellAuraEffects.h"
28#include "SpellHistory.h"
29#include "SpellMgr.h"
30
32{
33 /* Generic */
38
39 /* Warrior - Generic */
43 SPELL_CHARGE = 11578,
50
51 /* Warrior - Arms */
55 SPELL_REND = 47465,
59
60 /* Warrior - Fury */
69
70 /* Warrior - Protection */
81
82 /* Paladin - Generic */
93
94 /* Paladin - Holy*/
103
104 /* Paladin - Protection */
112
113 /* Paladin - Retribution */
119
120 /* Hunter - Generic */
128
129 /* Hunter - Beast Mastery */
133
134 /* Hunter - Marksmanship */
142
143 /* Hunter - Survival */
148
149 /* Rogue - Generic */
156
157 /* Rogue - Assassination */
162
163 /* Rogue - Combat */
169
170 /* Rogue - Sublety */
176
177 /* Priest - Generic */
186
187 /* Priest - Discipline */
194
195 /* Priest - Holy */
200 SPELL_RENEW = 48068,
201
202 /* Priest - Shadow */
211
212 /* Death Knight - Generic */
225
226 /* Death Knight - Blood */
234
235 /* Death Knight - Frost */
242
243 /* Death Knight - Unholy */
250
251 /* Shaman - Generic */
255
256 /* Shaman - Elemental*/
266
267 /* Shaman - Enhancement */
274
275 /* Shaman - Restoration*/
283
284 /* Mage - Generic */
292
293 /* Mage - Arcane */
301
302 /* Mage - Fire */
310
311 /* Mage - Frost */
319
320 /* Warlock - Generic */
329
330 /* Warlock - Affliction */
333 SPELL_HAUNT = 48181,
336
337 /* Warlock - Demonology */
346
347 /* Warlock - Destruction */
352
353 /* Druid - Generic */
356
357 /* Druid - Balance */
365 SPELL_WRATH = 48461,
366
367 /* Druid - Feral */
374 SPELL_RAKE = 48574,
375 SPELL_RIP = 49800,
378 SPELL_CLAW = 48570,
379 SPELL_DASH = 33357,
380 SPELL_MAIM = 49802,
381
382 /* Druid - Restoration */
392 SPELL_LIFEBLOOM = 48451
394
395PlayerAI::PlayerAI(Player* player) : UnitAI(player), me(player),
396 _selfSpec(player->GetPrimarySpecialization()),
397 _isSelfHealer(PlayerAI::IsPlayerHealer(player)),
398 _isSelfRangedAttacker(PlayerAI::IsPlayerRangedAttacker(player))
399{
400}
401
403{
406 return nullptr;
407}
408
409ChrSpecialization PlayerAI::GetSpec(Player const* who /*= nullptr*/) const
410{
411 return (!who || who == me) ? _selfSpec : who->GetPrimarySpecialization();
412}
413
415{
416 if (!who)
417 return false;
418
420 return chrSpec && chrSpec->GetRole() == ChrSpecializationRole::Healer;
421}
422
424{
425 if (!who)
426 return false;
427
429 return chrSpec && chrSpec->GetFlags().HasFlag(ChrSpecializationFlag::Ranged);
430}
431
433{
434 // Find highest spell rank that we know
435 uint32 knownRank, nextRank;
436 if (me->HasSpell(spellId))
437 {
438 // this will save us some lookups if the player has the highest rank (expected case)
439 knownRank = spellId;
440 nextRank = sSpellMgr->GetNextSpellInChain(spellId);
441 }
442 else
443 {
444 knownRank = 0;
445 nextRank = sSpellMgr->GetFirstSpellInChain(spellId);
446 }
447
448 while (nextRank && me->HasSpell(nextRank))
449 {
450 knownRank = nextRank;
451 nextRank = sSpellMgr->GetNextSpellInChain(knownRank);
452 }
453
454 if (!knownRank)
455 return {};
456
457 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(knownRank, me->GetMap()->GetDifficultyID());
458 if (!spellInfo)
459 return {};
460
461 if (me->GetSpellHistory()->HasGlobalCooldown(spellInfo))
462 return {};
463
464 Spell* spell = new Spell(me, spellInfo, TRIGGERED_NONE);
465 if (spell->CanAutoCast(target))
466 return{ spell, target };
467
468 delete spell;
469 return {};
470}
471
473{
474 Unit* pTarget = nullptr;
475 switch (target)
476 {
477 case TARGET_NONE:
478 break;
479 case TARGET_VICTIM:
480 pTarget = me->GetVictim();
481 if (!pTarget)
482 return {};
483 break;
484 case TARGET_CHARMER:
485 pTarget = me->GetCharmer();
486 if (!pTarget)
487 return {};
488 break;
489 case TARGET_SELF:
490 pTarget = me;
491 break;
492 }
493
494 return VerifySpellCast(spellId, pTarget);
495}
496
498{
499 if (spells.empty())
500 return{};
501
502 uint32 totalWeights = 0;
503 for (PossibleSpell const& wSpell : spells)
504 totalWeights += wSpell.second;
505
506 TargetedSpell selected;
507 uint32 randNum = urand(0, totalWeights - 1);
508 for (PossibleSpell const& wSpell : spells)
509 {
510 if (selected)
511 {
512 delete wSpell.first.first;
513 continue;
514 }
515
516 if (randNum < wSpell.second)
517 selected = wSpell.first;
518 else
519 {
520 randNum -= wSpell.second;
521 delete wSpell.first.first;
522 }
523 }
524
525 spells.clear();
526 return selected;
527}
528
530{
531 SpellCastTargets targets;
532 targets.SetUnitTarget(spell.second);
533 spell.first->prepare(targets);
534}
535
537{
539 return;
540
542 return;
543
544 Unit* victim = me->GetVictim();
545 if (!victim)
546 return;
547
548 uint32 rangedAttackSpell = 0;
549
551 if (ItemTemplate const* rangedTemplate = rangedItem ? rangedItem->GetTemplate() : nullptr)
552 {
553 switch (rangedTemplate->GetSubClass())
554 {
558 rangedAttackSpell = SPELL_SHOOT;
559 break;
561 rangedAttackSpell = SPELL_THROW;
562 break;
564 rangedAttackSpell = SPELL_SHOOT_WAND;
565 break;
566 }
567 }
568
569 if (!rangedAttackSpell)
570 return;
571
572 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(rangedAttackSpell, me->GetMap()->GetDifficultyID());
573 if (!spellInfo)
574 return;
575
576 Spell* spell = new Spell(me, spellInfo, TRIGGERED_CAST_DIRECTLY);
577 if (spell->CheckPetCast(victim) != SPELL_CAST_OK)
578 {
579 delete spell;
580 return;
581 }
582
583 SpellCastTargets targets;
584 targets.SetUnitTarget(victim);
585 spell->prepare(targets);
586
588}
589
591{
592 if (IsRangedAttacker())
594}
595
597{
599 std::set<Aura*> removableShapeshifts;
600 for (AuraEffect* auraEff : shapeshiftAuras)
601 {
602 Aura* aura = auraEff->GetBase();
603 if (!aura)
604 continue;
605 SpellInfo const* auraInfo = aura->GetSpellInfo();
606 if (!auraInfo)
607 continue;
609 continue;
610 if (!auraInfo->IsPositive() || auraInfo->IsPassive())
611 continue;
612 removableShapeshifts.insert(aura);
613 }
614
615 for (Aura* aura : removableShapeshifts)
617}
618
620{
621 return me->GetCharmer() ? me->GetCharmer()->GetVictim() : nullptr;
622}
623
625{
627 UnitAI const* const _ai;
628 bool operator()(Unit const* target) const
629 {
630 return _ai->CanAIAttack(target);
631 }
632};
633
635{
637 return false;
638 if (Unit* charmer = me->GetCharmer())
639 if (!charmer->IsValidAttackTarget(who))
640 return false;
641 return UnitAI::CanAIAttack(who);
642}
643
645{
646 if (Unit* charmer = me->GetCharmer())
647 {
648 if (UnitAI* charmerAI = charmer->GetAI())
649 return charmerAI->SelectTarget(SelectTargetMethod::Random, 0, ValidTargetSelectPredicate(this));
650 return charmer->GetVictim();
651 }
652 return nullptr;
653}
654
656{
657 PossibleSpellVector spells;
658 /*
659 switch (me->getClass())
660 {
661 case CLASS_WARRIOR:
662 if (!me->IsWithinMeleeRange(me->GetVictim()))
663 {
664 VerifyAndPushSpellCast(spells, SPELL_CHARGE, TARGET_VICTIM, 15);
665 VerifyAndPushSpellCast(spells, SPELL_INTERCEPT, TARGET_VICTIM, 10);
666 }
667 VerifyAndPushSpellCast(spells, SPELL_ENRAGED_REGEN, TARGET_NONE, 3);
668 VerifyAndPushSpellCast(spells, SPELL_INTIMIDATING_SHOUT, TARGET_VICTIM, 4);
669 if (me->GetVictim() && me->GetVictim()->HasUnitState(UNIT_STATE_CASTING))
670 {
671 VerifyAndPushSpellCast(spells, SPELL_PUMMEL, TARGET_VICTIM, 15);
672 VerifyAndPushSpellCast(spells, SPELL_SHIELD_BASH, TARGET_VICTIM, 15);
673 }
674 VerifyAndPushSpellCast(spells, SPELL_BLOODRAGE, TARGET_NONE, 5);
675 switch (GetSpec())
676 {
677 case TALENT_SPEC_WARRIOR_PROTECTION:
678 VerifyAndPushSpellCast(spells, SPELL_SHOCKWAVE, TARGET_VICTIM, 3);
679 VerifyAndPushSpellCast(spells, SPELL_CONCUSSION_BLOW, TARGET_VICTIM, 5);
680 VerifyAndPushSpellCast(spells, SPELL_DISARM, TARGET_VICTIM, 2);
681 VerifyAndPushSpellCast(spells, SPELL_LAST_STAND, TARGET_NONE, 5);
682 VerifyAndPushSpellCast(spells, SPELL_SHIELD_BLOCK, TARGET_NONE, 1);
683 VerifyAndPushSpellCast(spells, SPELL_SHIELD_SLAM, TARGET_VICTIM, 4);
684 VerifyAndPushSpellCast(spells, SPELL_SHIELD_WALL, TARGET_NONE, 5);
685 VerifyAndPushSpellCast(spells, SPELL_SPELL_REFLECTION, TARGET_NONE, 3);
686 VerifyAndPushSpellCast(spells, SPELL_DEVASTATE, TARGET_VICTIM, 2);
687 VerifyAndPushSpellCast(spells, SPELL_REND, TARGET_VICTIM, 1);
688 VerifyAndPushSpellCast(spells, SPELL_THUNDER_CLAP, TARGET_VICTIM, 2);
689 VerifyAndPushSpellCast(spells, SPELL_DEMO_SHOUT, TARGET_VICTIM, 1);
690 break;
691 case TALENT_SPEC_WARRIOR_ARMS:
692 VerifyAndPushSpellCast(spells, SPELL_SWEEPING_STRIKES, TARGET_NONE, 2);
693 VerifyAndPushSpellCast(spells, SPELL_MORTAL_STRIKE, TARGET_VICTIM, 5);
694 VerifyAndPushSpellCast(spells, SPELL_BLADESTORM, TARGET_NONE, 10);
695 VerifyAndPushSpellCast(spells, SPELL_REND, TARGET_VICTIM, 1);
696 VerifyAndPushSpellCast(spells, SPELL_RETALIATION, TARGET_NONE, 3);
697 VerifyAndPushSpellCast(spells, SPELL_SHATTERING_THROW, TARGET_VICTIM, 3);
698 VerifyAndPushSpellCast(spells, SPELL_SWEEPING_STRIKES, TARGET_NONE, 5);
699 VerifyAndPushSpellCast(spells, SPELL_THUNDER_CLAP, TARGET_VICTIM, 1);
700 VerifyAndPushSpellCast(spells, SPELL_EXECUTE, TARGET_VICTIM, 15);
701 break;
702 case TALENT_SPEC_WARRIOR_FURY:
703 VerifyAndPushSpellCast(spells, SPELL_DEATH_WISH, TARGET_NONE, 10);
704 VerifyAndPushSpellCast(spells, SPELL_BLOODTHIRST, TARGET_VICTIM, 4);
705 VerifyAndPushSpellCast(spells, SPELL_DEMO_SHOUT, TARGET_VICTIM, 2);
706 VerifyAndPushSpellCast(spells, SPELL_EXECUTE, TARGET_VICTIM, 15);
707 VerifyAndPushSpellCast(spells, SPELL_HEROIC_FURY, TARGET_NONE, 5);
708 VerifyAndPushSpellCast(spells, SPELL_RECKLESSNESS, TARGET_NONE, 8);
709 VerifyAndPushSpellCast(spells, SPELL_PIERCING_HOWL, TARGET_VICTIM, 2);
710 break;
711 }
712 break;
713 case CLASS_PALADIN:
714 VerifyAndPushSpellCast(spells, SPELL_AURA_MASTERY, TARGET_NONE, 3);
715 VerifyAndPushSpellCast(spells, SPELL_LAY_ON_HANDS, TARGET_CHARMER, 8);
716 VerifyAndPushSpellCast(spells, SPELL_BLESSING_OF_MIGHT, TARGET_CHARMER, 8);
717 VerifyAndPushSpellCast(spells, SPELL_AVENGING_WRATH, TARGET_NONE, 5);
718 VerifyAndPushSpellCast(spells, SPELL_DIVINE_PROTECTION, TARGET_NONE, 4);
719 VerifyAndPushSpellCast(spells, SPELL_DIVINE_SHIELD, TARGET_NONE, 2);
720 VerifyAndPushSpellCast(spells, SPELL_HAMMER_OF_JUSTICE, TARGET_VICTIM, 6);
721 VerifyAndPushSpellCast(spells, SPELL_HAND_OF_FREEDOM, TARGET_SELF, 3);
722 VerifyAndPushSpellCast(spells, SPELL_HAND_OF_PROTECTION, TARGET_SELF, 1);
723 if (Creature* creatureCharmer = GetCharmer())
724 {
725 if (creatureCharmer->IsDungeonBoss() || creatureCharmer->isWorldBoss())
726 VerifyAndPushSpellCast(spells, SPELL_HAND_OF_SACRIFICE, creatureCharmer, 10);
727 else
728 VerifyAndPushSpellCast(spells, SPELL_HAND_OF_PROTECTION, creatureCharmer, 3);
729 }
730
731 switch (GetSpec())
732 {
733 case TALENT_SPEC_PALADIN_PROTECTION:
734 VerifyAndPushSpellCast(spells, SPELL_HAMMER_OF_RIGHTEOUS, TARGET_VICTIM, 3);
735 VerifyAndPushSpellCast(spells, SPELL_DIVINE_SACRIFICE, TARGET_NONE, 2);
736 VerifyAndPushSpellCast(spells, SPELL_SHIELD_OF_RIGHTEOUS, TARGET_VICTIM, 4);
737 VerifyAndPushSpellCast(spells, SPELL_JUDGEMENT, TARGET_VICTIM, 2);
738 VerifyAndPushSpellCast(spells, SPELL_CONSECRATION, TARGET_VICTIM, 2);
739 VerifyAndPushSpellCast(spells, SPELL_HOLY_SHIELD, TARGET_NONE, 1);
740 break;
741 case TALENT_SPEC_PALADIN_HOLY:
742 VerifyAndPushSpellCast(spells, SPELL_HOLY_SHOCK, TARGET_CHARMER, 3);
743 VerifyAndPushSpellCast(spells, SPELL_HOLY_SHOCK, TARGET_VICTIM, 1);
744 VerifyAndPushSpellCast(spells, SPELL_FLASH_OF_LIGHT, TARGET_CHARMER, 4);
745 VerifyAndPushSpellCast(spells, SPELL_HOLY_LIGHT, TARGET_CHARMER, 3);
746 VerifyAndPushSpellCast(spells, SPELL_DIVINE_FAVOR, TARGET_NONE, 5);
747 VerifyAndPushSpellCast(spells, SPELL_DIVINE_ILLUMINATION, TARGET_NONE, 3);
748 break;
749 case TALENT_SPEC_PALADIN_RETRIBUTION:
750 VerifyAndPushSpellCast(spells, SPELL_CRUSADER_STRIKE, TARGET_VICTIM, 4);
751 VerifyAndPushSpellCast(spells, SPELL_DIVINE_STORM, TARGET_VICTIM, 5);
752 VerifyAndPushSpellCast(spells, SPELL_JUDGEMENT, TARGET_VICTIM, 3);
753 VerifyAndPushSpellCast(spells, SPELL_HAMMER_OF_WRATH, TARGET_VICTIM, 5);
754 VerifyAndPushSpellCast(spells, SPELL_RIGHTEOUS_FURY, TARGET_NONE, 2);
755 break;
756 }
757 break;
758 case CLASS_HUNTER:
759 VerifyAndPushSpellCast(spells, SPELL_DETERRENCE, TARGET_NONE, 3);
760 VerifyAndPushSpellCast(spells, SPELL_EXPLOSIVE_TRAP, TARGET_NONE, 1);
761 VerifyAndPushSpellCast(spells, SPELL_FREEZING_ARROW, TARGET_VICTIM, 2);
762 VerifyAndPushSpellCast(spells, SPELL_RAPID_FIRE, TARGET_NONE, 10);
763 VerifyAndPushSpellCast(spells, SPELL_KILL_SHOT, TARGET_VICTIM, 10);
764 if (me->GetVictim() && me->GetVictim()->GetPowerType() == POWER_MANA && !me->GetVictim()->GetAuraApplicationOfRankedSpell(SPELL_VIPER_STING, me->GetGUID()))
765 VerifyAndPushSpellCast(spells, SPELL_VIPER_STING, TARGET_VICTIM, 5);
766
767 switch (GetSpec())
768 {
769 case TALENT_SPEC_HUNTER_BEASTMASTER:
770 VerifyAndPushSpellCast(spells, SPELL_AIMED_SHOT, TARGET_VICTIM, 2);
771 VerifyAndPushSpellCast(spells, SPELL_ARCANE_SHOT, TARGET_VICTIM, 3);
772 VerifyAndPushSpellCast(spells, SPELL_STEADY_SHOT, TARGET_VICTIM, 2);
773 VerifyAndPushSpellCast(spells, SPELL_MULTI_SHOT, TARGET_VICTIM, 2);
774 break;
775 case TALENT_SPEC_HUNTER_MARKSMAN:
776 VerifyAndPushSpellCast(spells, SPELL_AIMED_SHOT, TARGET_VICTIM, 2);
777 VerifyAndPushSpellCast(spells, SPELL_CHIMERA_SHOT, TARGET_VICTIM, 5);
778 VerifyAndPushSpellCast(spells, SPELL_ARCANE_SHOT, TARGET_VICTIM, 3);
779 VerifyAndPushSpellCast(spells, SPELL_STEADY_SHOT, TARGET_VICTIM, 2);
780 VerifyAndPushSpellCast(spells, SPELL_READINESS, TARGET_NONE, 10);
781 VerifyAndPushSpellCast(spells, SPELL_SILENCING_SHOT, TARGET_VICTIM, 5);
782 break;
783 case TALENT_SPEC_HUNTER_SURVIVAL:
784 VerifyAndPushSpellCast(spells, SPELL_EXPLOSIVE_SHOT, TARGET_VICTIM, 8);
785 VerifyAndPushSpellCast(spells, SPELL_BLACK_ARROW, TARGET_VICTIM, 5);
786 VerifyAndPushSpellCast(spells, SPELL_MULTI_SHOT, TARGET_VICTIM, 3);
787 VerifyAndPushSpellCast(spells, SPELL_STEADY_SHOT, TARGET_VICTIM, 1);
788 break;
789 }
790 break;
791 case CLASS_ROGUE:
792 {
793 VerifyAndPushSpellCast(spells, SPELL_DISMANTLE, TARGET_VICTIM, 8);
794 VerifyAndPushSpellCast(spells, SPELL_EVASION, TARGET_NONE, 8);
795 VerifyAndPushSpellCast(spells, SPELL_VANISH, TARGET_NONE, 4);
796 VerifyAndPushSpellCast(spells, SPELL_BLIND, TARGET_VICTIM, 2);
797 VerifyAndPushSpellCast(spells, SPELL_CLOAK_OF_SHADOWS, TARGET_NONE, 2);
798
799 uint32 builder = 0, finisher = 0;
800 switch (GetSpec())
801 {
802 case TALENT_SPEC_ROGUE_ASSASSINATION:
803 builder = SPELL_MUTILATE, finisher = SPELL_ENVENOM;
804 VerifyAndPushSpellCast(spells, SPELL_COLD_BLOOD, TARGET_NONE, 20);
805 break;
806 case TALENT_SPEC_ROGUE_COMBAT:
807 builder = SPELL_SINISTER_STRIKE, finisher = SPELL_EVISCERATE;
808 VerifyAndPushSpellCast(spells, SPELL_ADRENALINE_RUSH, TARGET_NONE, 6);
809 VerifyAndPushSpellCast(spells, SPELL_BLADE_FLURRY, TARGET_NONE, 5);
810 VerifyAndPushSpellCast(spells, SPELL_KILLING_SPREE, TARGET_NONE, 25);
811 break;
812 case TALENT_SPEC_ROGUE_SUBTLETY:
813 builder = SPELL_HEMORRHAGE, finisher = SPELL_EVISCERATE;
814 VerifyAndPushSpellCast(spells, SPELL_PREPARATION, TARGET_NONE, 10);
815 if (!me->IsWithinMeleeRange(me->GetVictim()))
816 VerifyAndPushSpellCast(spells, SPELL_SHADOWSTEP, TARGET_VICTIM, 25);
817 VerifyAndPushSpellCast(spells, SPELL_SHADOW_DANCE, TARGET_NONE, 10);
818 break;
819 }
820
821 if (Unit* victim = me->GetVictim())
822 {
823 if (victim->HasUnitState(UNIT_STATE_CASTING))
824 VerifyAndPushSpellCast(spells, SPELL_KICK, TARGET_VICTIM, 25);
825
826 uint8 const cp = me->GetPower(POWER_COMBO_POINTS);
827 if (cp >= 4)
828 VerifyAndPushSpellCast(spells, finisher, TARGET_VICTIM, 10);
829 if (cp <= 4)
830 VerifyAndPushSpellCast(spells, builder, TARGET_VICTIM, 5);
831 }
832 break;
833 }
834 case CLASS_PRIEST:
835 VerifyAndPushSpellCast(spells, SPELL_FEAR_WARD, TARGET_SELF, 2);
836 VerifyAndPushSpellCast(spells, SPELL_POWER_WORD_FORT, TARGET_CHARMER, 1);
837 VerifyAndPushSpellCast(spells, SPELL_DIVINE_SPIRIT, TARGET_CHARMER, 1);
838 VerifyAndPushSpellCast(spells, SPELL_SHADOW_PROTECTION, TARGET_CHARMER, 2);
839 VerifyAndPushSpellCast(spells, SPELL_DIVINE_HYMN, TARGET_NONE, 5);
840 VerifyAndPushSpellCast(spells, SPELL_HYMN_OF_HOPE, TARGET_NONE, 5);
841 VerifyAndPushSpellCast(spells, SPELL_SHADOW_WORD_DEATH, TARGET_VICTIM, 1);
842 VerifyAndPushSpellCast(spells, SPELL_PSYCHIC_SCREAM, TARGET_VICTIM, 3);
843 switch (GetSpec())
844 {
845 case TALENT_SPEC_PRIEST_DISCIPLINE:
846 VerifyAndPushSpellCast(spells, SPELL_POWER_WORD_SHIELD, TARGET_CHARMER, 3);
847 VerifyAndPushSpellCast(spells, SPELL_INNER_FOCUS, TARGET_NONE, 3);
848 VerifyAndPushSpellCast(spells, SPELL_PAIN_SUPPRESSION, TARGET_CHARMER, 15);
849 VerifyAndPushSpellCast(spells, SPELL_POWER_INFUSION, TARGET_CHARMER, 10);
850 VerifyAndPushSpellCast(spells, SPELL_PENANCE, TARGET_CHARMER, 3);
851 VerifyAndPushSpellCast(spells, SPELL_FLASH_HEAL, TARGET_CHARMER, 1);
852 break;
853 case TALENT_SPEC_PRIEST_HOLY:
854 VerifyAndPushSpellCast(spells, SPELL_DESPERATE_PRAYER, TARGET_NONE, 3);
855 VerifyAndPushSpellCast(spells, SPELL_GUARDIAN_SPIRIT, TARGET_CHARMER, 5);
856 VerifyAndPushSpellCast(spells, SPELL_FLASH_HEAL, TARGET_CHARMER, 1);
857 VerifyAndPushSpellCast(spells, SPELL_RENEW, TARGET_CHARMER, 3);
858 break;
859 case TALENT_SPEC_PRIEST_SHADOW:
860 if (!me->HasAura(SPELL_SHADOWFORM))
861 {
862 VerifyAndPushSpellCast(spells, SPELL_SHADOWFORM, TARGET_NONE, 100);
863 break;
864 }
865 if (Unit* victim = me->GetVictim())
866 {
867 if (!victim->GetAuraApplicationOfRankedSpell(SPELL_VAMPIRIC_TOUCH, me->GetGUID()))
868 VerifyAndPushSpellCast(spells, SPELL_VAMPIRIC_TOUCH, TARGET_VICTIM, 4);
869 if (!victim->GetAuraApplicationOfRankedSpell(SPELL_SHADOW_WORD_PAIN, me->GetGUID()))
870 VerifyAndPushSpellCast(spells, SPELL_SHADOW_WORD_PAIN, TARGET_VICTIM, 3);
871 if (!victim->GetAuraApplicationOfRankedSpell(SPELL_DEVOURING_PLAGUE, me->GetGUID()))
872 VerifyAndPushSpellCast(spells, SPELL_DEVOURING_PLAGUE, TARGET_VICTIM, 4);
873 }
874 VerifyAndPushSpellCast(spells, SPELL_MIND_BLAST, TARGET_VICTIM, 3);
875 VerifyAndPushSpellCast(spells, SPELL_MIND_FLAY, TARGET_VICTIM, 2);
876 VerifyAndPushSpellCast(spells, SPELL_DISPERSION, TARGET_NONE, 10);
877 break;
878 }
879 break;
880 case CLASS_DEATH_KNIGHT:
881 {
882 if (!me->IsWithinMeleeRange(me->GetVictim()))
883 VerifyAndPushSpellCast(spells, SPELL_DEATH_GRIP, TARGET_VICTIM, 25);
884 VerifyAndPushSpellCast(spells, SPELL_STRANGULATE, TARGET_VICTIM, 15);
885 VerifyAndPushSpellCast(spells, SPELL_EMPOWER_RUNE_WEAP, TARGET_NONE, 5);
886 VerifyAndPushSpellCast(spells, SPELL_ICEBORN_FORTITUDE, TARGET_NONE, 15);
887 VerifyAndPushSpellCast(spells, SPELL_ANTI_MAGIC_SHELL, TARGET_NONE, 10);
888
889 bool hasFF = false, hasBP = false;
890 if (Unit* victim = me->GetVictim())
891 {
892 if (victim->HasUnitState(UNIT_STATE_CASTING))
893 VerifyAndPushSpellCast(spells, SPELL_MIND_FREEZE, TARGET_VICTIM, 25);
894
895 hasFF = !!victim->GetAuraApplicationOfRankedSpell(AURA_FROST_FEVER, me->GetGUID()), hasBP = !!victim->GetAuraApplicationOfRankedSpell(AURA_BLOOD_PLAGUE, me->GetGUID());
896 if (hasFF && hasBP)
897 VerifyAndPushSpellCast(spells, SPELL_PESTILENCE, TARGET_VICTIM, 3);
898 if (!hasFF)
899 VerifyAndPushSpellCast(spells, SPELL_ICY_TOUCH, TARGET_VICTIM, 4);
900 if (!hasBP)
901 VerifyAndPushSpellCast(spells, SPELL_PLAGUE_STRIKE, TARGET_VICTIM, 4);
902 }
903 switch (GetSpec())
904 {
905 case TALENT_SPEC_DEATHKNIGHT_BLOOD:
906 VerifyAndPushSpellCast(spells, SPELL_RUNE_TAP, TARGET_NONE, 2);
907 VerifyAndPushSpellCast(spells, SPELL_HYSTERIA, TARGET_SELF, 5);
908 if (Creature* creatureCharmer = GetCharmer())
909 if (!creatureCharmer->IsDungeonBoss() && !creatureCharmer->isWorldBoss())
910 VerifyAndPushSpellCast(spells, SPELL_HYSTERIA, creatureCharmer, 15);
911 VerifyAndPushSpellCast(spells, SPELL_HEART_STRIKE, TARGET_VICTIM, 2);
912 if (hasFF && hasBP)
913 VerifyAndPushSpellCast(spells, SPELL_DEATH_STRIKE, TARGET_VICTIM, 8);
914 VerifyAndPushSpellCast(spells, SPELL_DEATH_COIL_DK, TARGET_VICTIM, 1);
915 VerifyAndPushSpellCast(spells, SPELL_MARK_OF_BLOOD, TARGET_VICTIM, 20);
916 VerifyAndPushSpellCast(spells, SPELL_VAMPIRIC_BLOOD, TARGET_NONE, 10);
917 break;
918 case TALENT_SPEC_DEATHKNIGHT_FROST:
919 if (hasFF && hasBP)
920 VerifyAndPushSpellCast(spells, SPELL_OBLITERATE, TARGET_VICTIM, 5);
921 VerifyAndPushSpellCast(spells, SPELL_HOWLING_BLAST, TARGET_VICTIM, 2);
922 VerifyAndPushSpellCast(spells, SPELL_UNBREAKABLE_ARMOR, TARGET_NONE, 10);
923 VerifyAndPushSpellCast(spells, SPELL_DEATHCHILL, TARGET_NONE, 10);
924 VerifyAndPushSpellCast(spells, SPELL_FROST_STRIKE, TARGET_VICTIM, 3);
925 VerifyAndPushSpellCast(spells, SPELL_BLOOD_STRIKE, TARGET_VICTIM, 1);
926 break;
927 case TALENT_SPEC_DEATHKNIGHT_UNHOLY:
928 if (hasFF && hasBP)
929 VerifyAndPushSpellCast(spells, SPELL_SCOURGE_STRIKE, TARGET_VICTIM, 5);
930 VerifyAndPushSpellCast(spells, SPELL_DEATH_AND_DECAY, TARGET_VICTIM, 2);
931 VerifyAndPushSpellCast(spells, SPELL_ANTI_MAGIC_ZONE, TARGET_NONE, 8);
932 VerifyAndPushSpellCast(spells, SPELL_SUMMON_GARGOYLE, TARGET_VICTIM, 7);
933 VerifyAndPushSpellCast(spells, SPELL_BLOOD_STRIKE, TARGET_VICTIM, 1);
934 VerifyAndPushSpellCast(spells, SPELL_DEATH_COIL_DK, TARGET_VICTIM, 3);
935 break;
936 }
937 break;
938 }
939 case CLASS_SHAMAN:
940 VerifyAndPushSpellCast(spells, SPELL_HEROISM, TARGET_NONE, 25);
941 VerifyAndPushSpellCast(spells, SPELL_BLOODLUST, TARGET_NONE, 25);
942 VerifyAndPushSpellCast(spells, SPELL_GROUNDING_TOTEM, TARGET_NONE, 2);
943 switch (GetSpec())
944 {
945 case TALENT_SPEC_SHAMAN_RESTORATION:
946 if (Unit* charmer = me->GetCharmer())
947 if (!charmer->GetAuraApplicationOfRankedSpell(SPELL_EARTH_SHIELD, me->GetGUID()))
948 VerifyAndPushSpellCast(spells, SPELL_EARTH_SHIELD, charmer, 2);
949 if (me->HasAura(SPELL_SHA_NATURE_SWIFT))
950 VerifyAndPushSpellCast(spells, SPELL_HEALING_WAVE, TARGET_CHARMER, 20);
951 else
952 VerifyAndPushSpellCast(spells, SPELL_LESSER_HEAL_WAVE, TARGET_CHARMER, 1);
953 VerifyAndPushSpellCast(spells, SPELL_TIDAL_FORCE, TARGET_NONE, 4);
954 VerifyAndPushSpellCast(spells, SPELL_SHA_NATURE_SWIFT, TARGET_NONE, 4);
955 VerifyAndPushSpellCast(spells, SPELL_MANA_TIDE_TOTEM, TARGET_NONE, 3);
956 break;
957 case TALENT_SPEC_SHAMAN_ELEMENTAL:
958 if (Unit* victim = me->GetVictim())
959 {
960 if (victim->GetAuraOfRankedSpell(SPELL_FLAME_SHOCK, GetGUID()))
961 VerifyAndPushSpellCast(spells, SPELL_LAVA_BURST, TARGET_VICTIM, 5);
962 else
963 VerifyAndPushSpellCast(spells, SPELL_FLAME_SHOCK, TARGET_VICTIM, 3);
964 }
965 VerifyAndPushSpellCast(spells, SPELL_CHAIN_LIGHTNING, TARGET_VICTIM, 2);
966 VerifyAndPushSpellCast(spells, SPELL_LIGHTNING_BOLT, TARGET_VICTIM, 1);
967 VerifyAndPushSpellCast(spells, SPELL_ELEMENTAL_MASTERY, TARGET_VICTIM, 5);
968 VerifyAndPushSpellCast(spells, SPELL_THUNDERSTORM, TARGET_NONE, 3);
969 break;
970 case TALENT_SPEC_SHAMAN_ENHANCEMENT:
971 if (Aura const* maelstrom = me->GetAura(AURA_MAELSTROM_WEAPON))
972 if (maelstrom->GetStackAmount() == 5)
973 VerifyAndPushSpellCast(spells, SPELL_LIGHTNING_BOLT, TARGET_VICTIM, 5);
974 VerifyAndPushSpellCast(spells, SPELL_STORMSTRIKE, TARGET_VICTIM, 3);
975 VerifyAndPushSpellCast(spells, SPELL_EARTH_SHOCK, TARGET_VICTIM, 2);
976 VerifyAndPushSpellCast(spells, SPELL_LAVA_LASH, TARGET_VICTIM, 1);
977 VerifyAndPushSpellCast(spells, SPELL_SHAMANISTIC_RAGE, TARGET_NONE, 10);
978 break;
979 }
980 break;
981 case CLASS_MAGE:
982 if (me->GetVictim() && me->GetVictim()->HasUnitState(UNIT_STATE_CASTING))
983 VerifyAndPushSpellCast(spells, SPELL_COUNTERSPELL, TARGET_VICTIM, 25);
984 VerifyAndPushSpellCast(spells, SPELL_DAMPEN_MAGIC, TARGET_CHARMER, 2);
985 VerifyAndPushSpellCast(spells, SPELL_EVOCATION, TARGET_NONE, 3);
986 VerifyAndPushSpellCast(spells, SPELL_MANA_SHIELD, TARGET_NONE, 1);
987 VerifyAndPushSpellCast(spells, SPELL_MIRROR_IMAGE, TARGET_NONE, 3);
988 VerifyAndPushSpellCast(spells, SPELL_SPELLSTEAL, TARGET_VICTIM, 2);
989 VerifyAndPushSpellCast(spells, SPELL_ICE_BLOCK, TARGET_NONE, 1);
990 VerifyAndPushSpellCast(spells, SPELL_ICY_VEINS, TARGET_NONE, 3);
991 switch (GetSpec())
992 {
993 case TALENT_SPEC_MAGE_ARCANE:
994 if (Aura* abAura = me->GetAura(AURA_ARCANE_BLAST))
995 if (abAura->GetStackAmount() >= 3)
996 VerifyAndPushSpellCast(spells, SPELL_ARCANE_MISSILES, TARGET_VICTIM, 7);
997 VerifyAndPushSpellCast(spells, SPELL_ARCANE_BLAST, TARGET_VICTIM, 5);
998 VerifyAndPushSpellCast(spells, SPELL_ARCANE_BARRAGE, TARGET_VICTIM, 1);
999 VerifyAndPushSpellCast(spells, SPELL_ARCANE_POWER, TARGET_NONE, 8);
1000 VerifyAndPushSpellCast(spells, SPELL_PRESENCE_OF_MIND, TARGET_NONE, 7);
1001 break;
1002 case TALENT_SPEC_MAGE_FIRE:
1003 if (me->GetVictim() && !me->GetVictim()->GetAuraApplicationOfRankedSpell(SPELL_LIVING_BOMB))
1004 VerifyAndPushSpellCast(spells, SPELL_LIVING_BOMB, TARGET_VICTIM, 3);
1005 VerifyAndPushSpellCast(spells, SPELL_COMBUSTION, TARGET_VICTIM, 3);
1006 VerifyAndPushSpellCast(spells, SPELL_FIREBALL, TARGET_VICTIM, 2);
1007 VerifyAndPushSpellCast(spells, SPELL_FIRE_BLAST, TARGET_VICTIM, 1);
1008 VerifyAndPushSpellCast(spells, SPELL_DRAGONS_BREATH, TARGET_VICTIM, 2);
1009 VerifyAndPushSpellCast(spells, SPELL_BLAST_WAVE, TARGET_VICTIM, 1);
1010 break;
1011 case TALENT_SPEC_MAGE_FROST:
1012 VerifyAndPushSpellCast(spells, SPELL_DEEP_FREEZE, TARGET_VICTIM, 10);
1013 VerifyAndPushSpellCast(spells, SPELL_FROST_NOVA, TARGET_VICTIM, 3);
1014 VerifyAndPushSpellCast(spells, SPELL_FROSTBOLT, TARGET_VICTIM, 3);
1015 VerifyAndPushSpellCast(spells, SPELL_COLD_SNAP, TARGET_VICTIM, 5);
1016 if (me->GetVictim() && me->GetVictim()->HasAuraState(AURA_STATE_FROZEN, nullptr, me))
1017 VerifyAndPushSpellCast(spells, SPELL_ICE_LANCE, TARGET_VICTIM, 5);
1018 break;
1019 }
1020 break;
1021 case CLASS_WARLOCK:
1022 VerifyAndPushSpellCast(spells, SPELL_DEATH_COIL_W, TARGET_VICTIM, 2);
1023 VerifyAndPushSpellCast(spells, SPELL_FEAR, TARGET_VICTIM, 2);
1024 VerifyAndPushSpellCast(spells, SPELL_SEED_OF_CORRUPTION, TARGET_VICTIM, 4);
1025 VerifyAndPushSpellCast(spells, SPELL_HOWL_OF_TERROR, TARGET_NONE, 2);
1026 if (me->GetVictim() && !me->GetVictim()->GetAuraApplicationOfRankedSpell(SPELL_CORRUPTION, me->GetGUID()))
1027 VerifyAndPushSpellCast(spells, SPELL_CORRUPTION, TARGET_VICTIM, 10);
1028 switch (GetSpec())
1029 {
1030 case TALENT_SPEC_WARLOCK_AFFLICTION:
1031 if (Unit* victim = me->GetVictim())
1032 {
1033 VerifyAndPushSpellCast(spells, SPELL_SHADOW_BOLT, TARGET_VICTIM, 7);
1034 if (!victim->GetAuraApplicationOfRankedSpell(SPELL_UNSTABLE_AFFLICTION, me->GetGUID()))
1035 VerifyAndPushSpellCast(spells, SPELL_UNSTABLE_AFFLICTION, TARGET_VICTIM, 8);
1036 if (!victim->GetAuraApplicationOfRankedSpell(SPELL_HAUNT, me->GetGUID()))
1037 VerifyAndPushSpellCast(spells, SPELL_HAUNT, TARGET_VICTIM, 8);
1038 if (!victim->GetAuraApplicationOfRankedSpell(SPELL_CURSE_OF_AGONY, me->GetGUID()))
1039 VerifyAndPushSpellCast(spells, SPELL_CURSE_OF_AGONY, TARGET_VICTIM, 4);
1040 if (victim->HealthBelowPct(25))
1041 VerifyAndPushSpellCast(spells, SPELL_DRAIN_SOUL, TARGET_VICTIM, 100);
1042 }
1043 break;
1044 case TALENT_SPEC_WARLOCK_DEMONOLOGY:
1045 VerifyAndPushSpellCast(spells, SPELL_METAMORPHOSIS, TARGET_NONE, 15);
1046 VerifyAndPushSpellCast(spells, SPELL_SHADOW_BOLT, TARGET_VICTIM, 7);
1047 if (me->HasAura(AURA_DECIMATION))
1048 VerifyAndPushSpellCast(spells, SPELL_SOUL_FIRE, TARGET_VICTIM, 100);
1049 if (me->HasAura(SPELL_METAMORPHOSIS))
1050 {
1051 VerifyAndPushSpellCast(spells, SPELL_IMMOLATION_AURA, TARGET_NONE, 30);
1052 if (!me->IsWithinMeleeRange(me->GetVictim()))
1053 VerifyAndPushSpellCast(spells, SPELL_DEMON_CHARGE, TARGET_VICTIM, 20);
1054 }
1055 if (me->GetVictim() && !me->GetVictim()->GetAuraApplicationOfRankedSpell(SPELL_IMMOLATE, me->GetGUID()))
1056 VerifyAndPushSpellCast(spells, SPELL_IMMOLATE, TARGET_VICTIM, 5);
1057 if (me->HasAura(AURA_MOLTEN_CORE))
1058 VerifyAndPushSpellCast(spells, SPELL_INCINERATE, TARGET_VICTIM, 10);
1059 break;
1060 case TALENT_SPEC_WARLOCK_DESTRUCTION:
1061 if (me->GetVictim() && !me->GetVictim()->GetAuraApplicationOfRankedSpell(SPELL_IMMOLATE, me->GetGUID()))
1062 VerifyAndPushSpellCast(spells, SPELL_IMMOLATE, TARGET_VICTIM, 8);
1063 if (me->GetVictim() && me->GetVictim()->GetAuraApplicationOfRankedSpell(SPELL_IMMOLATE, me->GetGUID()))
1064 VerifyAndPushSpellCast(spells, SPELL_CONFLAGRATE, TARGET_VICTIM, 8);
1065 VerifyAndPushSpellCast(spells, SPELL_SHADOWFURY, TARGET_VICTIM, 5);
1066 VerifyAndPushSpellCast(spells, SPELL_CHAOS_BOLT, TARGET_VICTIM, 10);
1067 VerifyAndPushSpellCast(spells, SPELL_SHADOWBURN, TARGET_VICTIM, 3);
1068 VerifyAndPushSpellCast(spells, SPELL_INCINERATE, TARGET_VICTIM, 7);
1069 break;
1070 }
1071 break;
1072 case CLASS_MONK:
1073 switch (GetSpec())
1074 {
1075 case TALENT_SPEC_MONK_BREWMASTER:
1076 case TALENT_SPEC_MONK_BATTLEDANCER:
1077 case TALENT_SPEC_MONK_MISTWEAVER:
1078 break;
1079 }
1080 break;
1081 case CLASS_DRUID:
1082 VerifyAndPushSpellCast(spells, SPELL_INNERVATE, TARGET_CHARMER, 5);
1083 VerifyAndPushSpellCast(spells, SPELL_BARKSKIN, TARGET_NONE, 5);
1084 switch (GetSpec())
1085 {
1086 case TALENT_SPEC_DRUID_RESTORATION:
1087 if (!me->HasAura(SPELL_TREE_OF_LIFE))
1088 {
1089 CancelAllShapeshifts();
1090 VerifyAndPushSpellCast(spells, SPELL_TREE_OF_LIFE, TARGET_NONE, 100);
1091 break;
1092 }
1093 VerifyAndPushSpellCast(spells, SPELL_TRANQUILITY, TARGET_NONE, 10);
1094 VerifyAndPushSpellCast(spells, SPELL_NATURE_SWIFTNESS, TARGET_NONE, 7);
1095 if (Creature* creatureCharmer = GetCharmer())
1096 {
1097 VerifyAndPushSpellCast(spells, SPELL_NOURISH, creatureCharmer, 5);
1098 VerifyAndPushSpellCast(spells, SPELL_WILD_GROWTH, creatureCharmer, 5);
1099 if (!creatureCharmer->GetAuraApplicationOfRankedSpell(SPELL_REJUVENATION, me->GetGUID()))
1100 VerifyAndPushSpellCast(spells, SPELL_REJUVENATION, creatureCharmer, 8);
1101 if (!creatureCharmer->GetAuraApplicationOfRankedSpell(SPELL_REGROWTH, me->GetGUID()))
1102 VerifyAndPushSpellCast(spells, SPELL_REGROWTH, creatureCharmer, 8);
1103 uint8 lifebloomStacks = 0;
1104 if (Aura const* lifebloom = creatureCharmer->GetAura(SPELL_LIFEBLOOM, me->GetGUID()))
1105 lifebloomStacks = lifebloom->GetStackAmount();
1106 if (lifebloomStacks < 3)
1107 VerifyAndPushSpellCast(spells, SPELL_LIFEBLOOM, creatureCharmer, 5);
1108 if (creatureCharmer->GetAuraApplicationOfRankedSpell(SPELL_REJUVENATION) ||
1109 creatureCharmer->GetAuraApplicationOfRankedSpell(SPELL_REGROWTH))
1110 VerifyAndPushSpellCast(spells, SPELL_SWIFTMEND, creatureCharmer, 10);
1111 if (me->HasAura(SPELL_NATURE_SWIFTNESS))
1112 VerifyAndPushSpellCast(spells, SPELL_HEALING_TOUCH, creatureCharmer, 100);
1113 }
1114 break;
1115 case TALENT_SPEC_DRUID_BALANCE:
1116 {
1117 if (!me->HasAura(SPELL_MOONKIN_FORM))
1118 {
1119 CancelAllShapeshifts();
1120 VerifyAndPushSpellCast(spells, SPELL_MOONKIN_FORM, TARGET_NONE, 100);
1121 break;
1122 }
1123 uint32 const mainAttackSpell = me->HasAura(AURA_ECLIPSE_LUNAR) ? SPELL_STARFIRE : SPELL_WRATH;
1124 VerifyAndPushSpellCast(spells, SPELL_STARFALL, TARGET_NONE, 20);
1125 VerifyAndPushSpellCast(spells, mainAttackSpell, TARGET_VICTIM, 10);
1126 if (me->GetVictim() && !me->GetVictim()->GetAuraApplicationOfRankedSpell(SPELL_INSECT_SWARM, me->GetGUID()))
1127 VerifyAndPushSpellCast(spells, SPELL_INSECT_SWARM, TARGET_VICTIM, 7);
1128 if (me->GetVictim() && !me->GetVictim()->GetAuraApplicationOfRankedSpell(SPELL_MOONFIRE, me->GetGUID()))
1129 VerifyAndPushSpellCast(spells, SPELL_MOONFIRE, TARGET_VICTIM, 5);
1130 if (me->GetVictim() && me->GetVictim()->HasUnitState(UNIT_STATE_CASTING))
1131 VerifyAndPushSpellCast(spells, SPELL_TYPHOON, TARGET_NONE, 15);
1132 break;
1133 }
1134 case TALENT_SPEC_DRUID_CAT:
1135 case TALENT_SPEC_DRUID_BEAR:
1136 if (!me->HasAura(SPELL_CAT_FORM))
1137 {
1138 CancelAllShapeshifts();
1139 VerifyAndPushSpellCast(spells, SPELL_CAT_FORM, TARGET_NONE, 100);
1140 break;
1141 }
1142 VerifyAndPushSpellCast(spells, SPELL_BERSERK, TARGET_NONE, 20);
1143 VerifyAndPushSpellCast(spells, SPELL_SURVIVAL_INSTINCTS, TARGET_NONE, 15);
1144 VerifyAndPushSpellCast(spells, SPELL_TIGER_FURY, TARGET_NONE, 15);
1145 VerifyAndPushSpellCast(spells, SPELL_DASH, TARGET_NONE, 5);
1146 if (Unit* victim = me->GetVictim())
1147 {
1148 uint8 const cp = me->GetPower(POWER_COMBO_POINTS);
1149 if (victim->HasUnitState(UNIT_STATE_CASTING) && cp >= 1)
1150 VerifyAndPushSpellCast(spells, SPELL_MAIM, TARGET_VICTIM, 25);
1151 if (!me->IsWithinMeleeRange(victim))
1152 VerifyAndPushSpellCast(spells, SPELL_FERAL_CHARGE_CAT, TARGET_VICTIM, 25);
1153 if (cp >= 4)
1154 VerifyAndPushSpellCast(spells, SPELL_RIP, TARGET_VICTIM, 50);
1155 if (cp <= 4)
1156 {
1157 VerifyAndPushSpellCast(spells, SPELL_MANGLE_CAT, TARGET_VICTIM, 10);
1158 VerifyAndPushSpellCast(spells, SPELL_CLAW, TARGET_VICTIM, 5);
1159 if (!victim->GetAuraApplicationOfRankedSpell(SPELL_RAKE, me->GetGUID()))
1160 VerifyAndPushSpellCast(spells, SPELL_RAKE, TARGET_VICTIM, 8);
1161 if (!me->HasAura(SPELL_SAVAGE_ROAR))
1162 VerifyAndPushSpellCast(spells, SPELL_SAVAGE_ROAR, TARGET_NONE, 15);
1163 }
1164 }
1165 break;
1166 }
1167 break;
1168 case CLASS_DEMON_HUNTER:
1169 switch (GetSpec())
1170 {
1171 case TALENT_SPEC_DEMON_HUNTER_HAVOC:
1172 case TALENT_SPEC_DEMON_HUNTER_VENGEANCE:
1173 break;
1174 }
1175 break;
1176 }
1177 */
1178 return SelectSpellCast(spells);
1179}
1180
1181static const float CASTER_CHASE_DISTANCE = 28.0f;
1183{
1184 Creature* charmer = GetCharmer();
1185 if (!charmer)
1186 return;
1187
1188 // kill self if charm aura has infinite duration
1189 if (charmer->IsInEvadeMode())
1190 {
1192 {
1193 if (aura->GetCasterGUID() == charmer->GetGUID() && aura->GetBase()->IsPermanent())
1194 {
1195 me->KillSelf();
1196 return;
1197 }
1198 }
1199 }
1200
1201 if (charmer->IsEngaged())
1202 {
1203 Unit* target = me->GetVictim();
1204 if (!target || !CanAIAttack(target))
1205 {
1206 target = SelectAttackTarget();
1207 if (!target || !CanAIAttack(target))
1208 {
1209 if (!_isFollowing)
1210 {
1211 _isFollowing = true;
1212 me->AttackStop();
1213 me->CastStop();
1214
1217
1219 }
1220 return;
1221 }
1222 _isFollowing = false;
1223
1224 if (IsRangedAttacker())
1225 {
1226 _chaseCloser = !me->IsWithinLOSInMap(target);
1227 if (_chaseCloser)
1228 AttackStart(target);
1229 else
1231 }
1232 else
1233 AttackStart(target);
1234 _forceFacing = true;
1235 }
1236
1238 {
1239 float targetAngle = me->GetAbsoluteAngle(target);
1240 if (_forceFacing || fabs(me->GetOrientation() - targetAngle) > 0.4f)
1241 {
1242 me->SetFacingTo(targetAngle);
1243 _forceFacing = false;
1244 }
1245 }
1246
1247 if (_castCheckTimer <= diff)
1248 {
1250 _castCheckTimer = 0;
1251 else
1252 {
1253 if (IsRangedAttacker()) // chase to zero if the target isn't in line of sight
1254 {
1255 bool inLOS = me->IsWithinLOSInMap(target);
1256 if (_chaseCloser != !inLOS)
1257 {
1258 _chaseCloser = !inLOS;
1259 if (_chaseCloser)
1260 AttackStart(target);
1261 else
1263 }
1264 }
1266 DoCastAtTarget(shouldCast);
1267 _castCheckTimer = 500;
1268 }
1269 }
1270 else
1271 _castCheckTimer -= diff;
1272
1274 }
1275 else if (!_isFollowing)
1276 {
1277 _isFollowing = true;
1278 me->AttackStop();
1279 me->CastStop();
1280
1283
1285 }
1286}
1287
1289{
1290 if (me->IsCharmed())
1291 {
1292 me->CastStop();
1293 me->AttackStop();
1294
1295 if (me->GetMotionMaster()->Size() <= 1) // if there is no current movement (we dont want to erase/overwrite any existing stuff)
1296 me->GetMotionMaster()->MovePoint(0, me->GetPosition(), false); // force re-sync of current position for all clients
1297 }
1298 else
1299 {
1300 me->CastStop();
1301 me->AttackStop();
1302
1304 }
1305
1306 PlayerAI::OnCharmed(isNew);
1307}
ChrSpecialization
Definition: DBCEnums.h:357
uint32_t uint32
Definition: Define.h:142
@ ITEM_SUBCLASS_WEAPON_CROSSBOW
Definition: ItemTemplate.h:498
@ ITEM_SUBCLASS_WEAPON_GUN
Definition: ItemTemplate.h:483
@ ITEM_SUBCLASS_WEAPON_BOW
Definition: ItemTemplate.h:482
@ ITEM_SUBCLASS_WEAPON_WAND
Definition: ItemTemplate.h:499
@ ITEM_SUBCLASS_WEAPON_THROWN
Definition: ItemTemplate.h:496
@ MOTION_PRIORITY_NORMAL
@ CHASE_MOTION_TYPE
#define PET_FOLLOW_ANGLE
Definition: PetDefines.h:98
#define PET_FOLLOW_DIST
Definition: PetDefines.h:97
Spells
Definition: PlayerAI.cpp:32
@ SPELL_SCOURGE_STRIKE
Definition: PlayerAI.cpp:246
@ SPELL_DISPERSION
Definition: PlayerAI.cpp:210
@ SPELL_COLD_SNAP
Definition: PlayerAI.cpp:317
@ SPELL_ENRAGED_REGEN
Definition: PlayerAI.cpp:45
@ SPELL_SEED_OF_CORRUPTION
Definition: PlayerAI.cpp:328
@ SPELL_SILENCING_SHOT
Definition: PlayerAI.cpp:141
@ SPELL_HAMMER_OF_JUSTICE
Definition: PlayerAI.cpp:89
@ SPELL_EXECUTE
Definition: PlayerAI.cpp:65
@ PASSIVE_ILLUMINATION
Definition: PlayerAI.cpp:95
@ SPELL_AVENGERS_SHIELD
Definition: PlayerAI.cpp:107
@ SPELL_SHADOWSTEP
Definition: PlayerAI.cpp:175
@ SPELL_GUARDIAN_SPIRIT
Definition: PlayerAI.cpp:198
@ SPELL_CONFLAGRATE
Definition: PlayerAI.cpp:349
@ SPELL_VAMPIRIC_EMBRACE
Definition: PlayerAI.cpp:203
@ SPELL_DEEP_FREEZE
Definition: PlayerAI.cpp:314
@ SPELL_DEMONIC_EMPOWERMENT
Definition: PlayerAI.cpp:339
@ SPELL_MOONFIRE
Definition: PlayerAI.cpp:363
@ SPELL_SHIELD_BASH
Definition: PlayerAI.cpp:48
@ AURA_BLOOD_PLAGUE
Definition: PlayerAI.cpp:223
@ SPELL_SHADOWFORM
Definition: PlayerAI.cpp:204
@ SPELL_DEATH_WISH
Definition: PlayerAI.cpp:61
@ SPELL_RIPTIDE
Definition: PlayerAI.cpp:279
@ SPELL_SAVAGE_ROAR
Definition: PlayerAI.cpp:376
@ SPELL_AVENGING_WRATH
Definition: PlayerAI.cpp:86
@ SPELL_NATURE_SWIFTNESS
Definition: PlayerAI.cpp:386
@ SPELL_DEATH_COIL_W
Definition: PlayerAI.cpp:324
@ SPELL_STRANGULATE
Definition: PlayerAI.cpp:214
@ SPELL_SHAMANISTIC_RAGE
Definition: PlayerAI.cpp:273
@ SPELL_CHIMERA_SHOT
Definition: PlayerAI.cpp:137
@ SPELL_METAMORPHOSIS
Definition: PlayerAI.cpp:340
@ SPELL_CLOAK_OF_SHADOWS
Definition: PlayerAI.cpp:155
@ SPELL_SHIELD_WALL
Definition: PlayerAI.cpp:79
@ SPELL_SOUL_LINK
Definition: PlayerAI.cpp:338
@ SPELL_EVASION
Definition: PlayerAI.cpp:151
@ SPELL_IMMOLATION_AURA
Definition: PlayerAI.cpp:341
@ SPELL_ADRENALINE_RUSH
Definition: PlayerAI.cpp:166
@ SPELL_SHOOT
Definition: PlayerAI.cpp:35
@ SPELL_FROSTBOLT
Definition: PlayerAI.cpp:316
@ SPELL_FERAL_CHARGE_CAT
Definition: PlayerAI.cpp:373
@ SPELL_STARFIRE
Definition: PlayerAI.cpp:364
@ SPELL_ICE_BLOCK
Definition: PlayerAI.cpp:291
@ SPELL_DASH
Definition: PlayerAI.cpp:379
@ SPELL_AUTO_SHOT
Definition: PlayerAI.cpp:34
@ SPELL_PLAGUE_STRIKE
Definition: PlayerAI.cpp:222
@ SPELL_TYPHOON
Definition: PlayerAI.cpp:361
@ SPELL_CONCUSSION_BLOW
Definition: PlayerAI.cpp:74
@ SPELL_DIVINE_ILLUMINATION
Definition: PlayerAI.cpp:102
@ SPELL_ANTI_MAGIC_ZONE
Definition: PlayerAI.cpp:248
@ SPELL_BLOODLUST
Definition: PlayerAI.cpp:253
@ PASSIVE_SIPHON_LIFE
Definition: PlayerAI.cpp:331
@ AURA_DECIMATION
Definition: PlayerAI.cpp:343
@ SPELL_FLASH_HEAL
Definition: PlayerAI.cpp:199
@ SPELL_THUNDERSTORM
Definition: PlayerAI.cpp:259
@ SPELL_VAMPIRIC_BLOOD
Definition: PlayerAI.cpp:233
@ SPELL_DEATH_STRIKE
Definition: PlayerAI.cpp:230
@ SPELL_FERAL_SPIRIT
Definition: PlayerAI.cpp:270
@ SPELL_PAIN_SUPPRESSION
Definition: PlayerAI.cpp:191
@ SPELL_RAKE
Definition: PlayerAI.cpp:374
@ SPELL_STORMSTRIKE
Definition: PlayerAI.cpp:272
@ SPELL_BEACON_OF_LIGHT
Definition: PlayerAI.cpp:97
@ SPELL_HYSTERIA
Definition: PlayerAI.cpp:228
@ SPELL_SINISTER_STRIKE
Definition: PlayerAI.cpp:164
@ SPELL_HOWL_OF_TERROR
Definition: PlayerAI.cpp:322
@ PASSIVE_ELEMENTAL_FOCUS
Definition: PlayerAI.cpp:257
@ SPELL_PENANCE
Definition: PlayerAI.cpp:190
@ SPELL_VAMPIRIC_TOUCH
Definition: PlayerAI.cpp:205
@ SPELL_COUNTERSPELL
Definition: PlayerAI.cpp:290
@ SPELL_MIRROR_IMAGE
Definition: PlayerAI.cpp:288
@ PASSIVE_TRUESHOT_AURA
Definition: PlayerAI.cpp:136
@ SPELL_CHARGE
Definition: PlayerAI.cpp:43
@ SPELL_EVISCERATE
Definition: PlayerAI.cpp:168
@ SPELL_DIVINE_PROTECTION
Definition: PlayerAI.cpp:87
@ SPELL_LAST_STAND
Definition: PlayerAI.cpp:76
@ SPELL_ARCANE_BARRAGE
Definition: PlayerAI.cpp:296
@ SPELL_DEMON_CHARGE
Definition: PlayerAI.cpp:342
@ SPELL_BLOOD_STRIKE
Definition: PlayerAI.cpp:231
@ SPELL_POWER_INFUSION
Definition: PlayerAI.cpp:189
@ SPELL_MANGLE
Definition: PlayerAI.cpp:370
@ SPELL_BATTLE_STANCE
Definition: PlayerAI.cpp:40
@ SPELL_DEFENSIVE_STANCE
Definition: PlayerAI.cpp:42
@ SPELL_SOUL_FIRE
Definition: PlayerAI.cpp:345
@ SPELL_HOWLING_BLAST
Definition: PlayerAI.cpp:238
@ SPELL_SHATTERING_THROW
Definition: PlayerAI.cpp:57
@ PASSIVE_ICY_TALONS
Definition: PlayerAI.cpp:236
@ SPELL_BLACK_ARROW
Definition: PlayerAI.cpp:147
@ PASSIVE_UNHOLY_BLIGHT
Definition: PlayerAI.cpp:244
@ SPELL_RETALIATION
Definition: PlayerAI.cpp:56
@ SPELL_LIFEBLOOM
Definition: PlayerAI.cpp:392
@ SPELL_CLAW
Definition: PlayerAI.cpp:378
@ SPELL_LAVA_LASH
Definition: PlayerAI.cpp:269
@ SPELL_DEMO_SHOUT
Definition: PlayerAI.cpp:64
@ SPELL_EXPLOSIVE_SHOT
Definition: PlayerAI.cpp:146
@ SPELL_UNSTABLE_AFFLICTION
Definition: PlayerAI.cpp:332
@ SPELL_SHOOT_WAND
Definition: PlayerAI.cpp:37
@ SPELL_PREMEDITATION
Definition: PlayerAI.cpp:172
@ SPELL_BARKSKIN
Definition: PlayerAI.cpp:354
@ SPELL_KICK
Definition: PlayerAI.cpp:152
@ PASSIVE_TITANS_GRIP
Definition: PlayerAI.cpp:63
@ SPELL_MANA_SHIELD
Definition: PlayerAI.cpp:287
@ SPELL_LAVA_BURST
Definition: PlayerAI.cpp:263
@ SPELL_SHIELD_OF_RIGHTEOUS
Definition: PlayerAI.cpp:111
@ SPELL_PUMMEL
Definition: PlayerAI.cpp:47
@ SPELL_INSECT_SWARM
Definition: PlayerAI.cpp:358
@ SPELL_BLESSING_OF_MIGHT
Definition: PlayerAI.cpp:85
@ SPELL_BLIND
Definition: PlayerAI.cpp:154
@ SPELL_DETERRENCE
Definition: PlayerAI.cpp:121
@ SPELL_DIVINE_FAVOR
Definition: PlayerAI.cpp:101
@ PASSIVE_SPIRIT_WEAPONS
Definition: PlayerAI.cpp:268
@ SPELL_BLADE_FLURRY
Definition: PlayerAI.cpp:165
@ SPELL_FEAR
Definition: PlayerAI.cpp:321
@ SPELL_MIND_BLAST
Definition: PlayerAI.cpp:207
@ SPELL_ARCANE_SHOT
Definition: PlayerAI.cpp:138
@ SPELL_SPELLSTEAL
Definition: PlayerAI.cpp:289
@ AURA_MAELSTROM_WEAPON
Definition: PlayerAI.cpp:271
@ SPELL_ENVENOM
Definition: PlayerAI.cpp:161
@ SPELL_DRAGONS_BREATH
Definition: PlayerAI.cpp:308
@ SPELL_HEROIC_FURY
Definition: PlayerAI.cpp:66
@ SPELL_DESPERATE_PRAYER
Definition: PlayerAI.cpp:197
@ SPELL_RAPID_FIRE
Definition: PlayerAI.cpp:124
@ SPELL_HEROISM
Definition: PlayerAI.cpp:252
@ SPELL_ARCANE_POWER
Definition: PlayerAI.cpp:295
@ PASSIVE_LOCK_AND_LOAD
Definition: PlayerAI.cpp:144
@ SPELL_INNER_FOCUS
Definition: PlayerAI.cpp:192
@ SPELL_POWER_WORD_SHIELD
Definition: PlayerAI.cpp:193
@ SPELL_TOTEM_OF_WRATH
Definition: PlayerAI.cpp:258
@ SPELL_CONSECRATION
Definition: PlayerAI.cpp:98
@ SPELL_MARK_OF_BLOOD
Definition: PlayerAI.cpp:232
@ SPELL_COMBUSTION
Definition: PlayerAI.cpp:304
@ SPELL_HAND_OF_SACRIFICE
Definition: PlayerAI.cpp:92
@ SPELL_FLASH_OF_LIGHT
Definition: PlayerAI.cpp:99
@ AURA_FROST_FEVER
Definition: PlayerAI.cpp:221
@ SPELL_MOONKIN_FORM
Definition: PlayerAI.cpp:359
@ SPELL_DEATH_COIL_DK
Definition: PlayerAI.cpp:218
@ SPELL_DEATH_AND_DECAY
Definition: PlayerAI.cpp:247
@ SPELL_SHADOW_WORD_PAIN
Definition: PlayerAI.cpp:208
@ SPELL_WILD_GROWTH
Definition: PlayerAI.cpp:385
@ SPELL_BLAST_WAVE
Definition: PlayerAI.cpp:309
@ SPELL_CRUSADER_STRIKE
Definition: PlayerAI.cpp:115
@ SPELL_THUNDER_CLAP
Definition: PlayerAI.cpp:58
@ SPELL_MORTAL_STRIKE
Definition: PlayerAI.cpp:53
@ SPELL_SHADOW_PROTECTION
Definition: PlayerAI.cpp:181
@ AURA_ECLIPSE_LUNAR
Definition: PlayerAI.cpp:362
@ SPELL_SURVIVAL_INSTINCTS
Definition: PlayerAI.cpp:369
@ SPELL_EARTH_SHIELD
Definition: PlayerAI.cpp:278
@ SPELL_RECKLESSNESS
Definition: PlayerAI.cpp:67
@ SPELL_INTERCEPT
Definition: PlayerAI.cpp:44
@ SPELL_HOLY_SHOCK
Definition: PlayerAI.cpp:96
@ SPELL_TIGER_FURY
Definition: PlayerAI.cpp:377
@ SPELL_FIREBALL
Definition: PlayerAI.cpp:306
@ SPELL_SHADOW_BOLT
Definition: PlayerAI.cpp:325
@ SPELL_EVOCATION
Definition: PlayerAI.cpp:286
@ AURA_ARCANE_BLAST
Definition: PlayerAI.cpp:298
@ SPELL_STEADY_SHOT
Definition: PlayerAI.cpp:139
@ SPELL_LIVING_BOMB
Definition: PlayerAI.cpp:305
@ SPELL_FLAME_SHOCK
Definition: PlayerAI.cpp:262
@ SPELL_DIVINE_SHIELD
Definition: PlayerAI.cpp:88
@ SPELL_LESSER_HEAL_WAVE
Definition: PlayerAI.cpp:281
@ SPELL_HEALING_TOUCH
Definition: PlayerAI.cpp:389
@ SPELL_LIGHTNING_BOLT
Definition: PlayerAI.cpp:260
@ SPELL_UNBREAKABLE_ARMOR
Definition: PlayerAI.cpp:239
@ SPELL_HAMMER_OF_WRATH
Definition: PlayerAI.cpp:118
@ SPELL_HEART_STRIKE
Definition: PlayerAI.cpp:229
@ SPELL_MIND_FREEZE
Definition: PlayerAI.cpp:219
@ SPELL_CURSE_OF_AGONY
Definition: PlayerAI.cpp:334
@ SPELL_TIDAL_FORCE
Definition: PlayerAI.cpp:282
@ SPELL_AIMED_SHOT
Definition: PlayerAI.cpp:135
@ SPELL_REJUVENATION
Definition: PlayerAI.cpp:390
@ SPELL_BLOODRAGE
Definition: PlayerAI.cpp:49
@ SPELL_MAIM
Definition: PlayerAI.cpp:380
@ SPELL_SHA_NATURE_SWIFT
Definition: PlayerAI.cpp:276
@ PASSIVE_SOUL_WARDING
Definition: PlayerAI.cpp:188
@ SPELL_THROW
Definition: PlayerAI.cpp:36
@ SPELL_ICY_TOUCH
Definition: PlayerAI.cpp:220
@ SPELL_ICE_LANCE
Definition: PlayerAI.cpp:318
@ SPELL_LAY_ON_HANDS
Definition: PlayerAI.cpp:84
@ SPELL_VANISH
Definition: PlayerAI.cpp:153
@ SPELL_IMMOLATE
Definition: PlayerAI.cpp:327
@ SPELL_MANGLE_CAT
Definition: PlayerAI.cpp:372
@ SPELL_VIGILANCE
Definition: PlayerAI.cpp:71
@ SPELL_RENEW
Definition: PlayerAI.cpp:200
@ SPELL_CAT_FORM
Definition: PlayerAI.cpp:368
@ PASSIVE_BEAST_WITHIN
Definition: PlayerAI.cpp:131
@ SPELL_CORRUPTION
Definition: PlayerAI.cpp:323
@ SPELL_PIERCING_HOWL
Definition: PlayerAI.cpp:68
@ SPELL_VIPER_STING
Definition: PlayerAI.cpp:127
@ SPELL_MIND_FLAY
Definition: PlayerAI.cpp:206
@ SPELL_DRAIN_SOUL
Definition: PlayerAI.cpp:335
@ SPELL_PREPARATION
Definition: PlayerAI.cpp:174
@ SPELL_HEALING_WAVE
Definition: PlayerAI.cpp:280
@ SPELL_CHAOS_BOLT
Definition: PlayerAI.cpp:350
@ SPELL_SHOCKWAVE
Definition: PlayerAI.cpp:73
@ SPELL_DEATH_GRIP
Definition: PlayerAI.cpp:213
@ SPELL_ANTI_MAGIC_SHELL
Definition: PlayerAI.cpp:217
@ SPELL_ICY_VEINS
Definition: PlayerAI.cpp:312
@ SPELL_FROST_NOVA
Definition: PlayerAI.cpp:315
@ SPELL_RIGHTEOUS_FURY
Definition: PlayerAI.cpp:110
@ SPELL_HAUNT
Definition: PlayerAI.cpp:333
@ SPELL_BLADESTORM
Definition: PlayerAI.cpp:54
@ SPELL_WRATH
Definition: PlayerAI.cpp:365
@ SPELL_CHAIN_LIGHTNING
Definition: PlayerAI.cpp:264
@ PASSIVE_SPIRIT_REDEMPTION
Definition: PlayerAI.cpp:196
@ SPELL_SUMMON_GARGOYLE
Definition: PlayerAI.cpp:249
@ SPELL_HEMORRHAGE
Definition: PlayerAI.cpp:171
@ SPELL_HUNGER_FOR_BLOOD
Definition: PlayerAI.cpp:160
@ SPELL_SHIELD_SLAM
Definition: PlayerAI.cpp:78
@ SPELL_REND
Definition: PlayerAI.cpp:55
@ SPELL_DIVINE_STORM
Definition: PlayerAI.cpp:116
@ SPELL_HAND_OF_FREEDOM
Definition: PlayerAI.cpp:90
@ SPELL_MULTI_SHOT
Definition: PlayerAI.cpp:126
@ SPELL_SWEEPING_STRIKES
Definition: PlayerAI.cpp:52
@ SPELL_HAMMER_OF_RIGHTEOUS
Definition: PlayerAI.cpp:109
@ PASSIVE_BEAST_MASTERY
Definition: PlayerAI.cpp:132
@ SPELL_KILL_SHOT
Definition: PlayerAI.cpp:125
@ SPELL_FOCUS_MAGIC
Definition: PlayerAI.cpp:294
@ SPELL_SHADOWFURY
Definition: PlayerAI.cpp:351
@ SPELL_FROST_STRIKE
Definition: PlayerAI.cpp:237
@ SPELL_NOURISH
Definition: PlayerAI.cpp:388
@ SPELL_HYMN_OF_HOPE
Definition: PlayerAI.cpp:183
@ SPELL_DIVINE_SPIRIT
Definition: PlayerAI.cpp:180
@ SPELL_EMPOWER_RUNE_WEAP
Definition: PlayerAI.cpp:215
@ SPELL_COLD_BLOOD
Definition: PlayerAI.cpp:158
@ SPELL_DISMANTLE
Definition: PlayerAI.cpp:150
@ SPELL_DIVINE_HYMN
Definition: PlayerAI.cpp:182
@ SPELL_PAL_AURA_MASTERY
Definition: PlayerAI.cpp:83
@ SPELL_GROUNDING_TOTEM
Definition: PlayerAI.cpp:254
@ SPELL_ICE_BARRIER
Definition: PlayerAI.cpp:313
@ SPELL_BERSERK
Definition: PlayerAI.cpp:371
@ SPELL_BLOODTHIRST
Definition: PlayerAI.cpp:62
@ SPELL_PESTILENCE
Definition: PlayerAI.cpp:224
@ SPELL_PRESENCE_OF_MIND
Definition: PlayerAI.cpp:300
@ SPELL_FEAR_WARD
Definition: PlayerAI.cpp:178
@ SPELL_SHADOWBURN
Definition: PlayerAI.cpp:348
@ SPELL_ELEMENTAL_MASTERY
Definition: PlayerAI.cpp:265
@ SPELL_DAMPEN_MAGIC
Definition: PlayerAI.cpp:285
@ SPELL_KILLING_SPREE
Definition: PlayerAI.cpp:167
@ SPELL_ICEBORN_FORTITUDE
Definition: PlayerAI.cpp:216
@ SPELL_RIP
Definition: PlayerAI.cpp:375
@ SPELL_DEVOURING_PLAGUE
Definition: PlayerAI.cpp:209
@ SPELL_SHIELD_BLOCK
Definition: PlayerAI.cpp:77
@ SPELL_INTIMIDATING_SHOUT
Definition: PlayerAI.cpp:46
@ SPELL_SHADOW_DANCE
Definition: PlayerAI.cpp:173
@ SPELL_RUNE_TAP
Definition: PlayerAI.cpp:227
@ SPELL_DEVASTATE
Definition: PlayerAI.cpp:72
@ SPELL_MUTILATE
Definition: PlayerAI.cpp:159
@ SPELL_HOLY_SHIELD
Definition: PlayerAI.cpp:106
@ PASSIVE_MASTER_OF_GHOUL
Definition: PlayerAI.cpp:245
@ SPELL_POWER_WORD_FORT
Definition: PlayerAI.cpp:179
@ SPELL_HAND_OF_PROTECTION
Definition: PlayerAI.cpp:91
@ SPELL_PYROBLAST
Definition: PlayerAI.cpp:303
@ SPELL_FIRE_BLAST
Definition: PlayerAI.cpp:307
@ SPELL_SPELL_REFLECTION
Definition: PlayerAI.cpp:80
@ SPELL_SHADOW_WORD_DEATH
Definition: PlayerAI.cpp:184
@ SPELL_EARTH_SHOCK
Definition: PlayerAI.cpp:261
@ SPELL_REGROWTH
Definition: PlayerAI.cpp:391
@ SPELL_DIVINE_SACRIFICE
Definition: PlayerAI.cpp:108
@ SPELL_SEAL_OF_COMMAND
Definition: PlayerAI.cpp:114
@ SPELL_BESTIAL_WRATH
Definition: PlayerAI.cpp:130
@ SPELL_READINESS
Definition: PlayerAI.cpp:140
@ SPELL_DEATHCHILL
Definition: PlayerAI.cpp:241
@ SPELL_JUDGEMENT
Definition: PlayerAI.cpp:117
@ SPELL_ARCANE_BLAST
Definition: PlayerAI.cpp:297
@ SPELL_SWIFTMEND
Definition: PlayerAI.cpp:383
@ AURA_MOLTEN_CORE
Definition: PlayerAI.cpp:344
@ SPELL_MANA_TIDE_TOTEM
Definition: PlayerAI.cpp:277
@ SPELL_EXPLOSIVE_TRAP
Definition: PlayerAI.cpp:122
@ SPELL_PSYCHIC_SCREAM
Definition: PlayerAI.cpp:185
@ SPELL_STARFALL
Definition: PlayerAI.cpp:360
@ SPELL_TREE_OF_LIFE
Definition: PlayerAI.cpp:384
@ SPELL_TRANQUILITY
Definition: PlayerAI.cpp:387
@ SPELL_WYVERN_STING
Definition: PlayerAI.cpp:145
@ SPELL_ARCANE_MISSILES
Definition: PlayerAI.cpp:299
@ SPELL_DISARM
Definition: PlayerAI.cpp:75
@ SPELL_FREEZING_ARROW
Definition: PlayerAI.cpp:123
@ SPELL_INNERVATE
Definition: PlayerAI.cpp:355
@ SPELL_OBLITERATE
Definition: PlayerAI.cpp:240
@ SPELL_INCINERATE
Definition: PlayerAI.cpp:326
@ SPELL_BERSERKER_STANCE
Definition: PlayerAI.cpp:41
@ SPELL_HOLY_LIGHT
Definition: PlayerAI.cpp:100
@ SPELL_BLESS_OF_SANC
Definition: PlayerAI.cpp:105
static const float CASTER_CHASE_DISTANCE
Definition: PlayerAI.cpp:1181
@ EQUIPMENT_SLOT_RANGED
Definition: Player.h:648
#define INVENTORY_SLOT_BAG_0
Definition: Player.h:625
uint32 urand(uint32 min, uint32 max)
Definition: Random.cpp:42
@ RANGED_ATTACK
@ SPELL_ATTR0_NO_AURA_CANCEL
@ SPELL_CAST_OK
@ AURA_REMOVE_BY_CANCEL
@ SPELL_AURA_MOD_SHAPESHIFT
@ SPELL_AURA_MOD_CHARM
@ TRIGGERED_CAST_DIRECTLY
In Spell::prepare, will be cast directly without setting containers for executed spell.
Definition: SpellDefines.h:254
@ TRIGGERED_NONE
Not triggered.
Definition: SpellDefines.h:246
#define sSpellMgr
Definition: SpellMgr.h:849
@ UNIT_STATE_CHASE
Definition: Unit.h:260
@ UNIT_STATE_CANNOT_TURN
Definition: Unit.h:299
@ UNIT_STATE_CASTING
Definition: Unit.h:270
SpellInfo const * GetSpellInfo() const
Definition: SpellAuras.h:134
bool IsEngaged() const override
Definition: Creature.cpp:3601
bool IsInEvadeMode() const
Definition: Creature.h:203
Definition: Item.h:170
ItemTemplate const * GetTemplate() const
Definition: Item.cpp:1141
Difficulty GetDifficultyID() const
Definition: Map.h:324
uint32 Size() const
void MovePoint(uint32 id, Position const &pos, bool generatePath=true, Optional< float > finalOrient={}, Optional< float > speed={}, MovementWalkRunSpeedSelectionMode speedSelectionMode=MovementWalkRunSpeedSelectionMode::Default, Optional< float > closeEnoughDistance={})
void MoveFollow(Unit *target, float dist, ChaseAngle angle, Optional< Milliseconds > duration={}, MovementSlot slot=MOTION_SLOT_ACTIVE)
void Remove(MovementGenerator *movement, MovementSlot slot=MOTION_SLOT_ACTIVE)
bool IsCreature() const
Definition: ObjectGuid.h:320
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
void DoRangedAttackIfReady()
Definition: PlayerAI.cpp:536
static bool IsPlayerRangedAttacker(Player const *who)
Definition: PlayerAI.cpp:423
virtual Unit * SelectAttackTarget() const
Definition: PlayerAI.cpp:619
std::pair< TargetedSpell, uint32 > PossibleSpell
Definition: PlayerAI.h:48
void DoCastAtTarget(TargetedSpell spell)
Definition: PlayerAI.cpp:529
void DoAutoAttackIfReady()
Definition: PlayerAI.cpp:590
TargetedSpell SelectSpellCast(PossibleSpellVector &spells)
Definition: PlayerAI.cpp:497
static bool IsPlayerHealer(Player const *who)
Definition: PlayerAI.cpp:414
Player *const me
Definition: PlayerAI.h:51
TargetedSpell VerifySpellCast(uint32 spellId, Unit *target)
Definition: PlayerAI.cpp:432
PlayerAI(Player *player)
Definition: PlayerAI.cpp:395
SpellTarget
Definition: PlayerAI.h:55
@ TARGET_VICTIM
Definition: PlayerAI.h:57
@ TARGET_NONE
Definition: PlayerAI.h:56
@ TARGET_SELF
Definition: PlayerAI.h:59
@ TARGET_CHARMER
Definition: PlayerAI.h:58
ChrSpecialization const _selfSpec
Definition: PlayerAI.h:89
ChrSpecialization GetSpec(Player const *who=nullptr) const
Definition: PlayerAI.cpp:409
bool IsRangedAttacker(Player const *who=nullptr) const
Definition: PlayerAI.h:39
std::vector< PossibleSpell > PossibleSpellVector
Definition: PlayerAI.h:49
void CancelAllShapeshifts()
Definition: PlayerAI.cpp:596
Creature * GetCharmer() const
Definition: PlayerAI.cpp:402
ChrSpecialization GetPrimarySpecialization() const
Definition: Player.h:1841
Item * GetItemByPos(uint16 pos) const
Definition: Player.cpp:9582
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3792
ChrSpecializationEntry const * GetPrimarySpecializationEntry() const
Definition: Player.cpp:29827
void OnCharmed(bool isNew) override
Definition: PlayerAI.cpp:1288
bool CanAIAttack(Unit const *who) const override
Definition: PlayerAI.cpp:634
TargetedSpell SelectAppropriateCastForSpec()
Definition: PlayerAI.cpp:655
void UpdateAI(uint32 diff) override
Definition: PlayerAI.cpp:1182
Unit * SelectAttackTarget() const override
Definition: PlayerAI.cpp:644
void SetUnitTarget(Unit *target)
Definition: Spell.cpp:226
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
bool IsPassive() const
Definition: SpellInfo.cpp:1592
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:449
bool IsPositive() const
Definition: SpellInfo.cpp:1709
Definition: Spell.h:255
SpellCastResult prepare(SpellCastTargets const &targets, AuraEffect const *triggeredByAura=nullptr)
Definition: Spell.cpp:3426
SpellCastResult CheckPetCast(Unit *target)
Definition: Spell.cpp:6787
bool CanAutoCast(Unit *target)
Definition: Spell.cpp:7091
Definition: UnitAI.h:50
void AttackStartCaster(Unit *victim, float dist)
Definition: UnitAI.cpp:55
virtual void AttackStart(Unit *victim)
Definition: UnitAI.cpp:29
virtual bool CanAIAttack(Unit const *) const
Definition: UnitAI.h:57
virtual void OnCharmed(bool isNew)
Definition: UnitAI.cpp:49
Definition: Unit.h:627
bool IsStopped() const
Definition: Unit.h:1656
void CastStop(uint32 except_spellid=0)
Definition: Unit.cpp:1135
bool IsCharmed() const
Definition: Unit.h:1215
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition: Unit.cpp:3608
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition: Unit.h:1321
bool HasBreakableByDamageCrowdControlAura(Unit *excludeCasterChannel=nullptr) const
Definition: Unit.cpp:734
Unit * GetCharmer() const
Definition: Unit.h:1188
std::forward_list< AuraEffect * > AuraEffectList
Definition: Unit.h:644
MotionMaster * GetMotionMaster()
Definition: Unit.h:1652
Unit * GetVictim() const
Definition: Unit.h:715
void SetFacingTo(float const ori, bool force=true)
Definition: Unit.cpp:12653
bool HasUnitState(const uint32 f) const
Definition: Unit.h:732
SpellHistory * GetSpellHistory()
Definition: Unit.h:1457
ObjectGuid GetCharmerGUID() const
Definition: Unit.h:1187
bool isAttackReady(WeaponAttackType type=BASE_ATTACK) const
Definition: Unit.h:690
void KillSelf(bool durabilityLoss=true, bool skipSettingDeathState=false)
Definition: Unit.h:921
void resetAttackTimer(WeaponAttackType type=BASE_ATTACK)
Definition: Unit.cpp:630
bool AttackStop()
Definition: Unit.cpp:5781
Map * GetMap() const
Definition: Object.h:624
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition: Object.cpp:2991
bool IsWithinLOSInMap(WorldObject const *obj, LineOfSightChecks checks=LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags ignoreFlags=VMAP::ModelIgnoreFlags::Nothing) const
Definition: Object.cpp:1181
TC_GAME_API Creature * GetCreature(WorldObject const &u, ObjectGuid const &guid)
EnumFlag< ChrSpecializationFlag > GetFlags() const
Definition: DB2Structure.h:872
ChrSpecializationRole GetRole() const
Definition: DB2Structure.h:873
float GetAbsoluteAngle(float x, float y) const
Definition: Position.h:125
constexpr void GetPosition(float &x, float &y) const
Definition: Position.h:81
constexpr float GetOrientation() const
Definition: Position.h:79
ValidTargetSelectPredicate(UnitAI const *ai)
Definition: PlayerAI.cpp:626
UnitAI const *const _ai
Definition: PlayerAI.cpp:627
bool operator()(Unit const *target) const
Definition: PlayerAI.cpp:628