TrinityCore
Loading...
Searching...
No Matches
spell_priest.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/*
19 * Scripts for spells with SPELLFAMILY_PRIEST and SPELLFAMILY_GENERIC spells used by priest players.
20 * Ordered alphabetically using scriptname.
21 * Scriptnames of files in this file should be prefixed with "spell_pri_".
22 */
23
24#include "ScriptMgr.h"
25#include "AreaTriggerAI.h"
26#include "Containers.h"
27#include "G3DPosition.hpp"
28#include "GridNotifiers.h"
29#include "Log.h"
30#include "MoveSplineInitArgs.h"
31#include "ObjectAccessor.h"
32#include "PathGenerator.h"
33#include "Player.h"
34#include "SpellAuraEffects.h"
35#include "SpellHistory.h"
36#include "SpellMgr.h"
37#include "SpellScript.h"
38#include "TaskScheduler.h"
39#include "TemporarySummon.h"
40#include "CommonPredicates.h"
41#include <queue>
42
44{
196 SPELL_PRIEST_POWER_SURGE_HALO_VISUAL_RETURN = 467824, // TODO: cast when triggering first return halo from Divine Halo (from halo on expire script)
277
282
284{
313};
314
322
324{
325 public:
326 explicit RaidCheck(Unit const* caster) : _caster(caster) { }
327
328 bool operator()(WorldObject* obj) const
329 {
330 if (Unit* target = obj->ToUnit())
331 return !_caster->IsInRaidWith(target);
332
333 return true;
334 }
335
336 private:
337 Unit const* _caster;
338};
339
340// 108945 - Angelic Bulwark
342{
343 bool Validate(SpellInfo const* spellInfo) override
344 {
346 && ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
347 }
348
349 bool CheckProc(ProcEventInfo const& eventInfo) const
350 {
352 && eventInfo.GetActionTarget()->HealthBelowPctDamaged(GetEffect(EFFECT_0)->GetAmount(), eventInfo.GetDamageInfo()->GetDamage());
353 }
354
355 void HandleProc(ProcEventInfo const& eventInfo) const
356 {
357 Unit* caster = eventInfo.GetActionTarget();
358 if (!caster)
359 return;
360
361 SpellEffectValue absorb = caster->CountPctFromMaxHealth(GetEffect(EFFECT_1)->GetAmount());
362
364 {
366 .SpellValueOverrides = { { SPELLVALUE_BASE_POINT0, absorb } }
367 });
369 }
370
376};
377
378// 121536 - Angelic Feather talent
380{
381 bool Validate(SpellInfo const* /*spellInfo*/) override
382 {
384 }
385
386 void HandleEffectDummy(SpellEffIndex /*effIndex*/) const
387 {
388 Position destPos = GetHitDest()->GetPosition();
390
391 // Caster is prioritary
392 if (GetCaster()->IsInRange2d(&destPos, radius.Min, radius.Max))
393 {
395 }
396 else
397 {
402 }
403 }
404
409};
410
411// Angelic Feather areatrigger - created by SPELL_PRIEST_ANGELIC_FEATHER_AREATRIGGER
413{
415
416 // Called when the AreaTrigger has just been initialized, just before added to map
417 void OnInitialize() override
418 {
419 if (Unit* caster = at->GetCaster())
420 {
421 std::vector<AreaTrigger*> areaTriggers = caster->GetAreaTriggers(SPELL_PRIEST_ANGELIC_FEATHER_AREATRIGGER);
422
423 if (areaTriggers.size() >= 3)
424 areaTriggers.front()->SetDuration(0);
425 }
426 }
427
428 void OnUnitEnter(Unit* unit) override
429 {
430 if (Unit* caster = at->GetCaster())
431 {
432 if (caster->IsFriendlyTo(unit))
433 {
434 // If target already has aura, increase duration to max 130% of initial duration
435 caster->CastSpell(unit, SPELL_PRIEST_ANGELIC_FEATHER_AURA, true);
436 at->SetDuration(0);
437 }
438 }
439 }
440};
441
442// 391387 - Answered Prayers
444{
445 bool Validate(SpellInfo const* spellInfo) override
446 {
448 && ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
449 }
450
451 void HandleOnProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo) const
452 {
453 Milliseconds extraDuration = 0ms;
454 if (AuraEffect const* durationEffect = GetEffect(EFFECT_1))
455 extraDuration = duration_cast<Milliseconds>(FloatSeconds(durationEffect->GetAmount()));
456
457 Unit* target = eventInfo.GetActor();
458
459 Aura* answeredPrayers = target->GetAura(SPELL_PRIEST_ANSWERED_PRAYERS);
460
461 // Note: if caster has no aura, we must cast it first.
462 if (!answeredPrayers)
464 else
465 {
466 // Note: there's no BaseValue dummy that we can use as reference, so we hardcode the increasing stack value.
467 answeredPrayers->ModStackAmount(1);
468
469 // Note: if current stacks match max. stacks, trigger Apotheosis.
470 if (answeredPrayers->GetStackAmount() != aurEff->GetAmountAsInt())
471 return;
472
473 answeredPrayers->Remove();
474
475 if (Aura* apotheosis = GetTarget()->GetAura(SPELL_PRIEST_APOTHEOSIS))
476 {
477 apotheosis->SetDuration(apotheosis->GetDuration() + extraDuration.count());
478 apotheosis->SetMaxDuration(apotheosis->GetMaxDuration() + extraDuration.count());
479 }
480 else
481 target->CastSpell(target, SPELL_PRIEST_APOTHEOSIS,
483 .AddSpellMod(SPELLVALUE_DURATION, extraDuration.count()));
484 }
485 }
486
491};
492
493// 26169 - Oracle Healing Bonus
495{
496 bool Validate(SpellInfo const* /*spellInfo*/) override
497 {
499 }
500
501 bool CheckProc(ProcEventInfo& eventInfo)
502 {
503 if (eventInfo.GetActor() == eventInfo.GetActionTarget())
504 return false;
505
506 HealInfo* healInfo = eventInfo.GetHealInfo();
507 return healInfo && healInfo->GetHeal();
508 }
509
510 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& eventInfo)
511 {
513
514 CastSpellExtraArgs args(aurEff);
515 args.AddSpellBP0(CalculatePct(eventInfo.GetHealInfo()->GetHeal(), 10));
516 eventInfo.GetActor()->CastSpell(eventInfo.GetActor(), SPELL_PRIEST_ORACULAR_HEAL, args);
517 }
518
524};
525
526// 197862 - Archangel (attached to 472433 - Evangelism)
528{
529 bool Validate(SpellInfo const* /*spellInfo*/) override
530 {
532 }
533
534 bool Load() override
535 {
537 }
538
547
552};
553
554// 81749 - Atonement
556{
562
563 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
564 {
565 return eventInfo.GetDamageInfo() != nullptr;
566 }
567
568 void HandleOnProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
569 {
570 TriggerAtonementHealOnTargets(aurEff, eventInfo);
571 }
572
578
579 std::vector<ObjectGuid> _appliedAtonements;
580
581public:
582 void AddAtonementTarget(ObjectGuid const& target)
583 {
584 _appliedAtonements.push_back(target);
585
588 }
589
591 {
592 std::erase(_appliedAtonements, target);
593
596 }
597
598 std::vector<ObjectGuid> const& GetAtonementTargets() const
599 {
600 return _appliedAtonements;
601 }
602
608
609 void TriggerAtonementHealOnTargets(AuraEffect const* atonementEffect, ProcEventInfo const& eventInfo)
610 {
611 Unit* priest = GetUnitOwner();
612 DamageInfo* damageInfo = eventInfo.GetDamageInfo();
614
615 // Note: atonementEffect holds the correct amount since we passed the effect in the AuraScript that calls this method.
616 args.AddSpellMod(SPELLVALUE_BASE_POINT0, CalculatePct(damageInfo->GetDamage(), atonementEffect->GetAmount()));
617
619 .TriggeredBy = eventInfo.GetSpellInfo(),
620 .DamageSchoolMask = eventInfo.GetDamageInfo()->GetSchoolMask() });
621
622 float distanceLimit = GetEffectInfo(EFFECT_1).CalcValue();
623
624 std::erase_if(_appliedAtonements, [priest, distanceLimit, &args](ObjectGuid const& targetGuid)
625 {
626 if (Unit* target = ObjectAccessor::GetUnit(*priest, targetGuid))
627 {
628 if (target->IsInDist2d(priest, distanceLimit))
629 priest->CastSpell(target, SPELL_PRIEST_ATONEMENT_HEAL, args);
630
631 return false;
632 }
633
634 return true;
635 });
636 }
637
639 {
640 // Note: the damage dimish starts at the 6th application as of 10.0.5.
641 static constexpr std::array<SpellEffectValue, 20> DamageByStack = { 20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 17.5f, 15.0f, 12.5f, 10.0f, 7.5f, 5.5f, 4.0f, 2.5f, 2.0f, 1.5f, 1.25f, 1.0f, 0.75f, 0.63f, 0.5f };
642
643 for (SpellEffIndex effectIndex : { EFFECT_0, EFFECT_1, EFFECT_2 })
644 if (AuraEffect* sinOfTheMany = GetUnitOwner()->GetAuraEffect(SPELL_PRIEST_SINS_OF_THE_MANY, effectIndex))
645 sinOfTheMany->ChangeAmount(DamageByStack[std::min(_appliedAtonements.size(), DamageByStack.size() - 1)]);
646 }
647
649 {
650 Unit* priest = GetUnitOwner();
651 if (AuraEffect const* trinity = priest->GetAuraEffect(SPELL_PRIEST_TRINITY, EFFECT_0); trinity && std::ssize(_appliedAtonements) >= trinity->GetAmount())
653 else
654 priest->RemoveAurasDueToSpell(SPELL_PRIEST_TRINITY_EFFECT);
655 }
656};
657
658// 81751 - Atonement (Heal)
660{
661 bool Validate(SpellInfo const* /*spellInfo*/) override
662 {
664 }
665
666 void CalculateHealingBonus(SpellEffectInfo const& /*spellEffectInfo*/, Unit const* /*victim*/, int32 const& /*healing*/, int32 const& /*flatMod*/, float& pctMod) const
667 {
668 spell_pri_atonement::TriggerArgs const* args = std::any_cast<spell_pri_atonement::TriggerArgs>(&GetSpell()->m_customArg);
669 if (!args || !(args->DamageSchoolMask & SPELL_SCHOOL_MASK_SHADOW))
670 return;
671
672 if (AuraEffect* const abyssalReverieEffect = GetCaster()->GetAuraEffect(SPELL_PRIEST_ABYSSAL_REVERIE, EFFECT_0))
673 AddPct(pctMod, abyssalReverieEffect->GetAmount());
674 }
675
680};
681
682// 17 - Power Word: Shield
683// 2061 - Flash Heal
684// 200829 - Plea
685// 47750 - Penance
686// 194509 - Power Word: Radiance
688{
702
703 bool Load() override
704 {
705 Unit* caster = GetCaster();
706 if (!caster->HasAura(SPELL_PRIEST_ATONEMENT))
707 return false;
708
709 return true;
710 }
711
712 void HandleOnHitTarget() const
713 {
714 Unit* caster = GetCaster();
715 Unit* target = GetHitUnit();
716
719
720 switch (GetSpellInfo()->Id)
721 {
723 if (AuraEffect const* indemnity = caster->GetAuraEffect(SPELL_PRIEST_INDEMNITY, EFFECT_0))
725 (FloatSeconds(indemnity->GetAmount())
727 caster, &GetSpell()->GetPowerCost()))).count());
728 break;
730 // Power Word: Radiance applies Atonement at 60 % (without modifiers) of its total duration.
732 break;
733 default:
734 break;
735 }
736
737 caster->CastSpell(target, _effectSpellId, args);
738 }
739
744
746};
747
748// 194384 - Atonement (Buff)
750{
751 bool Validate(SpellInfo const* /*spellInfo*/) override
752 {
754 }
755
756 void HandleOnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
757 {
758 RegisterHelper<&spell_pri_atonement::AddAtonementTarget>();
759 }
760
761 void HandleOnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
762 {
763 RegisterHelper<&spell_pri_atonement::RemoveAtonementTarget>();
764 }
765
766 template<void(spell_pri_atonement::*func)(ObjectGuid const&)>
767 void RegisterHelper() const
768 {
769 if (Unit* caster = GetCaster())
770 if (Aura* atonement = caster->GetAura(SPELL_PRIEST_ATONEMENT))
771 if (spell_pri_atonement* script = atonement->GetScript<spell_pri_atonement>())
772 (script->*func)(GetTarget()->GetGUID());
773 }
774
780};
781
782// 195178 - Atonement (Passive)
784{
785 bool Validate(SpellInfo const* /*spellInfo*/) override
786 {
788 }
789
790 static bool CheckProc(ProcEventInfo const& eventInfo)
791 {
792 return eventInfo.GetDamageInfo() != nullptr;
793 }
794
795 void HandleOnProc(AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo) const
796 {
797 Unit* target = GetTarget();
798 Unit* summoner = target->GetOwner();
799 if (!summoner)
800 return;
801
802 if (AuraEffect const* atonementEffect = summoner->GetAuraEffect(SPELL_PRIEST_ATONEMENT, EFFECT_0))
803 if (spell_pri_atonement* script = atonementEffect->GetBase()->GetScript<spell_pri_atonement>())
804 script->TriggerAtonementHealOnTargets(atonementEffect, eventInfo);
805 }
806
811};
812
813// 155271 - Auspicious Spirits (attached to 148859 - Shadowy Apparition)
815{
816 bool Validate(SpellInfo const* /*spellInfo*/) override
817 {
819 }
820
821 bool Load() override
822 {
824 }
825
826 static void PreventTarget(SpellScript const&, WorldObject*& target)
827 {
828 target = nullptr;
829 }
830
835};
836
837// 33110 - Prayer of Mending (Heal)
839{
840 bool Validate(SpellInfo const* /*spellInfo*/) override
841 {
844 }
845
846 void HandleEffectHitTarget(SpellEffIndex /*effIndex*/) const
847 {
848 if (AuraEffect const* benediction = GetCaster()->GetAuraEffect(SPELL_PRIEST_BENEDICTION, EFFECT_0))
849 if (roll_chance(benediction->GetAmount()))
851 }
852
857};
858
859// 368275 - Binding Heals
861{
862 bool Validate(SpellInfo const* /*spellInfo*/) override
863 {
865 }
866
867 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
868 {
869 return eventInfo.GetActor() != eventInfo.GetActionTarget();
870 }
871
872 static void HandleEffectProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
873 {
874 Unit* caster = eventInfo.GetActor();
875
878 .TriggeringSpell = eventInfo.GetProcSpell(),
879 .TriggeringAura = aurEff,
880 .SpellValueOverrides = { { SPELLVALUE_BASE_POINT0, SpellEffectValue(CalculatePct(eventInfo.GetHealInfo()->GetHeal(), aurEff->GetAmount())) } }
881 });
882 }
883
889};
890
891// 215768 - Blaze of Light
893{
894 bool Validate(SpellInfo const* /*spellInfo*/) override
895 {
896 return ValidateSpellInfo(
897 {
900 });
901 }
902
903 void HandleProc(ProcEventInfo const& eventInfo) const
904 {
905 Unit* procTarget = eventInfo.GetActionTarget();
906
907 GetTarget()->CastSpell(procTarget, GetTarget()->IsValidAttackTarget(procTarget)
911 }
912
917};
918
919// 372307 - Burning Vehemence
921{
922 bool Validate(SpellInfo const* /*spellInfo*/) override
923 {
925 }
926
927 void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo) const
928 {
930 .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
931 .TriggeringSpell = eventInfo.GetProcSpell(),
932 .TriggeringAura = aurEff,
933 .SpellValueOverrides = { { SPELLVALUE_BASE_POINT0, SpellEffectValue(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount())) } }
934 });
935 }
936
941};
942
943// 204883 - Circle of Healing
945{
946 bool Validate(SpellInfo const* spellInfo) override
947 {
948 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
949 }
950
951 void FilterTargets(std::list<WorldObject*>& targets) const
952 {
953 // Note: we must remove one since target is always chosen.
954 uint32 const maxTargets = uint32(GetSpellInfo()->GetEffect(EFFECT_1).CalcValueAsInt(GetCaster()) - 1);
955
956 Trinity::SelectRandomInjuredTargets(targets, maxTargets, true);
957
958 if (Unit* explicitTarget = GetExplTargetUnit())
959 targets.push_front(explicitTarget);
960 }
961
966};
967
968// 17 - Power Word: Shield
970{
980
981 void HandleOnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) const
982 {
983 Unit* caster = GetCaster();
984 if (!caster)
985 return;
986
987 // Crystalline Reflection Heal
991 }
992
993 void HandleAfterAbsorb(AuraEffect const* /*aurEff*/, DamageInfo const& dmgInfo, uint32 const& absorbAmount) const
994 {
995 Unit* caster = GetCaster();
996 if (!caster)
997 return;
998
1000 if (!auraEff)
1001 return;
1002
1003 Unit* attacker = dmgInfo.GetAttacker();
1004 if (!attacker)
1005 return;
1006
1008 args.AddSpellMod(SPELLVALUE_BASE_POINT0, CalculatePct(absorbAmount, auraEff->GetAmount()));
1010 }
1011
1017};
1018
1019// 8092 - Mind Blast
1021{
1022 bool Validate(SpellInfo const* /*spellInfo*/) override
1023 {
1025 }
1026
1027 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
1028 {
1030 if (!aurEff)
1031 return;
1032
1033 if (roll_chance(aurEff->GetAmount()))
1035 }
1036
1041};
1042
1043// 1240364 - Death's Torment
1045{
1046public:
1047 struct Data
1048 {
1050 int32 BacklashPct = 10; // for some weird reason its 10% for backlash, not 15%
1051 int32 EnergizePct = 25; // for some weird reason its 25% for energize, not 15%
1052 };
1053
1054 bool Validate(SpellInfo const* spellInfo) override
1055 {
1057 && ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
1058 }
1059
1060 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
1061 {
1062 return eventInfo.GetProcSpell()->m_customArg.type() != typeid(Data);
1063 }
1064
1065 void HandleProc(ProcEventInfo const& eventInfo) const
1066 {
1067 Unit* caster = eventInfo.GetActor();
1068 Unit* target = eventInfo.GetActionTarget();
1069
1070 int32 maxHits = GetEffect(EFFECT_0)->GetAmountAsInt();
1071 SpellEffectValue effectiveness = GetEffect(EFFECT_1)->GetAmount();
1072
1073 for (int32 i = 1; i <= maxHits; ++i)
1074 {
1075 caster->m_Events.AddEventAtOffset([caster, targetGuid = target->GetGUID(), effectiveness]
1076 {
1077 if (Unit* target = ObjectAccessor::GetUnit(*caster, targetGuid))
1078 caster->CastSpell(target, SPELL_PRIEST_SHADOW_WORD_DEATH, CastSpellExtraArgsInit{
1079 .TriggerFlags = TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD | TRIGGERED_IGNORE_POWER_COST | TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
1080 .CustomArg = Data{ .DamagePct = effectiveness }
1081 });
1082 }, i * 250ms);
1083 }
1084 }
1085
1086 void Register() override
1087 {
1090 }
1091};
1092
1093// 1215265 - Dispersing Light
1095{
1096 bool Validate(SpellInfo const* spellInfo) override
1097 {
1099 && ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
1100 }
1101
1102 void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo) const
1103 {
1104 HealInfo* healInfo = eventInfo.GetHealInfo();
1105 if (!healInfo || !healInfo->GetHeal())
1106 return;
1107
1108 Unit* caster = eventInfo.GetActor();
1109 Unit* target = eventInfo.GetActionTarget();
1110
1112 {
1114 .TriggeringAura = aurEff,
1115 .SpellValueOverrides =
1116 {
1119 },
1120 .CustomArg = TriggerArgs{ .TargetToExclude = target->GetGUID() }
1121 });
1122 }
1123
1128
1129public:
1134};
1135
1136// 1215266 - Dispersing Light (Heal)
1138{
1139 void FilterTargets(std::list<WorldObject*>& targets) const
1140 {
1141 spell_pri_dispersing_light::TriggerArgs const* args = std::any_cast<spell_pri_dispersing_light::TriggerArgs>(&GetSpell()->m_customArg);
1142 if (!args || args->TargetToExclude.IsEmpty())
1143 return;
1144
1145 targets.remove_if(Trinity::ObjectGUIDCheck(args->TargetToExclude));
1146 }
1147
1152};
1153
1155{
1156Unit* GetSummon(Unit const* owner)
1157{
1158 for (Unit* summon : owner->m_Controlled)
1159 if (summon->GetEntry() == NPC_PRIEST_DIVINE_IMAGE)
1160 return summon;
1161
1162 return nullptr;
1163}
1164
1205
1206void Trigger(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
1207{
1208 Unit* target = eventInfo.GetActor();
1209 if (!target)
1210 return;
1211
1212 Unit* divineImage = GetSummon(target);
1213 if (!divineImage)
1214 return;
1215
1216 Optional<uint32> spellId = GetSpellToCast(eventInfo.GetSpellInfo()->Id);
1217 if (!spellId)
1218 return;
1219
1220 divineImage->CastSpell(SpellCastTargets(eventInfo.GetProcSpell()->m_targets), *spellId, aurEff);
1221}
1222}
1223
1224// 392988 - Divine Image
1226{
1227 bool Validate(SpellInfo const* /*spellInfo*/) override
1228 {
1229 return ValidateSpellInfo
1230 ({
1234 });
1235 }
1236
1237 static void HandleProc(AuraScript const& script, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
1238 {
1239 Unit* target = eventInfo.GetActor();
1240 if (!target)
1241 return;
1242
1243 // Note: if target has an active Divine Image, we should empower it rather than summoning a new one.
1244 if (Unit* divineImage = DivineImageHelpers::GetSummon(target))
1245 {
1246 // Note: Divine Image now teleports near the target when they cast a Holy Word spell if the Divine Image is further than 15 yards away (Patch 10.1.0).
1247 if (target->GetDistance(divineImage) > 15.0f)
1248 divineImage->NearTeleportTo(target->GetRandomNearPosition(3.0f));
1249
1250 if (TempSummon* tempSummon = divineImage->ToTempSummon())
1251 tempSummon->RefreshTimer();
1252
1253 divineImage->CastSpell(divineImage, SPELL_PRIEST_DIVINE_IMAGE_EMPOWER, eventInfo.GetProcSpell());
1254 }
1255 else
1256 {
1258 .SetTriggeringAura(aurEff)
1259 .SetTriggeringSpell(eventInfo.GetProcSpell())
1261
1262 // Note: Divine Image triggers a cast immediately based on the Holy Word cast.
1263 DivineImageHelpers::Trigger(script, aurEff, eventInfo);
1264 }
1265
1267 .SetTriggeringAura(aurEff)
1268 .SetTriggeringSpell(eventInfo.GetProcSpell())
1270 }
1271
1276};
1277
1278// 405216 - Divine Image (Spell Cast Check)
1280{
1316
1317 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
1318 {
1319 return DivineImageHelpers::GetSummon(eventInfo.GetActor()) != nullptr;
1320 }
1321
1326
1333};
1334
1335// 405963 Divine Image
1336// 409387 Divine Image
1338{
1339 void TrackStackApplicationTime(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
1340 {
1341 GetUnitOwner()->m_Events.AddEventAtOffset([spelId = GetId(), owner = GetUnitOwner()]
1342 {
1343 owner->RemoveAuraFromStack(spelId);
1345 }
1346
1351};
1352
1353// 33110 - Prayer of Mending (Heal)
1355{
1356 bool Validate(SpellInfo const* /*spellInfo*/) override
1357 {
1360 }
1361
1362 void CalculateHealingBonus(SpellEffectInfo const& /*spellEffectInfo*/, Unit const* victim, int32& /*healing*/, int32& /*flatMod*/, float& pctMod) const
1363 {
1364 if (AuraEffect const* divineServiceEffect = GetCaster()->GetAuraEffect(SPELL_PRIEST_DIVINE_SERVICE, EFFECT_0))
1365 if (Aura const* prayerOfMending = victim->GetAura(SPELL_PRIEST_PRAYER_OF_MENDING_AURA, GetCaster()->GetGUID()))
1366 AddPct(pctMod, divineServiceEffect->GetAmount() * prayerOfMending->GetStackAmount());
1367 }
1368
1373};
1374
1375// 122121 - Divine Star (Shadow)
1377{
1379 {
1380 Unit* caster = GetCaster();
1381
1382 if (caster->GetPowerType() != GetEffectInfo().MiscValue)
1383 PreventHitDefaultEffect(effIndex);
1384 }
1385
1390};
1391
1392// 110744 - Divine Star (Holy)
1393// 122121 - Divine Star (Shadow)
1395{
1397
1398 void OnInitialize() override
1399 {
1400 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(at->GetSpellId(), DIFFICULTY_NONE);
1401 if (!spellInfo)
1402 return;
1403
1404 if (spellInfo->GetEffects().size() <= EFFECT_1)
1405 return;
1406
1407 Unit* caster = at->GetCaster();
1408 if (!caster)
1409 return;
1410
1412
1413 // Note: max. distance at which the Divine Star can travel to is EFFECT_1's BasePoints yards.
1414 float maxTravelDistance = float(spellInfo->GetEffect(EFFECT_1).CalcValue(caster));
1415
1417 at->MovePositionToFirstCollision(destPos, maxTravelDistance, 0.0f);
1418
1419 PathGenerator firstPath(at);
1420 firstPath.CalculatePath(destPos.GetPositionX(), destPos.GetPositionY(), destPos.GetPositionZ(), false);
1421
1422 at->InitSplines(firstPath.GetPath());
1423 }
1424
1425 void OnUpdate(uint32 diff) override
1426 {
1427 _scheduler.Update(diff);
1428 }
1429
1430 void OnUnitEnter(Unit* unit) override
1431 {
1432 HandleUnitEnterExit(unit);
1433 }
1434
1435 void OnUnitExit(Unit* unit, AreaTriggerExitReason /*reason*/) override
1436 {
1437 // Note: this ensures any unit receives a second hit if they happen to be inside the AT when Divine Star starts its return path.
1438 HandleUnitEnterExit(unit);
1439 }
1440
1442 {
1443 Unit* caster = at->GetCaster();
1444 if (!caster)
1445 return;
1446
1448 return;
1449
1451
1452 if (caster->IsValidAttackTarget(unit))
1454 TriggerFlags);
1455 else if (caster->IsValidAssistTarget(unit))
1457 TriggerFlags);
1458
1459 _affectedUnits.push_back(unit->GetGUID());
1460 }
1461
1462 void OnDestinationReached() override
1463 {
1464 Unit* caster = at->GetCaster();
1465 if (!caster)
1466 return;
1467
1469 {
1470 _affectedUnits.clear();
1471
1473 }
1474 else
1475 at->Remove();
1476 }
1477
1479 {
1480 _scheduler.Schedule(0ms, [this](TaskContext& task)
1481 {
1482 Unit* caster = at->GetCaster();
1483 if (!caster)
1484 return;
1485
1487
1488 Movement::PointsArray returnSplinePoints;
1489
1490 returnSplinePoints.push_back(PositionToVector3(at->GetPosition()));
1491 returnSplinePoints.push_back(PositionToVector3(caster->GetPosition()));
1492
1493 at->InitSplines(returnSplinePoints);
1494
1495 task.Repeat(250ms);
1496 });
1497 }
1498
1499private:
1502 std::vector<ObjectGuid> _affectedUnits;
1503};
1504
1506{
1507 static void ModifyCooldown(Unit* priest, SpellInfo const* spellInfo, Milliseconds cooldownMod)
1508 {
1509 priest->GetSpellHistory()->ModifyCooldown(spellInfo, cooldownMod, true);
1510 }
1511};
1512
1513// 372760 - Divine Word
1515{
1528
1529 void HandleProc(ProcEventInfo const& procInfo) const
1530 {
1531 Unit* caster = GetTarget();
1532 switch (procInfo.GetSpellInfo()->Id)
1533 {
1537 .TriggeringSpell = procInfo.GetProcSpell()
1538 });
1540 Seconds(-GetSpellInfo()->GetEffect(EFFECT_1).CalcValueAsInt(caster)));
1541 break;
1544 .TriggerFlags = TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_IGNORE_CAST_TIME,
1545 .TriggeringSpell = procInfo.GetProcSpell()
1546 });
1547 break;
1551 .TriggeringSpell = procInfo.GetProcSpell()
1552 });
1553 break;
1554 default:
1555 break;
1556 }
1557 }
1558
1559 void Register() override
1560 {
1562 }
1563};
1564
1565// 372784 - Divine Word: Sanctuary
1567{
1568 bool Validate(SpellInfo const* /*spellInfo*/) override
1569 {
1571 }
1572
1573 void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) const
1574 {
1575 Unit* caster = GetTarget();
1576 for (AreaTrigger* at : caster->GetAreaTriggers(GetSpellInfo()->Id))
1577 caster->CastSpell(at->GetPosition(), SPELL_PRIEST_DIVINE_WORD_SANCTUARY_HEAL);
1578 }
1579
1584};
1585
1586// 372787 - Divine Word: Sanctuary
1588{
1589 bool Validate(SpellInfo const* spellInfo) override
1590 {
1591 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
1592 }
1593
1594 void FilterTargets(std::list<WorldObject*>& targets) const
1595 {
1597 Trinity::SelectRandomInjuredTargets(targets, maxTargets, true);
1598 }
1599
1604};
1605
1606// 1215241 - Divinity
1608{
1609 bool Validate(SpellInfo const* spellInfo) override
1610 {
1611 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_2 } })
1612 && ValidateSpellInfo({ SPELL_PRIEST_APOTHEOSIS, spellInfo->GetEffect(EFFECT_2).TriggerSpell });
1613 }
1614
1615 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
1616 {
1618 }
1619
1620 void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& procInfo)
1621 {
1623
1625 .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
1626 .TriggeringSpell = procInfo.GetProcSpell(),
1627 .TriggeringAura = aurEff,
1628 .SpellValueOverrides = { { SPELLVALUE_AURA_STACK, int32(sSpellMgr->AssertSpellInfo(aurEff->GetSpellEffectInfo().TriggerSpell, DIFFICULTY_NONE)->StackAmount) } }
1629 });
1630 }
1631
1637};
1638
1639// 391339 - Empowered Renew
1641{
1642 bool Validate(SpellInfo const* /*spellInfo*/) override
1643 {
1646 && sSpellMgr->AssertSpellInfo(SPELL_PRIEST_RENEW, DIFFICULTY_NONE)->GetEffect(EFFECT_0).IsAura(SPELL_AURA_PERIODIC_HEAL);
1647 }
1648
1649 void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo) const
1650 {
1652 Milliseconds(-aurEff->GetAmountAsInt()));
1653 }
1654
1659};
1660
1661// 139 - Renew
1663{
1664 bool Validate(SpellInfo const* /*spellInfo*/) override
1665 {
1667 }
1668
1669 void CalculateHealing(AuraEffect const* /*aurEff*/, Unit* /*victim*/, int32& /*healing*/, int32& /*flatMod*/, float& pctMod) const
1670 {
1671 if (Unit* caster = GetCaster())
1672 if (AuraEffect const* empRenew = caster->GetAuraEffect(SPELL_PRIEST_EMPOWERED_RENEW, EFFECT_1))
1673 AddPct(pctMod, empRenew->GetAmount());
1674 }
1675
1680};
1681
1682// 372616 - Empyreal Blaze
1684{
1685 bool Validate(SpellInfo const* /*spellInfo*/) override
1686 {
1688 }
1689
1690 static void HandleProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
1691 {
1692 Unit* caster = eventInfo.GetActor();
1693 if (!caster)
1694 return;
1695
1698 .TriggeringSpell = eventInfo.GetProcSpell(),
1699 .TriggeringAura = aurEff,
1700 .SpellValueOverrides = { { SPELLVALUE_AURA_STACK, aurEff->GetAmountAsInt() } }
1701 });
1702 }
1703
1708};
1709
1710// Triggered by 14914 - Holy Fire
1712{
1713 bool Validate(SpellInfo const* /*spellInfo*/) override
1714 {
1716 }
1717
1718 bool Load() override
1719 {
1721 }
1722
1723 void HandleHit() const
1724 {
1725 Unit* target = GetHitUnit();
1726 if (!target)
1727 return;
1728
1729 Aura* holyFireAura = target->GetAura(GetSpellInfo()->Id, GetCaster()->GetGUID());
1730 if (!holyFireAura)
1731 return;
1732
1734 }
1735
1740};
1741
1742// 447444 - Entropic Rift
1743// Triggered by 8092 - Mind Blast (Discipline) and 263165 - Void Torrent (Shadow)
1745{
1746 bool Validate(SpellInfo const* /*spellInfo*/) override
1747 {
1749 }
1750
1751 bool Load() override
1752 {
1753 Unit* caster = GetCaster();
1754 return caster->HasAura(SPELL_PRIEST_ENTROPIC_RIFT)
1755 && caster->IsPlayer()
1759 }
1760
1761 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
1762 {
1763 Unit* target = GetHitUnit();
1764
1766 .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
1767 .CustomArg = target->GetGUID()
1768 });
1769 }
1770
1778};
1779
1780// 450193 - Entropic Rift (Aura)
1782{
1783 bool Validate(SpellInfo const* /*spellInfo*/) override
1784 {
1786 }
1787
1788 void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
1789 {
1791 at->Remove();
1792 }
1793
1798};
1799
1800// 459314 - Entropic Rift (Periodic)
1802{
1803 bool Validate(SpellInfo const* /*spellInfo*/) override
1804 {
1806 }
1807
1808 void HandlePeriodic(AuraEffect const* /*aurEff*/) const
1809 {
1810 Unit* caster = GetTarget();
1811
1813 if (!at)
1814 return;
1815
1816 SpellInfo const* damageSpell = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_ENTROPIC_RIFT_DAMAGE, GetCastDifficulty());
1817
1818 for (ObjectGuid const& unitInAreaTrigger : at->GetInsideUnits())
1819 if (Unit* target = ObjectAccessor::GetUnit(*at, unitInAreaTrigger))
1820 if (caster->IsValidAttackTarget(target, damageSpell))
1822 }
1823
1828};
1829
1830// 447445 - Entropic Rift (AreaTrigger)
1832{
1834
1835 static constexpr std::array<DBCPosition2D, 2> OverrideScaleCurve =
1836 {{
1837 { .X = 0.0f, .Y = 1.0f },
1838 { .X = 1.0f, .Y = 1.0f },
1839 }};
1840
1841 void OnCreate(Spell const* creatingSpell) override
1842 {
1843 Unit* caster = at->GetCaster();
1844 if (!caster)
1845 return;
1846
1847 CastSpellExtraArgs args;
1849
1850 if (creatingSpell)
1851 {
1852 args.OriginalCastId = creatingSpell->m_castId;
1853
1854 if (ObjectGuid const* targetGUID = std::any_cast<ObjectGuid>(&creatingSpell->m_customArg))
1855 at->SetPathTarget(*targetGUID);
1856
1857 _searchRadius = creatingSpell->GetSpellInfo()->GetMinMaxRange();
1858 }
1859
1860 caster->CastSpell(caster, SPELL_PRIEST_ENTROPIC_RIFT_AURA, args);
1861 caster->CastSpell(caster, SPELL_PRIEST_ENTROPIC_RIFT_PERIODIC, args);
1862
1864 _scheduler.Schedule(500ms, [this](TaskContext& task)
1865 {
1867 task.Repeat(500ms);
1868 });
1869 }
1870
1871 void OnUpdate(uint32 diff) override
1872 {
1873 _scheduler.Update(diff);
1874 }
1875
1876 void OnDestinationReached() override
1877 {
1878 _movementSpeed = 7.0f; // Entropic Rift moves slower after reaching its target
1879 }
1880
1882 {
1883 at->SetOverrideScaleCurve(OverrideScaleCurve); // updates StartTimeOffset of the curve
1884
1885 Unit* target = UpdateTarget();
1886 if (!target)
1887 return;
1888
1889 at->SetPathTarget(target->GetGUID());
1890
1891 if (at->IsInDist2d(target, 0.5f))
1892 return;
1893
1894 PathGenerator path(at);
1895 path.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
1897 }
1898
1900 {
1901 SpellInfo const* damageSpell = sSpellMgr->GetSpellInfo(SPELL_PRIEST_ENTROPIC_RIFT_DAMAGE, DIFFICULTY_NONE);
1902 if (!damageSpell || damageSpell->GetEffects().empty())
1903 return nullptr;
1904
1905 Unit* caster = at->GetCaster();
1906 if (!caster)
1907 return nullptr;
1908
1909 SpellEffectInfo const& damageEffect = damageSpell->GetEffect(EFFECT_0);
1911
1912 Unit* target = ObjectAccessor::GetUnit(*at, at->m_areaTriggerData->OrbitPathTarget);
1913 if (!target || !check(target))
1914 {
1915 std::vector<Unit*> targets;
1916 Trinity::UnitListSearcher searcher(at, targets, check);
1918 Trinity::Containers::EraseIf(targets, [caster](Unit const* target) { return !caster->IsInCombatWith(target); });
1919 if (!targets.empty())
1921 }
1922
1923 return target;
1924 }
1925
1926private:
1928 float _movementSpeed = 12.0f;
1930};
1931
1932// 414553 - Epiphany
1934{
1935 bool Validate(SpellInfo const* /*spellInfo*/) override
1936 {
1938 }
1939
1940 static bool CheckProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
1941 {
1942 return roll_chance(aurEff->GetAmount());
1943 }
1944
1945 void HandleOnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) const
1946 {
1947 Unit* target = GetTarget();
1948
1950
1951 target->CastSpell(target, SPELL_PRIEST_EPIPHANY_HIGHLIGHT, aurEff);
1952 }
1953
1959};
1960
1961// 415673 - Essence Devourer (Heal)
1962// 415676 - Essence Devourer (Heal)
1964{
1965 static void FilterTargets(SpellScript const&, std::list<WorldObject*>& targets)
1966 {
1967 Trinity::SelectRandomInjuredTargets(targets, 1, true);
1968 }
1969
1974};
1975
1976// 1215245 - Eternal Sanctity
1978{
1979 bool Validate(SpellInfo const* /*spellInfo*/) override
1980 {
1982 }
1983
1984 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
1985 {
1986 return eventInfo.GetActor()->HasAura(SPELL_PRIEST_APOTHEOSIS);
1987 }
1988
1989 static void HandleEffectProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
1990 {
1991 if (Aura* apotheosisAura = eventInfo.GetActor()->GetAura(SPELL_PRIEST_APOTHEOSIS))
1992 apotheosisAura->SetDuration(apotheosisAura->GetDuration() + aurEff->GetAmountAsInt());
1993 }
1994
2000};
2001
2002// 472433 - Evangelism
2038
2039// 390832 - Expiation
2040// Triggered by 8092 - Mind Blast and 32379 - Shadow Word: Death
2042{
2048
2049 bool Load() override
2050 {
2052 }
2053
2054 void HandleHitTarget(SpellEffIndex /*effIndex*/) const
2055 {
2056 Unit* caster = GetCaster();
2057 Unit* target = GetHitUnit();
2058
2059 Aura const* expiation = caster->GetAura(SPELL_PRIEST_EXPIATION);
2060 if (!expiation)
2061 return;
2062
2063 AuraEffect const* expiationConsume = expiation->GetEffect(EFFECT_0);
2064 AuraEffect const* expiationDmgMul = expiation->GetEffect(EFFECT_1);
2065 if (!expiationConsume || !expiationDmgMul)
2066 return;
2067
2068 AuraEffect const* swPainAuraEffect = target->GetAuraEffect(SPELL_PRIEST_SHADOW_WORD_PAIN, EFFECT_1, caster->GetGUID());
2069 if (!swPainAuraEffect)
2070 return;
2071
2072 Aura* swPainAura = swPainAuraEffect->GetBase();
2073 int32 debuffDuration = swPainAura->GetDuration();
2074 int32 consumeDuration = std::min(debuffDuration, expiationConsume->GetAmountAsInt() * IN_MILLISECONDS);
2075 if (consumeDuration == 0)
2076 return;
2077
2078 float ticksConsumed = static_cast<float>(consumeDuration) / swPainAuraEffect->GetPeriod();
2079 SpellEffectValue damagePerTick = swPainAuraEffect->CalculateEstimatedAmount(caster, swPainAuraEffect->GetAmount()).value_or(swPainAuraEffect->GetAmount());
2080 SpellEffectValue totalDamage = static_cast<int32>(damagePerTick * ticksConsumed);
2081
2082 swPainAura->SetDuration(debuffDuration - consumeDuration);
2083
2085 {
2087 .SpellValueOverrides = { { SPELLVALUE_BASE_POINT0, CalculatePct(totalDamage, expiationDmgMul->GetAmount()) } }
2088 });
2089 }
2090
2095};
2096
2097// 33110 - Prayer of Mending (Heal)
2099{
2100 bool Validate(SpellInfo const* /*spellInfo*/) override
2101 {
2103 }
2104
2105 void CalculateHealingBonus(SpellEffectInfo const& /*spellEffectInfo*/, Unit* /*victim*/, int32& /*healing*/, int32& /*flatMod*/, float& pctMod) const
2106 {
2107 if (AuraEffect const* focusedMendingEffect = GetCaster()->GetAuraEffect(SPELL_PRIEST_FOCUSED_MENDING, EFFECT_0))
2108 {
2109 bool const* isEmpoweredByFocusedMending = std::any_cast<bool>(&GetSpell()->m_customArg);
2110
2111 if (isEmpoweredByFocusedMending && *isEmpoweredByFocusedMending)
2112 AddPct(pctMod, focusedMendingEffect->GetAmount());
2113 }
2114 }
2115
2120};
2121
2122// 390615 - From Darkness Comes Light (Talent)
2135
2136// 47788 - Guardian Spirit
2138{
2140
2141 bool Validate(SpellInfo const* spellInfo) override
2142 {
2144 }
2145
2146 bool Load() override
2147 {
2149 return true;
2150 }
2151
2152 static void CalculateAmount(AuraScript const&, AuraEffect const* /*aurEff*/, SpellEffectValue & amount, bool & /*canBeRecalculated*/)
2153 {
2154 // Set absorbtion amount to unlimited
2155 amount = -1;
2156 }
2157
2158 void Absorb(AuraEffect* /*aurEff*/, DamageInfo const& dmgInfo, uint32 & absorbAmount)
2159 {
2160 Unit* target = GetTarget();
2161 if (dmgInfo.GetDamage() < target->GetHealth())
2162 return;
2163
2165 // remove the aura now, we don't want 40% healing bonus
2168 args.AddSpellBP0(healAmount);
2169 target->CastSpell(target, SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL, args);
2170 absorbAmount = dmgInfo.GetDamage();
2171 }
2172
2178};
2179
2180// 373180 - Harsh Discipline
2181// Triggered by 194509 - Power Word: Radiance
2183{
2189
2190 bool Load() override
2191 {
2193 }
2194
2195 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
2196 {
2197 Unit* caster = GetCaster();
2198 SpellInfo const* penanceChannel = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_PENANCE_CHANNEL_DAMAGE, GetCastDifficulty());
2200
2201 // do the calc here
2202 float channelDuration = penanceChannel->GetDuration();
2203 float channelPeriod = penanceChannel->GetEffect(EFFECT_1).ApplyAuraPeriod;
2204
2205 float baseBolts = channelDuration / channelPeriod;
2206 if (caster->HasAura(SPELL_PRIEST_CASTIGATION))
2207 baseBolts += 1.0f;
2208
2209 SpellEffectValue basePeriod = channelDuration / baseBolts;
2210
2211 SpellEffectValue totalBolts = baseBolts + additionalBolts;
2212 SpellEffectValue newPeriod = channelDuration / totalBolts;
2213 SpellEffectValue pctDiff = GetPctOf(newPeriod - basePeriod, basePeriod);
2214
2217 .SpellValueOverrides = {
2218 { SPELLVALUE_BASE_POINT0, std::floor(pctDiff) },
2219 { SPELLVALUE_BASE_POINT1, additionalBolts }
2220 }
2221 });
2222 }
2223
2228};
2229
2230// 421558 - Heaven's Wrath
2232{
2233 bool Validate(SpellInfo const* /*spellInfo*/) override
2234 {
2236 }
2237
2238 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
2239 {
2241 }
2242
2243 static void HandleEffectProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
2244 {
2245 Unit* caster = eventInfo.GetActor();
2246 if (!caster)
2247 return;
2248
2249 SpellHistory::Duration cdReduction = -duration_cast<SpellHistory::Duration>(FloatSeconds(aurEff->GetAmount()));
2250 caster->GetSpellHistory()->ModifyCooldown(SPELL_PRIEST_ULTIMATE_PENITENCE, cdReduction, true);
2251 }
2252
2257};
2258
2259// 120517 - Halo (Holy)
2260// 120644 - Halo (Shadow)
2262{
2263 bool Validate(SpellInfo const* /*spellInfo*/) override
2264 {
2266 }
2267
2268 static void PreventUnwantedAura(SpellScript const&, WorldObject*& target)
2269 {
2270 target = nullptr;
2271 }
2272
2273 void Register() override
2274 {
2275 Optional<SpellEffIndex> selectedEffect;
2276 if (Unit* caster = GetSpell() ? GetCaster() : nullptr)
2277 {
2278 if (caster->HasAura(SPELL_PRIEST_DIVINE_HALO))
2279 selectedEffect = caster->HasAura(SPELL_PRIEST_PHANTOM_REACH) ? EFFECT_5 : EFFECT_2;
2280 else if (caster->HasAura(SPELL_PRIEST_POWER_SURGE))
2281 selectedEffect = caster->HasAura(SPELL_PRIEST_PHANTOM_REACH) ? EFFECT_4 : EFFECT_1;
2282 else
2283 selectedEffect = caster->HasAura(SPELL_PRIEST_PHANTOM_REACH) ? EFFECT_3 : EFFECT_0;
2284 }
2285
2286 if (selectedEffect != EFFECT_0)
2288
2289 if (selectedEffect != EFFECT_1)
2291
2292 if (selectedEffect != EFFECT_2)
2294
2295 if (selectedEffect != EFFECT_3)
2297
2298 if (selectedEffect != EFFECT_4)
2300
2301 if (selectedEffect != EFFECT_5)
2303 }
2304};
2305
2306// 449840 - Halo (Holy)
2307// 453094 - Halo (Shadow)
2309{
2310 bool Validate(SpellInfo const* /*spellInfo*/) override
2311 {
2313 }
2314
2315 static void PreventUnwantedAura(SpellScript const&, WorldObject*& target)
2316 {
2317 target = nullptr;
2318 }
2319
2332};
2333
2334// 120644 - Halo (Shadow)
2336{
2338 {
2339 Unit* caster = GetCaster();
2340
2341 if (caster->GetPowerType() != GetEffectInfo().MiscValue)
2342 PreventHitDefaultEffect(effIndex);
2343 }
2344
2349};
2350
2351// 120517 - Halo (Holy)
2352// 120644 - Halo (Shadow)
2354{
2356
2357 void OnUnitEnter(Unit* unit) override
2358 {
2359 if (Unit* caster = at->GetCaster())
2360 {
2361 if (caster->IsValidAttackTarget(unit))
2364 else if (caster->IsValidAssistTarget(unit))
2367 }
2368 }
2369};
2370
2371// 449840 - Halo (Holy)
2372// 453094 - Halo (Shadow)
2374{
2376
2377 void OnUnitExit(Unit* unit, AreaTriggerExitReason reason) override
2378 {
2380 return;
2381
2382 if (Unit* caster = at->GetCaster())
2383 {
2384 if (caster->IsValidAttackTarget(unit))
2387 else if (caster->IsValidAssistTarget(unit))
2390 }
2391 }
2392};
2393
2394// 391154 - Holy Mending
2396{
2397 bool Validate(SpellInfo const* /*spellInfo*/) override
2398 {
2400 }
2401
2402 static bool CheckProc(AuraScript const&, AuraEffect const* /*aurEff*/, ProcEventInfo const& procInfo)
2403 {
2404 return procInfo.GetActionTarget()->HasAura(SPELL_PRIEST_RENEW, procInfo.GetActor()->GetGUID());
2405 }
2406
2407 static void HandleProc(AuraScript const&, AuraEffect* aurEff, ProcEventInfo const& eventInfo)
2408 {
2410 }
2411
2417};
2418
2419// 63733 - Holy Words
2421{
2441
2442 void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo const& eventInfo) const
2443 {
2444 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
2445 if (!spellInfo)
2446 return;
2447
2448 uint32 targetSpellId;
2449 SpellEffIndex cdReductionEffIndex;
2450 switch (spellInfo->Id)
2451 {
2452 case SPELL_PRIEST_HEAL:
2453 case SPELL_PRIEST_FLASH_HEAL: // reduce Holy Word: Serenity cd by 6 seconds
2454 targetSpellId = SPELL_PRIEST_HOLY_WORD_SERENITY;
2455 cdReductionEffIndex = EFFECT_1;
2456 // cdReduction = sSpellMgr->GetSpellInfo(SPELL_PRIEST_HOLY_WORD_SERENITY, GetCastDifficulty())->GetEffect(EFFECT_1)->CalcValueAsInt(player);
2457 break;
2458 case SPELL_PRIEST_PRAYER_OF_HEALING: // reduce Holy Word: Sanctify cd by 6 seconds
2459 targetSpellId = SPELL_PRIEST_HOLY_WORD_SANCTIFY;
2460 cdReductionEffIndex = EFFECT_2;
2461 break;
2462 case SPELL_PRIEST_RENEW: // reuce Holy Word: Sanctify cd by 2 seconds
2463 targetSpellId = SPELL_PRIEST_HOLY_WORD_SANCTIFY;
2464 cdReductionEffIndex = EFFECT_3;
2465 break;
2466 case SPELL_PRIEST_SMITE: // reduce Holy Word: Chastise cd by 4 seconds
2467 targetSpellId = SPELL_PRIEST_HOLY_WORD_CHASTISE;
2468 cdReductionEffIndex = EFFECT_1;
2469 break;
2470 default:
2471 TC_LOG_WARN("spells.priest", "HolyWords aura has been proced by an unknown spell: {}", GetSpellInfo()->Id);
2472 return;
2473 }
2474
2475 SpellInfo const* targetSpellInfo = sSpellMgr->AssertSpellInfo(targetSpellId, GetCastDifficulty());
2476 int32 cdReduction = targetSpellInfo->GetEffect(cdReductionEffIndex).CalcValueAsInt(GetTarget());
2477 spell_pri_holy_words_base::ModifyCooldown(GetTarget(), targetSpellInfo, Seconds(-cdReduction));
2478 }
2479
2484};
2485
2486// 88625 - Holy Word: Chastise
2515
2516// 265202 - Holy Word: Salvation
2518{
2519 bool Validate(SpellInfo const* spellInfo) override
2520 {
2521 return ValidateSpellInfo
2522 ({
2525 }) && ValidateSpellEffect({
2527 { spellInfo->Id, EFFECT_1 }
2529 }
2530
2531 bool Load() override
2532 {
2535 return true;
2536 }
2537
2538 void HandleApplyBuffs(SpellEffIndex /*effIndex*/) const
2539 {
2540 Unit* caster = GetCaster();
2541 Unit* target = GetHitUnit();
2542
2543 CastSpellExtraArgs args;
2545
2546 // amount of Prayer of Mending is SPELL_PRIEST_HOLY_WORD_SALVATION's EFFECT_1.
2548
2550 args.AddSpellMod(SPELLVALUE_BASE_POINT0, basePoints);
2551 caster->CastSpell(target, SPELL_PRIEST_PRAYER_OF_MENDING_AURA, args);
2552
2553 // a full duration Renew is triggered.
2554 caster->CastSpell(target, SPELL_PRIEST_RENEW, CastSpellExtraArgs(TRIGGERED_FULL_MASK).SetTriggeringSpell(GetSpell()));
2555 }
2556
2561
2562 SpellInfo const* _spellInfoHeal = nullptr;
2564};
2565
2566// 2050 - Holy Word: Serenity
2567// 34861 - Holy Word: Sanctify
2569{
2570 bool Validate(SpellInfo const* /*spellInfo*/) override
2571 {
2574 }
2575
2576 bool Load() override
2577 {
2579 }
2580
2581 void ReduceCooldown() const
2582 {
2583 // cooldown reduced by SPELL_PRIEST_HOLY_WORD_SALVATION's Seconds(EFFECT_2).
2584 int32 cooldownReduction = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_HOLY_WORD_SALVATION, GetCastDifficulty())->GetEffect(EFFECT_2).CalcValueAsInt(GetCaster());
2585
2587 }
2588
2593};
2594
2595// 373427 - Inescapable Torment
2596// Triggered by 8092 - Mind Blast, 32379 - Shadow Word: Death
2597// Triggered by 47758 - Penance (Channel) and 373129 - Dark Reprimand (Channel)
2599{
2600 bool Validate(SpellInfo const* /*spellInfo*/) override
2601 {
2604 }
2605
2606 bool Load() override
2607 {
2609 }
2610
2611 static TempSummon* GetSummon(Unit const* owner)
2612 {
2613 for (Unit* summon : owner->m_Controlled)
2614 if (summon->GetEntry() == NPC_PRIEST_SHADOWFIEND || summon->GetEntry() == NPC_PRIEST_MINDBENDER || summon->GetEntry() == NPC_PRIEST_VOIDWRAITH)
2615 return summon->ToTempSummon();
2616 return nullptr;
2617 }
2618
2619 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
2620 {
2621 Unit const* caster = GetCaster();
2622 TempSummon* summon = GetSummon(caster);
2623 if (!summon)
2624 return;
2625
2628 .TriggeringSpell = GetSpell()
2629 });
2630
2631 int32 durationExtend = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_INESCAPABLE_TORMENT, DIFFICULTY_NONE)->GetEffect(EFFECT_1).CalcValueAsInt(caster);
2632 summon->ModifyTimer(Milliseconds(durationExtend));
2633 }
2634
2639};
2640
2641// 373212 - Insidious Ire
2643{
2644 static void HandleProc(AuraScript const&, ProcEventInfo const& eventInfo)
2645 {
2646 Unit* caster = eventInfo.GetActor();
2647 Unit* target = eventInfo.GetActionTarget();
2648
2649 Aura const* requiredAuras[] =
2650 {
2651 target->GetAura(SPELL_PRIEST_SHADOW_WORD_PAIN, caster->GetGUID()),
2652 target->GetAura(SPELL_PRIEST_DEVOURING_PLAGUE, caster->GetGUID()),
2653 target->GetAura(SPELL_PRIEST_VAMPIRIC_TOUCH, caster->GetGUID())
2654 };
2655
2656 if (advstd::ranges::contains(requiredAuras, nullptr))
2657 {
2659 return;
2660 }
2661
2662 int32 shortestDuration = std::ranges::min(requiredAuras, {}, [](Aura const* a) { return a->GetDuration(); })->GetDuration();
2663
2666 .SpellValueOverrides = { { SPELLVALUE_DURATION, shortestDuration } }
2667 });
2668 }
2669
2670 void Register() override
2671 {
2673 }
2674};
2675
2676// 40438 - Priest Tier 6 Trinket
2678{
2679 bool Validate(SpellInfo const* /*spellInfo*/) override
2680 {
2682 }
2683
2684 void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo const& eventInfo)
2685 {
2687 Unit* caster = eventInfo.GetActor();
2688 if (eventInfo.GetSpellTypeMask() & PROC_SPELL_TYPE_HEAL)
2689 caster->CastSpell(nullptr, SPELL_PRIEST_DIVINE_BLESSING, true);
2690
2691 if (eventInfo.GetSpellTypeMask() & PROC_SPELL_TYPE_DAMAGE)
2692 caster->CastSpell(nullptr, SPELL_PRIEST_DIVINE_WRATH, true);
2693 }
2694
2699};
2700
2701// 471504 - Lasting Words
2702// Triggered by 2050 - Holy Word: Serenity and 34861 - Holy Word: Sanctify
2704{
2705 bool Validate(SpellInfo const* /*spellInfo*/) override
2706 {
2709 }
2710
2711 bool Load() override
2712 {
2714 }
2715
2716 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
2717 {
2718 Unit* caster = GetCaster();
2719
2720 AuraEffect const* lastingWordsEff = caster->GetAuraEffect(SPELL_PRIEST_LASTING_WORDS, _spellEff);
2721 if (!lastingWordsEff)
2722 return;
2723
2726 .TriggeringSpell = GetSpell(),
2727 .SpellValueOverrides = { { SPELLVALUE_DURATION, lastingWordsEff->GetAmountAsInt() } }
2728 });
2729 }
2730
2735
2737
2738public:
2739 explicit spell_pri_lasting_words(SpellEffIndex spellEff) : _spellEff(spellEff) { }
2740};
2741
2742// 92833 - Leap of Faith
2744{
2745 bool Validate(SpellInfo const* /*spellInfo*/) override
2746 {
2748 }
2749
2750 void HandleEffectDummy(SpellEffIndex /*effIndex*/) const
2751 {
2752 Position destPos = GetHitDest()->GetPosition();
2753
2754 SpellCastTargets targets;
2755 targets.SetDst(destPos);
2756 targets.SetUnitTarget(GetCaster());
2757 GetHitUnit()->CastSpell(std::move(targets), GetEffectValueAsInt(), GetCastDifficulty());
2758 }
2759
2764};
2765
2766// 1706 - Levitate
2768{
2769 bool Validate(SpellInfo const* /*spellInfo*/) override
2770 {
2772 }
2773
2774 void HandleDummy(SpellEffIndex /*effIndex*/) const
2775 {
2777 }
2778
2783};
2784
2785// 373178 - Light's Wrath
2787{
2788 bool Validate(SpellInfo const* spellInfo) override
2789 {
2790 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
2791 }
2792
2793 void OnPrecast() override
2794 {
2795 Aura const* atonement = GetCaster()->GetAura(SPELL_PRIEST_ATONEMENT);
2796 if (!atonement)
2797 return;
2798
2799 spell_pri_atonement const* script = atonement->GetScript<spell_pri_atonement>();
2800 if (!script)
2801 return;
2802
2803 for (ObjectGuid const& atonementTarget : script->GetAtonementTargets())
2804 {
2805 if (Unit* target = ObjectAccessor::GetUnit(*GetCaster(), atonementTarget))
2806 {
2807 target->CancelSpellMissiles(SPELL_PRIEST_LIGHTS_WRATH_VISUAL, false, false);
2809 }
2810 }
2811 }
2812
2813 void CalculateDamageBonus(SpellEffectInfo const& /*spellEffectInfo*/, Unit const* /*victim*/, int32 const& /*damage*/, int32 const& /*flatMod*/, float& pctMod) const
2814 {
2815 Aura const* atonement = GetCaster()->GetAura(SPELL_PRIEST_ATONEMENT);
2816 if (!atonement)
2817 return;
2818
2819 // Atonement size may have changed when missile hits, we need to take an updated count of Atonement applications.
2820 if (spell_pri_atonement const* script = atonement->GetScript<spell_pri_atonement>())
2821 AddPct(pctMod, GetEffectInfo(EFFECT_1).CalcValue(GetCaster()) * script->GetAtonementTargets().size());
2822 }
2823
2828};
2829
2830// 1253590 - Master the Darkness
2832{
2833 bool Validate(SpellInfo const* /*spellInfo*/) override
2834 {
2836 }
2837
2838 static bool CheckProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& /*eventInfo*/)
2839 {
2840 return roll_chance(aurEff->GetAmount());
2841 }
2842
2843 static void HandleOnProc(AuraScript const&, AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo)
2844 {
2846 }
2847
2853};
2854
2855// 375994 - Mental Decay
2857{
2858 bool Validate(SpellInfo const* /*spellInfo*/) override
2859 {
2861 }
2862
2863 static void HandleEffectProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
2864 {
2865 Unit* caster = eventInfo.GetActor();
2866 if (!caster)
2867 return;
2868
2869 Unit* target = eventInfo.GetActionTarget();
2870 int32 durationExtend = aurEff->GetAmount() * int32(IN_MILLISECONDS);
2871
2872 if (Aura* shadowWordPain = target->GetOwnedAura(SPELL_PRIEST_SHADOW_WORD_PAIN, caster->GetGUID()))
2873 {
2874 shadowWordPain->SetMaxDuration(shadowWordPain->GetDuration() + durationExtend);
2875 shadowWordPain->SetDuration(shadowWordPain->GetDuration() + durationExtend);
2876 }
2877
2878 if (Aura* vampiricTouch = target->GetOwnedAura(SPELL_PRIEST_VAMPIRIC_TOUCH, caster->GetGUID()))
2879 {
2880 vampiricTouch->SetMaxDuration(vampiricTouch->GetDuration() + durationExtend);
2881 vampiricTouch->SetDuration(vampiricTouch->GetDuration() + durationExtend);
2882 }
2883 }
2884
2889};
2890
2891// 205369 - Mind Bomb
2893{
2894 bool Validate(SpellInfo const* /*spellInfo*/) override
2895 {
2897 }
2898
2899 void RemoveEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
2900 {
2901 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH || GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
2902 if (Unit* caster = GetCaster())
2903 caster->CastSpell(GetTarget()->GetPosition(), SPELL_PRIEST_MIND_BOMB_STUN, true);
2904 }
2905
2910};
2911
2912// 373202 - Mind Devourer
2913// Triggered by 8092 - Mind Blast
2915{
2916 bool Validate(SpellInfo const* /*spellInfo*/) override
2917 {
2920 }
2921
2922 bool Load() override
2923 {
2925 }
2926
2927 void HandleEffectHitTarget(SpellEffIndex /*effIndex*/) const
2928 {
2930 if (aurEff && roll_chance(aurEff->GetAmount()))
2932 }
2933
2938};
2939
2940// 373204 - Mind Devourer (Aura)
2941// Attached to 335467 - Devouring Plague
2943{
2944 void CalculateDamage(AuraEffect const* /*aurEff*/, Unit* /*victim*/, int32& /*damage*/, int32& /*flatMod*/, float& pctMod) const
2945 {
2946 AddPct(pctMod, DamageIncrease);
2947 }
2948
2953
2954public:
2956};
2957
2959{
2960 bool Validate(SpellInfo const* /*spellInfo*/) override
2961 {
2963 }
2964
2965 void OnPrecast() override
2966 {
2968 if (!mindDevourer || !GetSpell()->m_appliedMods.contains(mindDevourer->GetBase()))
2969 return;
2970
2971 _damageIncrease = mindDevourer->GetAmount();
2972 }
2973
2974 void CalculateDamage(SpellEffectInfo const& /*spellEffectInfo*/, Unit* /*victim*/, int32& /*damage*/, int32& /*flatMod*/, float& pctMod) const
2975 {
2976 AddPct(pctMod, _damageIncrease);
2977 }
2978
2980 {
2981 if (!_damageIncrease)
2982 return;
2983
2984 if (Aura* devouringPlague = GetHitAura())
2985 if (spell_pri_mind_devourer_buff_aura* script = devouringPlague->GetScript<spell_pri_mind_devourer_buff_aura>())
2986 script->DamageIncrease = _damageIncrease;
2987
2989 }
2990
2996
2998};
2999
3000// 390686 - Painful Punishment
3002{
3003 bool Validate(SpellInfo const* /*spellInfo*/) override
3004 {
3005 return ValidateSpellInfo
3006 ({
3009 });
3010 }
3011
3012 static void HandleEffectProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
3013 {
3014 Unit* caster = eventInfo.GetActor();
3015 Unit* target = eventInfo.GetActionTarget();
3016 if (!caster || !target)
3017 return;
3018
3019 int32 additionalDuration = aurEff->GetAmountAsInt();
3020
3021 if (Aura* shadowWordPain = target->GetOwnedAura(SPELL_PRIEST_SHADOW_WORD_PAIN, caster->GetGUID()))
3022 shadowWordPain->SetDuration(shadowWordPain->GetDuration() + additionalDuration);
3023
3024 if (Aura* purgeTheWicked = target->GetOwnedAura(SPELL_PRIEST_PURGE_THE_WICKED_PERIODIC, caster->GetGUID()))
3025 purgeTheWicked->SetDuration(purgeTheWicked->GetDuration() + additionalDuration);
3026 }
3027
3032};
3033
3034// 372991 - Pain Transformation
3035// Triggered by 33206 - Pain Suppression
3067
3068// 47540 - Penance
3069// 400169 - Dark Reprimand
3071{
3072public:
3073 spell_pri_penance(uint32 damageSpellId, uint32 healingSpellId) : _damageSpellId(damageSpellId), _healingSpellId(healingSpellId)
3074 {
3075 }
3076
3077 bool Validate(SpellInfo const* /*spellInfo*/) override
3078 {
3080 }
3081
3083 {
3084 Unit* caster = GetCaster();
3085
3086 if (Unit* target = GetExplTargetUnit())
3087 {
3088 if (!caster->IsFriendlyTo(target))
3089 {
3090 if (!caster->IsValidAttackTarget(target))
3092
3093 if (!caster->isInFront(target))
3095 }
3096 }
3097
3098 return SPELL_CAST_OK;
3099 }
3100
3101 void HandleDummy(SpellEffIndex /*effIndex*/) const
3102 {
3103 Unit* caster = GetCaster();
3104
3105 if (Unit* target = GetHitUnit())
3106 {
3107 if (caster->IsFriendlyTo(target))
3109 .SetTriggeringSpell(GetSpell()));
3110 else
3112 .SetTriggeringSpell(GetSpell()));
3113 }
3114 }
3115
3121
3122private:
3125};
3126
3127// 47758 - Penance (Channel Damage), 47757 - Penance (Channel Healing)
3128// 373129 - Dark Reprimand (Channel Damage), 400171 - Dark Reprimand (Channel Healing)
3130{
3131 bool Validate(SpellInfo const* /*spellInfo*/) override
3132 {
3134 }
3135
3136 void HandleOnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
3137 {
3138 if (Unit* caster = GetCaster())
3139 caster->RemoveAura(SPELL_PRIEST_POWER_OF_THE_DARK_SIDE);
3140 }
3141
3146};
3147
3148// 114239 - Phantasm
3150{
3151 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
3152 {
3154 }
3155
3160};
3161
3162// 262484 - Power Leech (Passive for Shadowfiend)
3163// 284621 - Power Leech (Passive for Mindbender)
3165{
3186
3187 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
3188 {
3189 return eventInfo.GetDamageInfo() != nullptr;
3190 }
3191
3192 void HandleOnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) const
3193 {
3194 Unit* target = GetTarget();
3195 Player* summoner = Object::ToPlayer(target->GetOwner());
3196 if (!summoner)
3197 return;
3198
3199 SpellInfo const* spellInfo = nullptr;
3200 int32 divisor = 1;
3201
3203 {
3204 if (target->GetEntry() == NPC_PRIEST_SHADOWFIEND)
3205 {
3206 // Note: divisor is 100 because effect value is 5 and its supposed to restore 0.5%
3208 divisor = 10;
3209 }
3210 else
3211 {
3212 // Note: divisor is 100 because effect value is 20 and its supposed to restore 0.2%
3214 divisor = 100;
3215 }
3216 }
3217 else
3218 spellInfo = sSpellMgr->AssertSpellInfo(target->GetEntry() == NPC_PRIEST_SHADOWFIEND
3221
3222 target->CastSpell(summoner, spellInfo->Id, CastSpellExtraArgs(aurEff)
3224
3225 // Note: Essence Devourer talent.
3228 }
3229
3235};
3236
3237// 198069 - Power of the Dark Side
3239{
3240 bool Validate(SpellInfo const* /*spellInfo*/) override
3241 {
3243 }
3244
3245 void HandleOnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
3246 {
3247 if (Unit* caster = GetCaster())
3248 caster->CastSpell(caster, SPELL_PRIEST_POWER_OF_THE_DARK_SIDE_TINT, true);
3249 }
3250
3251 void HandleOnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
3252 {
3253 if (Unit* caster = GetCaster())
3254 caster->RemoveAura(SPELL_PRIEST_POWER_OF_THE_DARK_SIDE_TINT);
3255 }
3256
3262};
3263
3264// 47666 - Penance (Damage)
3265// 373130 - Dark Reprimand (Damage)
3267{
3268 bool Validate(SpellInfo const* /*spellInfo*/) override
3269 {
3271 }
3272
3273 void CalculateDamageBonus(SpellEffectInfo const& /*spellEffectInfo*/, Unit* /*victim*/, int32& /*damage*/, int32& /*flatMod*/, float& pctMod) const
3274 {
3275 if (AuraEffect* powerOfTheDarkSide = GetCaster()->GetAuraEffect(SPELL_PRIEST_POWER_OF_THE_DARK_SIDE, EFFECT_0))
3276 AddPct(pctMod, powerOfTheDarkSide->GetAmount());
3277 }
3278
3283};
3284
3285// 47750 - Penance (Healing)
3286// 400187 - Dark Reprimand (Healing)
3288{
3289 bool Validate(SpellInfo const* /*spellInfo*/) override
3290 {
3292 }
3293
3294 void CalculateHealingBonus(SpellEffectInfo const& /*spellEffectInfo*/, Unit* /*victim*/, int32& /*healing*/, int32& /*flatMod*/, float& pctMod) const
3295 {
3296 if (AuraEffect* powerOfTheDarkSide = GetCaster()->GetAuraEffect(SPELL_PRIEST_POWER_OF_THE_DARK_SIDE, EFFECT_0))
3297 AddPct(pctMod, powerOfTheDarkSide->GetAmount());
3298 }
3299
3304};
3305
3306// 453109 - Power Surge
3307// Triggered by 120517 - Halo (Holy) and 120644 - Halo (Shadow)
3309{
3321
3322 static void HandleProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
3323 {
3324 Unit* caster = eventInfo.GetActor();
3325
3326 uint32 spellId = 0;
3327 switch (eventInfo.GetSpellInfo()->Id)
3328 {
3331 break;
3334 break;
3335 default:
3336 return;
3337 }
3338
3341 .TriggeringSpell = eventInfo.GetProcSpell(),
3342 .TriggeringAura = aurEff
3343 };
3344
3345 caster->CastSpell(caster, SPELL_PRIEST_POWER_SURGE_HALO_VISUAL, args);
3346 caster->CastSpell(caster, spellId, args);
3347 }
3348
3353};
3354
3355// 453112 - Power Surge (Holy - Periodic)
3356// 453113 - Power Surge (Shadow - Periodic)
3379
3380// 194509 - Power Word: Radiance
3382{
3383 bool Validate(SpellInfo const* /*spellInfo*/) override
3384 {
3386 }
3387
3388 void FilterTargets(std::list<WorldObject*>& targets)
3389 {
3390 Unit* caster = GetCaster();
3391 Unit* explTarget = GetExplTargetUnit();
3392
3393 // we must add one since explicit target is always chosen.
3394 uint32 maxTargets = GetEffectInfo(EFFECT_2).CalcValueAsInt(caster) + 1;
3395
3396 Trinity::SortTargetsWithPriorityRules(targets, maxTargets, GetRadianceRules(caster, explTarget));
3397
3398 for (WorldObject const* target : targets)
3399 {
3400 if (target == explTarget)
3401 continue;
3402
3403 _visualTargets.push_back(target->GetGUID());
3404 }
3405 }
3406
3407 void HandleEffectHitTarget(SpellEffIndex /*effIndex*/) const
3408 {
3409 for (ObjectGuid const& guid : _visualTargets)
3410 if (Unit* target = ObjectAccessor::GetUnit(*GetHitUnit(), guid))
3412 }
3413
3414 static std::array<Trinity::TargetPriorityRule, 5> GetRadianceRules(Unit const* caster, Unit const* explTarget)
3415 {
3416 return
3417 {
3418 [explTarget](WorldObject const* target) { return target == explTarget; },
3419 [caster](Unit const* target) { return !target->HasAura(SPELL_PRIEST_ATONEMENT_EFFECT, caster->GetGUID()); },
3420 [](Unit const* target) { return !target->IsFullHealth(); },
3421 [](WorldObject const* target) { return target->IsPlayer() || (target->IsCreature() && target->ToCreature()->IsTreatedAsRaidUnit()); },
3422 [caster](Unit const* target) { return target->IsInRaidWith(caster); }
3423 };
3424 }
3425
3431
3432 std::vector<ObjectGuid> _visualTargets;
3433};
3434
3435// 472433 - Evangelism (attached to 194509 - Power Word: Radiance)
3437{
3438 bool Validate(SpellInfo const* /*spellInfo*/) override
3439 {
3441 && sSpellMgr->AssertSpellInfo(SPELL_PRIEST_EVANGELISM, DIFFICULTY_NONE)->GetEffect(EFFECT_1).TargetA.GetTarget() == Targets();
3442 }
3443
3444 void CalculateHealing(SpellEffectInfo const& /*effectInfo*/, Unit* /*victim*/, int32& /*healing*/, int32& /*flatMod*/, float& pctMod) const
3445 {
3446 spell_pri_evangelism::TriggerArgs const* evangelism = std::any_cast<spell_pri_evangelism::TriggerArgs>(&GetSpell()->m_customArg);
3447 if (!evangelism)
3448 return;
3449
3450 ApplyPct(pctMod, evangelism->EffectivenessPct);
3451 }
3452
3457};
3458
3459// 17 - Power Word: Shield
3461{
3476
3477 void CalculateAbsorb(AuraEffect const* aurEff, Unit* /*victim*/, int32& /*absorb*/, int32& /*flatMod*/, float& pctMod)
3478 {
3479 Unit* caster = GetCaster();
3480
3481 // Mastery: Grace (TBD: move into DoEffectCalcDamageAndHealing hook with a new SpellScript and AuraScript).
3482 if (AuraEffect const* masteryGraceEffect = caster->GetAuraEffect(SPELL_PRIEST_MASTERY_GRACE, EFFECT_0))
3484 AddPct(pctMod, masteryGraceEffect->GetAmount());
3485
3486 float critChanceDone = caster->SpellCritChanceDone(nullptr, aurEff, GetSpellInfo()->GetSchoolMask(), GetSpellInfo()->GetAttackType());
3487 float critChanceTaken = GetUnitOwner()->SpellCritChanceTaken(caster, nullptr, aurEff, GetSpellInfo()->GetSchoolMask(), critChanceDone, GetSpellInfo()->GetAttackType());
3488
3489 if (roll_chance(critChanceTaken))
3490 pctMod *= 2;
3491 }
3492
3493 void HandleOnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) const
3494 {
3495 Unit* caster = GetCaster();
3496 if (!caster)
3497 return;
3498
3499 // Note: Strength of Soul PvP talent.
3502 }
3503
3504 void HandleOnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) const
3505 {
3507
3508 // Note: Shield Discipline talent.
3509 if (Unit* caster = GetCaster())
3510 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL && caster->HasAura(SPELL_PRIEST_SHIELD_DISCIPLINE))
3511 caster->CastSpell(caster, SPELL_PRIEST_SHIELD_DISCIPLINE_EFFECT, aurEff);
3512 }
3513
3520};
3521
3522// 47515 - Divine Aegis
3524{
3525 bool Validate(SpellInfo const* /*spellInfo*/) override
3526 {
3528 }
3529
3530 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
3531 {
3532 return eventInfo.GetHealInfo() != nullptr;
3533 }
3534
3535 static void HandleProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
3536 {
3537 Unit* caster = eventInfo.GetActor();
3538 if (!caster)
3539 return;
3540
3541 SpellEffectValue aegisAmount = CalculatePct(eventInfo.GetHealInfo()->GetHeal(), aurEff->GetAmount());
3542
3543 CastSpellExtraArgs args(aurEff);
3545 args.AddSpellMod(SPELLVALUE_BASE_POINT0, aegisAmount);
3547 }
3548
3554};
3555
3556// 472361 - Divine Procession
3558{
3564
3565 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) const
3566 {
3567 Unit* caster = GetTarget();
3568
3569 Aura const* atonementAura = caster->GetAura(SPELL_PRIEST_ATONEMENT);
3570 if (!atonementAura)
3571 return;
3572
3573 spell_pri_atonement const* atonementScript = atonementAura->GetScript<spell_pri_atonement>();
3574 if (!atonementScript)
3575 return;
3576
3577 std::vector<ObjectGuid> const& atonementTargets = atonementScript->GetAtonementTargets();
3578 if (atonementTargets.empty())
3579 return;
3580
3581 // smallest Atonement duration should get increased
3582 auto it = std::ranges::min_element(atonementTargets, std::ranges::less(), [caster](ObjectGuid const& guidA)
3583 {
3584 Unit const* target = ObjectAccessor::GetUnit(*caster, guidA);
3585 if (!target)
3586 return std::numeric_limits<int32>::max();
3587
3588 Aura const* atonementEffect = target->GetAura(SPELL_PRIEST_ATONEMENT_EFFECT, caster->GetGUID());
3589 if (!atonementEffect)
3590 return std::numeric_limits<int32>::max();
3591
3592 return atonementEffect->GetDuration();
3593 });
3594
3595 if (Unit const* target = ObjectAccessor::GetUnit(*caster, *it))
3596 {
3597 if (Aura* atonement = target->GetAura(SPELL_PRIEST_ATONEMENT_EFFECT, caster->GetGUID()))
3598 {
3599 if (atonement->GetDuration() < 30 * IN_MILLISECONDS)
3600 {
3601 int32 newDuration = atonement->GetDuration() + aurEff->GetAmountAsInt();
3602 atonement->SetDuration(newDuration);
3603 atonement->SetMaxDuration(newDuration);
3604 }
3605 }
3606 }
3607 }
3608
3613};
3614
3615// 129250 - Power Word: Solace
3617{
3618 bool Validate(SpellInfo const* /*spellInfo*/) override
3619 {
3621 }
3622
3629
3634};
3635
3636// Base class used by various Prayer of Mending spells
3638{
3639public:
3645
3646 bool Load() override
3647 {
3649 return true;
3650 }
3651
3652 void CastPrayerOfMendingAura(Unit* caster, Unit* target, Unit* visualSender, int32 stack, bool firstCast) const
3653 {
3654 CastSpellExtraArgs args;
3657
3658 // Note: this line's purpose is to show the correct amount in Points field in SMSG_AURA_UPDATE.
3659 SpellEffectInfo const* healEffectDummy = &_spellInfoHeal->GetEffect(EFFECT_0);
3660 uint32 basePoints = caster->SpellHealingBonusDone(target, _spellInfoHeal, healEffectDummy->CalcValueAsInt(caster), HEAL, *healEffectDummy);
3661 args.AddSpellMod(SPELLVALUE_BASE_POINT0, basePoints);
3662
3663 // Note: Focused Mending talent.
3664 args.SetCustomArg(firstCast);
3665
3666 caster->CastSpell(target, SPELL_PRIEST_PRAYER_OF_MENDING_AURA, args);
3667
3668 // Note: the visualSender is the priest if it is first cast or the aura holder when the aura triggers.
3669 visualSender->SendPlaySpellVisual(target, SPELL_VISUAL_PRIEST_PRAYER_OF_MENDING, 0, 0, 40.0f);
3670 }
3671
3672protected:
3673 SpellInfo const* _spellInfoHeal = nullptr;
3674};
3675
3676// 33076 - Prayer of Mending (Dummy)
3678{
3679 bool Validate(SpellInfo const* /*spellInfo*/) override
3680 {
3681 return ValidateSpellInfo
3682 ({
3686 });
3687 }
3688
3689 void HandleEffectDummy(SpellEffIndex /*effIndex*/) const
3690 {
3691 Unit* caster = GetCaster();
3692 Unit* target = GetHitUnit();
3693
3694 // Note: we need to increase BasePoints by 1 since it's 4 as default. Also HACKFIX, we shouldn't reduce it by 1 if the target has the aura already.
3696
3697 CastPrayerOfMendingAura(caster, target, caster, stackAmount, true);
3698
3699 // Note: Epiphany talent.
3700 if (caster->HasAura(SPELL_PRIEST_EPIPHANY))
3702 }
3703
3708};
3709
3710// 41635 - Prayer of Mending (Aura)
3712{
3718
3719 void HandleHeal(AuraEffect const* aurEff, ProcEventInfo const& /*eventInfo*/)
3720 {
3721 // Note: caster is the priest who cast the spell and target is current holder of the aura.
3722 Unit* target = GetTarget();
3723
3724 if (Unit* caster = GetCaster())
3725 {
3726 CastSpellExtraArgs args(aurEff);
3728
3729 caster->CastSpell(target, SPELL_PRIEST_PRAYER_OF_MENDING_HEAL, args);
3730
3731 // Note: jump is only executed if higher than 1 stack.
3732 int32 stackAmount = GetStackAmount();
3733 if (stackAmount > 1)
3734 {
3735 args.OriginalCaster = caster->GetGUID();
3736
3737 int32 newStackAmount = stackAmount - 1;
3738 if (AuraEffect* sayYourPrayers = caster->GetAuraEffect(SPELL_PRIEST_SAY_YOUR_PRAYERS, EFFECT_0))
3739 if (roll_chance(sayYourPrayers->GetAmount()))
3740 ++newStackAmount;
3741
3742 args.AddSpellMod(SPELLVALUE_BASE_POINT0, newStackAmount);
3743
3744 target->CastSpell(target, SPELL_PRIEST_PRAYER_OF_MENDING_JUMP, args);
3745 }
3746
3747 Remove();
3748 }
3749 }
3750
3755
3756public:
3757 void SetEmpoweredByFocusedMending(bool isEmpowered)
3758 {
3759 _isEmpoweredByFocusedMending = isEmpowered;
3760 }
3761
3762private:
3764};
3765
3767{
3768 void HandleEffectDummy(SpellEffIndex /*effIndex*/) const
3769 {
3770 Aura* aura = GetHitAura();
3771 if (!aura)
3772 return;
3773
3775 if (!script)
3776 return;
3777
3778 if (bool const* isEmpoweredByFocusedMending = std::any_cast<bool>(&GetSpell()->m_customArg))
3779 script->SetEmpoweredByFocusedMending(isEmpoweredByFocusedMending);
3780 }
3781
3786};
3787
3788// 155793 - Prayer of Mending (Jump)
3808
3809// 391209 - Prayerful Litany (attached to 596 - Prayer of Healing)
3811{
3812 bool Validate(SpellInfo const* /*spellInfo*/) override
3813 {
3815 }
3816
3817 bool Load() override
3818 {
3820 }
3821
3822 void CalcPrimaryTargetHealing(SpellEffectInfo const& /*effectInfo*/, Unit const* victim, int32& /*healing*/, int32& /*flatMod*/, float& pctMod) const
3823 {
3824 if (victim == GetExplTargetUnit())
3825 if (AuraEffect const* prayerfulLitanyEff = GetCaster()->GetAuraEffect(SPELL_PRIEST_PRAYERFUL_LITANY, EFFECT_0))
3826 AddPct(pctMod, prayerfulLitanyEff->GetAmount());
3827 }
3828
3833};
3834
3835// 193063 - Protective Light (Aura)
3837{
3838 static bool CheckEffectProc(AuraScript const&, AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo)
3839 {
3840 return eventInfo.GetActionTarget() == eventInfo.GetActor();
3841 }
3842
3843 static void HandleEffectProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
3844 {
3845 eventInfo.GetActor()->CastSpell(eventInfo.GetActor(), SPELL_PRIEST_PROTECTIVE_LIGHT_AURA, aurEff);
3846 }
3847
3853};
3854
3855// 405554 - Priest Holy 10.1 Class Set 2pc
3884
3885// 411097 - Priest Holy 10.1 Class Set 2pc (Chooser)
3887{
3888 bool Validate(SpellInfo const* /*spellInfo*/) override
3889 {
3891 }
3892
3893 static void FilterTargets(SpellScript const&, std::list<WorldObject*>& targets)
3894 {
3895 Trinity::SelectRandomInjuredTargets(targets, 1, true);
3896 }
3897
3898 void HandleEffectDummy(SpellEffIndex /*effIndex*/) const
3899 {
3900 Unit* caster = GetCaster();
3901 Unit* target = GetHitUnit();
3902
3903 // Note: we need to increase BasePoints by 1 since it's 4 as default. Also HACKFIX, we shouldn't reduce it by 1 if the target has the aura already.
3905
3906 CastPrayerOfMendingAura(caster, target, caster, stackAmount, true);
3907 }
3908
3914};
3915
3916// 155793 - Prayer of Mending (Jump)
3935
3936// 41635 - Prayer of Mending (Aura)
3958
3959// 17 - Power Word: Shield
3961{
3962 bool Validate(SpellInfo const* /*spellInfo*/) override
3963 {
3965 }
3966
3972
3973 void HandleEffectHitTarget(SpellEffIndex /*effIndex*/) const
3974 {
3975 Unit* caster = GetCaster();
3976 if (AuraEffect const* effect = caster->GetAuraEffect(SPELL_PRIEST_ASSURED_SAFETY, EFFECT_0))
3977 CastPrayerOfMendingAura(caster, GetHitUnit(), caster, effect->GetAmountAsInt(), false);
3978 }
3979
3984};
3985
3986// 373036 - Protector of the Frail
3988{
3989 bool Validate(SpellInfo const* /*spellInfo*/) override
3990 {
3992 }
3993
3994 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
3995 {
3996 Unit* caster = GetCaster();
3997
3998 int32 cdReduction = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_PROTECTOR_OF_THE_FRAIL, GetCastDifficulty())->GetEffect(EFFECT_1).CalcValueAsInt(caster);
4000 }
4001
4006};
4007
4008// 204197 - Purge the Wicked
4009// Called by Penance - 47540, Dark Reprimand - 400169
4011{
4012 bool Validate(SpellInfo const* /*spellInfo*/) override
4013 {
4014 return ValidateSpellInfo
4015 ({
4018 });
4019 }
4020
4021 void HandleDummy(SpellEffIndex /*effIndex*/) const
4022 {
4023 Unit* caster = GetCaster();
4024 Unit* target = GetHitUnit();
4025
4028 }
4029
4034};
4035
4036// 204215 - Purge the Wicked
4038{
4044
4045 void FilterTargets(std::list<WorldObject*>& targets) const
4046 {
4047 Unit* caster = GetCaster();
4048 Unit* explTarget = GetExplTargetUnit();
4049
4050 targets.remove_if([&](WorldObject* object) -> bool
4051 {
4052 // Note: we must remove any non-unit target, the explicit target and any other target that may be under any crowd control aura.
4053 Unit* target = object->ToUnit();
4054 return !target || target == explTarget || target->HasBreakableByDamageCrowdControlAura();
4055 });
4056
4057 if (targets.empty())
4058 return;
4059
4060 // Note: there's no SPELL_EFFECT_DUMMY with BasePoints 1 in any of the spells related to use as reference so we hardcode the value.
4061 uint32 spreadCount = 1;
4062
4063 // Note: we must sort our list of targets whose priority is 1) aura, 2) distance, and 3) duration.
4064 targets.sort([&](WorldObject const* lhs, WorldObject const* rhs) -> bool
4065 {
4066 Unit const* targetA = lhs->ToUnit();
4067 Unit const* targetB = rhs->ToUnit();
4068
4069 Aura* auraA = targetA->GetAura(SPELL_PRIEST_PURGE_THE_WICKED_PERIODIC, caster->GetGUID());
4070 Aura* auraB = targetB->GetAura(SPELL_PRIEST_PURGE_THE_WICKED_PERIODIC, caster->GetGUID());
4071
4072 if (!auraA)
4073 {
4074 if (auraB)
4075 return true;
4076 return explTarget->GetExactDist(targetA) < explTarget->GetExactDist(targetB);
4077 }
4078 if (!auraB)
4079 return false;
4080
4081 return auraA->GetDuration() < auraB->GetDuration();
4082 });
4083
4084 // Note: Revel in Purity talent.
4086 spreadCount += sSpellMgr->AssertSpellInfo(SPELL_PRIEST_REVEL_IN_PURITY, DIFFICULTY_NONE)->GetEffect(EFFECT_1).CalcValueAsInt(GetCaster());
4087
4088 if (targets.size() > spreadCount)
4089 targets.resize(spreadCount);
4090 }
4091
4092 void HandleDummy(SpellEffIndex /*effIndex*/) const
4093 {
4094 Unit* caster = GetCaster();
4095 Unit* target = GetHitUnit();
4096
4098 }
4099
4105};
4106
4107// 390622 - Rhapsody
4109{
4110 bool Validate(SpellInfo const* /*spellInfo*/) override
4111 {
4113 }
4114
4115 void HandlePeriodic(AuraEffect const* aurEff) const
4116 {
4117 Unit* target = GetTarget();
4118 if (Aura* rhapsodyStack = target->GetAura(SPELL_PRIEST_RHAPSODY_PROC, GetCasterGUID()))
4119 rhapsodyStack->ModStackAmount(1);
4120 else
4121 target->CastSpell(target, SPELL_PRIEST_RHAPSODY_PROC,
4123 }
4124
4129};
4130
4131// 390636 - Rhapsody
4133{
4134 void PreventChargeDrop(ProcEventInfo const& /*eventInfo*/)
4135 {
4137 }
4138
4139 void RemoveAura(ProcEventInfo const& /*eventInfo*/) const
4140 {
4141 // delay charge drop to allow spellmod to be applied to both damaging and healing spells
4143 }
4144
4150};
4151
4152// 47536 - Rapture
4154{
4155 bool Validate(SpellInfo const* /*spellInfo*/) override
4156 {
4158 }
4159
4161 {
4163 }
4164
4165 void HandleAfterCast() const
4166 {
4167 Unit* caster = GetCaster();
4168
4169 if (Unit* target = ObjectAccessor::GetUnit(*caster, _raptureTarget))
4172 .SetTriggeringSpell(GetSpell()));
4173 }
4174
4180
4181private:
4183};
4184
4185// 8092 - Mind Blast
4187{
4188 bool Validate(SpellInfo const* /*spellInfo*/) override
4189 {
4190 return ValidateSpellInfo
4191 ({
4194 });
4195 }
4196
4202
4207};
4208
4209// 208771 - Sanctuary (Absorb)
4211{
4212 bool Validate(SpellInfo const* /*spellInfo*/) override
4213 {
4215 }
4216
4217 void CalcAbsorbAmount(AuraEffect const* /*aurEff*/, DamageInfo& dmgInfo, uint32& /*absorbAmount*/)
4218 {
4220
4221 Unit const* attacker = dmgInfo.GetAttacker();
4222 if (!attacker)
4223 return;
4224
4225 AuraEffect* amountHolderEffect = attacker->GetAuraEffect(SPELL_PRIEST_SANCTUARY_AURA, EFFECT_0, GetCasterGUID());
4226 if (!amountHolderEffect)
4227 return;
4228
4229 if (dmgInfo.GetDamage() >= uint32(amountHolderEffect->GetAmountAsInt()))
4230 {
4231 amountHolderEffect->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
4232 dmgInfo.AbsorbDamage(amountHolderEffect->GetAmountAsInt());
4233 }
4234 else
4235 {
4236 amountHolderEffect->ChangeAmount(amountHolderEffect->GetAmount() - int32(dmgInfo.GetDamage()));
4237 dmgInfo.AbsorbDamage(dmgInfo.GetDamage());
4238 }
4239 }
4240
4245};
4246
4247// 1280131 - Searing Light
4249{
4250 bool Validate(SpellInfo const* /*spellInfo*/) override
4251 {
4253 }
4254
4255 void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo) const
4256 {
4257 SpellEffectValue dotDmg = CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount());
4258 dotDmg /= sSpellMgr->AssertSpellInfo(SPELL_PRIEST_SEARING_LIGHT_DAMAGE, GetCastDifficulty())->GetEffect(EFFECT_0).GetPeriodicTickCount();
4259
4261 .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS,
4262 .SpellValueOverrides = { { SPELLVALUE_BASE_POINT0, dotDmg } }
4263 });
4264 }
4265
4270};
4271
4272// Smite - 585
4274{
4279
4280 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
4281 {
4282 Player* caster = Object::ToPlayer(GetCaster());
4283 if (!caster)
4284 return;
4285
4286 if (AuraEffect const* sanctuaryEffect = caster->GetAuraEffect(SPELL_PRIEST_SANCTUARY, EFFECT_0))
4287 {
4288 if (Unit* target = GetHitUnit())
4289 {
4290 SpellEffectValue absorbAmount = CalculatePct(caster->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_SHADOW), sanctuaryEffect->GetAmount());
4292
4295 .SetTriggeringSpell(GetSpell()));
4296
4298 .AddSpellMod(SPELLVALUE_BASE_POINT0, absorbAmount)
4300 .SetTriggeringSpell(GetSpell()));
4301 }
4302 }
4303 }
4304
4309};
4310
4311// 280391 - Sins of the Many
4335
4336// 20711 - Spirit of Redemption
4338{
4339 bool Validate(SpellInfo const* /*spellInfo*/) override
4340 {
4342 }
4343
4344 void HandleAbsorb(AuraEffect const* aurEff, DamageInfo const& /*dmgInfo*/, uint32 const& /*absorbAmount*/) const
4345 {
4346 Unit* target = GetTarget();
4347 target->CastSpell(target, SPELL_PRIEST_SPIRIT_OF_REDEMPTION, aurEff);
4348 target->SetFullHealth();
4349 }
4350
4355};
4356
4357// 34433 - Shadowfiend
4358// 123040 - Mindbender (Discipline)
4359// 451235 - Voidwrath
4385
4386// 186263 - Shadow Mend
4388{
4400
4401 void HandleEffectHit() const
4402 {
4403 if (Unit* target = GetHitUnit())
4404 {
4405 Unit* caster = GetCaster();
4406
4407 int32 periodicAmount = GetHitHeal() / 20;
4408 int32 damageForAuraRemoveAmount = periodicAmount * 10;
4409
4410 // Handle Masochism talent
4411 if (caster->HasAura(SPELL_PRIEST_MASOCHISM_TALENT) && caster->GetGUID() == target->GetGUID())
4413 else if (target->IsInCombat() && periodicAmount)
4414 {
4417 args.AddSpellMod(SPELLVALUE_BASE_POINT0, periodicAmount);
4418 args.AddSpellMod(SPELLVALUE_BASE_POINT1, damageForAuraRemoveAmount);
4420 }
4421 }
4422 }
4423
4428};
4429
4430// 187464 - Shadow Mend (Damage)
4432{
4433 bool Validate(SpellInfo const* /*spellInfo*/) override
4434 {
4436 }
4437
4446
4447 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
4448 {
4449 return eventInfo.GetDamageInfo() != nullptr;
4450 }
4451
4452 void HandleProc(AuraEffect* aurEff, ProcEventInfo const& eventInfo)
4453 {
4454 SpellEffectValue newAmount = aurEff->GetAmount() - eventInfo.GetDamageInfo()->GetDamage();
4455
4456 aurEff->ChangeAmount(newAmount);
4457 if (newAmount < 0)
4458 Remove();
4459 }
4460
4467};
4468
4469// 32379 - Shadow Word: Death
4471{
4472 static constexpr Seconds BACKLASH_DELAY = 1s;
4473
4474 bool Validate(SpellInfo const* spellInfo) override
4475 {
4477 && ValidateSpellEffect({ { spellInfo->Id, EFFECT_5 } })
4481 }
4482
4483 void HandleDamageCalculation(SpellEffectInfo const& /*spellEffectInfo*/, Unit const* victim, int32 const& /*damage*/, int32 const& /*flatMod*/, float& pctMod) const
4484 {
4485 if (victim->HealthBelowPct(GetEffectInfo(EFFECT_2).CalcValue(GetCaster())))
4486 AddPct(pctMod, GetEffectInfo(EFFECT_3).CalcValue(GetCaster()));
4487
4488 // handles Death's Torment talent
4489 if (spell_pri_deaths_torment::Data const* deathsTorment = std::any_cast<spell_pri_deaths_torment::Data>(&GetSpell()->m_customArg))
4490 ApplyPct(pctMod, deathsTorment->DamagePct);
4491 }
4492
4493 void DetermineKillStatus(DamageInfo const& damageInfo, uint32& /*resistAmount*/, int32& /*absorbAmount*/) const
4494 {
4495 bool killed = damageInfo.GetDamage() >= damageInfo.GetVictim()->GetHealth();
4496 if (!killed)
4497 {
4498 Unit* caster = GetCaster();
4499 int32 backlashDamage = caster->CountPctFromMaxHealth(GetEffectInfo(EFFECT_5).CalcValue(caster));
4500
4501 // Death's Torment effectiveness on backlash too
4502 if (spell_pri_deaths_torment::Data const* deathsTorment = std::any_cast<spell_pri_deaths_torment::Data>(&GetSpell()->m_customArg))
4503 backlashDamage = CalculatePct(backlashDamage, deathsTorment->BacklashPct);
4504
4505 if (AuraEffect const* titheEvasion = caster->GetAuraEffect(SPELL_PRIEST_TITHE_EVASION, EFFECT_0))
4506 AddPct(backlashDamage, -titheEvasion->GetAmount());
4507
4508 caster->m_Events.AddEventAtOffset([caster, originalCastId = GetSpell()->m_castId, backlashDamage]
4509 {
4512 .SetOriginalCastId(originalCastId)
4513 .AddSpellMod(SPELLVALUE_BASE_POINT0, backlashDamage));
4514
4515 }, BACKLASH_DELAY);
4516 }
4517 }
4518
4520 {
4521 if (spell_pri_deaths_torment::Data const* deathsTorment = std::any_cast<spell_pri_deaths_torment::Data>(&GetSpell()->m_customArg))
4522 SetEffectValue(CalculatePct(GetEffectValue(), deathsTorment->EnergizePct));
4523 }
4524
4525 void Register() override
4526 {
4528
4529 // abuse OnCalculateResistAbsorb to determine if this spell will kill target or not (its still not perfect - happens before absorbs are applied)
4531
4533 }
4534};
4535
4536// 341491 - Shadowy Apparitions
4538{
4539 bool Validate(SpellInfo const* /*spellInfo*/) override
4540 {
4542 }
4543
4544 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
4545 {
4546 // PROC_FLAG_DEAL_HARMFUL_PERIODIC is set on the spell for Tormented Spirits talent
4547 // Devouring Plague cannot proc this on periodic ticks
4548 return !(eventInfo.GetTypeMask() & PROC_FLAG_DEAL_HARMFUL_PERIODIC)
4549 && !eventInfo.GetSpellInfo()->IsAffected(SPELLFAMILY_PRIEST, { 0x8000, 0x0, 0x0, 0x0 });
4550 }
4551
4552public:
4553 static void HandleProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
4554 {
4555 Unit* caster = eventInfo.GetActor();
4558 .TriggeringAura = aurEff
4559 });
4560 }
4561
4567};
4568
4569// 341263 - Shadowy Apparition (Dummy)
4571{
4572 static constexpr uint32 GetSpellVisual(Races race, Gender gender)
4573 {
4574 switch (race)
4575 {
4576 case RACE_HUMAN:
4577 case RACE_KUL_TIRAN:
4580 default:
4582 case RACE_ORC:
4583 case RACE_MAGHAR_ORC:
4585 case RACE_DWARF:
4590 case RACE_NIGHTELF:
4592 case RACE_UNDEAD_PLAYER:
4594 case RACE_TAUREN:
4597 case RACE_GNOME:
4598 case RACE_MECHAGNOME:
4600 case RACE_TROLL:
4603 case RACE_GOBLIN:
4604 case RACE_VULPERA:
4606 case RACE_BLOODELF:
4607 case RACE_NIGHTBORNE:
4608 case RACE_VOID_ELF:
4610 case RACE_DRAENEI:
4613 case RACE_WORGEN:
4620 case RACE_HARANIR_HORDE:
4621 return SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_HUMAN_MALE; // not handled on retail as of patch 12.0.1, uses human male fallback
4622 }
4623 }
4624
4625 bool Validate(SpellInfo const* /*spellInfo*/) override
4626 {
4628 }
4629
4630 void FilterTargets(std::list<WorldObject*>& targets) const
4631 {
4632 targets.remove_if(Trinity::UnitAuraCheck(false, SPELL_PRIEST_VAMPIRIC_TOUCH, GetCaster()->GetGUID()));
4633 }
4634
4635 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
4636 {
4637 Unit* caster = GetCaster();
4638 Unit* target = GetHitUnit();
4639
4640 caster->SendPlaySpellVisual(target, GetSpellVisual(static_cast<Races>(caster->GetRace()), caster->GetGender()), 0, 0, 6.0f);
4643 .TriggeringSpell = GetSpell()
4644 });
4645 }
4646
4652};
4653
4654// 109186 - Surge of Light
4656{
4657 bool Validate(SpellInfo const* /*spellInfo*/) override
4658 {
4659 return ValidateSpellInfo
4660 ({
4663 });
4664 }
4665
4666 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
4667 {
4668 if (eventInfo.GetSpellInfo()->Id == SPELL_PRIEST_SMITE)
4669 return true;
4670
4672 return eventInfo.GetHealInfo();
4673
4674 return false;
4675 }
4676
4677 void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) const
4678 {
4679 if (roll_chance(aurEff->GetAmount()))
4681 }
4682
4688};
4689
4690// 28809 - Greater Heal
4692{
4693 bool Validate(SpellInfo const* /*spellInfo*/) override
4694 {
4696 }
4697
4698 void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
4699 {
4701 eventInfo.GetActor()->CastSpell(eventInfo.GetActionTarget(), SPELL_PRIEST_ARMOR_OF_FAITH, aurEff);
4702 }
4703
4708};
4709
4710// 37594 - Greater Heal Refund
4712{
4713 bool Validate(SpellInfo const* /*spellInfo*/) override
4714 {
4716 }
4717
4718 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
4719 {
4720 if (HealInfo* healInfo = eventInfo.GetHealInfo())
4721 if (Unit* healTarget = healInfo->GetTarget())
4722 if (healInfo->GetEffectiveHeal())
4723 if (healTarget->GetHealth() >= healTarget->GetMaxHealth())
4724 return true;
4725
4726 return false;
4727 }
4728
4729 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
4730 {
4733 }
4734
4740};
4741
4742// 70770 - Item - Priest T10 Healer 2P Bonus
4744{
4745 bool Validate(SpellInfo const* /*spellInfo*/) override
4746 {
4748 && sSpellMgr->AssertSpellInfo(SPELL_PRIEST_BLESSED_HEALING, DIFFICULTY_NONE)->GetEffect(EFFECT_0).GetPeriodicTickCount() > 0;
4749 }
4750
4751 bool CheckProc(ProcEventInfo& eventInfo)
4752 {
4753 HealInfo* healInfo = eventInfo.GetHealInfo();
4754 return healInfo && healInfo->GetHeal();
4755 }
4756
4757 void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
4758 {
4760
4761 SpellEffectInfo const& hotEffect = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_BLESSED_HEALING, GetCastDifficulty())->GetEffect(EFFECT_0);
4762 SpellEffectValue amount = CalculatePct(static_cast<int32>(eventInfo.GetHealInfo()->GetHeal()), aurEff->GetAmount());
4763
4764 amount /= hotEffect.GetPeriodicTickCount();
4765
4766 Unit* caster = eventInfo.GetActor();
4767 Unit* target = eventInfo.GetActionTarget();
4768
4769 CastSpellExtraArgs args(aurEff);
4770 args.AddSpellBP0(amount);
4771 caster->CastSpell(target, SPELL_PRIEST_BLESSED_HEALING, args);
4772 }
4773
4779};
4780
4781// 200128 - Trail of Light
4783{
4784 bool Validate(SpellInfo const* /*spellInfo*/) override
4785 {
4787 }
4788
4789 bool CheckProc(ProcEventInfo const& eventInfo)
4790 {
4791 if (_healQueue.empty() || _healQueue.back() != eventInfo.GetActionTarget()->GetGUID())
4792 _healQueue.push(eventInfo.GetActionTarget()->GetGUID());
4793
4794 if (_healQueue.size() > 2)
4795 _healQueue.pop();
4796
4797 if (_healQueue.size() == 2)
4798 return true;
4799
4800 return false;
4801 }
4802
4803 void HandleOnProc(AuraEffect* aurEff, ProcEventInfo const& eventInfo) const
4804 {
4805 Unit* caster = GetTarget();
4806 Unit* oldTarget = ObjectAccessor::GetUnit(*caster, _healQueue.front());
4807 if (!oldTarget)
4808 return;
4809
4810 // Note: old target may not be friendly anymore due to charm and faction change effects.
4811 if (!caster->IsValidAssistTarget(oldTarget))
4812 return;
4813
4814 SpellInfo const* healSpellInfo = sSpellMgr->GetSpellInfo(SPELL_PRIEST_TRAIL_OF_LIGHT_HEAL, DIFFICULTY_NONE);
4815 if (!healSpellInfo)
4816 return;
4817
4818 // Note: distance may be greater than the heal's spell range.
4819 if (!caster->IsWithinDist(oldTarget, healSpellInfo->GetMaxRange(true, caster)))
4820 return;
4821
4822 SpellEffectValue healAmount = CalculatePct(eventInfo.GetHealInfo()->GetHeal(), aurEff->GetAmount());
4823
4824 caster->CastSpell(oldTarget, SPELL_PRIEST_TRAIL_OF_LIGHT_HEAL, CastSpellExtraArgs(aurEff).AddSpellBP0(healAmount));
4825 }
4826
4832
4833private:
4834 std::queue<ObjectGuid> _healQueue;
4835};
4836
4837// 390693 - Train of Thought
4838// Called by Flash Heal, Renew, Smite
4840{
4841 bool Validate(SpellInfo const* /*spellInfo*/) override
4842 {
4843 return ValidateSpellInfo
4844 ({
4847 });
4848 }
4849
4850 static bool CheckEffect0(AuraScript const&, AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo)
4851 {
4852 // Renew & Flash Heal
4853 return eventInfo.GetSpellInfo()->IsAffected(SPELLFAMILY_PRIEST, { 0x840 });
4854 }
4855
4856 static bool CheckEffect1(AuraScript const&, AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo)
4857 {
4858 // Smite
4859 return eventInfo.GetSpellInfo()->IsAffected(SPELLFAMILY_PRIEST, { 0x80 });
4860 }
4861
4866
4867 void ReducePenanceCooldown(AuraEffect const* aurEff, ProcEventInfo const& /*eventInfo*/) const
4868 {
4870 }
4871
4879};
4880
4881// 373446 - Translucent Image
4882// Triggered by 586 - Fade
4884{
4885 bool Load() override
4886 {
4888 }
4889
4890 static void PreventEffect(SpellScript const&, WorldObject*& target)
4891 {
4892 target = nullptr;
4893 }
4894
4899};
4900
4901// 390705 - Twilight Equilibrium
4903{
4908
4909 void HandleProc(ProcEventInfo const& eventInfo) const
4910 {
4911 uint32 spellId = 0;
4912
4915 else if (eventInfo.GetDamageInfo()->GetSchoolMask() & SPELL_SCHOOL_MASK_HOLY)
4917 else
4918 return;
4919
4920 Unit* caster = GetTarget();
4922 }
4923
4928};
4929
4930// ID - 390707 Twilight Equilibrium (attached to 589 - Shadow Word: Pain)
4932{
4933 bool Validate(SpellInfo const* /*spellInfo*/) override
4934 {
4936 }
4937
4938 void OnApply(AuraEffect const* /*aurEff*/, SpellEffectValue& /*amount*/, bool& /*canBeRecalculated*/)
4939 {
4940 _damageMultiplier = 1.0f;
4941 if (Unit* caster = GetCaster())
4942 {
4943 if (AuraEffect* twilightEquilibrium = caster->GetAuraEffect(SPELL_PRIEST_TWILIGHT_EQUILIBRIUM_SHADOW, EFFECT_0))
4944 {
4945 // snapshot Twilight Equilibrium value
4946 AddPct(_damageMultiplier, twilightEquilibrium->GetAmount());
4947 twilightEquilibrium->GetBase()->Remove();
4948 }
4949 }
4950 }
4951
4952 void CalcDamage(AuraEffect const* /*aurEff*/, Unit* /*victim*/, int32& /*damageOrHealing*/, int32& /*flatMod*/, float& pctMod) const
4953 {
4954 pctMod *= _damageMultiplier;
4955 }
4956
4962
4963 float _damageMultiplier = 1.0f;
4964};
4965
4966// 109142 - Twist of Fate (Shadow)
4967// 265259 - Twist of Fate (Discipline)
4969{
4970 static bool CheckProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
4971 {
4972 return eventInfo.GetActionTarget()->GetHealthPct() < aurEff->GetAmount();
4973 }
4974
4979};
4980
4981// 421453 - Ultimate Penitence
4983{
4988
4989 void TriggerImmunity() const
4990 {
4991 Unit* caster = GetCaster();
4993 {
4995 .TriggeringSpell = GetSpell()
4996 });
4997
4998 SpellEffectValue preferHealing = 1;
4999 if (Unit const* target = GetExplTargetUnit(); target && !GetCaster()->IsFriendlyTo(target))
5000 preferHealing = 0;
5001
5002 caster->m_Events.AddEventAtOffset([caster, originalCastId = GetSpell()->m_originalCastId, preferHealing]
5003 {
5005 {
5007 .OriginalCastId = originalCastId,
5008 .SpellValueOverrides = { { SPELLVALUE_BASE_POINT1, preferHealing } }
5009 });
5010 }, 250ms);
5011 }
5012
5017};
5018
5019// 421453 - Ultimate Penitence (Aura)
5021{
5022 void CalculateAmount(AuraEffect const* /*aurEff*/, SpellEffectValue& amount, bool& canBeRecalculated) const
5023 {
5024 canBeRecalculated = false;
5025 Unit* caster = GetCaster();
5026 if (!caster)
5027 return;
5028
5029 amount = caster->CountPctFromMaxHealth(GetEffectInfo(EFFECT_0).CalcValue(caster));
5030 }
5031
5036};
5037
5038// 421434 - Ultimate Penitence (Channel)
5040{
5052
5053 void HandlePeriodic(AuraEffect const* aurEff) const
5054 {
5055 if (aurEff->GetAmountAsInt() == 1) // set by spell_pri_ultimate_penitence
5056 (void)(TryHealing() || TryDealingDamage());
5057 else
5058 (void)(TryDealingDamage() || TryHealing());
5059 }
5060
5070
5071 bool TryHealing() const
5072 {
5074 Trinity::Containers::EraseIf(allies, [](WorldObject const* ally) { return !ally->IsUnit() || ally->ToUnit()->IsFullHealth(); });
5075 if (allies.empty())
5076 return false;
5077
5078 Unit* caster = GetTarget();
5079
5081
5083 return true;
5084 }
5085
5086 std::list<WorldObject*> SearchTargetCandidates(uint32 spellId, SpellTargetCheckTypes checkType) const
5087 {
5088 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(spellId, GetCastDifficulty());
5089 SpellEffectInfo const& spellEffect = spellInfo->GetEffect(EFFECT_0);
5090
5091 std::list<WorldObject*> targets;
5092 if (uint32 containerTypeMask = Spell::GetSearcherTypeMask(spellInfo, spellEffect, TARGET_OBJECT_TYPE_UNIT, spellEffect.ImplicitTargetConditions.get()))
5093 {
5094 Unit* caster = GetTarget();
5095
5096 SpellRange range = spellInfo->GetMinMaxRange(true, caster);
5097
5098 Trinity::WorldObjectSpellAreaTargetCheck check(range, caster, caster, caster, spellInfo, checkType, spellEffect.ImplicitTargetConditions.get(), TARGET_OBJECT_TYPE_UNIT);
5099 Trinity::WorldObjectListSearcher searcher(caster->GetPhaseShift(), targets, check, containerTypeMask);
5100 Spell::SearchTargets(searcher, containerTypeMask, caster, caster, range.Max + EXTRA_CELL_SEARCH_RADIUS);
5101 }
5102
5103 return targets;
5104 }
5105
5114
5115 static std::array<Trinity::TargetPriorityRule, 2> GetHealingRules(Unit const* caster)
5116 {
5117 return
5118 {
5119 [](WorldObject const* target) { return target->IsPlayer() || (target->IsCreature() && target->ToCreature()->IsTreatedAsRaidUnit()); },
5120 [caster](Unit const* target) { return !caster->IsPlayer() || !caster->ToPlayer()->GetGroup() || target->IsInRaidWith(caster); }
5121 };
5122 }
5123
5129};
5130
5131// 432154 - Ultimate Penitence (Jump)
5133{
5134 static constexpr Position JumpOffset = { 0.0f, 0.0f, 5.0f };
5135
5136 static void SetDestTarget(SpellScript const&, SpellDestination& dest)
5137 {
5139 }
5140
5145};
5146
5147// 341273 - Unfurling Darkness
5148// Triggered by 34914 - Vampiric Touch
5150{
5156
5158 {
5159 bool canTriggerDirectDamage = [&]
5160 {
5161 if (!GetSpell()->m_originalCastId.IsEmpty())
5162 return false; // not when triggered by Shadow Crash (Whispering Shadows talent)
5163 if (AuraEffect const* unfurlingDarkness = GetCaster()->GetAuraEffect(SPELL_PRIEST_UNFURLING_DARKNESS_AURA, EFFECT_0))
5164 if (GetSpell()->m_appliedMods.contains(unfurlingDarkness->GetBase()))
5165 return true;
5166 return false;
5167 }();
5168
5169 if (!canTriggerDirectDamage)
5170 target = nullptr;
5171 }
5172
5174 {
5175 if (!GetSpell()->m_originalCastId.IsEmpty())
5176 return; // not when triggered by Shadow Crash (Whispering Shadows talent)
5177
5178 Unit* caster = GetCaster();
5179
5180 if (AuraEffect const* unfurlingDarkness = GetCaster()->GetAuraEffect(SPELL_PRIEST_UNFURLING_DARKNESS_AURA, EFFECT_0))
5181 {
5182 if (GetSpell()->m_appliedMods.contains(unfurlingDarkness->GetBase()))
5183 {
5184 unfurlingDarkness->GetBase()->Remove();
5185 return;
5186 }
5187 }
5188
5190 caster->CastSpell(caster, SPELL_PRIEST_UNFURLING_DARKNESS_AURA, true);
5191 }
5192
5198};
5199
5200// 15286 - Vampiric Embrace
5202{
5203 bool Validate(SpellInfo const* /*spellInfo*/) override
5204 {
5206 }
5207
5208 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
5209 {
5210 // Not proc from Mind Sear
5211 return !(eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[1] & 0x80000);
5212 }
5213
5214 void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
5215 {
5217 DamageInfo* damageInfo = eventInfo.GetDamageInfo();
5218 if (!damageInfo || !damageInfo->GetDamage())
5219 return;
5220
5221 SpellEffectValue selfHeal = CalculatePct(damageInfo->GetDamage(), aurEff->GetAmount());
5222 SpellEffectValue teamHeal = selfHeal / 2;
5223
5224 CastSpellExtraArgs args(aurEff);
5225 args.AddSpellMod(SPELLVALUE_BASE_POINT0, teamHeal);
5226 args.AddSpellMod(SPELLVALUE_BASE_POINT1, selfHeal);
5228 }
5229
5235};
5236
5237// 15290 - Vampiric Embrace (heal)
5239{
5240 void FilterTargets(std::list<WorldObject*>& unitList) const
5241 {
5242 unitList.remove(GetCaster());
5243 }
5244
5249};
5250
5251// 34914 - Vampiric Touch
5253{
5254 bool Validate(SpellInfo const* /*spellInfo*/) override
5255 {
5257 }
5258
5259 void HandleDispel(DispelInfo const* dispelInfo) const
5260 {
5261 if (Unit* caster = GetCaster())
5262 caster->CastSpell(dispelInfo->GetDispeller(), SPELL_PRIEST_SIN_AND_PUNISHMENT, true);
5263 }
5264
5265 void HandleApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
5266 {
5267 if (Unit* caster = GetCaster())
5268 if (caster->HasAura(SPELL_PRIEST_MISERY))
5269 caster->CastSpell(GetTarget(), SPELL_PRIEST_SHADOW_WORD_PAIN, true);
5270 }
5271
5277};
5278
5279// 390994 - Voice of Harmony
5281{
5282 bool Validate(SpellInfo const* /*spellInfo*/) override
5283 {
5284 return ValidateSpellInfo
5285 ({
5289 });
5290 }
5291
5292 static bool CheckHolyWordSanctify(AuraScript const&, AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo)
5293 {
5294 // Divine Star
5295 // Halo
5296 return eventInfo.GetSpellInfo()->IsAffected(SPELLFAMILY_PRIEST, { 0x0, 0x0, 0x0, 0x4040 });
5297 }
5298
5299 static bool CheckHolyWordSerenity(AuraScript const&, AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo)
5300 {
5301 // Power Word: Life
5302 // Prayer of Mending
5303 return eventInfo.GetSpellInfo()->IsAffected(SPELLFAMILY_PRIEST, { 0x0, 0x0, 0x8000, 0x400000 });
5304 }
5305
5306 static bool CheckHolyWordChastise(AuraScript const&, AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo)
5307 {
5308 // Holy Fire
5309 return eventInfo.GetSpellInfo()->IsAffected(SPELLFAMILY_PRIEST, { 0x100000, 0x0, 0x0, 0x0 });
5310 }
5311
5312 template <uint32 TargetSpellId>
5313 void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& /*eventInfo*/) const
5314 {
5315 SpellInfo const* targetSpellInfo = sSpellMgr->AssertSpellInfo(TargetSpellId, GetCastDifficulty());
5316 Milliseconds cdReduction = -duration_cast<Milliseconds>(FloatSeconds(aurEff->GetAmount()));
5317 spell_pri_holy_words_base::ModifyCooldown(GetTarget(), targetSpellInfo, cdReduction);
5318 }
5319
5320 void Register() override
5321 {
5325 OnEffectProc += AuraEffectProcFn(spell_pri_voice_of_harmony::HandleProc<SPELL_PRIEST_HOLY_WORD_SANCTIFY>, EFFECT_0, SPELL_AURA_DUMMY);
5326 OnEffectProc += AuraEffectProcFn(spell_pri_voice_of_harmony::HandleProc<SPELL_PRIEST_HOLY_WORD_SERENITY>, EFFECT_1, SPELL_AURA_DUMMY);
5327 OnEffectProc += AuraEffectProcFn(spell_pri_voice_of_harmony::HandleProc<SPELL_PRIEST_HOLY_WORD_CHASTISE>, EFFECT_2, SPELL_AURA_DUMMY);
5328 }
5329};
5330
5331// 1242173 - Void Volley
5333{
5334 class BoltEvent : public BasicEvent
5335 {
5336 public:
5337 static constexpr Milliseconds Period = 75ms;
5338
5339 explicit BoltEvent(Unit* caster, ObjectGuid target, ObjectGuid originalCastId, int32 count) :
5340 _caster(caster), _target(target), _originalCastId(originalCastId), _count(count) { }
5341
5342 bool Execute(uint64 time, uint32) override
5343 {
5345 if (!target)
5346 return true;
5347
5350 .OriginalCastId = _originalCastId
5351 });
5352
5353 if (--_count)
5354 {
5356 return false;
5357 }
5358 return true;
5359 }
5360
5361 private:
5366 };
5367
5368 bool Validate(SpellInfo const* spellInfo) override
5369 {
5371 && ValidateSpellEffect({ { spellInfo->Id, EFFECT_2 } });
5372 }
5373
5374 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
5375 {
5376 Unit* caster = GetCaster();
5377 Unit* target = GetHitUnit();
5378
5381 .TriggeringSpell = GetSpell()
5382 });
5383
5385 if (bolts > 1)
5386 caster->m_Events.AddEventAtOffset(new BoltEvent(caster, target->GetGUID(), GetSpell()->m_originalCastId, bolts - 1), BoltEvent::Period);
5387 }
5388
5393};
5394
5395// 205385 - Shadow Crash
5414
5415// 391286 - Whispering Shadows (Dot Application)
5417{
5418 bool Validate(SpellInfo const* /*spellInfo*/) override
5419 {
5421 }
5422
5423 void FilterTargets(std::list<WorldObject*>& targets) const
5424 {
5425 if (targets.size() <= GetSpellValue()->MaxAffectedTargets)
5426 return;
5427
5428 auto getVampiricTouch = [&](WorldObject const* target)
5429 {
5430 return target->ToUnit()->GetAura(SPELL_PRIEST_VAMPIRIC_TOUCH, GetCaster()->GetGUID());
5431 };
5432
5433 // prioritize targets without Vampiric Touch
5434 targets.sort([&](WorldObject const* target1, WorldObject const* target2)
5435 {
5436 int32 duration1 = 0;
5437 if (Aura const* aura1 = getVampiricTouch(target1))
5438 duration1 = aura1->GetDuration();
5439 int32 duration2 = 0;
5440 if (Aura const* aura2 = getVampiricTouch(target2))
5441 duration2 = aura2->GetDuration();
5442 return duration1 < duration2;
5443 });
5444
5445 // remove targets that definitely will not get Vampiric Touch applied (excess targets with longest remaining duration)
5446 while (targets.size() > GetSpellValue()->MaxAffectedTargets && getVampiricTouch(targets.back()) != nullptr)
5447 targets.pop_back();
5448
5449 Trinity::Containers::RandomResize(targets, GetSpellValue()->MaxAffectedTargets);
5450 }
5451
5458
5464};
5465
5467{
5534 RegisterSpellScriptWithArgs(spell_pri_lasting_words, "spell_pri_lasting_words_serenity", EFFECT_0);
5535 RegisterSpellScriptWithArgs(spell_pri_lasting_words, "spell_pri_lasting_words_sanctify", EFFECT_1);
5609}
AreaTriggerExitReason
Definition AreaTrigger.h:70
@ IN_MILLISECONDS
Definition Common.h:38
@ DIFFICULTY_NONE
Definition DBCEnums.h:936
uint8_t uint8
Definition Define.h:156
int32_t int32
Definition Define.h:150
uint64_t uint64
Definition Define.h:153
uint32_t uint32
Definition Define.h:154
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition Duration.h:24
std::chrono::duration< double, Seconds::period > FloatSeconds
Definition Duration.h:29
std::chrono::seconds Seconds
Seconds shorthand typedef.
Definition Duration.h:28
@ GRID_MAP_TYPE_MASK_PLAYER
Definition GridDefines.h:80
@ GRID_MAP_TYPE_MASK_CREATURE
Definition GridDefines.h:77
#define TC_LOG_WARN(filterType__, message__,...)
Definition Log.h:179
#define EXTRA_CELL_SEARCH_RADIUS
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition Optional.h:25
Races
Definition RaceMask.h:28
@ RACE_DARK_IRON_DWARF
Definition RaceMask.h:63
@ RACE_TROLL
Definition RaceMask.h:37
@ RACE_UNDEAD_PLAYER
Definition RaceMask.h:34
@ RACE_PANDAREN_NEUTRAL
Definition RaceMask.h:53
@ RACE_ORC
Definition RaceMask.h:31
@ RACE_LIGHTFORGED_DRAENEI
Definition RaceMask.h:59
@ RACE_DRAENEI
Definition RaceMask.h:40
@ RACE_EARTHEN_DWARF_HORDE
Definition RaceMask.h:79
@ RACE_NIGHTBORNE
Definition RaceMask.h:56
@ RACE_HIGHMOUNTAIN_TAUREN
Definition RaceMask.h:57
@ RACE_HARANIR_HORDE
Definition RaceMask.h:84
@ RACE_EARTHEN_DWARF_ALLIANCE
Definition RaceMask.h:80
@ RACE_DRACTHYR_HORDE
Definition RaceMask.h:68
@ RACE_ZANDALARI_TROLL
Definition RaceMask.h:60
@ RACE_VOID_ELF
Definition RaceMask.h:58
@ RACE_NIGHTELF
Definition RaceMask.h:33
@ RACE_BLOODELF
Definition RaceMask.h:39
@ RACE_DWARF
Definition RaceMask.h:32
@ RACE_GNOME
Definition RaceMask.h:36
@ RACE_GOBLIN
Definition RaceMask.h:38
@ RACE_KUL_TIRAN
Definition RaceMask.h:61
@ RACE_HUMAN
Definition RaceMask.h:30
@ RACE_DRACTHYR_ALLIANCE
Definition RaceMask.h:67
@ RACE_WORGEN
Definition RaceMask.h:51
@ RACE_PANDAREN_ALLIANCE
Definition RaceMask.h:54
@ RACE_VULPERA
Definition RaceMask.h:64
@ RACE_MECHAGNOME
Definition RaceMask.h:66
@ RACE_HARANIR_ALLIANCE
Definition RaceMask.h:81
@ RACE_MAGHAR_ORC
Definition RaceMask.h:65
@ RACE_PANDAREN_HORDE
Definition RaceMask.h:55
@ RACE_TAUREN
Definition RaceMask.h:35
bool roll_chance(float chance, PseudoRandomDistributionState &state)
Definition Random.cpp:131
#define RegisterSpellAndAuraScriptPair(script_1, script_2)
Definition ScriptMgr.h:1381
#define RegisterAreaTriggerAI(ai_name)
Definition ScriptMgr.h:1428
#define RegisterSpellScript(spell_script)
Definition ScriptMgr.h:1383
#define RegisterSpellScriptWithArgs(spell_script, script_name,...)
Definition ScriptMgr.h:1382
SpellEffIndex
@ EFFECT_3
@ EFFECT_6
@ EFFECT_1
@ EFFECT_5
@ EFFECT_0
@ EFFECT_4
@ EFFECT_2
@ SPELL_EFFECT_CREATE_AREATRIGGER
@ SPELL_EFFECT_DUMMY
@ SPELL_EFFECT_SCRIPT_EFFECT
@ SPELL_EFFECT_TRIGGER_MISSILE
@ SPELL_EFFECT_HEAL
@ SPELL_EFFECT_ENERGIZE
@ SPELL_EFFECT_SCHOOL_DAMAGE
@ SPELL_EFFECT_APPLY_AURA
Gender
@ GENDER_MALE
Targets
@ TARGET_UNIT_DEST_AREA_ALLY
@ TARGET_UNIT_CASTER_AREA_PARTY
@ TARGET_UNIT_DEST_AREA_ENEMY
@ TARGET_UNIT_SRC_AREA_ALLY
@ TARGET_UNIT_SRC_AREA_ENEMY
@ TARGET_UNIT_TARGET_ENEMY
@ TARGET_UNIT_DEST_AREA_ENTRY
@ TARGET_DEST_CASTER
@ TARGET_UNIT_CASTER
SpellSchoolMask
@ SPELL_SCHOOL_MASK_SHADOW
@ SPELL_SCHOOL_MASK_NONE
@ SPELL_SCHOOL_MASK_HOLY
SpellCastResult
@ SPELL_FAILED_UNIT_NOT_INFRONT
@ SPELL_FAILED_BAD_TARGETS
@ SPELL_CAST_OK
@ SPELLFAMILY_PRIEST
AuraEffectHandleModes
@ AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK
@ AURA_EFFECT_HANDLE_REAL
@ AURA_REMOVE_BY_DEATH
@ AURA_REMOVE_BY_EXPIRE
@ AURA_REMOVE_BY_ENEMY_SPELL
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_PROC_TRIGGER_SPELL
@ SPELL_AURA_PERIODIC_HEAL
@ SPELL_AURA_DUMMY
@ SPELL_AURA_ADD_FLAT_MODIFIER_BY_SPELL_LABEL
@ SPELL_AURA_MOD_SPEED_ALWAYS
@ SPELL_AURA_SCHOOL_ABSORB
@ SPELL_AURA_PERIODIC_LEECH
@ SPELL_AURA_PERIODIC_DUMMY
@ SPELL_AURA_MECHANIC_IMMUNITY_MASK
@ SPELLVALUE_AURA_STACK
@ SPELLVALUE_MAX_TARGETS
@ SPELLVALUE_DURATION
double SpellEffectValue
This is a double instead of float to be able to store full range of int32.
TriggerCastFlags
@ TRIGGERED_FULL_MASK
Used when doing CastSpell with triggered == true.
@ TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD
Will ignore Spell and Category cooldowns.
@ TRIGGERED_CAST_DIRECTLY
In Spell::prepare, will be cast directly without setting containers for executed spell.
@ TRIGGERED_IGNORE_CASTER_AURASTATE
Will ignore caster aura states including combat requirements and death state.
@ TRIGGERED_IGNORE_CAST_IN_PROGRESS
Will not check if a current cast is in progress.
@ TRIGGERED_IGNORE_SHAPESHIFT
Will ignore shapeshift checks.
@ TRIGGERED_IGNORE_POWER_COST
Will ignore power and reagent cost.
@ TRIGGERED_IGNORE_GCD
Will ignore GCD.
@ TRIGGERED_DISALLOW_PROC_EVENTS
Disallows proc events from triggered spell (default)
@ TRIGGERED_DONT_REPORT_CAST_ERROR
Will return SPELL_FAILED_DONT_REPORT in CheckCast functions.
@ TRIGGERED_SUPPRESS_CASTER_ANIM
Will not play cast animations on caster.
@ TRIGGERED_IGNORE_CAST_TIME
Will always be instantly cast.
@ SPELLVALUE_DURATION_PCT
@ SPELLVALUE_BASE_POINT1
@ SPELLVALUE_BASE_POINT0
SpellTargetCheckTypes
Definition SpellInfo.h:80
@ TARGET_CHECK_ENEMY
Definition SpellInfo.h:83
@ TARGET_CHECK_ALLY
Definition SpellInfo.h:84
@ TARGET_OBJECT_TYPE_UNIT
Definition SpellInfo.h:68
#define sSpellMgr
Definition SpellMgr.h:812
@ PROC_SPELL_TYPE_HEAL
Definition SpellMgr.h:214
@ PROC_SPELL_TYPE_DAMAGE
Definition SpellMgr.h:213
@ PROC_FLAG_DEAL_HARMFUL_PERIODIC
Definition SpellMgr.h:121
#define AuraProcFn(F)
#define SpellObjectTargetSelectFn(F, I, N)
#define SpellCheckCastFn(F)
#define AuraEffectProcFn(F, I, N)
#define SpellOnResistAbsorbCalculateFn(F)
#define SpellEffectFn(F, I, N)
#define AuraEffectCalcAbsorbFn(F, I)
#define AuraEffectCalcAmountFn(F, I, N)
#define SpellObjectAreaTargetSelectFn(F, I, N)
#define AuraEffectPeriodicFn(F, I, N)
#define AuraCheckEffectProcFn(F, I, N)
#define AuraEffectCalcHealingFn(F, I, N)
#define SpellCalcDamageFn(F)
#define SpellCastFn(F)
#define SpellDestinationTargetSelectFn(F, I, N)
#define AuraEffectAbsorbFn(F, I)
#define SPELL_EFFECT_ANY
Definition SpellScript.h:60
#define AuraEffectApplyFn(F, I, N, M)
#define AuraEffectAbsorbOverkillFn(F, I)
#define AuraCheckProcFn(F)
#define SpellHitFn(F)
#define AuraEffectCalcDamageFn(F, I, N)
#define SPELL_AURA_ANY
Definition SpellScript.h:61
#define SpellCalcHealingFn(F)
#define AuraDispelFn(F)
#define AuraEffectRemoveFn(F, I, N, M)
@ HEAL
@ CR_VERSATILITY_DAMAGE_DONE
Definition Unit.h:359
float GetPctOf(T value, T max)
Definition Util.h:78
T AddPct(T &base, U pct)
Definition Util.h:85
T ApplyPct(T &base, U pct)
Definition Util.h:91
T CalculatePct(T base, U pct)
Definition Util.h:72
AreaTrigger *const at
AreaTriggerAI(AreaTrigger *a, uint32 scriptId={}) noexcept
GuidUnorderedSet const & GetInsideUnits() const
void InitSplines(std::vector< G3D::Vector3 > const &splinePoints, Optional< float > overrideSpeed={}, Optional< bool > speedIsTimeInSeconds={})
uint32 GetSpellId() const
UF::UpdateField< UF::AreaTriggerData, int32(WowCS::EntityFragment::CGObject), TYPEID_AREATRIGGER > m_areaTriggerData
void SetOverrideScaleCurve(float overrideScale)
void SetDuration(int32 newDuration)
Unit * GetCaster() const
void SetPathTarget(ObjectGuid pathTarget)
void ChangeAmount(SpellEffectValue newAmount, bool mark=true, bool onStackOrReapply=false, AuraEffect const *triggeredBy=nullptr)
SpellEffectInfo const & GetSpellEffectInfo() const
int32 GetAmountAsInt() const
int32 GetPeriod() const
static Optional< SpellEffectValue > CalculateEstimatedAmount(Unit const *caster, Unit *target, SpellInfo const *spellInfo, SpellEffectInfo const &spellEffectInfo, SpellEffectValue amount, uint8 stack, AuraEffect const *aurEff)
Aura * GetBase() const
SpellEffectValue GetAmount() const
HookList< EffectCalcDamageAndHealingHandler > DoEffectCalcDamageAndHealing
void PreventDefaultAction()
AuraApplication const * GetTargetApplication() const
int32 GetDuration() const
HookList< EffectApplyHandler > AfterEffectRemove
HookList< CheckEffectProcHandler > DoCheckEffectProc
HookList< EffectPeriodicHandler > OnEffectPeriodic
SpellInfo const * GetSpellInfo() const
HookList< EffectApplyHandler > AfterEffectApply
int32 GetMaxDuration() const
HookList< EffectAbsorbHandler > AfterEffectAbsorb
HookList< EffectCalcAmountHandler > DoEffectCalcAmount
Unit * GetCaster() const
SpellEffectInfo const & GetEffectInfo(SpellEffIndex effIndex) const
AuraEffect * GetEffect(uint8 effIndex) const
HookList< EffectAbsorbHandler > OnEffectAbsorb
Aura * GetAura() const
Unit * GetTarget() const
ObjectGuid GetCasterGUID() const
HookList< AuraProcHandler > AfterProc
Difficulty GetCastDifficulty() const
HookList< CheckProcHandler > DoCheckProc
HookList< EffectApplyHandler > OnEffectRemove
HookList< AuraDispelHandler > AfterDispel
HookList< EffectProcHandler > OnEffectProc
Unit * GetUnitOwner() const
HookList< AuraProcHandler > DoPrepareProc
HookList< AuraProcHandler > OnProc
uint8 GetStackAmount() const
HookList< EffectApplyHandler > OnEffectApply
uint32 GetId() const
void DropChargeDelayed(uint32 delay, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
int32 GetDuration() const
Definition SpellAuras.h:222
AuraEffect * GetEffect(uint32 index) const
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT, bool resetPeriodicTimer=true)
int32 CalcMaxDuration() const
Definition SpellAuras.h:219
void SetDuration(int32 duration, bool withMods=false)
uint8 GetStackAmount() const
Definition SpellAuras.h:238
Script * GetScript() const
Definition SpellAuras.h:355
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
bool IsUnit() const
Definition BaseEntity.h:171
ObjectGuid const & GetGUID() const
Definition BaseEntity.h:163
bool IsPlayer() const
Definition BaseEntity.h:173
void AbsorbDamage(uint32 amount)
Definition Unit.cpp:212
Unit * GetVictim() const
Definition Unit.h:461
Unit * GetAttacker() const
Definition Unit.h:460
SpellInfo const * GetSpellInfo() const
Definition Unit.h:462
SpellSchoolMask GetSchoolMask() const
Definition Unit.h:463
uint32 GetDamage() const
Definition Unit.h:466
WorldObject * GetDispeller() const
Definition Unit.h:410
void AddEvent(BasicEvent *event, Milliseconds e_time, bool set_addtime=true)
void AddEventAtOffset(BasicEvent *event, Milliseconds offset)
uint32 GetHeal() const
Definition Unit.h:496
bool IsEmpty() const
Definition ObjectGuid.h:362
Player * ToPlayer()
Definition Object.h:126
uint32 GetEntry() const
Definition Object.h:89
Unit * ToUnit()
Definition Object.h:116
Movement::PointsArray const & GetPath() const
bool CalculatePath(float srcX, float srcY, float srcZ, float destX, float destY, float destZ, bool forceDest=false)
ChrSpecialization GetPrimarySpecialization() const
Definition Player.h:1993
float GetRatingBonusValue(CombatRating cr) const
Definition Player.cpp:5139
Group * GetGroup(Optional< uint8 > partyIndex)
Definition Player.h:2781
HealInfo * GetHealInfo() const
Definition Unit.h:525
Unit * GetActionTarget() const
Definition Unit.h:514
ProcFlagsSpellType GetSpellTypeMask() const
Definition Unit.h:517
Spell const * GetProcSpell() const
Definition Unit.h:527
SpellInfo const * GetSpellInfo() const
Definition Unit.cpp:281
ProcFlagsInit GetTypeMask() const
Definition Unit.h:516
DamageInfo * GetDamageInfo() const
Definition Unit.h:524
Unit * GetActor() const
Definition Unit.h:513
Unit const * _caster
RaidCheck(Unit const *caster)
bool operator()(WorldObject *obj) const
void SetDst(float x, float y, float z, float orientation, uint32 mapId=MAPID_INVALID)
Definition Spell.cpp:341
SpellDestination const * GetDst() const
Definition Spell.cpp:331
void SetUnitTarget(Unit *target)
Definition Spell.cpp:194
SpellEffectValue CalcValue(WorldObject const *caster=nullptr, SpellEffectValue const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
uint32 GetPeriodicTickCount() const
uint32 TriggerSpell
Definition SpellInfo.h:234
std::shared_ptr< std::vector< Condition > > ImplicitTargetConditions
Definition SpellInfo.h:237
bool IsEffect() const
int32 CalcValueAsInt(WorldObject const *caster=nullptr, SpellEffectValue const *basePoints=nullptr, Unit const *target=nullptr, float *variance=nullptr, uint32 castItemId=0, int32 itemLevel=-1) const
SpellRange CalcRadius(WorldObject const *caster=nullptr, SpellTargetIndex targetIndex=SpellTargetIndex::TargetA, Spell *spell=nullptr) const
uint32 ApplyAuraPeriod
Definition SpellInfo.h:217
SpellImplicitTargetInfo TargetB
Definition SpellInfo.h:229
void ResetCooldown(uint32 spellId, bool update=false)
void ModifyCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown=false)
Milliseconds Duration
Targets GetTarget() const
bool IsAffected(uint32 familyName, flag128 const &familyFlags) const
SpellRange GetMinMaxRange(bool positive=false, WorldObject const *caster=nullptr, Spell *spell=nullptr) const
float GetMaxRange(bool positive=false, WorldObject const *caster=nullptr, Spell *spell=nullptr) const
uint32 const Id
Definition SpellInfo.h:328
flag128 SpellFamilyFlags
Definition SpellInfo.h:415
int32 GetDuration() const
SpellEffectInfo const & GetEffect(SpellEffIndex index) const
Definition SpellInfo.h:590
std::vector< SpellEffectInfo > const & GetEffects() const
Definition SpellInfo.h:589
bool HasLabel(uint32 labelId) const
uint32 SpellFamilyName
Definition SpellInfo.h:414
uint32 m_scriptSpellId
static bool ValidateSpellInfo(std::initializer_list< uint32 > spellIds)
static bool ValidateSpellEffect(std::initializer_list< std::pair< uint32, SpellEffIndex > > effects)
HookList< DamageAndHealingCalcHandler > CalcDamage
HookList< CastHandler > AfterCast
WorldLocation * GetHitDest() const
HookList< CheckCastHandler > OnCheckCast
Aura * GetHitAura(bool dynObjAura=false, bool withRemoved=false) const
Unit * GetCaster() const
HookList< HitHandler > AfterHit
void SetEffectValue(SpellEffectValue value)
SpellEffectValue GetEffectValue() const
HookList< DestinationTargetSelectHandler > OnDestinationTargetSelect
int32 GetEffectValueAsInt() const
HookList< HitHandler > OnHit
HookList< EffectHandler > OnEffectHit
void PreventHitDefaultEffect(SpellEffIndex effIndex)
Unit * GetHitUnit() const
SpellValue const * GetSpellValue() const
SpellEffectInfo const & GetEffectInfo() const
HookList< EffectHandler > OnEffectHitTarget
HookList< ObjectTargetSelectHandler > OnObjectTargetSelect
HookList< CastHandler > OnCast
HookList< OnCalculateResistAbsorbHandler > OnCalculateResistAbsorb
HookList< CastHandler > BeforeCast
Spell * GetSpell() const
HookList< EffectHandler > OnEffectLaunchTarget
Difficulty GetCastDifficulty() const
int32 GetHitHeal() const
HookList< EffectHandler > OnEffectLaunch
HookList< DamageAndHealingCalcHandler > CalcHealing
Unit * GetExplTargetUnit() const
SpellInfo const * GetSpellInfo() const
HookList< ObjectAreaTargetSelectHandler > OnObjectAreaTargetSelect
Unit * GetOriginalCaster() const
Definition Spell.h:277
SpellInfo const * GetSpellInfo() const
Definition Spell.h:702
SpellCastTargets m_targets
Definition Spell.h:651
ObjectGuid m_originalCastId
Definition Spell.h:605
std::any m_customArg
Definition Spell.h:649
void SetSpellValue(CastSpellExtraArgsInit::SpellValueOverride const &value)
Definition Spell.cpp:8729
static uint32 GetSearcherTypeMask(SpellInfo const *spellInfo, SpellEffectInfo const &spellEffectInfo, SpellTargetObjectTypes objType, ConditionContainer const *condList)
Definition Spell.cpp:2125
static void SearchTargets(SEARCHER &searcher, uint32 containerMask, WorldObject *referer, Position const *pos, float radius)
Definition Spell.cpp:2163
ObjectGuid m_castId
Definition Spell.h:604
TaskContext & Repeat(TaskScheduler::duration_t duration)
TaskScheduler & Schedule(duration_t time, task_handler_t task)
TaskScheduler & Update()
Update the scheduler to the current time.
void ModifyTimer(Milliseconds mod)
Definition Unit.h:647
float GetHealthPct() const
Definition Unit.h:808
uint64 CountPctFromMaxHealth(float pct) const
Definition Unit.h:809
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3846
void SetFullHealth()
Definition Unit.h:814
void SendPlaySpellVisual(Unit *target, uint32 spellVisualId, uint8 missReason, uint8 reflectStatus, float travelSpeed, bool speedAsTime=false, float launchDelay=0.0f)
Definition Unit.cpp:12400
Aura * GetOwnedAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, Aura *except=nullptr) const
Definition Unit.cpp:3830
Powers GetPowerType() const
Definition Unit.h:823
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition Unit.cpp:4622
bool IsFullHealth() const
Definition Unit.h:803
TempSummon * ToTempSummon()
Definition Unit.h:1844
ControlList m_Controlled
Definition Unit.h:1252
bool IsInCombatWith(Unit const *who) const
Definition Unit.h:1074
float SpellCritChanceDone(Spell *spell, AuraEffect const *aurEff, SpellSchoolMask schoolMask, WeaponAttackType attackType=BASE_ATTACK) const
Definition Unit.cpp:7140
virtual bool HasSpell(uint32) const
Definition Unit.h:1099
Gender GetGender() const
Definition Unit.h:779
float SpellCritChanceTaken(Unit const *caster, Spell *spell, AuraEffect const *aurEff, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType=BASE_ATTACK) const
Definition Unit.cpp:7194
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition Unit.cpp:4792
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4718
uint64 GetHealth() const
Definition Unit.h:800
bool HealthBelowPctDamaged(float pct, uint32 damage) const
Definition Unit.h:805
bool HealthBelowPct(float pct) const
Definition Unit.h:804
void NearTeleportTo(TeleportLocation const &target, bool casting=false)
Definition Unit.cpp:13054
bool IsInRaidWith(Unit const *unit) const
Definition Unit.cpp:12272
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4822
SpellHistory * GetSpellHistory()
Definition Unit.h:1521
bool HasBreakableByDamageCrowdControlAura(Unit const *excludeCasterChannel=nullptr) const
Definition Unit.cpp:783
void RemoveMovementImpairingAuras(bool withRoot)
Definition Unit.cpp:4312
std::vector< AreaTrigger * > GetAreaTriggers(uint32 spellId) const
Definition Unit.cpp:5494
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const
Definition Unit.cpp:7103
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3992
int32 SpellHealingBonusDone(Unit *victim, SpellInfo const *spellProto, int32 healamount, DamageEffectType damagetype, SpellEffectInfo const &spellEffectInfo, uint32 stack=1, Spell *spell=nullptr, AuraEffect const *aurEff=nullptr) const
Definition Unit.cpp:7347
ObjectGuid GetTarget() const
Definition Unit.h:1847
uint8 GetRace() const
Definition Unit.h:773
AreaTrigger * GetAreaTrigger(uint32 spellId) const
Definition Unit.cpp:5488
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2222
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2329
PhaseShift & GetPhaseShift()
Definition Object.h:310
Unit * GetOwner() const
Definition Object.cpp:1603
bool isInFront(WorldObject const *target, float arc=float(M_PI)) const
Definition Object.cpp:668
Position GetRandomNearPosition(float radius)
Definition Object.cpp:2774
bool IsValidAssistTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2487
EventProcessor m_Events
Definition Object.h:561
void MovePositionToFirstCollision(Position &pos, float dist, float angle) const
Definition Object.cpp:2833
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:430
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:494
bool IsFriendlyTo(WorldObject const *target) const
Definition Object.cpp:2191
bool Validate(SpellInfo const *) override
void CalculateHealingBonus(SpellEffectInfo const &, Unit const *, int32 const &, int32 const &, float &pctMod) const
bool Validate(SpellInfo const *spellInfo) override
bool CheckProc(ProcEventInfo const &eventInfo) const
void HandleProc(ProcEventInfo const &eventInfo) const
void HandleEffectDummy(SpellEffIndex) const
bool Validate(SpellInfo const *) override
void HandleOnProc(AuraEffect const *aurEff, ProcEventInfo const &eventInfo) const
bool Validate(SpellInfo const *spellInfo) override
bool CheckProc(ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *) override
void Register() override
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *) override
void Register() override
void HandleDummy(SpellEffIndex) const
bool Load() override
bool Validate(SpellInfo const *) override
void HandleEffectHitTarget(SpellEffIndex) const
void HandleOnRemove(AuraEffect const *, AuraEffectHandleModes)
void HandleOnApply(AuraEffect const *, AuraEffectHandleModes)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleOnProc(AuraEffect const *, ProcEventInfo const &eventInfo) const
static bool CheckProc(ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
void AddAtonementTarget(ObjectGuid const &target)
void UpdateTrinityEffect() const
void UpdateSinsOfTheManyValue() const
void TriggerAtonementHealOnTargets(AuraEffect const *atonementEffect, ProcEventInfo const &eventInfo)
void RemoveAtonementTarget(ObjectGuid const &target)
std::vector< ObjectGuid > const & GetAtonementTargets() const
void HandleOnProc(AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
void Register() override
static bool CheckProc(AuraScript const &, ProcEventInfo const &eventInfo)
std::vector< ObjectGuid > _appliedAtonements
bool Validate(SpellInfo const *spellInfo) override
bool Validate(SpellInfo const *) override
static void PreventTarget(SpellScript const &, WorldObject *&target)
void Register() override
bool Validate(SpellInfo const *) override
void HandleEffectHitTarget(SpellEffIndex) const
bool Validate(SpellInfo const *) override
static void HandleEffectProc(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
static bool CheckProc(AuraScript const &, ProcEventInfo const &eventInfo)
void HandleProc(ProcEventInfo const &eventInfo) const
bool Validate(SpellInfo const *) override
void HandleEffectProc(AuraEffect const *aurEff, ProcEventInfo const &eventInfo) const
bool Validate(SpellInfo const *) override
void FilterTargets(std::list< WorldObject * > &targets) const
bool Validate(SpellInfo const *spellInfo) override
void HandleAfterAbsorb(AuraEffect const *, DamageInfo const &dmgInfo, uint32 const &absorbAmount) const
bool Validate(SpellInfo const *) override
void HandleOnApply(AuraEffect const *aurEff, AuraEffectHandleModes) const
bool Validate(SpellInfo const *) override
void HandleEffectHit(SpellEffIndex) const
void HandleProc(ProcEventInfo const &eventInfo) const
bool Validate(SpellInfo const *spellInfo) override
static bool CheckProc(AuraScript const &, ProcEventInfo const &eventInfo)
void FilterTargets(std::list< WorldObject * > &targets) const
bool Validate(SpellInfo const *spellInfo) override
void HandleProc(AuraEffect const *aurEff, ProcEventInfo const &eventInfo) const
static bool CheckProc(AuraScript const &, ProcEventInfo const &eventInfo)
static void HandleProc(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
void HandleAfterRemove(AuraEffect const *, AuraEffectHandleModes) const
static bool CheckProc(AuraScript const &, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
void TrackStackApplicationTime(AuraEffect const *, AuraEffectHandleModes) const
static void HandleProc(AuraScript const &script, AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &) const
void CalculateHealingBonus(SpellEffectInfo const &, Unit const *victim, int32 &, int32 &, float &pctMod) const
bool Validate(SpellInfo const *) override
void HandleHitTarget(SpellEffIndex effIndex)
void FilterTargets(std::list< WorldObject * > &targets) const
bool Validate(SpellInfo const *spellInfo) override
bool Validate(SpellInfo const *) override
void HandleEffectPeriodic(AuraEffect const *) const
bool Validate(SpellInfo const *spellInfo) override
void Register() override
void HandleProc(ProcEventInfo const &procInfo) const
bool Validate(SpellInfo const *spellInfo) override
void HandleProc(AuraEffect const *aurEff, ProcEventInfo const &procInfo)
void Register() override
static bool CheckProc(AuraScript const &, ProcEventInfo const &eventInfo)
void CalculateHealing(AuraEffect const *, Unit *, int32 &, int32 &, float &pctMod) const
bool Validate(SpellInfo const *) override
void HandleProc(AuraEffect const *aurEff, ProcEventInfo const &eventInfo) const
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
static void HandleProc(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleRemove(AuraEffect const *, AuraEffectHandleModes) const
void HandlePeriodic(AuraEffect const *) const
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleEffectHit(SpellEffIndex) const
static bool CheckProc(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo &)
void HandleOnProc(AuraEffect const *aurEff, ProcEventInfo &) const
void Register() override
bool Validate(SpellInfo const *) override
static void FilterTargets(SpellScript const &, std::list< WorldObject * > &targets)
static void HandleEffectProc(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
static bool CheckProc(AuraScript const &, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
void Register() override
bool Validate(SpellInfo const *) override
void HandleDummy(SpellEffIndex) const
void Register() override
void HandleHitTarget(SpellEffIndex) const
bool Validate(SpellInfo const *) override
bool Load() override
bool Validate(SpellInfo const *) override
void CalculateHealingBonus(SpellEffectInfo const &, Unit *, int32 &, int32 &, float &pctMod) const
void HandleEffectProc(AuraEffect const *aurEff, ProcEventInfo &) const
void Absorb(AuraEffect *, DamageInfo const &dmgInfo, uint32 &absorbAmount)
bool Validate(SpellInfo const *spellInfo) override
static void CalculateAmount(AuraScript const &, AuraEffect const *, SpellEffectValue &amount, bool &)
bool Validate(SpellInfo const *) override
static void PreventUnwantedAura(SpellScript const &, WorldObject *&target)
bool Validate(SpellInfo const *) override
static void PreventUnwantedAura(SpellScript const &, WorldObject *&target)
void HandleHitTarget(SpellEffIndex effIndex)
void Register() override
bool Validate(SpellInfo const *) override
void HandleEffectHit(SpellEffIndex) const
static bool CheckProc(AuraScript const &, ProcEventInfo const &eventInfo)
static void HandleEffectProc(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
static void FilterTargets(SpellScript const &, std::list< WorldObject * > &targets)
void HandleEffectDummy(SpellEffIndex) const
bool Validate(SpellInfo const *) override
static bool CheckProc(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo &)
bool Validate(SpellInfo const *) override
void HandleProc(AuraEffect const *aurEff, ProcEventInfo const &eventInfo) const
void HandleOnRemove(AuraEffect const *aurEff, AuraEffectHandleModes) const
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleEffectDummy(SpellEffIndex) const
static void HandleProc(AuraScript const &, AuraEffect *aurEff, ProcEventInfo const &eventInfo)
static bool CheckProc(AuraScript const &, AuraEffect const *, ProcEventInfo const &procInfo)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
SpellEffectInfo const * _healEffectDummy
bool Validate(SpellInfo const *spellInfo) override
void HandleApplyBuffs(SpellEffIndex) const
bool Validate(SpellInfo const *) override
void Register() override
void HandleProc(AuraEffect *, ProcEventInfo const &eventInfo) const
void HandleEffectHit(SpellEffIndex) const
static TempSummon * GetSummon(Unit const *owner)
bool Validate(SpellInfo const *) override
static void HandleProc(AuraScript const &, ProcEventInfo const &eventInfo)
void HandleProc(AuraEffect *, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleEffectHit(SpellEffIndex) const
spell_pri_lasting_words(SpellEffIndex spellEff)
bool Validate(SpellInfo const *) override
void HandleEffectDummy(SpellEffIndex) const
void Register() override
void HandleDummy(SpellEffIndex) const
bool Validate(SpellInfo const *) override
void OnPrecast() override
void CalculateDamageBonus(SpellEffectInfo const &, Unit const *, int32 const &, int32 const &, float &pctMod) const
bool Validate(SpellInfo const *spellInfo) override
bool Validate(SpellInfo const *) override
static void HandleOnProc(AuraScript const &, AuraEffect const *, ProcEventInfo const &eventInfo)
static bool CheckProc(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo const &)
static void HandleEffectProc(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
void RemoveEffect(AuraEffect const *, AuraEffectHandleModes) const
void Register() override
bool Validate(SpellInfo const *) override
void CalculateDamage(AuraEffect const *, Unit *, int32 &, int32 &, float &pctMod) const
bool Validate(SpellInfo const *) override
void ModifyAuraValueAndRemoveBuff(SpellEffIndex) const
void CalculateDamage(SpellEffectInfo const &, Unit *, int32 &, int32 &, float &pctMod) const
void HandleEffectHitTarget(SpellEffIndex) const
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleHit(SpellEffIndex) const
bool Validate(SpellInfo const *) override
static void HandleEffectProc(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
void HandleOnRemove(AuraEffect const *, AuraEffectHandleModes) const
bool Validate(SpellInfo const *) override
spell_pri_penance(uint32 damageSpellId, uint32 healingSpellId)
void HandleDummy(SpellEffIndex) const
void Register() override
SpellCastResult CheckCast() const
bool Validate(SpellInfo const *) override
void HandleEffectHit(SpellEffIndex) const
void Register() override
static bool CheckProc(AuraScript const &, ProcEventInfo const &eventInfo)
void HandleOnProc(AuraEffect const *aurEff, ProcEventInfo &) const
bool Validate(SpellInfo const *) override
void CalculateDamageBonus(SpellEffectInfo const &, Unit *, int32 &, int32 &, float &pctMod) const
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void CalculateHealingBonus(SpellEffectInfo const &, Unit *, int32 &, int32 &, float &pctMod) const
void HandleOnRemove(AuraEffect const *, AuraEffectHandleModes) const
bool Validate(SpellInfo const *) override
void HandleOnApply(AuraEffect const *, AuraEffectHandleModes) const
bool Validate(SpellInfo const *) override
spell_pri_power_surge_periodic(uint32 haloSpellId)
void HandleEffectPeriodic(AuraEffect const *) const
static void HandleProc(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
void Register() override
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void CalculateHealing(SpellEffectInfo const &, Unit *, int32 &, int32 &, float &pctMod) const
bool Validate(SpellInfo const *) override
void FilterTargets(std::list< WorldObject * > &targets)
void HandleEffectHitTarget(SpellEffIndex) const
static std::array< Trinity::TargetPriorityRule, 5 > GetRadianceRules(Unit const *caster, Unit const *explTarget)
std::vector< ObjectGuid > _visualTargets
void CalculateAbsorb(AuraEffect const *aurEff, Unit *, int32 &, int32 &, float &pctMod)
void HandleOnRemove(AuraEffect const *aurEff, AuraEffectHandleModes) const
void HandleOnApply(AuraEffect const *aurEff, AuraEffectHandleModes) const
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void RestoreMana(SpellEffIndex) const
bool Validate(SpellInfo const *) override
void CastPrayerOfMendingAura(Unit *caster, Unit *target, Unit *visualSender, int32 stack, bool firstCast) const
bool Validate(SpellInfo const *) override
void HandleHeal(AuraEffect const *aurEff, ProcEventInfo const &)
void SetEmpoweredByFocusedMending(bool isEmpowered)
void HandleEffectDummy(SpellEffIndex) const
bool Validate(SpellInfo const *) override
void HandleJump(SpellEffIndex) const
static void FilterTargets(SpellScript const &, std::list< WorldObject * > &targets)
void HandleEffectDummy(SpellEffIndex) const
void CalcPrimaryTargetHealing(SpellEffectInfo const &, Unit const *victim, int32 &, int32 &, float &pctMod) const
bool Validate(SpellInfo const *) override
static bool CheckEffectProc(AuraScript const &, AuraEffect const *, ProcEventInfo const &eventInfo)
static void HandleEffectProc(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
void HandleEffectHit(SpellEffIndex) const
void HandleDummy(SpellEffIndex) const
bool Validate(SpellInfo const *) override
void FilterTargets(std::list< WorldObject * > &targets) const
void HandleDummy(SpellEffIndex) const
bool Validate(SpellInfo const *) override
void Register() override
bool Validate(SpellInfo const *) override
void HandleAfterCast() const
void HandleEffectDummy(SpellEffIndex)
ObjectGuid _raptureTarget
void RemoveAura(ProcEventInfo const &) const
void PreventChargeDrop(ProcEventInfo const &)
void HandlePeriodic(AuraEffect const *aurEff) const
bool Validate(SpellInfo const *) override
void Register() override
void CalcAbsorbAmount(AuraEffect const *, DamageInfo &dmgInfo, uint32 &)
bool Validate(SpellInfo const *) override
void HandleEffectHit(SpellEffIndex) const
bool Validate(SpellInfo const *) override
void Register() override
void HandleEffectHitTarget(SpellEffIndex) const
bool Validate(SpellInfo const *) override
void HandleEffectProc(AuraEffect const *aurEff, ProcEventInfo const &eventInfo) const
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
bool Validate(SpellInfo const *) override
void HandleDummyTick(AuraEffect const *aurEff) const
void HandleProc(AuraEffect *aurEff, ProcEventInfo const &eventInfo)
static bool CheckProc(AuraScript const &, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
void Register() override
void HandleDeathsTormentEnergize(SpellEffIndex)
void HandleDamageCalculation(SpellEffectInfo const &, Unit const *victim, int32 const &, int32 const &, float &pctMod) const
void DetermineKillStatus(DamageInfo const &damageInfo, uint32 &, int32 &) const
bool Validate(SpellInfo const *spellInfo) override
static constexpr Seconds BACKLASH_DELAY
void FilterTargets(std::list< WorldObject * > &targets) const
static constexpr uint32 GetSpellVisual(Races race, Gender gender)
bool Validate(SpellInfo const *) override
void HandleEffectHit(SpellEffIndex) const
static void HandleProc(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
static bool CheckProc(AuraScript const &, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
void HandleOnRemove(AuraEffect const *, AuraEffectHandleModes) const
bool Validate(SpellInfo const *) override
void HandleOnApply(AuraEffect const *, AuraEffectHandleModes) const
void HandleAbsorb(AuraEffect const *aurEff, DamageInfo const &, uint32 const &) const
bool Validate(SpellInfo const *) override
static bool CheckProc(AuraScript const &, ProcEventInfo const &eventInfo)
void HandleEffectProc(AuraEffect const *aurEff, ProcEventInfo &) const
bool Validate(SpellInfo const *) override
void HandleProc(AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
bool CheckProc(ProcEventInfo &eventInfo)
bool Validate(SpellInfo const *) override
void HandleProc(AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
void Register() override
bool Validate(SpellInfo const *) override
void HandleProc(AuraEffect const *aurEff, ProcEventInfo &)
static bool CheckProc(AuraScript const &, ProcEventInfo const &eventInfo)
void HandleOnProc(AuraEffect *aurEff, ProcEventInfo const &eventInfo) const
bool Validate(SpellInfo const *) override
std::queue< ObjectGuid > _healQueue
bool CheckProc(ProcEventInfo const &eventInfo)
static bool CheckEffect1(AuraScript const &, AuraEffect const *, ProcEventInfo const &eventInfo)
static bool CheckEffect0(AuraScript const &, AuraEffect const *, ProcEventInfo const &eventInfo)
void ReducePenanceCooldown(AuraEffect const *aurEff, ProcEventInfo const &) const
bool Validate(SpellInfo const *) override
void ReducePowerWordShieldCooldown(AuraEffect const *aurEff, ProcEventInfo const &) const
static void PreventEffect(SpellScript const &, WorldObject *&target)
void CalcDamage(AuraEffect const *, Unit *, int32 &, int32 &, float &pctMod) const
bool Validate(SpellInfo const *) override
void OnApply(AuraEffect const *, SpellEffectValue &, bool &)
void HandleProc(ProcEventInfo const &eventInfo) const
bool Validate(SpellInfo const *) override
static bool CheckProc(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
void CalculateAmount(AuraEffect const *, SpellEffectValue &amount, bool &canBeRecalculated) const
void HandlePeriodic(AuraEffect const *aurEff) const
std::list< WorldObject * > SearchTargetCandidates(uint32 spellId, SpellTargetCheckTypes checkType) const
static std::array< Trinity::TargetPriorityRule, 2 > GetHealingRules(Unit const *caster)
void HandleRemoveEffect(AuraEffect const *, AuraEffectHandleModes) const
bool Validate(SpellInfo const *) override
static constexpr Position JumpOffset
static void SetDestTarget(SpellScript const &, SpellDestination &dest)
bool Validate(SpellInfo const *) override
void PreventDirectDamage(WorldObject *&target) const
bool Validate(SpellInfo const *) override
void FilterTargets(std::list< WorldObject * > &unitList) const
void HandleEffectProc(AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
static bool CheckProc(AuraScript const &, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
void HandleDispel(DispelInfo const *dispelInfo) const
void HandleApplyEffect(AuraEffect const *, AuraEffectHandleModes) const
static bool CheckHolyWordSanctify(AuraScript const &, AuraEffect const *, ProcEventInfo const &eventInfo)
void HandleProc(AuraEffect const *aurEff, ProcEventInfo const &) const
bool Validate(SpellInfo const *) override
static bool CheckHolyWordChastise(AuraScript const &, AuraEffect const *, ProcEventInfo const &eventInfo)
static bool CheckHolyWordSerenity(AuraScript const &, AuraEffect const *, ProcEventInfo const &eventInfo)
bool Execute(uint64 time, uint32) override
static constexpr Milliseconds Period
BoltEvent(Unit *caster, ObjectGuid target, ObjectGuid originalCastId, int32 count)
void Register() override
void HandleEffectHit(SpellEffIndex) const
bool Validate(SpellInfo const *spellInfo) override
void HandleEffectHitTarget(SpellEffIndex) const
bool Validate(SpellInfo const *) override
void FilterTargets(std::list< WorldObject * > &targets) const
bool Validate(SpellInfo const *) override
void HandleEffectHitTarget(SpellEffIndex effIndex)
Unit * GetSummon(Unit const *owner)
Optional< uint32 > GetSpellToCast(uint32 spellId)
void Trigger(AuraScript const &, AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
std::vector< Vector3 > PointsArray
TC_GAME_API Unit * GetUnit(WorldObject const &, ObjectGuid const &guid)
constexpr void EraseIf(Container &c, Predicate p)
Definition Containers.h:283
auto SelectRandomContainerElement(C const &container) -> std::add_const_t< decltype(*std::ranges::begin(container))> &
Definition Containers.h:110
void RandomResize(C &container, std::size_t requestedSize)
Definition Containers.h:67
void SelectRandomInjuredTargets(std::list< WorldObject * > &targets, size_t maxTargets, bool prioritizePlayers, Unit const *prioritizeGroupMembersOf)
Definition Spell.cpp:9516
void SortTargetsWithPriorityRules(std::list< WorldObject * > &targets, size_t maxTargets, std::span< TargetPriorityRule const > rules)
Definition Spell.cpp:9581
struct advstd::ranges::Contains contains
PriestSpells
@ SPELL_PRIEST_DIVINE_HYMN_HEAL
PriestSummons
@ NPC_PRIEST_DIVINE_IMAGE
@ NPC_PRIEST_MINDBENDER
@ NPC_PRIEST_VOIDWRAITH
@ NPC_PRIEST_SHADOWFIEND
void AddSC_priest_spell_scripts()
PriestSpellLabels
@ SPELL_LABEL_PRIEST_APOTHEOSIS
@ SPELL_PRIEST_POWER_SURGE_PERIODIC_SHADOW
@ SPELL_PRIEST_SEARING_LIGHT_DAMAGE
@ SPELL_PRIEST_MASTER_THE_DARKNESS_AURA
@ SPELL_PRIEST_ANGELIC_BULWARK_BUFF
@ SPELL_PRIEST_PENANCE_HEALING
@ SPELL_PRIEST_LEVITATE_EFFECT
@ SPELL_PRIEST_DIVINE_BLESSING
@ SPELL_PRIEST_POWER_OF_THE_DARK_SIDE
@ SPELL_PRIEST_DAZZLING_LIGHT
@ SPELL_PRIEST_MINDBENDER_SHADOW
@ SPELL_PRIEST_HOLY_10_1_CLASS_SET_2P_CHOOSER
@ SPELL_PRIEST_MASTERY_GRACE
@ SPELL_PRIEST_POWER_LEECH_MINDBENDER_INSANITY
@ SPELL_PRIEST_LIGHT_ERUPTION
@ SPELL_PRIEST_HOLY_10_1_CLASS_SET_4P_EFFECT
@ SPELL_PRIEST_HOLY_WORD_CHASTISE_STUN
@ SPELL_PRIEST_HALO_HOLY
@ SPELL_PRIEST_ABYSSAL_REVERIE
@ SPELL_PRIEST_ULTIMATE_PENITENCE_DAMAGE
@ SPELL_PRIEST_BLAZE_OF_LIGHT_DECREASE
@ SPELL_PRIEST_TWILIGHT_EQUILIBRIUM_HOLY
@ SPELL_PRIEST_DIVINE_HYMN_HEAL
@ SPELL_PRIEST_DARK_REPRIMAND_CHANNEL_HEALING
@ SPELL_PRIEST_ENTROPIC_RIFT
@ SPELL_PRIEST_TRAIL_OF_LIGHT_HEAL
@ SPELL_PRIEST_ASSURED_SAFETY
@ SPELL_PRIEST_HOLY_WORD_SERENITY
@ SPELL_PRIEST_INESCAPABLE_TORMENT
@ SPELL_PRIEST_SURGE_OF_LIGHT_EFFECT
@ SPELL_PRIEST_CRYSTALLINE_REFLECTION_HEAL
@ SPELL_PRIEST_DARK_REPRIMAND_CHANNEL_DAMAGE
@ SPELL_PRIEST_ANGELIC_FEATHER_AURA
@ SPELL_PRIEST_POWER_WORD_SHIELD
@ SPELL_PRIEST_PENANCE_DAMAGE
@ SPELL_PRIEST_EMPYREAL_BLAZE_AURA
@ SPELL_PRIEST_EMPYREAL_BLAZE
@ SPELL_PRIEST_ARMOR_OF_FAITH
@ SPELL_PRIEST_ATONEMENT_HEAL
@ SPELL_PRIEST_BODY_AND_SOUL_SPEED
@ SPELL_PRIEST_HOLY_10_1_CLASS_SET_4P
@ SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL
@ SPELL_PRIEST_PENANCE_CHANNEL_DAMAGE
@ SPELL_PRIEST_BLAZE_OF_LIGHT
@ SPELL_PRIEST_PRAYER_OF_MENDING_AURA
@ SPELL_PRIEST_FOCUSED_MENDING
@ SPELL_PRIEST_POWER_LEECH_MINDBENDER_MANA
@ SPELL_PRIEST_DIVINE_STAR_SHADOW_HEAL
@ SPELL_PRIEST_DARK_INDULGENCE
@ SPELL_PRIEST_MINDBENDER_DISC
@ SPELL_PRIEST_HOLY_NOVA
@ SPELL_PRIEST_REVEL_IN_PURITY
@ SPELL_PRIEST_BURNING_VEHEMENCE_DAMAGE
@ SPELL_PRIEST_SMITE
@ SPELL_PRIEST_DARK_REPRIMAND_DAMAGE
@ SPELL_PRIEST_POWER_WORD_SOLACE_ENERGIZE
@ SPELL_PRIEST_INSIDIOUS_IRE_AURA
@ SPELL_PRIEST_VAMPIRIC_TOUCH
@ SPELL_PRIEST_HALO_SHADOW_HEAL
@ SPELL_PRIEST_MIND_DEVOURER_AURA
@ SPELL_PRIEST_EPIPHANY
@ SPELL_PRIEST_DEVOURING_PLAGUE
@ SPELL_PRIEST_SHIELD_DISCIPLINE
@ SPELL_PRIEST_PENANCE_CHANNEL_HEALING
@ SPELL_PRIEST_MASOCHISM_TALENT
@ SPELL_PRIEST_PENANCE
@ SPELL_PRIEST_THE_PENITENT_AURA
@ SPELL_PRIEST_ENTROPIC_RIFT_AURA
@ SPELL_PRIEST_DISPERSING_LIGHT_HEAL
@ SPELL_PRIEST_DIVINE_AEGIS
@ SPELL_PRIEST_VOID_SHIELD
@ SPELL_PRIEST_WHISPERING_SHADOWS
@ SPELL_PRIEST_MINDGAMES
@ SPELL_PRIEST_DIVINITY_AURA
@ SPELL_PRIEST_EMPOWERED_RENEW_HEAL
@ SPELL_PRIEST_TITHE_EVASION
@ SPELL_PRIEST_UNFURLING_DARKNESS_AURA
@ SPELL_PRIEST_PRAYER_OF_HEALING
@ SPELL_PRIEST_MINDGAMES_VENTHYR
@ SPELL_PRIEST_DARK_REPRIMAND
@ SPELL_PRIEST_GREATER_HEAL
@ SPELL_PRIEST_EPIPHANY_HIGHLIGHT
@ SPELL_PRIEST_HOLY_FIRE
@ SPELL_PRIEST_PROTECTIVE_LIGHT_AURA
@ SPELL_PRIEST_HOLY_WORD_SANCTIFY
@ SPELL_PRIEST_ANGELIC_FEATHER_AREATRIGGER
@ SPELL_PRIEST_PRAYER_OF_MENDING
@ SPELL_PRIEST_FLASH_HEAL
@ SPELL_PRIEST_MIND_BOMB_STUN
@ SPELL_PRIEST_ULTIMATE_PENITENCE_FALLING_FACING_CONTROL
@ SPELL_PRIEST_TRANSLUCENT_IMAGE
@ SPELL_PRIEST_AUSPICIOUS_SPIRITS
@ SPELL_PRIEST_VOID_VOLLEY_DAMAGE
@ SPELL_PRIEST_PURGE_THE_WICKED_PERIODIC
@ SPELL_PRIEST_POWER_OF_THE_DARK_SIDE_TINT
@ SPELL_PRIEST_SHADOW_WORD_PAIN
@ SPELL_PRIEST_CRYSTALLINE_REFLECTION
@ SPELL_PRIEST_PROTECTOR_OF_THE_FRAIL
@ SPELL_PRIEST_ESSENCE_DEVOURER
@ SPELL_PRIEST_PAIN_TRANSFORMATION
@ SPELL_PRIEST_ORACULAR_HEAL
@ SPELL_PRIEST_MISERY
@ SPELL_PRIEST_POWER_SURGE
@ SPELL_PRIEST_SHADOW_COVENANT_EFFECT
@ SPELL_PRIEST_EXPIATION_DAMAGE
@ SPELL_PRIEST_EVANGELISM
@ SPELL_PRIEST_PRAYER_OF_MENDING_HEAL
@ SPELL_PRIEST_LIGHTS_WRATH_VISUAL
@ SPELL_PRIEST_WHISPERING_SHADOWS_DUMMY
@ SPELL_PRIEST_HOLY_WORD_CHASTISE_INCAPACITATE
@ SPELL_PRIEST_VAMPIRIC_EMBRACE_HEAL
@ SPELL_PRIEST_HALO_SHADOW_DAMAGE
@ SPELL_PRIEST_SHADOWY_APPARITION_DUMMY
@ SPELL_PRIEST_DIVINE_AEGIS_ABSORB
@ SPELL_PRIEST_DIVINE_STAR_HOLY_DAMAGE
@ SPELL_PRIEST_UNFURLING_DARKNESS_DEBUFF
@ SPELL_PRIEST_DARK_REPRIMAND_HEALING
@ SPELL_PRIEST_ATONEMENT_EFFECT
@ SPELL_PRIEST_HOLY_MENDING_HEAL
@ SPELL_PRIEST_DIVINITY
@ SPELL_PRIEST_PAIN_SUPPRESSION
@ SPELL_PRIEST_PAIN_TRANSFORMATION_HEAL
@ SPELL_PRIEST_DIVINE_STAR_SHADOW_DAMAGE
@ SPELL_PRIEST_DISPERSING_LIGHT
@ SPELL_PRIEST_SHADOW_WORD_DEATH_DAMAGE
@ SPELL_PRIEST_POWER_WORD_LIFE
@ SPELL_PRIEST_DIVINE_WRATH
@ SPELL_PRIEST_DIVINE_HALO
@ SPELL_PRIEST_BLESSED_LIGHT
@ SPELL_PRIEST_ULTIMATE_PENITENCE_CHANNEL
@ SPELL_PRIEST_DIVINE_STAR_HOLY
@ SPELL_PRIEST_DIVINE_IMAGE_EMPOWER_STACK
@ SPELL_PRIEST_SEARING_LIGHT
@ SPELL_PRIEST_ULTIMATE_PENITENCE_HEAL
@ SPELL_PRIEST_POWER_LEECH_SHADOWFIEND_MANA
@ SPELL_PRIEST_POWER_WORD_RADIANCE
@ SPELL_PRIEST_DIVINE_IMAGE_SUMMON
@ SPELL_PRIEST_DIVINE_IMAGE_EMPOWER
@ SPELL_PRIEST_DIVINE_SERVICE
@ SPELL_PRIEST_MASOCHISM_PERIODIC_HEAL
@ SPELL_PRIEST_EXPIATION
@ SPELL_PRIEST_INDEMNITY
@ SPELL_PRIEST_INESCAPABLE_TORMENT_TELEPORT
@ SPELL_PRIEST_SCHISM
@ SPELL_PRIEST_POWER_SURGE_HALO_VISUAL_RETURN
@ SPELL_PRIEST_WEAKENED_SOUL
@ SPELL_PRIEST_SPIRIT_OF_REDEMPTION
@ SPELL_PRIEST_TRINITY
@ SPELL_PRIEST_HEAL
@ SPELL_PRIEST_HALO_HOLY_DAMAGE
@ SPELL_PRIEST_SURGE_OF_LIGHT
@ SPELL_PRIEST_DIVINE_FAVOR_SERENITY
@ SPELL_PRIEST_MIND_DEVOURER
@ SPELL_PRIEST_ANGELIC_BULWARK_DEBUFF
@ SPELL_PRIEST_VOID_TORRENT
@ SPELL_PRIEST_SANCTUARY
@ SPELL_PRIEST_STRENGTH_OF_SOUL
@ SPELL_PRIEST_ANSWERED_PRAYERS
@ SPELL_PRIEST_BINDING_HEALS_HEAL
@ SPELL_PRIEST_HOLY_WORD_CHASTISE
@ SPELL_PVP_RULES_ENABLED_HARDCODED
@ SPELL_PRIEST_PURGE_THE_WICKED_DUMMY
@ SPELL_PRIEST_SHADOWY_APPARITION_MISSILE
@ SPELL_PRIEST_TRANQUIL_LIGHT
@ SPELL_PRIEST_SHIELD_DISCIPLINE_EFFECT
@ SPELL_PRIEST_ENTROPIC_RIFT_AREATRIGGER
@ SPELL_PRIEST_RENEW
@ SPELL_PRIEST_HALO_HOLY_HEAL
@ SPELL_PRIEST_CRYSTALLINE_REFLECTION_REFLECT
@ SPELL_PRIEST_TWILIGHT_EQUILIBRIUM_SHADOW
@ SPELL_PRIEST_HEAVENS_WRATH
@ SPELL_PRIEST_HALO_SHADOW
@ SPELL_PRIEST_CIRCLE_OF_HEALING
@ SPELL_PRIEST_DIVINE_FAVOR_CHASTISE
@ SPELL_PRIEST_ENTROPIC_RIFT_DAMAGE
@ SPELL_PRIEST_PRAYER_OF_MENDING_JUMP
@ SPELL_PRIEST_APOTHEOSIS
@ SPELL_PRIEST_POWER_LEECH_SHADOWFIEND_INSANITY
@ SPELL_PRIEST_ATONEMENT
@ SPELL_PRIEST_ULTIMATE_PENITENCE_IMMUNITY
@ SPELL_PRIEST_SEARING_LIGHT_DIVINE_IMAGE
@ SPELL_PRIEST_SINS_OF_THE_MANY
@ SPELL_PRIEST_PHANTOM_REACH
@ SPELL_PRIEST_ESSENCE_DEVOURER_MINDBENDER_HEAL
@ SPELL_PRIEST_MASTER_THE_DARKNESS
@ SPELL_PRIEST_LASTING_WORDS
@ SPELL_PRIEST_HEALING_LIGHT
@ SPELL_PRIEST_DIVINE_STAR_SHADOW
@ SPELL_PRIEST_UNFURLING_DARKNESS
@ SPELL_PRIEST_BLAZE_OF_LIGHT_INCREASE
@ SPELL_PRIEST_RENEWED_HOPE
@ SPELL_PRIEST_SANCTUARY_ABSORB
@ SPELL_PRIEST_SAY_YOUR_PRAYERS
@ SPELL_PRIEST_ITEM_EFFICIENCY
@ SPELL_PRIEST_SHADOW_WORD_DEATH
@ SPELL_PRIEST_POWER_SURGE_PERIODIC_HOLY
@ SPELL_PRIEST_CENSURE
@ SPELL_PRIEST_SHADOW_MEND_PERIODIC_DUMMY
@ SPELL_PRIEST_ULTIMATE_PENITENCE
@ SPELL_PRIEST_EMPOWERED_RENEW
@ SPELL_PRIEST_RHAPSODY_PROC
@ SPELL_PRIEST_BLESSED_HEALING
@ SPELL_PRIEST_TRINITY_EFFECT
@ SPELL_PRIEST_PRAYERFUL_LITANY
@ SPELL_PRIEST_BENEDICTION
@ SPELL_PRIEST_ESSENCE_DEVOURER_SHADOWFIEND_HEAL
@ SPELL_PRIEST_SCHISM_AURA
@ SPELL_PRIEST_RENEWED_HOPE_EFFECT
@ SPELL_PRIEST_SHADOW_MEND_DAMAGE
@ SPELL_PRIEST_DIVINE_WORD_SANCTUARY_AREATRIGGER
@ SPELL_PRIEST_SANCTUARY_AURA
@ SPELL_PRIEST_ARCHANGEL
@ SPELL_PRIEST_VOID_SHIELD_EFFECT
@ SPELL_PRIEST_BODY_AND_SOUL
@ SPELL_PRIEST_STRENGTH_OF_SOUL_EFFECT
@ SPELL_PRIEST_ARCHANGEL_AURA
@ SPELL_PRIEST_ENTROPIC_RIFT_PERIODIC
@ SPELL_PRIEST_LEAP_OF_FAITH_EFFECT
@ SPELL_PRIEST_MIND_BLAST
@ SPELL_PRIEST_INESCAPABLE_TORMENT_DAMAGE
@ SPELL_PRIEST_PURGE_THE_WICKED
@ SPELL_PRIEST_SHADOW_COVENANT
@ SPELL_PRIEST_HOLY_WORD_SALVATION
@ SPELL_PRIEST_DIVINE_WORD_SANCTUARY_HEAL
@ SPELL_PRIEST_VOICE_OF_HARMONY
@ SPELL_PRIEST_FROM_DARKNESS_COMES_LIGHT_AURA
@ SPELL_PRIEST_HARSH_DISCIPLINE
@ SPELL_PRIEST_CASTIGATION
@ SPELL_PRIEST_SIN_AND_PUNISHMENT
@ SPELL_PRIEST_HARSH_DISCIPLINE_AURA
@ SPELL_PRIEST_DIVINE_STAR_HOLY_HEAL
@ SPELL_PRIEST_POWER_SURGE_HALO_VISUAL
PriestSpellVisuals
@ SPELL_VISUAL_PRIEST_POWER_WORD_RADIANCE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_ORC_FEMALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_TROLL_MALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_PANDAREN_FEMALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_WORGEN_FEMALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_TROLL_FEMALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_DWARF_FEMALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_UNDEAD_MALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_GNOME_MALE
@ SPELL_VISUAL_PRIEST_PRAYER_OF_MENDING
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_GOBLIN_MALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_PANDAREN_MALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_ORC_MALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_UNDEAD_FEMALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_HUMAN_MALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_HUMAN_FEMALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_WORGEN_MALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_TAUREN_MALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_TAUREN_FEMALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_BELF_MALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_BELF_FEMALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_NIGHTELF_MALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_DWARF_MALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_DRAENEI_FEMALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_NIGHTELF_FEMALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_GNOME_FEMALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_GOBLIN_FEMALE
@ SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_DRAENEI_MALE
TriggerCastFlags TriggerFlags
CastSpellExtraArgs & SetTriggeringSpell(Spell const *triggeringSpell)
Definition Spell.cpp:9646
CastSpellExtraArgs & SetOriginalCaster(ObjectGuid const &guid)
CastSpellExtraArgs & SetTriggerFlags(TriggerCastFlags flag)
CastSpellExtraArgs & AddSpellBP0(SpellEffectValue val)
CastSpellExtraArgs & SetCustomArg(std::any customArg)
CastSpellExtraArgs & AddSpellMod(SpellValueMod mod, int32 val)
CastSpellExtraArgs & SetTriggeringAura(AuraEffect const *triggeringAura)
constexpr float GetPositionX() const
Definition Position.h:87
constexpr float GetPositionY() const
Definition Position.h:88
constexpr bool IsInDist2d(float x, float y, float dist) const
Definition Position.h:151
float GetExactDist(float x, float y, float z) const
Definition Position.h:129
constexpr void GetPosition(float &x, float &y) const
Definition Position.h:92
constexpr float GetPositionZ() const
Definition Position.h:89
void RelocateOffset(Position const &offset)
Definition Spell.cpp:90
uint32 MaxAffectedTargets
Definition Spell.h:244
areatrigger_pri_angelic_feather(AreaTrigger *areatrigger)
void OnUnitEnter(Unit *unit) override
void OnUnitEnter(Unit *unit) override
void OnDestinationReached() override
void OnUpdate(uint32 diff) override
void OnUnitExit(Unit *unit, AreaTriggerExitReason) override
void HandleUnitEnterExit(Unit *unit)
std::vector< ObjectGuid > _affectedUnits
void OnUpdate(uint32 diff) override
void OnCreate(Spell const *creatingSpell) override
static constexpr std::array< DBCPosition2D, 2 > OverrideScaleCurve
void OnUnitExit(Unit *unit, AreaTriggerExitReason reason) override
void OnUnitEnter(Unit *unit) override
static void ModifyCooldown(Unit *priest, SpellInfo const *spellInfo, Milliseconds cooldownMod)