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{
194 SPELL_PRIEST_POWER_SURGE_HALO_VISUAL_RETURN = 467824, // TODO: cast when triggering first return halo from Divine Halo (from halo on expire script)
275
280
282{
311};
312
320
322{
323 public:
324 explicit RaidCheck(Unit const* caster) : _caster(caster) { }
325
326 bool operator()(WorldObject* obj) const
327 {
328 if (Unit* target = obj->ToUnit())
329 return !_caster->IsInRaidWith(target);
330
331 return true;
332 }
333
334 private:
335 Unit const* _caster;
336};
337
338// 108945 - Angelic Bulwark
340{
341 bool Validate(SpellInfo const* spellInfo) override
342 {
344 && ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
345 }
346
347 bool CheckProc(ProcEventInfo const& eventInfo) const
348 {
350 && eventInfo.GetActionTarget()->HealthBelowPctDamaged(GetEffect(EFFECT_0)->GetAmount(), eventInfo.GetDamageInfo()->GetDamage());
351 }
352
353 void HandleProc(ProcEventInfo const& eventInfo) const
354 {
355 Unit* caster = eventInfo.GetActionTarget();
356 if (!caster)
357 return;
358
359 SpellEffectValue absorb = caster->CountPctFromMaxHealth(GetEffect(EFFECT_1)->GetAmount());
360
362 {
364 .SpellValueOverrides = { { SPELLVALUE_BASE_POINT0, absorb } }
365 });
367 }
368
374};
375
376// 121536 - Angelic Feather talent
378{
379 bool Validate(SpellInfo const* /*spellInfo*/) override
380 {
382 }
383
384 void HandleEffectDummy(SpellEffIndex /*effIndex*/) const
385 {
386 Position destPos = GetHitDest()->GetPosition();
388
389 // Caster is prioritary
390 if (GetCaster()->IsInRange2d(&destPos, radius.Min, radius.Max))
391 {
393 }
394 else
395 {
400 }
401 }
402
407};
408
409// Angelic Feather areatrigger - created by SPELL_PRIEST_ANGELIC_FEATHER_AREATRIGGER
411{
413
414 // Called when the AreaTrigger has just been initialized, just before added to map
415 void OnInitialize() override
416 {
417 if (Unit* caster = at->GetCaster())
418 {
419 std::vector<AreaTrigger*> areaTriggers = caster->GetAreaTriggers(SPELL_PRIEST_ANGELIC_FEATHER_AREATRIGGER);
420
421 if (areaTriggers.size() >= 3)
422 areaTriggers.front()->SetDuration(0);
423 }
424 }
425
426 void OnUnitEnter(Unit* unit) override
427 {
428 if (Unit* caster = at->GetCaster())
429 {
430 if (caster->IsFriendlyTo(unit))
431 {
432 // If target already has aura, increase duration to max 130% of initial duration
433 caster->CastSpell(unit, SPELL_PRIEST_ANGELIC_FEATHER_AURA, true);
434 at->SetDuration(0);
435 }
436 }
437 }
438};
439
440// 391387 - Answered Prayers
442{
443 bool Validate(SpellInfo const* spellInfo) override
444 {
446 && ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
447 }
448
449 void HandleOnProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo) const
450 {
451 Milliseconds extraDuration = 0ms;
452 if (AuraEffect const* durationEffect = GetEffect(EFFECT_1))
453 extraDuration = duration_cast<Milliseconds>(FloatSeconds(durationEffect->GetAmount()));
454
455 Unit* target = eventInfo.GetActor();
456
457 Aura* answeredPrayers = target->GetAura(SPELL_PRIEST_ANSWERED_PRAYERS);
458
459 // Note: if caster has no aura, we must cast it first.
460 if (!answeredPrayers)
462 else
463 {
464 // Note: there's no BaseValue dummy that we can use as reference, so we hardcode the increasing stack value.
465 answeredPrayers->ModStackAmount(1);
466
467 // Note: if current stacks match max. stacks, trigger Apotheosis.
468 if (answeredPrayers->GetStackAmount() != aurEff->GetAmountAsInt())
469 return;
470
471 answeredPrayers->Remove();
472
473 if (Aura* apotheosis = GetTarget()->GetAura(SPELL_PRIEST_APOTHEOSIS))
474 {
475 apotheosis->SetDuration(apotheosis->GetDuration() + extraDuration.count());
476 apotheosis->SetMaxDuration(apotheosis->GetMaxDuration() + extraDuration.count());
477 }
478 else
479 target->CastSpell(target, SPELL_PRIEST_APOTHEOSIS,
481 .AddSpellMod(SPELLVALUE_DURATION, extraDuration.count()));
482 }
483 }
484
489};
490
491// 26169 - Oracle Healing Bonus
493{
494 bool Validate(SpellInfo const* /*spellInfo*/) override
495 {
497 }
498
499 void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
500 {
502 Unit* caster = eventInfo.GetActor();
503 if (caster == eventInfo.GetProcTarget())
504 return;
505
506 HealInfo* healInfo = eventInfo.GetHealInfo();
507 if (!healInfo || !healInfo->GetHeal())
508 return;
509
510 CastSpellExtraArgs args(aurEff);
511 args.AddSpellBP0(CalculatePct(static_cast<int32>(healInfo->GetHeal()), 10));
512 caster->CastSpell(caster, SPELL_PRIEST_ORACULAR_HEAL, args);
513 }
514
519};
520
521// 197862 - Archangel (attached to 472433 - Evangelism)
523{
524 bool Validate(SpellInfo const* /*spellInfo*/) override
525 {
527 }
528
529 bool Load() override
530 {
532 }
533
542
547};
548
549// 81749 - Atonement
551{
557
558 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
559 {
560 return eventInfo.GetDamageInfo() != nullptr;
561 }
562
563 void HandleOnProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
564 {
565 TriggerAtonementHealOnTargets(aurEff, eventInfo);
566 }
567
573
574 std::vector<ObjectGuid> _appliedAtonements;
575
576public:
577 void AddAtonementTarget(ObjectGuid const& target)
578 {
579 _appliedAtonements.push_back(target);
580
583 }
584
586 {
587 std::erase(_appliedAtonements, target);
588
591 }
592
593 std::vector<ObjectGuid> const& GetAtonementTargets() const
594 {
595 return _appliedAtonements;
596 }
597
603
604 void TriggerAtonementHealOnTargets(AuraEffect const* atonementEffect, ProcEventInfo const& eventInfo)
605 {
606 Unit* priest = GetUnitOwner();
607 DamageInfo* damageInfo = eventInfo.GetDamageInfo();
609
610 // Note: atonementEffect holds the correct amount since we passed the effect in the AuraScript that calls this method.
611 args.AddSpellMod(SPELLVALUE_BASE_POINT0, CalculatePct(damageInfo->GetDamage(), atonementEffect->GetAmount()));
612
614 .TriggeredBy = eventInfo.GetSpellInfo(),
615 .DamageSchoolMask = eventInfo.GetDamageInfo()->GetSchoolMask() });
616
617 float distanceLimit = GetEffectInfo(EFFECT_1).CalcValue();
618
619 std::erase_if(_appliedAtonements, [priest, distanceLimit, &args](ObjectGuid const& targetGuid)
620 {
621 if (Unit* target = ObjectAccessor::GetUnit(*priest, targetGuid))
622 {
623 if (target->IsInDist2d(priest, distanceLimit))
624 priest->CastSpell(target, SPELL_PRIEST_ATONEMENT_HEAL, args);
625
626 return false;
627 }
628
629 return true;
630 });
631 }
632
634 {
635 // Note: the damage dimish starts at the 6th application as of 10.0.5.
636 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 };
637
638 for (SpellEffIndex effectIndex : { EFFECT_0, EFFECT_1, EFFECT_2 })
639 if (AuraEffect* sinOfTheMany = GetUnitOwner()->GetAuraEffect(SPELL_PRIEST_SINS_OF_THE_MANY, effectIndex))
640 sinOfTheMany->ChangeAmount(DamageByStack[std::min(_appliedAtonements.size(), DamageByStack.size() - 1)]);
641 }
642
644 {
645 Unit* priest = GetUnitOwner();
646 if (AuraEffect const* trinity = priest->GetAuraEffect(SPELL_PRIEST_TRINITY, EFFECT_0); trinity && std::ssize(_appliedAtonements) >= trinity->GetAmount())
648 else
649 priest->RemoveAurasDueToSpell(SPELL_PRIEST_TRINITY_EFFECT);
650 }
651};
652
653// 81751 - Atonement (Heal)
655{
656 bool Validate(SpellInfo const* /*spellInfo*/) override
657 {
659 }
660
661 void CalculateHealingBonus(SpellEffectInfo const& /*spellEffectInfo*/, Unit const* /*victim*/, int32 const& /*healing*/, int32 const& /*flatMod*/, float& pctMod) const
662 {
663 spell_pri_atonement::TriggerArgs const* args = std::any_cast<spell_pri_atonement::TriggerArgs>(&GetSpell()->m_customArg);
664 if (!args || !(args->DamageSchoolMask & SPELL_SCHOOL_MASK_SHADOW))
665 return;
666
667 if (AuraEffect* const abyssalReverieEffect = GetCaster()->GetAuraEffect(SPELL_PRIEST_ABYSSAL_REVERIE, EFFECT_0))
668 AddPct(pctMod, abyssalReverieEffect->GetAmount());
669 }
670
675};
676
677// 17 - Power Word: Shield
678// 2061 - Flash Heal
679// 200829 - Plea
680// 47750 - Penance
681// 194509 - Power Word: Radiance
683{
697
698 bool Load() override
699 {
700 Unit* caster = GetCaster();
701 if (!caster->HasAura(SPELL_PRIEST_ATONEMENT))
702 return false;
703
704 return true;
705 }
706
707 void HandleOnHitTarget() const
708 {
709 Unit* caster = GetCaster();
710 Unit* target = GetHitUnit();
711
714
715 switch (GetSpellInfo()->Id)
716 {
718 if (AuraEffect const* indemnity = caster->GetAuraEffect(SPELL_PRIEST_INDEMNITY, EFFECT_0))
720 (FloatSeconds(indemnity->GetAmount())
722 caster, &GetSpell()->GetPowerCost()))).count());
723 break;
725 // Power Word: Radiance applies Atonement at 60 % (without modifiers) of its total duration.
727 break;
728 default:
729 break;
730 }
731
732 caster->CastSpell(target, _effectSpellId, args);
733 }
734
739
741};
742
743// 194384 - Atonement (Buff)
745{
746 bool Validate(SpellInfo const* /*spellInfo*/) override
747 {
749 }
750
751 void HandleOnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
752 {
753 RegisterHelper<&spell_pri_atonement::AddAtonementTarget>();
754 }
755
756 void HandleOnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
757 {
758 RegisterHelper<&spell_pri_atonement::RemoveAtonementTarget>();
759 }
760
761 template<void(spell_pri_atonement::*func)(ObjectGuid const&)>
762 void RegisterHelper() const
763 {
764 if (Unit* caster = GetCaster())
765 if (Aura* atonement = caster->GetAura(SPELL_PRIEST_ATONEMENT))
766 if (spell_pri_atonement* script = atonement->GetScript<spell_pri_atonement>())
767 (script->*func)(GetTarget()->GetGUID());
768 }
769
775};
776
777// 195178 - Atonement (Passive)
779{
780 bool Validate(SpellInfo const* /*spellInfo*/) override
781 {
783 }
784
785 static bool CheckProc(ProcEventInfo const& eventInfo)
786 {
787 return eventInfo.GetDamageInfo() != nullptr;
788 }
789
790 void HandleOnProc(AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo) const
791 {
792 Unit* target = GetTarget();
793 Unit* summoner = target->GetOwner();
794 if (!summoner)
795 return;
796
797 if (AuraEffect const* atonementEffect = summoner->GetAuraEffect(SPELL_PRIEST_ATONEMENT, EFFECT_0))
798 if (spell_pri_atonement* script = atonementEffect->GetBase()->GetScript<spell_pri_atonement>())
799 script->TriggerAtonementHealOnTargets(atonementEffect, eventInfo);
800 }
801
806};
807
808// 155271 - Auspicious Spirits (attached to 148859 - Shadowy Apparition)
810{
811 bool Validate(SpellInfo const* /*spellInfo*/) override
812 {
814 }
815
816 bool Load() override
817 {
819 }
820
821 static void PreventTarget(SpellScript const&, WorldObject*& target)
822 {
823 target = nullptr;
824 }
825
830};
831
832// 33110 - Prayer of Mending (Heal)
834{
835 bool Validate(SpellInfo const* /*spellInfo*/) override
836 {
839 }
840
841 void HandleEffectHitTarget(SpellEffIndex /*effIndex*/) const
842 {
843 if (AuraEffect const* benediction = GetCaster()->GetAuraEffect(SPELL_PRIEST_BENEDICTION, EFFECT_0))
844 if (roll_chance(benediction->GetAmount()))
846 }
847
852};
853
854// 368275 - Binding Heals
856{
857 bool Validate(SpellInfo const* /*spellInfo*/) override
858 {
860 }
861
862 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
863 {
864 return eventInfo.GetActor() != eventInfo.GetProcTarget();
865 }
866
867 static void HandleEffectProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
868 {
869 Unit* caster = eventInfo.GetActor();
870
873 .TriggeringSpell = eventInfo.GetProcSpell(),
874 .TriggeringAura = aurEff,
875 .SpellValueOverrides = { { SPELLVALUE_BASE_POINT0, SpellEffectValue(CalculatePct(eventInfo.GetHealInfo()->GetHeal(), aurEff->GetAmount())) } }
876 });
877 }
878
884};
885
886// 215768 - Blaze of Light
888{
889 bool Validate(SpellInfo const* /*spellInfo*/) override
890 {
891 return ValidateSpellInfo(
892 {
895 });
896 }
897
898 void HandleProc(ProcEventInfo const& eventInfo) const
899 {
900 Unit* procTarget = eventInfo.GetProcTarget();
901 if (!procTarget)
902 return;
903
904 if (GetTarget()->IsValidAttackTarget(procTarget))
906 else
908 }
909
914};
915
916// 372307 - Burning Vehemence
918{
919 bool Validate(SpellInfo const* /*spellInfo*/) override
920 {
922 }
923
924 void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo) const
925 {
927 .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
928 .TriggeringSpell = eventInfo.GetProcSpell(),
929 .TriggeringAura = aurEff,
930 .SpellValueOverrides = { { SPELLVALUE_BASE_POINT0, SpellEffectValue(CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount())) } }
931 });
932 }
933
938};
939
940// 204883 - Circle of Healing
942{
943 bool Validate(SpellInfo const* spellInfo) override
944 {
945 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
946 }
947
948 void FilterTargets(std::list<WorldObject*>& targets) const
949 {
950 // Note: we must remove one since target is always chosen.
951 uint32 const maxTargets = uint32(GetSpellInfo()->GetEffect(EFFECT_1).CalcValueAsInt(GetCaster()) - 1);
952
953 Trinity::SelectRandomInjuredTargets(targets, maxTargets, true);
954
955 if (Unit* explicitTarget = GetExplTargetUnit())
956 targets.push_front(explicitTarget);
957 }
958
963};
964
965// 17 - Power Word: Shield
967{
977
978 void HandleOnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) const
979 {
980 Unit* caster = GetCaster();
981 if (!caster)
982 return;
983
984 // Crystalline Reflection Heal
988 }
989
990 void HandleAfterAbsorb(AuraEffect const* /*aurEff*/, DamageInfo const& dmgInfo, uint32 const& absorbAmount) const
991 {
992 Unit* caster = GetCaster();
993 if (!caster)
994 return;
995
997 if (!auraEff)
998 return;
999
1000 Unit* attacker = dmgInfo.GetAttacker();
1001 if (!attacker)
1002 return;
1003
1005 args.AddSpellMod(SPELLVALUE_BASE_POINT0, CalculatePct(absorbAmount, auraEff->GetAmount()));
1007 }
1008
1014};
1015
1016// 8092 - Mind Blast
1018{
1019 bool Validate(SpellInfo const* /*spellInfo*/) override
1020 {
1022 }
1023
1024 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
1025 {
1027 if (!aurEff)
1028 return;
1029
1030 if (roll_chance(aurEff->GetAmount()))
1032 }
1033
1038};
1039
1040// 1240364 - Death's Torment
1042{
1043public:
1044 struct Data
1045 {
1047 int32 BacklashPct = 10; // for some weird reason its 10% for backlash, not 15%
1048 int32 EnergizePct = 25; // for some weird reason its 25% for energize, not 15%
1049 };
1050
1051 bool Validate(SpellInfo const* spellInfo) override
1052 {
1054 && ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
1055 }
1056
1057 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
1058 {
1059 return eventInfo.GetProcSpell()->m_customArg.type() != typeid(Data);
1060 }
1061
1062 void HandleProc(ProcEventInfo const& eventInfo) const
1063 {
1064 Unit* caster = eventInfo.GetActor();
1065 Unit* target = eventInfo.GetActionTarget();
1066
1067 int32 maxHits = GetEffect(EFFECT_0)->GetAmountAsInt();
1068 SpellEffectValue effectiveness = GetEffect(EFFECT_1)->GetAmount();
1069
1070 for (int32 i = 1; i <= maxHits; ++i)
1071 {
1072 caster->m_Events.AddEventAtOffset([caster, targetGuid = target->GetGUID(), effectiveness]
1073 {
1074 if (Unit* target = ObjectAccessor::GetUnit(*caster, targetGuid))
1075 caster->CastSpell(target, SPELL_PRIEST_SHADOW_WORD_DEATH, CastSpellExtraArgsInit{
1076 .TriggerFlags = TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD | TRIGGERED_IGNORE_POWER_COST | TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
1077 .CustomArg = Data{ .DamagePct = effectiveness }
1078 });
1079 }, i * 250ms);
1080 }
1081 }
1082
1083 void Register() override
1084 {
1087 }
1088};
1089
1090// 1215265 - Dispersing Light
1092{
1093 bool Validate(SpellInfo const* spellInfo) override
1094 {
1096 && ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
1097 }
1098
1099 void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo) const
1100 {
1101 HealInfo* healInfo = eventInfo.GetHealInfo();
1102 if (!healInfo || !healInfo->GetHeal())
1103 return;
1104
1105 Unit* caster = eventInfo.GetActor();
1106 Unit* target = eventInfo.GetActionTarget();
1107
1109 {
1111 .TriggeringAura = aurEff,
1112 .SpellValueOverrides =
1113 {
1116 },
1117 .CustomArg = TriggerArgs{ .TargetToExclude = target->GetGUID() }
1118 });
1119 }
1120
1125
1126public:
1131};
1132
1133// 1215266 - Dispersing Light (Heal)
1135{
1136 void FilterTargets(std::list<WorldObject*>& targets) const
1137 {
1138 spell_pri_dispersing_light::TriggerArgs const* args = std::any_cast<spell_pri_dispersing_light::TriggerArgs>(&GetSpell()->m_customArg);
1139 if (!args || args->TargetToExclude.IsEmpty())
1140 return;
1141
1142 targets.remove_if(Trinity::ObjectGUIDCheck(args->TargetToExclude));
1143 }
1144
1149};
1150
1152{
1153Unit* GetSummon(Unit const* owner)
1154{
1155 for (Unit* summon : owner->m_Controlled)
1156 if (summon->GetEntry() == NPC_PRIEST_DIVINE_IMAGE)
1157 return summon;
1158
1159 return nullptr;
1160}
1161
1202
1203void Trigger(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
1204{
1205 Unit* target = eventInfo.GetActor();
1206 if (!target)
1207 return;
1208
1209 Unit* divineImage = GetSummon(target);
1210 if (!divineImage)
1211 return;
1212
1213 Optional<uint32> spellId = GetSpellToCast(eventInfo.GetSpellInfo()->Id);
1214 if (!spellId)
1215 return;
1216
1217 divineImage->CastSpell(SpellCastTargets(eventInfo.GetProcSpell()->m_targets), *spellId, aurEff);
1218}
1219}
1220
1221// 392988 - Divine Image
1223{
1224 bool Validate(SpellInfo const* /*spellInfo*/) override
1225 {
1226 return ValidateSpellInfo
1227 ({
1231 });
1232 }
1233
1234 static void HandleProc(AuraScript const& script, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
1235 {
1236 Unit* target = eventInfo.GetActor();
1237 if (!target)
1238 return;
1239
1240 // Note: if target has an active Divine Image, we should empower it rather than summoning a new one.
1241 if (Unit* divineImage = DivineImageHelpers::GetSummon(target))
1242 {
1243 // 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).
1244 if (target->GetDistance(divineImage) > 15.0f)
1245 divineImage->NearTeleportTo(target->GetRandomNearPosition(3.0f));
1246
1247 if (TempSummon* tempSummon = divineImage->ToTempSummon())
1248 tempSummon->RefreshTimer();
1249
1250 divineImage->CastSpell(divineImage, SPELL_PRIEST_DIVINE_IMAGE_EMPOWER, eventInfo.GetProcSpell());
1251 }
1252 else
1253 {
1255 .SetTriggeringAura(aurEff)
1256 .SetTriggeringSpell(eventInfo.GetProcSpell())
1258
1259 // Note: Divine Image triggers a cast immediately based on the Holy Word cast.
1260 DivineImageHelpers::Trigger(script, aurEff, eventInfo);
1261 }
1262
1264 .SetTriggeringAura(aurEff)
1265 .SetTriggeringSpell(eventInfo.GetProcSpell())
1267 }
1268
1273};
1274
1275// 405216 - Divine Image (Spell Cast Check)
1277{
1313
1314 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
1315 {
1316 return DivineImageHelpers::GetSummon(eventInfo.GetActor()) != nullptr;
1317 }
1318
1323
1330};
1331
1332// 405963 Divine Image
1333// 409387 Divine Image
1335{
1336 void TrackStackApplicationTime(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
1337 {
1338 GetUnitOwner()->m_Events.AddEventAtOffset([spelId = GetId(), owner = GetUnitOwner()]
1339 {
1340 owner->RemoveAuraFromStack(spelId);
1342 }
1343
1348};
1349
1350// 33110 - Prayer of Mending (Heal)
1352{
1353 bool Validate(SpellInfo const* /*spellInfo*/) override
1354 {
1357 }
1358
1359 void CalculateHealingBonus(SpellEffectInfo const& /*spellEffectInfo*/, Unit const* victim, int32& /*healing*/, int32& /*flatMod*/, float& pctMod) const
1360 {
1361 if (AuraEffect const* divineServiceEffect = GetCaster()->GetAuraEffect(SPELL_PRIEST_DIVINE_SERVICE, EFFECT_0))
1362 if (Aura const* prayerOfMending = victim->GetAura(SPELL_PRIEST_PRAYER_OF_MENDING_AURA, GetCaster()->GetGUID()))
1363 AddPct(pctMod, divineServiceEffect->GetAmount() * prayerOfMending->GetStackAmount());
1364 }
1365
1370};
1371
1372// 122121 - Divine Star (Shadow)
1374{
1376 {
1377 Unit* caster = GetCaster();
1378
1379 if (caster->GetPowerType() != GetEffectInfo().MiscValue)
1380 PreventHitDefaultEffect(effIndex);
1381 }
1382
1387};
1388
1389// 110744 - Divine Star (Holy)
1390// 122121 - Divine Star (Shadow)
1392{
1394
1395 void OnInitialize() override
1396 {
1397 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(at->GetSpellId(), DIFFICULTY_NONE);
1398 if (!spellInfo)
1399 return;
1400
1401 if (spellInfo->GetEffects().size() <= EFFECT_1)
1402 return;
1403
1404 Unit* caster = at->GetCaster();
1405 if (!caster)
1406 return;
1407
1409
1410 // Note: max. distance at which the Divine Star can travel to is EFFECT_1's BasePoints yards.
1411 float maxTravelDistance = float(spellInfo->GetEffect(EFFECT_1).CalcValue(caster));
1412
1414 at->MovePositionToFirstCollision(destPos, maxTravelDistance, 0.0f);
1415
1416 PathGenerator firstPath(at);
1417 firstPath.CalculatePath(destPos.GetPositionX(), destPos.GetPositionY(), destPos.GetPositionZ(), false);
1418
1419 at->InitSplines(firstPath.GetPath());
1420 }
1421
1422 void OnUpdate(uint32 diff) override
1423 {
1424 _scheduler.Update(diff);
1425 }
1426
1427 void OnUnitEnter(Unit* unit) override
1428 {
1429 HandleUnitEnterExit(unit);
1430 }
1431
1432 void OnUnitExit(Unit* unit, AreaTriggerExitReason /*reason*/) override
1433 {
1434 // Note: this ensures any unit receives a second hit if they happen to be inside the AT when Divine Star starts its return path.
1435 HandleUnitEnterExit(unit);
1436 }
1437
1439 {
1440 Unit* caster = at->GetCaster();
1441 if (!caster)
1442 return;
1443
1445 return;
1446
1448
1449 if (caster->IsValidAttackTarget(unit))
1451 TriggerFlags);
1452 else if (caster->IsValidAssistTarget(unit))
1454 TriggerFlags);
1455
1456 _affectedUnits.push_back(unit->GetGUID());
1457 }
1458
1459 void OnDestinationReached() override
1460 {
1461 Unit* caster = at->GetCaster();
1462 if (!caster)
1463 return;
1464
1466 {
1467 _affectedUnits.clear();
1468
1470 }
1471 else
1472 at->Remove();
1473 }
1474
1476 {
1477 _scheduler.Schedule(0ms, [this](TaskContext& task)
1478 {
1479 Unit* caster = at->GetCaster();
1480 if (!caster)
1481 return;
1482
1484
1485 Movement::PointsArray returnSplinePoints;
1486
1487 returnSplinePoints.push_back(PositionToVector3(at->GetPosition()));
1488 returnSplinePoints.push_back(PositionToVector3(caster->GetPosition()));
1489
1490 at->InitSplines(returnSplinePoints);
1491
1492 task.Repeat(250ms);
1493 });
1494 }
1495
1496private:
1499 std::vector<ObjectGuid> _affectedUnits;
1500};
1501
1503{
1504 static void ModifyCooldown(Unit* priest, SpellInfo const* spellInfo, Milliseconds cooldownMod)
1505 {
1506 priest->GetSpellHistory()->ModifyCooldown(spellInfo, cooldownMod, true);
1507 }
1508};
1509
1510// 372760 - Divine Word
1512{
1525
1526 void HandleProc(ProcEventInfo const& procInfo) const
1527 {
1528 Unit* caster = GetTarget();
1529 switch (procInfo.GetSpellInfo()->Id)
1530 {
1534 .TriggeringSpell = procInfo.GetProcSpell()
1535 });
1537 Seconds(-GetSpellInfo()->GetEffect(EFFECT_1).CalcValueAsInt(caster)));
1538 break;
1541 .TriggerFlags = TRIGGERED_IGNORE_GCD | TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_IGNORE_CAST_TIME,
1542 .TriggeringSpell = procInfo.GetProcSpell()
1543 });
1544 break;
1548 .TriggeringSpell = procInfo.GetProcSpell()
1549 });
1550 break;
1551 default:
1552 break;
1553 }
1554 }
1555
1556 void Register() override
1557 {
1559 }
1560};
1561
1562// 372784 - Divine Word: Sanctuary
1564{
1565 bool Validate(SpellInfo const* /*spellInfo*/) override
1566 {
1568 }
1569
1570 void HandleEffectPeriodic(AuraEffect const* /*aurEff*/) const
1571 {
1572 Unit* caster = GetTarget();
1573 for (AreaTrigger* at : caster->GetAreaTriggers(GetSpellInfo()->Id))
1574 caster->CastSpell(at->GetPosition(), SPELL_PRIEST_DIVINE_WORD_SANCTUARY_HEAL);
1575 }
1576
1581};
1582
1583// 372787 - Divine Word: Sanctuary
1585{
1586 bool Validate(SpellInfo const* spellInfo) override
1587 {
1588 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
1589 }
1590
1591 void FilterTargets(std::list<WorldObject*>& targets) const
1592 {
1594 Trinity::SelectRandomInjuredTargets(targets, maxTargets, true);
1595 }
1596
1601};
1602
1603// 1215241 - Divinity
1605{
1606 bool Validate(SpellInfo const* spellInfo) override
1607 {
1608 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_2 } })
1609 && ValidateSpellInfo({ SPELL_PRIEST_APOTHEOSIS, spellInfo->GetEffect(EFFECT_2).TriggerSpell });
1610 }
1611
1612 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
1613 {
1615 }
1616
1617 void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& procInfo)
1618 {
1620
1622 .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
1623 .TriggeringSpell = procInfo.GetProcSpell(),
1624 .TriggeringAura = aurEff,
1625 .SpellValueOverrides = { { SPELLVALUE_AURA_STACK, int32(sSpellMgr->AssertSpellInfo(aurEff->GetSpellEffectInfo().TriggerSpell, DIFFICULTY_NONE)->StackAmount) } }
1626 });
1627 }
1628
1634};
1635
1636// 391339 - Empowered Renew
1638{
1639 bool Validate(SpellInfo const* /*spellInfo*/) override
1640 {
1643 && sSpellMgr->AssertSpellInfo(SPELL_PRIEST_RENEW, DIFFICULTY_NONE)->GetEffect(EFFECT_0).IsAura(SPELL_AURA_PERIODIC_HEAL);
1644 }
1645
1646 void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo) const
1647 {
1649 Milliseconds(-aurEff->GetAmountAsInt()));
1650 }
1651
1656};
1657
1658// 139 - Renew
1660{
1661 bool Validate(SpellInfo const* /*spellInfo*/) override
1662 {
1664 }
1665
1666 void CalculateHealing(AuraEffect const* /*aurEff*/, Unit* /*victim*/, int32& /*healing*/, int32& /*flatMod*/, float& pctMod) const
1667 {
1668 if (Unit* caster = GetCaster())
1669 if (AuraEffect const* empRenew = caster->GetAuraEffect(SPELL_PRIEST_EMPOWERED_RENEW, EFFECT_1))
1670 AddPct(pctMod, empRenew->GetAmount());
1671 }
1672
1677};
1678
1679// 372616 - Empyreal Blaze
1681{
1682 bool Validate(SpellInfo const* /*spellInfo*/) override
1683 {
1685 }
1686
1687 static void HandleProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
1688 {
1689 Unit* caster = eventInfo.GetActor();
1690 if (!caster)
1691 return;
1692
1695 .TriggeringSpell = eventInfo.GetProcSpell(),
1696 .TriggeringAura = aurEff,
1697 .SpellValueOverrides = { { SPELLVALUE_AURA_STACK, aurEff->GetAmountAsInt() } }
1698 });
1699 }
1700
1705};
1706
1707// Triggered by 14914 - Holy Fire
1709{
1710 bool Validate(SpellInfo const* /*spellInfo*/) override
1711 {
1713 }
1714
1715 bool Load() override
1716 {
1718 }
1719
1720 void HandleHit() const
1721 {
1722 Unit* target = GetHitUnit();
1723 if (!target)
1724 return;
1725
1726 Aura* holyFireAura = target->GetAura(GetSpellInfo()->Id, GetCaster()->GetGUID());
1727 if (!holyFireAura)
1728 return;
1729
1731 }
1732
1737};
1738
1739// 447444 - Entropic Rift
1740// Triggered by 8092 - Mind Blast (Discipline) and 263165 - Void Torrent (Shadow)
1742{
1743 bool Validate(SpellInfo const* /*spellInfo*/) override
1744 {
1746 }
1747
1748 bool Load() override
1749 {
1750 Unit* caster = GetCaster();
1751 return caster->HasAura(SPELL_PRIEST_ENTROPIC_RIFT)
1752 && caster->IsPlayer()
1756 }
1757
1758 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
1759 {
1760 Unit* target = GetHitUnit();
1761
1763 .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_DONT_REPORT_CAST_ERROR,
1764 .CustomArg = target->GetGUID()
1765 });
1766 }
1767
1775};
1776
1777// 450193 - Entropic Rift (Aura)
1779{
1780 bool Validate(SpellInfo const* /*spellInfo*/) override
1781 {
1783 }
1784
1785 void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
1786 {
1788 at->Remove();
1789 }
1790
1795};
1796
1797// 459314 - Entropic Rift (Periodic)
1799{
1800 bool Validate(SpellInfo const* /*spellInfo*/) override
1801 {
1803 }
1804
1805 void HandlePeriodic(AuraEffect const* /*aurEff*/) const
1806 {
1807 Unit* caster = GetTarget();
1808
1810 if (!at)
1811 return;
1812
1813 SpellInfo const* damageSpell = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_ENTROPIC_RIFT_DAMAGE, GetCastDifficulty());
1814
1815 for (ObjectGuid const& unitInAreaTrigger : at->GetInsideUnits())
1816 if (Unit* target = ObjectAccessor::GetUnit(*at, unitInAreaTrigger))
1817 if (caster->IsValidAttackTarget(target, damageSpell))
1819 }
1820
1825};
1826
1827// 447445 - Entropic Rift (AreaTrigger)
1829{
1831
1832 static constexpr std::array<DBCPosition2D, 2> OverrideScaleCurve =
1833 {{
1834 { .X = 0.0f, .Y = 1.0f },
1835 { .X = 1.0f, .Y = 1.0f },
1836 }};
1837
1838 void OnCreate(Spell const* creatingSpell) override
1839 {
1840 Unit* caster = at->GetCaster();
1841 if (!caster)
1842 return;
1843
1844 CastSpellExtraArgs args;
1846
1847 if (creatingSpell)
1848 {
1849 args.OriginalCastId = creatingSpell->m_castId;
1850
1851 if (ObjectGuid const* targetGUID = std::any_cast<ObjectGuid>(&creatingSpell->m_customArg))
1852 at->SetPathTarget(*targetGUID);
1853
1854 _searchRadius = creatingSpell->GetSpellInfo()->GetMinMaxRange();
1855 }
1856
1857 caster->CastSpell(caster, SPELL_PRIEST_ENTROPIC_RIFT_AURA, args);
1858 caster->CastSpell(caster, SPELL_PRIEST_ENTROPIC_RIFT_PERIODIC, args);
1859
1861 _scheduler.Schedule(500ms, [this](TaskContext& task)
1862 {
1864 task.Repeat(500ms);
1865 });
1866 }
1867
1868 void OnUpdate(uint32 diff) override
1869 {
1870 _scheduler.Update(diff);
1871 }
1872
1873 void OnDestinationReached() override
1874 {
1875 _movementSpeed = 7.0f; // Entropic Rift moves slower after reaching its target
1876 }
1877
1879 {
1880 at->SetOverrideScaleCurve(OverrideScaleCurve); // updates StartTimeOffset of the curve
1881
1882 Unit* target = UpdateTarget();
1883 if (!target)
1884 return;
1885
1886 at->SetPathTarget(target->GetGUID());
1887
1888 if (at->IsInDist2d(target, 0.5f))
1889 return;
1890
1891 PathGenerator path(at);
1892 path.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), false);
1894 }
1895
1897 {
1898 SpellInfo const* damageSpell = sSpellMgr->GetSpellInfo(SPELL_PRIEST_ENTROPIC_RIFT_DAMAGE, DIFFICULTY_NONE);
1899 if (!damageSpell || damageSpell->GetEffects().empty())
1900 return nullptr;
1901
1902 Unit* caster = at->GetCaster();
1903 if (!caster)
1904 return nullptr;
1905
1906 SpellEffectInfo const& damageEffect = damageSpell->GetEffect(EFFECT_0);
1908
1909 Unit* target = ObjectAccessor::GetUnit(*at, at->m_areaTriggerData->OrbitPathTarget);
1910 if (!target || !check(target))
1911 {
1912 std::vector<Unit*> targets;
1913 Trinity::UnitListSearcher searcher(at, targets, check);
1915 Trinity::Containers::EraseIf(targets, [caster](Unit const* target) { return !caster->IsInCombatWith(target); });
1916 if (!targets.empty())
1918 }
1919
1920 return target;
1921 }
1922
1923private:
1925 float _movementSpeed = 12.0f;
1927};
1928
1929// 414553 - Epiphany
1931{
1932 bool Validate(SpellInfo const* /*spellInfo*/) override
1933 {
1935 }
1936
1937 static bool CheckProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
1938 {
1939 return roll_chance(aurEff->GetAmount());
1940 }
1941
1942 void HandleOnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) const
1943 {
1944 Unit* target = GetTarget();
1945
1947
1948 target->CastSpell(target, SPELL_PRIEST_EPIPHANY_HIGHLIGHT, aurEff);
1949 }
1950
1956};
1957
1958// 415673 - Essence Devourer (Heal)
1959// 415676 - Essence Devourer (Heal)
1961{
1962 static void FilterTargets(SpellScript const&, std::list<WorldObject*>& targets)
1963 {
1964 Trinity::SelectRandomInjuredTargets(targets, 1, true);
1965 }
1966
1971};
1972
1973// 1215245 - Eternal Sanctity
1975{
1976 bool Validate(SpellInfo const* /*spellInfo*/) override
1977 {
1979 }
1980
1981 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
1982 {
1983 return eventInfo.GetActor()->HasAura(SPELL_PRIEST_APOTHEOSIS);
1984 }
1985
1986 static void HandleEffectProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
1987 {
1988 if (Aura* apotheosisAura = eventInfo.GetActor()->GetAura(SPELL_PRIEST_APOTHEOSIS))
1989 apotheosisAura->SetDuration(apotheosisAura->GetDuration() + aurEff->GetAmountAsInt());
1990 }
1991
1997};
1998
1999// 472433 - Evangelism
2035
2036// 390832 - Expiation
2037// Triggered by 8092 - Mind Blast and 32379 - Shadow Word: Death
2039{
2045
2046 bool Load() override
2047 {
2049 }
2050
2051 void HandleHitTarget(SpellEffIndex /*effIndex*/) const
2052 {
2053 Unit* caster = GetCaster();
2054 Unit* target = GetHitUnit();
2055
2056 Aura const* expiation = caster->GetAura(SPELL_PRIEST_EXPIATION);
2057 if (!expiation)
2058 return;
2059
2060 AuraEffect const* expiationConsume = expiation->GetEffect(EFFECT_0);
2061 AuraEffect const* expiationDmgMul = expiation->GetEffect(EFFECT_1);
2062 if (!expiationConsume || !expiationDmgMul)
2063 return;
2064
2065 AuraEffect const* swPainAuraEffect = target->GetAuraEffect(SPELL_PRIEST_SHADOW_WORD_PAIN, EFFECT_1, caster->GetGUID());
2066 if (!swPainAuraEffect)
2067 return;
2068
2069 Aura* swPainAura = swPainAuraEffect->GetBase();
2070 int32 debuffDuration = swPainAura->GetDuration();
2071 int32 consumeDuration = std::min(debuffDuration, expiationConsume->GetAmountAsInt() * IN_MILLISECONDS);
2072 if (consumeDuration == 0)
2073 return;
2074
2075 float ticksConsumed = static_cast<float>(consumeDuration) / swPainAuraEffect->GetPeriod();
2076 SpellEffectValue damagePerTick = swPainAuraEffect->CalculateEstimatedAmount(caster, swPainAuraEffect->GetAmount()).value_or(swPainAuraEffect->GetAmount());
2077 SpellEffectValue totalDamage = static_cast<int32>(damagePerTick * ticksConsumed);
2078
2079 swPainAura->SetDuration(debuffDuration - consumeDuration);
2080
2082 {
2084 .SpellValueOverrides = { { SPELLVALUE_BASE_POINT0, CalculatePct(totalDamage, expiationDmgMul->GetAmount()) } }
2085 });
2086 }
2087
2092};
2093
2094// 33110 - Prayer of Mending (Heal)
2096{
2097 bool Validate(SpellInfo const* /*spellInfo*/) override
2098 {
2100 }
2101
2102 void CalculateHealingBonus(SpellEffectInfo const& /*spellEffectInfo*/, Unit* /*victim*/, int32& /*healing*/, int32& /*flatMod*/, float& pctMod) const
2103 {
2104 if (AuraEffect const* focusedMendingEffect = GetCaster()->GetAuraEffect(SPELL_PRIEST_FOCUSED_MENDING, EFFECT_0))
2105 {
2106 bool const* isEmpoweredByFocusedMending = std::any_cast<bool>(&GetSpell()->m_customArg);
2107
2108 if (isEmpoweredByFocusedMending && *isEmpoweredByFocusedMending)
2109 AddPct(pctMod, focusedMendingEffect->GetAmount());
2110 }
2111 }
2112
2117};
2118
2119// 390615 - From Darkness Comes Light (Talent)
2132
2133// 47788 - Guardian Spirit
2135{
2137
2138 bool Validate(SpellInfo const* spellInfo) override
2139 {
2141 }
2142
2143 bool Load() override
2144 {
2146 return true;
2147 }
2148
2149 static void CalculateAmount(AuraScript const&, AuraEffect const* /*aurEff*/, SpellEffectValue & amount, bool & /*canBeRecalculated*/)
2150 {
2151 // Set absorbtion amount to unlimited
2152 amount = -1;
2153 }
2154
2155 void Absorb(AuraEffect* /*aurEff*/, DamageInfo const& dmgInfo, uint32 & absorbAmount)
2156 {
2157 Unit* target = GetTarget();
2158 if (dmgInfo.GetDamage() < target->GetHealth())
2159 return;
2160
2162 // remove the aura now, we don't want 40% healing bonus
2165 args.AddSpellBP0(healAmount);
2166 target->CastSpell(target, SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL, args);
2167 absorbAmount = dmgInfo.GetDamage();
2168 }
2169
2175};
2176
2177// 373180 - Harsh Discipline
2178// Triggered by 194509 - Power Word: Radiance
2180{
2186
2187 bool Load() override
2188 {
2190 }
2191
2192 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
2193 {
2194 Unit* caster = GetCaster();
2195 SpellInfo const* penanceChannel = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_PENANCE_CHANNEL_DAMAGE, GetCastDifficulty());
2197
2198 // do the calc here
2199 float channelDuration = penanceChannel->GetDuration();
2200 float channelPeriod = penanceChannel->GetEffect(EFFECT_1).ApplyAuraPeriod;
2201
2202 float baseBolts = channelDuration / channelPeriod;
2203 if (caster->HasAura(SPELL_PRIEST_CASTIGATION))
2204 baseBolts += 1.0f;
2205
2206 SpellEffectValue basePeriod = channelDuration / baseBolts;
2207
2208 SpellEffectValue totalBolts = baseBolts + additionalBolts;
2209 SpellEffectValue newPeriod = channelDuration / totalBolts;
2210 SpellEffectValue pctDiff = GetPctOf(newPeriod - basePeriod, basePeriod);
2211
2214 .SpellValueOverrides = {
2215 { SPELLVALUE_BASE_POINT0, std::floor(pctDiff) },
2216 { SPELLVALUE_BASE_POINT1, additionalBolts }
2217 }
2218 });
2219 }
2220
2225};
2226
2227// 421558 - Heaven's Wrath
2229{
2230 bool Validate(SpellInfo const* /*spellInfo*/) override
2231 {
2233 }
2234
2235 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
2236 {
2238 }
2239
2240 static void HandleEffectProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
2241 {
2242 Unit* caster = eventInfo.GetActor();
2243 if (!caster)
2244 return;
2245
2246 SpellHistory::Duration cdReduction = -duration_cast<SpellHistory::Duration>(FloatSeconds(aurEff->GetAmount()));
2247 caster->GetSpellHistory()->ModifyCooldown(SPELL_PRIEST_ULTIMATE_PENITENCE, cdReduction, true);
2248 }
2249
2254};
2255
2256// 120517 - Halo (Holy)
2257// 120644 - Halo (Shadow)
2259{
2260 bool Validate(SpellInfo const* /*spellInfo*/) override
2261 {
2263 }
2264
2265 static void PreventUnwantedAura(SpellScript const&, WorldObject*& target)
2266 {
2267 target = nullptr;
2268 }
2269
2270 void Register() override
2271 {
2272 Optional<SpellEffIndex> selectedEffect;
2273 if (Unit* caster = GetSpell() ? GetCaster() : nullptr)
2274 {
2275 if (caster->HasAura(SPELL_PRIEST_DIVINE_HALO))
2276 selectedEffect = caster->HasAura(SPELL_PRIEST_PHANTOM_REACH) ? EFFECT_5 : EFFECT_2;
2277 else if (caster->HasAura(SPELL_PRIEST_POWER_SURGE))
2278 selectedEffect = caster->HasAura(SPELL_PRIEST_PHANTOM_REACH) ? EFFECT_4 : EFFECT_1;
2279 else
2280 selectedEffect = caster->HasAura(SPELL_PRIEST_PHANTOM_REACH) ? EFFECT_3 : EFFECT_0;
2281 }
2282
2283 if (selectedEffect != EFFECT_0)
2285
2286 if (selectedEffect != EFFECT_1)
2288
2289 if (selectedEffect != EFFECT_2)
2291
2292 if (selectedEffect != EFFECT_3)
2294
2295 if (selectedEffect != EFFECT_4)
2297
2298 if (selectedEffect != EFFECT_5)
2300 }
2301};
2302
2303// 449840 - Halo (Holy)
2304// 453094 - Halo (Shadow)
2306{
2307 bool Validate(SpellInfo const* /*spellInfo*/) override
2308 {
2310 }
2311
2312 static void PreventUnwantedAura(SpellScript const&, WorldObject*& target)
2313 {
2314 target = nullptr;
2315 }
2316
2329};
2330
2331// 120644 - Halo (Shadow)
2333{
2335 {
2336 Unit* caster = GetCaster();
2337
2338 if (caster->GetPowerType() != GetEffectInfo().MiscValue)
2339 PreventHitDefaultEffect(effIndex);
2340 }
2341
2346};
2347
2348// 120517 - Halo (Holy)
2349// 120644 - Halo (Shadow)
2351{
2353
2354 void OnUnitEnter(Unit* unit) override
2355 {
2356 if (Unit* caster = at->GetCaster())
2357 {
2358 if (caster->IsValidAttackTarget(unit))
2361 else if (caster->IsValidAssistTarget(unit))
2364 }
2365 }
2366};
2367
2368// 449840 - Halo (Holy)
2369// 453094 - Halo (Shadow)
2371{
2373
2374 void OnUnitExit(Unit* unit, AreaTriggerExitReason reason) override
2375 {
2377 return;
2378
2379 if (Unit* caster = at->GetCaster())
2380 {
2381 if (caster->IsValidAttackTarget(unit))
2384 else if (caster->IsValidAssistTarget(unit))
2387 }
2388 }
2389};
2390
2391// 391154 - Holy Mending
2393{
2394 bool Validate(SpellInfo const* /*spellInfo*/) override
2395 {
2397 }
2398
2399 static bool CheckProc(AuraScript const&, AuraEffect const* /*aurEff*/, ProcEventInfo const& procInfo)
2400 {
2401 return procInfo.GetProcTarget()->HasAura(SPELL_PRIEST_RENEW, procInfo.GetActor()->GetGUID());
2402 }
2403
2404 static void HandleProc(AuraScript const&, AuraEffect* aurEff, ProcEventInfo const& eventInfo)
2405 {
2407 }
2408
2414};
2415
2416// 63733 - Holy Words
2418{
2438
2439 void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo const& eventInfo) const
2440 {
2441 SpellInfo const* spellInfo = eventInfo.GetSpellInfo();
2442 if (!spellInfo)
2443 return;
2444
2445 uint32 targetSpellId;
2446 SpellEffIndex cdReductionEffIndex;
2447 switch (spellInfo->Id)
2448 {
2449 case SPELL_PRIEST_HEAL:
2450 case SPELL_PRIEST_FLASH_HEAL: // reduce Holy Word: Serenity cd by 6 seconds
2451 targetSpellId = SPELL_PRIEST_HOLY_WORD_SERENITY;
2452 cdReductionEffIndex = EFFECT_1;
2453 // cdReduction = sSpellMgr->GetSpellInfo(SPELL_PRIEST_HOLY_WORD_SERENITY, GetCastDifficulty())->GetEffect(EFFECT_1)->CalcValueAsInt(player);
2454 break;
2455 case SPELL_PRIEST_PRAYER_OF_HEALING: // reduce Holy Word: Sanctify cd by 6 seconds
2456 targetSpellId = SPELL_PRIEST_HOLY_WORD_SANCTIFY;
2457 cdReductionEffIndex = EFFECT_2;
2458 break;
2459 case SPELL_PRIEST_RENEW: // reuce Holy Word: Sanctify cd by 2 seconds
2460 targetSpellId = SPELL_PRIEST_HOLY_WORD_SANCTIFY;
2461 cdReductionEffIndex = EFFECT_3;
2462 break;
2463 case SPELL_PRIEST_SMITE: // reduce Holy Word: Chastise cd by 4 seconds
2464 targetSpellId = SPELL_PRIEST_HOLY_WORD_CHASTISE;
2465 cdReductionEffIndex = EFFECT_1;
2466 break;
2467 default:
2468 TC_LOG_WARN("spells.priest", "HolyWords aura has been proced by an unknown spell: {}", GetSpellInfo()->Id);
2469 return;
2470 }
2471
2472 SpellInfo const* targetSpellInfo = sSpellMgr->AssertSpellInfo(targetSpellId, GetCastDifficulty());
2473 int32 cdReduction = targetSpellInfo->GetEffect(cdReductionEffIndex).CalcValueAsInt(GetTarget());
2474 spell_pri_holy_words_base::ModifyCooldown(GetTarget(), targetSpellInfo, Seconds(-cdReduction));
2475 }
2476
2481};
2482
2483// 88625 - Holy Word: Chastise
2512
2513// 265202 - Holy Word: Salvation
2515{
2516 bool Validate(SpellInfo const* spellInfo) override
2517 {
2518 return ValidateSpellInfo
2519 ({
2522 }) && ValidateSpellEffect({
2524 { spellInfo->Id, EFFECT_1 }
2526 }
2527
2528 bool Load() override
2529 {
2532 return true;
2533 }
2534
2535 void HandleApplyBuffs(SpellEffIndex /*effIndex*/) const
2536 {
2537 Unit* caster = GetCaster();
2538 Unit* target = GetHitUnit();
2539
2540 CastSpellExtraArgs args;
2542
2543 // amount of Prayer of Mending is SPELL_PRIEST_HOLY_WORD_SALVATION's EFFECT_1.
2545
2547 args.AddSpellMod(SPELLVALUE_BASE_POINT0, basePoints);
2548 caster->CastSpell(target, SPELL_PRIEST_PRAYER_OF_MENDING_AURA, args);
2549
2550 // a full duration Renew is triggered.
2551 caster->CastSpell(target, SPELL_PRIEST_RENEW, CastSpellExtraArgs(TRIGGERED_FULL_MASK).SetTriggeringSpell(GetSpell()));
2552 }
2553
2558
2559 SpellInfo const* _spellInfoHeal = nullptr;
2561};
2562
2563// 2050 - Holy Word: Serenity
2564// 34861 - Holy Word: Sanctify
2566{
2567 bool Validate(SpellInfo const* /*spellInfo*/) override
2568 {
2571 }
2572
2573 bool Load() override
2574 {
2576 }
2577
2578 void ReduceCooldown() const
2579 {
2580 // cooldown reduced by SPELL_PRIEST_HOLY_WORD_SALVATION's Seconds(EFFECT_2).
2581 int32 cooldownReduction = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_HOLY_WORD_SALVATION, GetCastDifficulty())->GetEffect(EFFECT_2).CalcValueAsInt(GetCaster());
2582
2584 }
2585
2590};
2591
2592// 373427 - Inescapable Torment
2593// Triggered by 8092 - Mind Blast, 32379 - Shadow Word: Death
2594// Triggered by 47758 - Penance (Channel) and 373129 - Dark Reprimand (Channel)
2596{
2597 bool Validate(SpellInfo const* /*spellInfo*/) override
2598 {
2601 }
2602
2603 bool Load() override
2604 {
2606 }
2607
2608 static TempSummon* GetSummon(Unit const* owner)
2609 {
2610 for (Unit* summon : owner->m_Controlled)
2611 if (summon->GetEntry() == NPC_PRIEST_SHADOWFIEND || summon->GetEntry() == NPC_PRIEST_MINDBENDER || summon->GetEntry() == NPC_PRIEST_VOIDWRAITH)
2612 return summon->ToTempSummon();
2613 return nullptr;
2614 }
2615
2616 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
2617 {
2618 Unit const* caster = GetCaster();
2619 TempSummon* summon = GetSummon(caster);
2620 if (!summon)
2621 return;
2622
2625 .TriggeringSpell = GetSpell()
2626 });
2627
2628 int32 durationExtend = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_INESCAPABLE_TORMENT, DIFFICULTY_NONE)->GetEffect(EFFECT_1).CalcValueAsInt(caster);
2629 summon->ModifyTimer(Milliseconds(durationExtend));
2630 }
2631
2636};
2637
2638// 373212 - Insidious Ire
2640{
2641 static void HandleProc(AuraScript const&, ProcEventInfo const& eventInfo)
2642 {
2643 Unit* caster = eventInfo.GetActor();
2644 Unit* target = eventInfo.GetActionTarget();
2645
2646 Aura const* requiredAuras[] =
2647 {
2648 target->GetAura(SPELL_PRIEST_SHADOW_WORD_PAIN, caster->GetGUID()),
2649 target->GetAura(SPELL_PRIEST_DEVOURING_PLAGUE, caster->GetGUID()),
2650 target->GetAura(SPELL_PRIEST_VAMPIRIC_TOUCH, caster->GetGUID())
2651 };
2652
2653 if (advstd::ranges::contains(requiredAuras, nullptr))
2654 {
2656 return;
2657 }
2658
2659 int32 shortestDuration = std::ranges::min(requiredAuras, {}, [](Aura const* a) { return a->GetDuration(); })->GetDuration();
2660
2663 .SpellValueOverrides = { { SPELLVALUE_DURATION, shortestDuration } }
2664 });
2665 }
2666
2667 void Register() override
2668 {
2670 }
2671};
2672
2673// 40438 - Priest Tier 6 Trinket
2675{
2676 bool Validate(SpellInfo const* /*spellInfo*/) override
2677 {
2679 }
2680
2681 void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo const& eventInfo)
2682 {
2684 Unit* caster = eventInfo.GetActor();
2685 if (eventInfo.GetSpellTypeMask() & PROC_SPELL_TYPE_HEAL)
2686 caster->CastSpell(nullptr, SPELL_PRIEST_DIVINE_BLESSING, true);
2687
2688 if (eventInfo.GetSpellTypeMask() & PROC_SPELL_TYPE_DAMAGE)
2689 caster->CastSpell(nullptr, SPELL_PRIEST_DIVINE_WRATH, true);
2690 }
2691
2696};
2697
2698// 471504 - Lasting Words
2699// Triggered by 2050 - Holy Word: Serenity and 34861 - Holy Word: Sanctify
2701{
2702 bool Validate(SpellInfo const* /*spellInfo*/) override
2703 {
2706 }
2707
2708 bool Load() override
2709 {
2711 }
2712
2713 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
2714 {
2715 Unit* caster = GetCaster();
2716
2717 AuraEffect const* lastingWordsEff = caster->GetAuraEffect(SPELL_PRIEST_LASTING_WORDS, _spellEff);
2718 if (!lastingWordsEff)
2719 return;
2720
2723 .TriggeringSpell = GetSpell(),
2724 .SpellValueOverrides = { { SPELLVALUE_DURATION, lastingWordsEff->GetAmountAsInt() } }
2725 });
2726 }
2727
2732
2734
2735public:
2736 explicit spell_pri_lasting_words(SpellEffIndex spellEff) : _spellEff(spellEff) { }
2737};
2738
2739// 92833 - Leap of Faith
2741{
2742 bool Validate(SpellInfo const* /*spellInfo*/) override
2743 {
2745 }
2746
2747 void HandleEffectDummy(SpellEffIndex /*effIndex*/) const
2748 {
2749 Position destPos = GetHitDest()->GetPosition();
2750
2751 SpellCastTargets targets;
2752 targets.SetDst(destPos);
2753 targets.SetUnitTarget(GetCaster());
2754 GetHitUnit()->CastSpell(std::move(targets), GetEffectValueAsInt(), GetCastDifficulty());
2755 }
2756
2761};
2762
2763// 1706 - Levitate
2765{
2766 bool Validate(SpellInfo const* /*spellInfo*/) override
2767 {
2769 }
2770
2771 void HandleDummy(SpellEffIndex /*effIndex*/) const
2772 {
2774 }
2775
2780};
2781
2782// 373178 - Light's Wrath
2784{
2785 bool Validate(SpellInfo const* spellInfo) override
2786 {
2787 return ValidateSpellEffect({ { spellInfo->Id, EFFECT_1 } });
2788 }
2789
2790 void OnPrecast() override
2791 {
2792 Aura const* atonement = GetCaster()->GetAura(SPELL_PRIEST_ATONEMENT);
2793 if (!atonement)
2794 return;
2795
2796 spell_pri_atonement const* script = atonement->GetScript<spell_pri_atonement>();
2797 if (!script)
2798 return;
2799
2800 for (ObjectGuid const& atonementTarget : script->GetAtonementTargets())
2801 {
2802 if (Unit* target = ObjectAccessor::GetUnit(*GetCaster(), atonementTarget))
2803 {
2804 target->CancelSpellMissiles(SPELL_PRIEST_LIGHTS_WRATH_VISUAL, false, false);
2806 }
2807 }
2808 }
2809
2810 void CalculateDamageBonus(SpellEffectInfo const& /*spellEffectInfo*/, Unit const* /*victim*/, int32 const& /*damage*/, int32 const& /*flatMod*/, float& pctMod) const
2811 {
2812 Aura const* atonement = GetCaster()->GetAura(SPELL_PRIEST_ATONEMENT);
2813 if (!atonement)
2814 return;
2815
2816 // Atonement size may have changed when missile hits, we need to take an updated count of Atonement applications.
2817 if (spell_pri_atonement const* script = atonement->GetScript<spell_pri_atonement>())
2818 AddPct(pctMod, GetEffectInfo(EFFECT_1).CalcValue(GetCaster()) * script->GetAtonementTargets().size());
2819 }
2820
2825};
2826
2827// 375994 - Mental Decay
2829{
2830 bool Validate(SpellInfo const* /*spellInfo*/) override
2831 {
2833 }
2834
2835 static void HandleEffectProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
2836 {
2837 Unit* caster = eventInfo.GetActor();
2838 if (!caster)
2839 return;
2840
2841 Unit* target = eventInfo.GetActionTarget();
2842 int32 durationExtend = aurEff->GetAmount() * int32(IN_MILLISECONDS);
2843
2844 if (Aura* shadowWordPain = target->GetOwnedAura(SPELL_PRIEST_SHADOW_WORD_PAIN, caster->GetGUID()))
2845 {
2846 shadowWordPain->SetMaxDuration(shadowWordPain->GetDuration() + durationExtend);
2847 shadowWordPain->SetDuration(shadowWordPain->GetDuration() + durationExtend);
2848 }
2849
2850 if (Aura* vampiricTouch = target->GetOwnedAura(SPELL_PRIEST_VAMPIRIC_TOUCH, caster->GetGUID()))
2851 {
2852 vampiricTouch->SetMaxDuration(vampiricTouch->GetDuration() + durationExtend);
2853 vampiricTouch->SetDuration(vampiricTouch->GetDuration() + durationExtend);
2854 }
2855 }
2856
2861};
2862
2863// 205369 - Mind Bomb
2865{
2866 bool Validate(SpellInfo const* /*spellInfo*/) override
2867 {
2869 }
2870
2871 void RemoveEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
2872 {
2873 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_DEATH || GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE)
2874 if (Unit* caster = GetCaster())
2875 caster->CastSpell(GetTarget()->GetPosition(), SPELL_PRIEST_MIND_BOMB_STUN, true);
2876 }
2877
2882};
2883
2884// 373202 - Mind Devourer
2885// Triggered by 8092 - Mind Blast
2887{
2888 bool Validate(SpellInfo const* /*spellInfo*/) override
2889 {
2892 }
2893
2894 bool Load() override
2895 {
2897 }
2898
2899 void HandleEffectHitTarget(SpellEffIndex /*effIndex*/) const
2900 {
2902 if (aurEff && roll_chance(aurEff->GetAmount()))
2904 }
2905
2910};
2911
2912// 373204 - Mind Devourer (Aura)
2913// Attached to 335467 - Devouring Plague
2915{
2916 void CalculateDamage(AuraEffect const* /*aurEff*/, Unit* /*victim*/, int32& /*damage*/, int32& /*flatMod*/, float& pctMod) const
2917 {
2918 AddPct(pctMod, DamageIncrease);
2919 }
2920
2925
2926public:
2928};
2929
2931{
2932 bool Validate(SpellInfo const* /*spellInfo*/) override
2933 {
2935 }
2936
2937 void OnPrecast() override
2938 {
2940 if (!mindDevourer || !GetSpell()->m_appliedMods.contains(mindDevourer->GetBase()))
2941 return;
2942
2943 _damageIncrease = mindDevourer->GetAmount();
2944 }
2945
2946 void CalculateDamage(SpellEffectInfo const& /*spellEffectInfo*/, Unit* /*victim*/, int32& /*damage*/, int32& /*flatMod*/, float& pctMod) const
2947 {
2948 AddPct(pctMod, _damageIncrease);
2949 }
2950
2952 {
2953 if (!_damageIncrease)
2954 return;
2955
2956 if (Aura* devouringPlague = GetHitAura())
2957 if (spell_pri_mind_devourer_buff_aura* script = devouringPlague->GetScript<spell_pri_mind_devourer_buff_aura>())
2958 script->DamageIncrease = _damageIncrease;
2959
2961 }
2962
2968
2970};
2971
2972// 390686 - Painful Punishment
2974{
2975 bool Validate(SpellInfo const* /*spellInfo*/) override
2976 {
2977 return ValidateSpellInfo
2978 ({
2981 });
2982 }
2983
2984 static void HandleEffectProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
2985 {
2986 Unit* caster = eventInfo.GetActor();
2987 Unit* target = eventInfo.GetActionTarget();
2988 if (!caster || !target)
2989 return;
2990
2991 int32 additionalDuration = aurEff->GetAmountAsInt();
2992
2993 if (Aura* shadowWordPain = target->GetOwnedAura(SPELL_PRIEST_SHADOW_WORD_PAIN, caster->GetGUID()))
2994 shadowWordPain->SetDuration(shadowWordPain->GetDuration() + additionalDuration);
2995
2996 if (Aura* purgeTheWicked = target->GetOwnedAura(SPELL_PRIEST_PURGE_THE_WICKED_PERIODIC, caster->GetGUID()))
2997 purgeTheWicked->SetDuration(purgeTheWicked->GetDuration() + additionalDuration);
2998 }
2999
3004};
3005
3006// 372991 - Pain Transformation
3007// Triggered by 33206 - Pain Suppression
3039
3040// 47540 - Penance
3041// 400169 - Dark Reprimand
3043{
3044public:
3045 spell_pri_penance(uint32 damageSpellId, uint32 healingSpellId) : _damageSpellId(damageSpellId), _healingSpellId(healingSpellId)
3046 {
3047 }
3048
3049 bool Validate(SpellInfo const* /*spellInfo*/) override
3050 {
3052 }
3053
3055 {
3056 Unit* caster = GetCaster();
3057
3058 if (Unit* target = GetExplTargetUnit())
3059 {
3060 if (!caster->IsFriendlyTo(target))
3061 {
3062 if (!caster->IsValidAttackTarget(target))
3064
3065 if (!caster->isInFront(target))
3067 }
3068 }
3069
3070 return SPELL_CAST_OK;
3071 }
3072
3073 void HandleDummy(SpellEffIndex /*effIndex*/) const
3074 {
3075 Unit* caster = GetCaster();
3076
3077 if (Unit* target = GetHitUnit())
3078 {
3079 if (caster->IsFriendlyTo(target))
3081 .SetTriggeringSpell(GetSpell()));
3082 else
3084 .SetTriggeringSpell(GetSpell()));
3085 }
3086 }
3087
3093
3094private:
3097};
3098
3099// 47758 - Penance (Channel Damage), 47757 - Penance (Channel Healing)
3100// 373129 - Dark Reprimand (Channel Damage), 400171 - Dark Reprimand (Channel Healing)
3102{
3103 bool Validate(SpellInfo const* /*spellInfo*/) override
3104 {
3106 }
3107
3108 void HandleOnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
3109 {
3110 if (Unit* caster = GetCaster())
3111 caster->RemoveAura(SPELL_PRIEST_POWER_OF_THE_DARK_SIDE);
3112 }
3113
3118};
3119
3120// 114239 - Phantasm
3122{
3123 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
3124 {
3126 }
3127
3132};
3133
3134// 262484 - Power Leech (Passive for Shadowfiend)
3135// 284621 - Power Leech (Passive for Mindbender)
3137{
3158
3159 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
3160 {
3161 return eventInfo.GetDamageInfo() != nullptr;
3162 }
3163
3164 void HandleOnProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) const
3165 {
3166 Unit* target = GetTarget();
3167 Player* summoner = Object::ToPlayer(target->GetOwner());
3168 if (!summoner)
3169 return;
3170
3171 SpellInfo const* spellInfo = nullptr;
3172 int32 divisor = 1;
3173
3175 {
3176 if (target->GetEntry() == NPC_PRIEST_SHADOWFIEND)
3177 {
3178 // Note: divisor is 100 because effect value is 5 and its supposed to restore 0.5%
3180 divisor = 10;
3181 }
3182 else
3183 {
3184 // Note: divisor is 100 because effect value is 20 and its supposed to restore 0.2%
3186 divisor = 100;
3187 }
3188 }
3189 else
3190 spellInfo = sSpellMgr->AssertSpellInfo(target->GetEntry() == NPC_PRIEST_SHADOWFIEND
3193
3194 target->CastSpell(summoner, spellInfo->Id, CastSpellExtraArgs(aurEff)
3196
3197 // Note: Essence Devourer talent.
3200 }
3201
3207};
3208
3209// 198069 - Power of the Dark Side
3211{
3212 bool Validate(SpellInfo const* /*spellInfo*/) override
3213 {
3215 }
3216
3217 void HandleOnApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
3218 {
3219 if (Unit* caster = GetCaster())
3220 caster->CastSpell(caster, SPELL_PRIEST_POWER_OF_THE_DARK_SIDE_TINT, true);
3221 }
3222
3223 void HandleOnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
3224 {
3225 if (Unit* caster = GetCaster())
3226 caster->RemoveAura(SPELL_PRIEST_POWER_OF_THE_DARK_SIDE_TINT);
3227 }
3228
3234};
3235
3236// 47666 - Penance (Damage)
3237// 373130 - Dark Reprimand (Damage)
3239{
3240 bool Validate(SpellInfo const* /*spellInfo*/) override
3241 {
3243 }
3244
3245 void CalculateDamageBonus(SpellEffectInfo const& /*spellEffectInfo*/, Unit* /*victim*/, int32& /*damage*/, int32& /*flatMod*/, float& pctMod) const
3246 {
3247 if (AuraEffect* powerOfTheDarkSide = GetCaster()->GetAuraEffect(SPELL_PRIEST_POWER_OF_THE_DARK_SIDE, EFFECT_0))
3248 AddPct(pctMod, powerOfTheDarkSide->GetAmount());
3249 }
3250
3255};
3256
3257// 47750 - Penance (Healing)
3258// 400187 - Dark Reprimand (Healing)
3260{
3261 bool Validate(SpellInfo const* /*spellInfo*/) override
3262 {
3264 }
3265
3266 void CalculateHealingBonus(SpellEffectInfo const& /*spellEffectInfo*/, Unit* /*victim*/, int32& /*healing*/, int32& /*flatMod*/, float& pctMod) const
3267 {
3268 if (AuraEffect* powerOfTheDarkSide = GetCaster()->GetAuraEffect(SPELL_PRIEST_POWER_OF_THE_DARK_SIDE, EFFECT_0))
3269 AddPct(pctMod, powerOfTheDarkSide->GetAmount());
3270 }
3271
3276};
3277
3278// 453109 - Power Surge
3279// Triggered by 120517 - Halo (Holy) and 120644 - Halo (Shadow)
3281{
3293
3294 static void HandleProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
3295 {
3296 Unit* caster = eventInfo.GetActor();
3297
3298 uint32 spellId = 0;
3299 switch (eventInfo.GetSpellInfo()->Id)
3300 {
3303 break;
3306 break;
3307 default:
3308 return;
3309 }
3310
3313 .TriggeringSpell = eventInfo.GetProcSpell(),
3314 .TriggeringAura = aurEff
3315 };
3316
3317 caster->CastSpell(caster, SPELL_PRIEST_POWER_SURGE_HALO_VISUAL, args);
3318 caster->CastSpell(caster, spellId, args);
3319 }
3320
3325};
3326
3327// 453112 - Power Surge (Holy - Periodic)
3328// 453113 - Power Surge (Shadow - Periodic)
3351
3352// 194509 - Power Word: Radiance
3354{
3355 bool Validate(SpellInfo const* /*spellInfo*/) override
3356 {
3358 }
3359
3360 void FilterTargets(std::list<WorldObject*>& targets)
3361 {
3362 Unit* caster = GetCaster();
3363 Unit* explTarget = GetExplTargetUnit();
3364
3365 // we must add one since explicit target is always chosen.
3366 uint32 maxTargets = GetEffectInfo(EFFECT_2).CalcValueAsInt(caster) + 1;
3367
3368 Trinity::SortTargetsWithPriorityRules(targets, maxTargets, GetRadianceRules(caster, explTarget));
3369
3370 for (WorldObject const* target : targets)
3371 {
3372 if (target == explTarget)
3373 continue;
3374
3375 _visualTargets.push_back(target->GetGUID());
3376 }
3377 }
3378
3379 void HandleEffectHitTarget(SpellEffIndex /*effIndex*/) const
3380 {
3381 for (ObjectGuid const& guid : _visualTargets)
3382 if (Unit* target = ObjectAccessor::GetUnit(*GetHitUnit(), guid))
3384 }
3385
3386 static std::array<Trinity::TargetPriorityRule, 5> GetRadianceRules(Unit const* caster, Unit const* explTarget)
3387 {
3388 return
3389 {
3390 [explTarget](WorldObject const* target) { return target == explTarget; },
3391 [caster](Unit const* target) { return !target->HasAura(SPELL_PRIEST_ATONEMENT_EFFECT, caster->GetGUID()); },
3392 [](Unit const* target) { return !target->IsFullHealth(); },
3393 [](WorldObject const* target) { return target->IsPlayer() || (target->IsCreature() && target->ToCreature()->IsTreatedAsRaidUnit()); },
3394 [caster](Unit const* target) { return target->IsInRaidWith(caster); }
3395 };
3396 }
3397
3403
3404 std::vector<ObjectGuid> _visualTargets;
3405};
3406
3407// 472433 - Evangelism (attached to 194509 - Power Word: Radiance)
3409{
3410 bool Validate(SpellInfo const* /*spellInfo*/) override
3411 {
3413 && sSpellMgr->AssertSpellInfo(SPELL_PRIEST_EVANGELISM, DIFFICULTY_NONE)->GetEffect(EFFECT_1).TargetA.GetTarget() == Targets();
3414 }
3415
3416 void CalculateHealing(SpellEffectInfo const& /*effectInfo*/, Unit* /*victim*/, int32& /*healing*/, int32& /*flatMod*/, float& pctMod) const
3417 {
3418 spell_pri_evangelism::TriggerArgs const* evangelism = std::any_cast<spell_pri_evangelism::TriggerArgs>(&GetSpell()->m_customArg);
3419 if (!evangelism)
3420 return;
3421
3422 ApplyPct(pctMod, evangelism->EffectivenessPct);
3423 }
3424
3429};
3430
3431// 17 - Power Word: Shield
3433{
3448
3449 void CalculateAbsorb(AuraEffect const* aurEff, Unit* /*victim*/, int32& /*absorb*/, int32& /*flatMod*/, float& pctMod)
3450 {
3451 Unit* caster = GetCaster();
3452
3453 // Mastery: Grace (TBD: move into DoEffectCalcDamageAndHealing hook with a new SpellScript and AuraScript).
3454 if (AuraEffect const* masteryGraceEffect = caster->GetAuraEffect(SPELL_PRIEST_MASTERY_GRACE, EFFECT_0))
3456 AddPct(pctMod, masteryGraceEffect->GetAmount());
3457
3458 float critChanceDone = caster->SpellCritChanceDone(nullptr, aurEff, GetSpellInfo()->GetSchoolMask(), GetSpellInfo()->GetAttackType());
3459 float critChanceTaken = GetUnitOwner()->SpellCritChanceTaken(caster, nullptr, aurEff, GetSpellInfo()->GetSchoolMask(), critChanceDone, GetSpellInfo()->GetAttackType());
3460
3461 if (roll_chance(critChanceTaken))
3462 pctMod *= 2;
3463 }
3464
3465 void HandleOnApply(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) const
3466 {
3467 Unit* caster = GetCaster();
3468 if (!caster)
3469 return;
3470
3471 // Note: Strength of Soul PvP talent.
3474 }
3475
3476 void HandleOnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) const
3477 {
3479
3480 // Note: Shield Discipline talent.
3481 if (Unit* caster = GetCaster())
3482 if (GetTargetApplication()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL && caster->HasAura(SPELL_PRIEST_SHIELD_DISCIPLINE))
3483 caster->CastSpell(caster, SPELL_PRIEST_SHIELD_DISCIPLINE_EFFECT, aurEff);
3484 }
3485
3492};
3493
3494// 47515 - Divine Aegis
3496{
3497 bool Validate(SpellInfo const* /*spellInfo*/) override
3498 {
3500 }
3501
3502 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
3503 {
3504 return eventInfo.GetHealInfo() != nullptr;
3505 }
3506
3507 static void HandleProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
3508 {
3509 Unit* caster = eventInfo.GetActor();
3510 if (!caster)
3511 return;
3512
3513 SpellEffectValue aegisAmount = CalculatePct(eventInfo.GetHealInfo()->GetHeal(), aurEff->GetAmount());
3514
3515 CastSpellExtraArgs args(aurEff);
3517 args.AddSpellMod(SPELLVALUE_BASE_POINT0, aegisAmount);
3518 caster->CastSpell(eventInfo.GetProcTarget(), SPELL_PRIEST_DIVINE_AEGIS_ABSORB, args);
3519 }
3520
3525};
3526
3527// 472361 - Divine Procession
3529{
3535
3536 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) const
3537 {
3538 Unit* caster = GetTarget();
3539
3540 Aura const* atonementAura = caster->GetAura(SPELL_PRIEST_ATONEMENT);
3541 if (!atonementAura)
3542 return;
3543
3544 spell_pri_atonement const* atonementScript = atonementAura->GetScript<spell_pri_atonement>();
3545 if (!atonementScript)
3546 return;
3547
3548 std::vector<ObjectGuid> const& atonementTargets = atonementScript->GetAtonementTargets();
3549 if (atonementTargets.empty())
3550 return;
3551
3552 // smallest Atonement duration should get increased
3553 auto it = std::ranges::min_element(atonementTargets, std::ranges::less(), [caster](ObjectGuid const& guidA)
3554 {
3555 Unit const* target = ObjectAccessor::GetUnit(*caster, guidA);
3556 if (!target)
3557 return std::numeric_limits<int32>::max();
3558
3559 Aura const* atonementEffect = target->GetAura(SPELL_PRIEST_ATONEMENT_EFFECT, caster->GetGUID());
3560 if (!atonementEffect)
3561 return std::numeric_limits<int32>::max();
3562
3563 return atonementEffect->GetDuration();
3564 });
3565
3566 if (Unit const* target = ObjectAccessor::GetUnit(*caster, *it))
3567 {
3568 if (Aura* atonement = target->GetAura(SPELL_PRIEST_ATONEMENT_EFFECT, caster->GetGUID()))
3569 {
3570 if (atonement->GetDuration() < 30 * IN_MILLISECONDS)
3571 {
3572 int32 newDuration = atonement->GetDuration() + aurEff->GetAmountAsInt();
3573 atonement->SetDuration(newDuration);
3574 atonement->SetMaxDuration(newDuration);
3575 }
3576 }
3577 }
3578 }
3579
3584};
3585
3586// 129250 - Power Word: Solace
3588{
3589 bool Validate(SpellInfo const* /*spellInfo*/) override
3590 {
3592 }
3593
3600
3605};
3606
3607// Base class used by various Prayer of Mending spells
3609{
3610public:
3616
3617 bool Load() override
3618 {
3620 return true;
3621 }
3622
3623 void CastPrayerOfMendingAura(Unit* caster, Unit* target, Unit* visualSender, int32 stack, bool firstCast) const
3624 {
3625 CastSpellExtraArgs args;
3628
3629 // Note: this line's purpose is to show the correct amount in Points field in SMSG_AURA_UPDATE.
3630 SpellEffectInfo const* healEffectDummy = &_spellInfoHeal->GetEffect(EFFECT_0);
3631 uint32 basePoints = caster->SpellHealingBonusDone(target, _spellInfoHeal, healEffectDummy->CalcValueAsInt(caster), HEAL, *healEffectDummy);
3632 args.AddSpellMod(SPELLVALUE_BASE_POINT0, basePoints);
3633
3634 // Note: Focused Mending talent.
3635 args.SetCustomArg(firstCast);
3636
3637 caster->CastSpell(target, SPELL_PRIEST_PRAYER_OF_MENDING_AURA, args);
3638
3639 // Note: the visualSender is the priest if it is first cast or the aura holder when the aura triggers.
3640 visualSender->SendPlaySpellVisual(target, SPELL_VISUAL_PRIEST_PRAYER_OF_MENDING, 0, 0, 40.0f);
3641 }
3642
3643protected:
3644 SpellInfo const* _spellInfoHeal = nullptr;
3645};
3646
3647// 33076 - Prayer of Mending (Dummy)
3649{
3650 bool Validate(SpellInfo const* /*spellInfo*/) override
3651 {
3652 return ValidateSpellInfo
3653 ({
3657 });
3658 }
3659
3660 void HandleEffectDummy(SpellEffIndex /*effIndex*/) const
3661 {
3662 Unit* caster = GetCaster();
3663 Unit* target = GetHitUnit();
3664
3665 // 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.
3667
3668 CastPrayerOfMendingAura(caster, target, caster, stackAmount, true);
3669
3670 // Note: Epiphany talent.
3671 if (caster->HasAura(SPELL_PRIEST_EPIPHANY))
3673 }
3674
3679};
3680
3681// 41635 - Prayer of Mending (Aura)
3683{
3689
3690 void HandleHeal(AuraEffect const* aurEff, ProcEventInfo const& /*eventInfo*/)
3691 {
3692 // Note: caster is the priest who cast the spell and target is current holder of the aura.
3693 Unit* target = GetTarget();
3694
3695 if (Unit* caster = GetCaster())
3696 {
3697 CastSpellExtraArgs args(aurEff);
3699
3700 caster->CastSpell(target, SPELL_PRIEST_PRAYER_OF_MENDING_HEAL, args);
3701
3702 // Note: jump is only executed if higher than 1 stack.
3703 int32 stackAmount = GetStackAmount();
3704 if (stackAmount > 1)
3705 {
3706 args.OriginalCaster = caster->GetGUID();
3707
3708 int32 newStackAmount = stackAmount - 1;
3709 if (AuraEffect* sayYourPrayers = caster->GetAuraEffect(SPELL_PRIEST_SAY_YOUR_PRAYERS, EFFECT_0))
3710 if (roll_chance(sayYourPrayers->GetAmount()))
3711 ++newStackAmount;
3712
3713 args.AddSpellMod(SPELLVALUE_BASE_POINT0, newStackAmount);
3714
3715 target->CastSpell(target, SPELL_PRIEST_PRAYER_OF_MENDING_JUMP, args);
3716 }
3717
3718 Remove();
3719 }
3720 }
3721
3726
3727public:
3728 void SetEmpoweredByFocusedMending(bool isEmpowered)
3729 {
3730 _isEmpoweredByFocusedMending = isEmpowered;
3731 }
3732
3733private:
3735};
3736
3738{
3739 void HandleEffectDummy(SpellEffIndex /*effIndex*/) const
3740 {
3741 Aura* aura = GetHitAura();
3742 if (!aura)
3743 return;
3744
3746 if (!script)
3747 return;
3748
3749 if (bool const* isEmpoweredByFocusedMending = std::any_cast<bool>(&GetSpell()->m_customArg))
3750 script->SetEmpoweredByFocusedMending(isEmpoweredByFocusedMending);
3751 }
3752
3757};
3758
3759// 155793 - Prayer of Mending (Jump)
3779
3780// 391209 - Prayerful Litany (attached to 596 - Prayer of Healing)
3782{
3783 bool Validate(SpellInfo const* /*spellInfo*/) override
3784 {
3786 }
3787
3788 bool Load() override
3789 {
3791 }
3792
3793 void CalcPrimaryTargetHealing(SpellEffectInfo const& /*effectInfo*/, Unit const* victim, int32& /*healing*/, int32& /*flatMod*/, float& pctMod) const
3794 {
3795 if (victim == GetExplTargetUnit())
3796 if (AuraEffect const* prayerfulLitanyEff = GetCaster()->GetAuraEffect(SPELL_PRIEST_PRAYERFUL_LITANY, EFFECT_0))
3797 AddPct(pctMod, prayerfulLitanyEff->GetAmount());
3798 }
3799
3804};
3805
3806// 193063 - Protective Light (Aura)
3808{
3809 bool CheckEffectProc(AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo) const
3810 {
3811 return eventInfo.GetProcTarget() == GetCaster();
3812 }
3813
3814 void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) const
3815 {
3817 }
3818
3824};
3825
3826// 405554 - Priest Holy 10.1 Class Set 2pc
3855
3856// 411097 - Priest Holy 10.1 Class Set 2pc (Chooser)
3858{
3859 bool Validate(SpellInfo const* /*spellInfo*/) override
3860 {
3862 }
3863
3864 static void FilterTargets(SpellScript const&, std::list<WorldObject*>& targets)
3865 {
3866 Trinity::SelectRandomInjuredTargets(targets, 1, true);
3867 }
3868
3869 void HandleEffectDummy(SpellEffIndex /*effIndex*/) const
3870 {
3871 Unit* caster = GetCaster();
3872 Unit* target = GetHitUnit();
3873
3874 // 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.
3876
3877 CastPrayerOfMendingAura(caster, target, caster, stackAmount, true);
3878 }
3879
3885};
3886
3887// 155793 - Prayer of Mending (Jump)
3906
3907// 41635 - Prayer of Mending (Aura)
3929
3930// 17 - Power Word: Shield
3932{
3933 bool Validate(SpellInfo const* /*spellInfo*/) override
3934 {
3936 }
3937
3943
3944 void HandleEffectHitTarget(SpellEffIndex /*effIndex*/) const
3945 {
3946 Unit* caster = GetCaster();
3947 if (AuraEffect const* effect = caster->GetAuraEffect(SPELL_PRIEST_ASSURED_SAFETY, EFFECT_0))
3948 CastPrayerOfMendingAura(caster, GetHitUnit(), caster, effect->GetAmountAsInt(), false);
3949 }
3950
3955};
3956
3957// 373036 - Protector of the Frail
3959{
3960 bool Validate(SpellInfo const* /*spellInfo*/) override
3961 {
3963 }
3964
3965 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
3966 {
3967 Unit* caster = GetCaster();
3968
3969 int32 cdReduction = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_PROTECTOR_OF_THE_FRAIL, GetCastDifficulty())->GetEffect(EFFECT_1).CalcValueAsInt(caster);
3971 }
3972
3977};
3978
3979// 204197 - Purge the Wicked
3980// Called by Penance - 47540, Dark Reprimand - 400169
3982{
3983 bool Validate(SpellInfo const* /*spellInfo*/) override
3984 {
3985 return ValidateSpellInfo
3986 ({
3989 });
3990 }
3991
3992 void HandleDummy(SpellEffIndex /*effIndex*/) const
3993 {
3994 Unit* caster = GetCaster();
3995 Unit* target = GetHitUnit();
3996
3999 }
4000
4005};
4006
4007// 204215 - Purge the Wicked
4009{
4015
4016 void FilterTargets(std::list<WorldObject*>& targets) const
4017 {
4018 Unit* caster = GetCaster();
4019 Unit* explTarget = GetExplTargetUnit();
4020
4021 targets.remove_if([&](WorldObject* object) -> bool
4022 {
4023 // Note: we must remove any non-unit target, the explicit target and any other target that may be under any crowd control aura.
4024 Unit* target = object->ToUnit();
4025 return !target || target == explTarget || target->HasBreakableByDamageCrowdControlAura();
4026 });
4027
4028 if (targets.empty())
4029 return;
4030
4031 // 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.
4032 uint32 spreadCount = 1;
4033
4034 // Note: we must sort our list of targets whose priority is 1) aura, 2) distance, and 3) duration.
4035 targets.sort([&](WorldObject const* lhs, WorldObject const* rhs) -> bool
4036 {
4037 Unit const* targetA = lhs->ToUnit();
4038 Unit const* targetB = rhs->ToUnit();
4039
4040 Aura* auraA = targetA->GetAura(SPELL_PRIEST_PURGE_THE_WICKED_PERIODIC, caster->GetGUID());
4041 Aura* auraB = targetB->GetAura(SPELL_PRIEST_PURGE_THE_WICKED_PERIODIC, caster->GetGUID());
4042
4043 if (!auraA)
4044 {
4045 if (auraB)
4046 return true;
4047 return explTarget->GetExactDist(targetA) < explTarget->GetExactDist(targetB);
4048 }
4049 if (!auraB)
4050 return false;
4051
4052 return auraA->GetDuration() < auraB->GetDuration();
4053 });
4054
4055 // Note: Revel in Purity talent.
4057 spreadCount += sSpellMgr->AssertSpellInfo(SPELL_PRIEST_REVEL_IN_PURITY, DIFFICULTY_NONE)->GetEffect(EFFECT_1).CalcValueAsInt(GetCaster());
4058
4059 if (targets.size() > spreadCount)
4060 targets.resize(spreadCount);
4061 }
4062
4063 void HandleDummy(SpellEffIndex /*effIndex*/) const
4064 {
4065 Unit* caster = GetCaster();
4066 Unit* target = GetHitUnit();
4067
4069 }
4070
4076};
4077
4078// 390622 - Rhapsody
4080{
4081 bool Validate(SpellInfo const* /*spellInfo*/) override
4082 {
4084 }
4085
4086 void HandlePeriodic(AuraEffect const* aurEff) const
4087 {
4088 Unit* target = GetTarget();
4089 if (Aura* rhapsodyStack = target->GetAura(SPELL_PRIEST_RHAPSODY_PROC, GetCasterGUID()))
4090 rhapsodyStack->ModStackAmount(1);
4091 else
4092 target->CastSpell(target, SPELL_PRIEST_RHAPSODY_PROC,
4094 }
4095
4100};
4101
4102// 390636 - Rhapsody
4104{
4105 void PreventChargeDrop(ProcEventInfo const& /*eventInfo*/)
4106 {
4108 }
4109
4110 void RemoveAura(ProcEventInfo const& /*eventInfo*/) const
4111 {
4112 // delay charge drop to allow spellmod to be applied to both damaging and healing spells
4114 }
4115
4121};
4122
4123// 47536 - Rapture
4125{
4126 bool Validate(SpellInfo const* /*spellInfo*/) override
4127 {
4129 }
4130
4132 {
4134 }
4135
4136 void HandleAfterCast() const
4137 {
4138 Unit* caster = GetCaster();
4139
4140 if (Unit* target = ObjectAccessor::GetUnit(*caster, _raptureTarget))
4143 .SetTriggeringSpell(GetSpell()));
4144 }
4145
4151
4152private:
4154};
4155
4156// 8092 - Mind Blast
4158{
4159 bool Validate(SpellInfo const* /*spellInfo*/) override
4160 {
4161 return ValidateSpellInfo
4162 ({
4165 });
4166 }
4167
4173
4178};
4179
4180// 208771 - Sanctuary (Absorb)
4182{
4183 bool Validate(SpellInfo const* /*spellInfo*/) override
4184 {
4186 }
4187
4188 void CalcAbsorbAmount(AuraEffect const* /*aurEff*/, DamageInfo& dmgInfo, uint32& /*absorbAmount*/)
4189 {
4191
4192 Unit const* attacker = dmgInfo.GetAttacker();
4193 if (!attacker)
4194 return;
4195
4196 AuraEffect* amountHolderEffect = attacker->GetAuraEffect(SPELL_PRIEST_SANCTUARY_AURA, EFFECT_0, GetCasterGUID());
4197 if (!amountHolderEffect)
4198 return;
4199
4200 if (dmgInfo.GetDamage() >= uint32(amountHolderEffect->GetAmountAsInt()))
4201 {
4202 amountHolderEffect->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
4203 dmgInfo.AbsorbDamage(amountHolderEffect->GetAmountAsInt());
4204 }
4205 else
4206 {
4207 amountHolderEffect->ChangeAmount(amountHolderEffect->GetAmount() - int32(dmgInfo.GetDamage()));
4208 dmgInfo.AbsorbDamage(dmgInfo.GetDamage());
4209 }
4210 }
4211
4216};
4217
4218// 1280131 - Searing Light
4220{
4221 bool Validate(SpellInfo const* /*spellInfo*/) override
4222 {
4224 }
4225
4226 void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo) const
4227 {
4228 SpellEffectValue dotDmg = CalculatePct(eventInfo.GetDamageInfo()->GetDamage(), aurEff->GetAmount());
4229 dotDmg /= sSpellMgr->AssertSpellInfo(SPELL_PRIEST_SEARING_LIGHT_DAMAGE, GetCastDifficulty())->GetEffect(EFFECT_0).GetPeriodicTickCount();
4230
4232 .TriggerFlags = TRIGGERED_IGNORE_CAST_IN_PROGRESS,
4233 .SpellValueOverrides = { { SPELLVALUE_BASE_POINT0, dotDmg } }
4234 });
4235 }
4236
4241};
4242
4243// Smite - 585
4245{
4250
4251 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
4252 {
4253 Player* caster = Object::ToPlayer(GetCaster());
4254 if (!caster)
4255 return;
4256
4257 if (AuraEffect const* sanctuaryEffect = caster->GetAuraEffect(SPELL_PRIEST_SANCTUARY, EFFECT_0))
4258 {
4259 if (Unit* target = GetHitUnit())
4260 {
4261 SpellEffectValue absorbAmount = CalculatePct(caster->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_SHADOW), sanctuaryEffect->GetAmount());
4263
4266 .SetTriggeringSpell(GetSpell()));
4267
4269 .AddSpellMod(SPELLVALUE_BASE_POINT0, absorbAmount)
4271 .SetTriggeringSpell(GetSpell()));
4272 }
4273 }
4274 }
4275
4280};
4281
4282// 280391 - Sins of the Many
4306
4307// 20711 - Spirit of Redemption
4309{
4310 bool Validate(SpellInfo const* /*spellInfo*/) override
4311 {
4313 }
4314
4315 void HandleAbsorb(AuraEffect const* aurEff, DamageInfo const& /*dmgInfo*/, uint32 const& /*absorbAmount*/) const
4316 {
4317 Unit* target = GetTarget();
4318 target->CastSpell(target, SPELL_PRIEST_SPIRIT_OF_REDEMPTION, aurEff);
4319 target->SetFullHealth();
4320 }
4321
4326};
4327
4328// 34433 - Shadowfiend
4329// 123040 - Mindbender (Discipline)
4330// 451235 - Voidwrath
4356
4357// 186263 - Shadow Mend
4359{
4371
4372 void HandleEffectHit() const
4373 {
4374 if (Unit* target = GetHitUnit())
4375 {
4376 Unit* caster = GetCaster();
4377
4378 int32 periodicAmount = GetHitHeal() / 20;
4379 int32 damageForAuraRemoveAmount = periodicAmount * 10;
4380
4381 // Handle Masochism talent
4382 if (caster->HasAura(SPELL_PRIEST_MASOCHISM_TALENT) && caster->GetGUID() == target->GetGUID())
4384 else if (target->IsInCombat() && periodicAmount)
4385 {
4388 args.AddSpellMod(SPELLVALUE_BASE_POINT0, periodicAmount);
4389 args.AddSpellMod(SPELLVALUE_BASE_POINT1, damageForAuraRemoveAmount);
4391 }
4392 }
4393 }
4394
4399};
4400
4401// 187464 - Shadow Mend (Damage)
4403{
4404 bool Validate(SpellInfo const* /*spellInfo*/) override
4405 {
4407 }
4408
4417
4418 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
4419 {
4420 return eventInfo.GetDamageInfo() != nullptr;
4421 }
4422
4423 void HandleProc(AuraEffect* aurEff, ProcEventInfo const& eventInfo)
4424 {
4425 SpellEffectValue newAmount = aurEff->GetAmount() - eventInfo.GetDamageInfo()->GetDamage();
4426
4427 aurEff->ChangeAmount(newAmount);
4428 if (newAmount < 0)
4429 Remove();
4430 }
4431
4438};
4439
4440// 32379 - Shadow Word: Death
4442{
4443 static constexpr Seconds BACKLASH_DELAY = 1s;
4444
4445 bool Validate(SpellInfo const* spellInfo) override
4446 {
4448 && ValidateSpellEffect({ { spellInfo->Id, EFFECT_5 } })
4452 }
4453
4454 void HandleDamageCalculation(SpellEffectInfo const& /*spellEffectInfo*/, Unit const* victim, int32 const& /*damage*/, int32 const& /*flatMod*/, float& pctMod) const
4455 {
4456 if (victim->HealthBelowPct(GetEffectInfo(EFFECT_2).CalcValue(GetCaster())))
4457 AddPct(pctMod, GetEffectInfo(EFFECT_3).CalcValue(GetCaster()));
4458
4459 // handles Death's Torment talent
4460 if (spell_pri_deaths_torment::Data const* deathsTorment = std::any_cast<spell_pri_deaths_torment::Data>(&GetSpell()->m_customArg))
4461 ApplyPct(pctMod, deathsTorment->DamagePct);
4462 }
4463
4464 void DetermineKillStatus(DamageInfo const& damageInfo, uint32& /*resistAmount*/, int32& /*absorbAmount*/) const
4465 {
4466 bool killed = damageInfo.GetDamage() >= damageInfo.GetVictim()->GetHealth();
4467 if (!killed)
4468 {
4469 Unit* caster = GetCaster();
4470 int32 backlashDamage = caster->CountPctFromMaxHealth(GetEffectInfo(EFFECT_5).CalcValue(caster));
4471
4472 // Death's Torment effectiveness on backlash too
4473 if (spell_pri_deaths_torment::Data const* deathsTorment = std::any_cast<spell_pri_deaths_torment::Data>(&GetSpell()->m_customArg))
4474 backlashDamage = CalculatePct(backlashDamage, deathsTorment->BacklashPct);
4475
4476 if (AuraEffect const* titheEvasion = caster->GetAuraEffect(SPELL_PRIEST_TITHE_EVASION, EFFECT_0))
4477 AddPct(backlashDamage, -titheEvasion->GetAmount());
4478
4479 caster->m_Events.AddEventAtOffset([caster, originalCastId = GetSpell()->m_castId, backlashDamage]
4480 {
4483 .SetOriginalCastId(originalCastId)
4484 .AddSpellMod(SPELLVALUE_BASE_POINT0, backlashDamage));
4485
4486 }, BACKLASH_DELAY);
4487 }
4488 }
4489
4491 {
4492 if (spell_pri_deaths_torment::Data const* deathsTorment = std::any_cast<spell_pri_deaths_torment::Data>(&GetSpell()->m_customArg))
4493 SetEffectValue(CalculatePct(GetEffectValue(), deathsTorment->EnergizePct));
4494 }
4495
4496 void Register() override
4497 {
4499
4500 // abuse OnCalculateResistAbsorb to determine if this spell will kill target or not (its still not perfect - happens before absorbs are applied)
4502
4504 }
4505};
4506
4507// 341491 - Shadowy Apparitions
4509{
4510 bool Validate(SpellInfo const* /*spellInfo*/) override
4511 {
4513 }
4514
4515 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
4516 {
4517 // PROC_FLAG_DEAL_HARMFUL_PERIODIC is set on the spell for Tormented Spirits talent
4518 // Devouring Plague cannot proc this on periodic ticks
4519 return !(eventInfo.GetTypeMask() & PROC_FLAG_DEAL_HARMFUL_PERIODIC)
4520 && !eventInfo.GetSpellInfo()->IsAffected(SPELLFAMILY_PRIEST, { 0x8000, 0x0, 0x0, 0x0 });
4521 }
4522
4523public:
4524 static void HandleProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
4525 {
4526 Unit* caster = eventInfo.GetActor();
4529 .TriggeringAura = aurEff
4530 });
4531 }
4532
4538};
4539
4540// 341263 - Shadowy Apparition (Dummy)
4542{
4543 static constexpr uint32 GetSpellVisual(Races race, Gender gender)
4544 {
4545 switch (race)
4546 {
4547 case RACE_HUMAN:
4548 case RACE_KUL_TIRAN:
4551 default:
4553 case RACE_ORC:
4554 case RACE_MAGHAR_ORC:
4556 case RACE_DWARF:
4561 case RACE_NIGHTELF:
4563 case RACE_UNDEAD_PLAYER:
4565 case RACE_TAUREN:
4568 case RACE_GNOME:
4569 case RACE_MECHAGNOME:
4571 case RACE_TROLL:
4574 case RACE_GOBLIN:
4575 case RACE_VULPERA:
4577 case RACE_BLOODELF:
4578 case RACE_NIGHTBORNE:
4579 case RACE_VOID_ELF:
4581 case RACE_DRAENEI:
4584 case RACE_WORGEN:
4591 case RACE_HARANIR_HORDE:
4592 return SPELL_VISUAL_PRIEST_SHADOWY_APPARITION_HUMAN_MALE; // not handled on retail as of patch 12.0.1, uses human male fallback
4593 }
4594 }
4595
4596 bool Validate(SpellInfo const* /*spellInfo*/) override
4597 {
4599 }
4600
4601 void FilterTargets(std::list<WorldObject*>& targets) const
4602 {
4603 targets.remove_if(Trinity::UnitAuraCheck(false, SPELL_PRIEST_VAMPIRIC_TOUCH, GetCaster()->GetGUID()));
4604 }
4605
4606 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
4607 {
4608 Unit* caster = GetCaster();
4609 Unit* target = GetHitUnit();
4610
4611 caster->SendPlaySpellVisual(target, GetSpellVisual(static_cast<Races>(caster->GetRace()), caster->GetGender()), 0, 0, 6.0f);
4614 .TriggeringSpell = GetSpell()
4615 });
4616 }
4617
4623};
4624
4625// 109186 - Surge of Light
4627{
4628 bool Validate(SpellInfo const* /*spellInfo*/) override
4629 {
4630 return ValidateSpellInfo
4631 ({
4634 });
4635 }
4636
4637 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
4638 {
4639 if (eventInfo.GetSpellInfo()->Id == SPELL_PRIEST_SMITE)
4640 return true;
4641
4643 return eventInfo.GetHealInfo();
4644
4645 return false;
4646 }
4647
4648 void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/) const
4649 {
4650 if (roll_chance(aurEff->GetAmount()))
4652 }
4653
4659};
4660
4661// 28809 - Greater Heal
4663{
4664 bool Validate(SpellInfo const* /*spellInfo*/) override
4665 {
4667 }
4668
4669 void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
4670 {
4672 eventInfo.GetActor()->CastSpell(eventInfo.GetProcTarget(), SPELL_PRIEST_ARMOR_OF_FAITH, aurEff);
4673 }
4674
4679};
4680
4681// 37594 - Greater Heal Refund
4683{
4684 bool Validate(SpellInfo const* /*spellInfo*/) override
4685 {
4687 }
4688
4689 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
4690 {
4691 if (HealInfo* healInfo = eventInfo.GetHealInfo())
4692 if (Unit* healTarget = healInfo->GetTarget())
4693 if (healInfo->GetEffectiveHeal())
4694 if (healTarget->GetHealth() >= healTarget->GetMaxHealth())
4695 return true;
4696
4697 return false;
4698 }
4699
4700 void HandleProc(AuraEffect const* aurEff, ProcEventInfo& /*eventInfo*/)
4701 {
4704 }
4705
4711};
4712
4713// 70770 - Item - Priest T10 Healer 2P Bonus
4715{
4716 bool Validate(SpellInfo const* /*spellInfo*/) override
4717 {
4719 && sSpellMgr->AssertSpellInfo(SPELL_PRIEST_BLESSED_HEALING, DIFFICULTY_NONE)->GetEffect(EFFECT_0).GetPeriodicTickCount() > 0;
4720 }
4721
4722 void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
4723 {
4725
4726 HealInfo* healInfo = eventInfo.GetHealInfo();
4727 if (!healInfo || !healInfo->GetHeal())
4728 return;
4729
4730 SpellEffectInfo const& hotEffect = sSpellMgr->AssertSpellInfo(SPELL_PRIEST_BLESSED_HEALING, GetCastDifficulty())->GetEffect(EFFECT_0);
4731 SpellEffectValue amount = CalculatePct(static_cast<int32>(healInfo->GetHeal()), aurEff->GetAmount());
4732
4733 amount /= hotEffect.GetPeriodicTickCount();
4734
4735 Unit* caster = eventInfo.GetActor();
4736 Unit* target = eventInfo.GetProcTarget();
4737
4738 CastSpellExtraArgs args(aurEff);
4739 args.AddSpellBP0(amount);
4740 caster->CastSpell(target, SPELL_PRIEST_BLESSED_HEALING, args);
4741 }
4742
4747};
4748
4749// 200128 - Trail of Light
4751{
4752 bool Validate(SpellInfo const* /*spellInfo*/) override
4753 {
4755 }
4756
4757 bool CheckProc(ProcEventInfo const& eventInfo)
4758 {
4759 if (_healQueue.empty() || _healQueue.back() != eventInfo.GetActionTarget()->GetGUID())
4760 _healQueue.push(eventInfo.GetActionTarget()->GetGUID());
4761
4762 if (_healQueue.size() > 2)
4763 _healQueue.pop();
4764
4765 if (_healQueue.size() == 2)
4766 return true;
4767
4768 return false;
4769 }
4770
4771 void HandleOnProc(AuraEffect* aurEff, ProcEventInfo const& eventInfo) const
4772 {
4773 Unit* caster = GetTarget();
4774 Unit* oldTarget = ObjectAccessor::GetUnit(*caster, _healQueue.front());
4775 if (!oldTarget)
4776 return;
4777
4778 // Note: old target may not be friendly anymore due to charm and faction change effects.
4779 if (!caster->IsValidAssistTarget(oldTarget))
4780 return;
4781
4782 SpellInfo const* healSpellInfo = sSpellMgr->GetSpellInfo(SPELL_PRIEST_TRAIL_OF_LIGHT_HEAL, DIFFICULTY_NONE);
4783 if (!healSpellInfo)
4784 return;
4785
4786 // Note: distance may be greater than the heal's spell range.
4787 if (!caster->IsWithinDist(oldTarget, healSpellInfo->GetMaxRange(true, caster)))
4788 return;
4789
4790 SpellEffectValue healAmount = CalculatePct(eventInfo.GetHealInfo()->GetHeal(), aurEff->GetAmount());
4791
4792 caster->CastSpell(oldTarget, SPELL_PRIEST_TRAIL_OF_LIGHT_HEAL, CastSpellExtraArgs(aurEff).AddSpellBP0(healAmount));
4793 }
4794
4800
4801private:
4802 std::queue<ObjectGuid> _healQueue;
4803};
4804
4805// 390693 - Train of Thought
4806// Called by Flash Heal, Renew, Smite
4808{
4809 bool Validate(SpellInfo const* /*spellInfo*/) override
4810 {
4811 return ValidateSpellInfo
4812 ({
4815 });
4816 }
4817
4818 static bool CheckEffect0(AuraScript const&, AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo)
4819 {
4820 // Renew & Flash Heal
4821 return eventInfo.GetSpellInfo()->IsAffected(SPELLFAMILY_PRIEST, { 0x840 });
4822 }
4823
4824 static bool CheckEffect1(AuraScript const&, AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo)
4825 {
4826 // Smite
4827 return eventInfo.GetSpellInfo()->IsAffected(SPELLFAMILY_PRIEST, { 0x80 });
4828 }
4829
4834
4835 void ReducePenanceCooldown(AuraEffect const* aurEff, ProcEventInfo const& /*eventInfo*/) const
4836 {
4838 }
4839
4847};
4848
4849// 373446 - Translucent Image
4850// Triggered by 586 - Fade
4852{
4853 bool Load() override
4854 {
4856 }
4857
4858 static void PreventEffect(SpellScript const&, WorldObject*& target)
4859 {
4860 target = nullptr;
4861 }
4862
4867};
4868
4869// 390705 - Twilight Equilibrium
4871{
4876
4877 void HandleProc(ProcEventInfo const& eventInfo) const
4878 {
4879 uint32 spellId = 0;
4880
4883 else if (eventInfo.GetDamageInfo()->GetSchoolMask() & SPELL_SCHOOL_MASK_HOLY)
4885 else
4886 return;
4887
4888 Unit* caster = GetTarget();
4890 }
4891
4896};
4897
4898// ID - 390707 Twilight Equilibrium (attached to 589 - Shadow Word: Pain)
4900{
4901 bool Validate(SpellInfo const* /*spellInfo*/) override
4902 {
4904 }
4905
4906 void OnApply(AuraEffect const* /*aurEff*/, SpellEffectValue& /*amount*/, bool& /*canBeRecalculated*/)
4907 {
4908 _damageMultiplier = 1.0f;
4909 if (Unit* caster = GetCaster())
4910 {
4911 if (AuraEffect* twilightEquilibrium = caster->GetAuraEffect(SPELL_PRIEST_TWILIGHT_EQUILIBRIUM_SHADOW, EFFECT_0))
4912 {
4913 // snapshot Twilight Equilibrium value
4914 AddPct(_damageMultiplier, twilightEquilibrium->GetAmount());
4915 twilightEquilibrium->GetBase()->Remove();
4916 }
4917 }
4918 }
4919
4920 void CalcDamage(AuraEffect const* /*aurEff*/, Unit* /*victim*/, int32& /*damageOrHealing*/, int32& /*flatMod*/, float& pctMod) const
4921 {
4922 pctMod *= _damageMultiplier;
4923 }
4924
4930
4931 float _damageMultiplier = 1.0f;
4932};
4933
4934// 109142 - Twist of Fate (Shadow)
4935// 265259 - Twist of Fate (Discipline)
4937{
4938 static bool CheckProc(AuraScript const&, AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
4939 {
4940 return eventInfo.GetProcTarget()->GetHealthPct() < aurEff->GetAmount();
4941 }
4942
4947};
4948
4949// 421453 - Ultimate Penitence
4951{
4956
4957 void TriggerImmunity() const
4958 {
4959 Unit* caster = GetCaster();
4961 {
4963 .TriggeringSpell = GetSpell()
4964 });
4965
4966 SpellEffectValue preferHealing = 1;
4967 if (Unit const* target = GetExplTargetUnit(); target && !GetCaster()->IsFriendlyTo(target))
4968 preferHealing = 0;
4969
4970 caster->m_Events.AddEventAtOffset([caster, originalCastId = GetSpell()->m_originalCastId, preferHealing]
4971 {
4973 {
4975 .OriginalCastId = originalCastId,
4976 .SpellValueOverrides = { { SPELLVALUE_BASE_POINT1, preferHealing } }
4977 });
4978 }, 250ms);
4979 }
4980
4985};
4986
4987// 421453 - Ultimate Penitence (Aura)
4989{
4990 void CalculateAmount(AuraEffect const* /*aurEff*/, SpellEffectValue& amount, bool& canBeRecalculated) const
4991 {
4992 canBeRecalculated = false;
4993 Unit* caster = GetCaster();
4994 if (!caster)
4995 return;
4996
4997 amount = caster->CountPctFromMaxHealth(GetEffectInfo(EFFECT_0).CalcValue(caster));
4998 }
4999
5004};
5005
5006// 421434 - Ultimate Penitence (Channel)
5008{
5020
5021 void HandlePeriodic(AuraEffect const* aurEff) const
5022 {
5023 if (aurEff->GetAmountAsInt() == 1) // set by spell_pri_ultimate_penitence
5024 (void)(TryHealing() || TryDealingDamage());
5025 else
5026 (void)(TryDealingDamage() || TryHealing());
5027 }
5028
5038
5039 bool TryHealing() const
5040 {
5042 Trinity::Containers::EraseIf(allies, [](WorldObject const* ally) { return !ally->IsUnit() || ally->ToUnit()->IsFullHealth(); });
5043 if (allies.empty())
5044 return false;
5045
5046 Unit* caster = GetTarget();
5047
5049
5051 return true;
5052 }
5053
5054 std::list<WorldObject*> SearchTargetCandidates(uint32 spellId, SpellTargetCheckTypes checkType) const
5055 {
5056 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(spellId, GetCastDifficulty());
5057 SpellEffectInfo const& spellEffect = spellInfo->GetEffect(EFFECT_0);
5058
5059 std::list<WorldObject*> targets;
5060 if (uint32 containerTypeMask = Spell::GetSearcherTypeMask(spellInfo, spellEffect, TARGET_OBJECT_TYPE_UNIT, spellEffect.ImplicitTargetConditions.get()))
5061 {
5062 Unit* caster = GetTarget();
5063
5064 SpellRange range = spellInfo->GetMinMaxRange(true, caster);
5065
5066 Trinity::WorldObjectSpellAreaTargetCheck check(range, caster, caster, caster, spellInfo, checkType, spellEffect.ImplicitTargetConditions.get(), TARGET_OBJECT_TYPE_UNIT);
5067 Trinity::WorldObjectListSearcher searcher(caster->GetPhaseShift(), targets, check, containerTypeMask);
5068 Spell::SearchTargets(searcher, containerTypeMask, caster, caster, range.Max + EXTRA_CELL_SEARCH_RADIUS);
5069 }
5070
5071 return targets;
5072 }
5073
5082
5083 static std::array<Trinity::TargetPriorityRule, 2> GetHealingRules(Unit const* caster)
5084 {
5085 return
5086 {
5087 [](WorldObject const* target) { return target->IsPlayer() || (target->IsCreature() && target->ToCreature()->IsTreatedAsRaidUnit()); },
5088 [caster](Unit const* target) { return !caster->IsPlayer() || !caster->ToPlayer()->GetGroup() || target->IsInRaidWith(caster); }
5089 };
5090 }
5091
5097};
5098
5099// 432154 - Ultimate Penitence (Jump)
5101{
5102 static constexpr Position JumpOffset = { 0.0f, 0.0f, 5.0f };
5103
5104 static void SetDestTarget(SpellScript const&, SpellDestination& dest)
5105 {
5107 }
5108
5113};
5114
5115// 341273 - Unfurling Darkness
5116// Triggered by 34914 - Vampiric Touch
5118{
5124
5126 {
5127 bool canTriggerDirectDamage = [&]
5128 {
5129 if (!GetSpell()->m_originalCastId.IsEmpty())
5130 return false; // not when triggered by Shadow Crash (Whispering Shadows talent)
5131 if (AuraEffect const* unfurlingDarkness = GetCaster()->GetAuraEffect(SPELL_PRIEST_UNFURLING_DARKNESS_AURA, EFFECT_0))
5132 if (GetSpell()->m_appliedMods.contains(unfurlingDarkness->GetBase()))
5133 return true;
5134 return false;
5135 }();
5136
5137 if (!canTriggerDirectDamage)
5138 target = nullptr;
5139 }
5140
5142 {
5143 if (!GetSpell()->m_originalCastId.IsEmpty())
5144 return; // not when triggered by Shadow Crash (Whispering Shadows talent)
5145
5146 Unit* caster = GetCaster();
5147
5148 if (AuraEffect const* unfurlingDarkness = GetCaster()->GetAuraEffect(SPELL_PRIEST_UNFURLING_DARKNESS_AURA, EFFECT_0))
5149 {
5150 if (GetSpell()->m_appliedMods.contains(unfurlingDarkness->GetBase()))
5151 {
5152 unfurlingDarkness->GetBase()->Remove();
5153 return;
5154 }
5155 }
5156
5158 caster->CastSpell(caster, SPELL_PRIEST_UNFURLING_DARKNESS_AURA, true);
5159 }
5160
5166};
5167
5168// 15286 - Vampiric Embrace
5170{
5171 bool Validate(SpellInfo const* /*spellInfo*/) override
5172 {
5174 }
5175
5176 static bool CheckProc(AuraScript const&, ProcEventInfo const& eventInfo)
5177 {
5178 // Not proc from Mind Sear
5179 return !(eventInfo.GetDamageInfo()->GetSpellInfo()->SpellFamilyFlags[1] & 0x80000);
5180 }
5181
5182 void HandleEffectProc(AuraEffect const* aurEff, ProcEventInfo const& eventInfo)
5183 {
5185 DamageInfo* damageInfo = eventInfo.GetDamageInfo();
5186 if (!damageInfo || !damageInfo->GetDamage())
5187 return;
5188
5189 SpellEffectValue selfHeal = CalculatePct(damageInfo->GetDamage(), aurEff->GetAmount());
5190 SpellEffectValue teamHeal = selfHeal / 2;
5191
5192 CastSpellExtraArgs args(aurEff);
5193 args.AddSpellMod(SPELLVALUE_BASE_POINT0, teamHeal);
5194 args.AddSpellMod(SPELLVALUE_BASE_POINT1, selfHeal);
5196 }
5197
5203};
5204
5205// 15290 - Vampiric Embrace (heal)
5207{
5208 void FilterTargets(std::list<WorldObject*>& unitList) const
5209 {
5210 unitList.remove(GetCaster());
5211 }
5212
5217};
5218
5219// 34914 - Vampiric Touch
5221{
5222 bool Validate(SpellInfo const* /*spellInfo*/) override
5223 {
5225 }
5226
5227 void HandleDispel(DispelInfo const* dispelInfo) const
5228 {
5229 if (Unit* caster = GetCaster())
5230 caster->CastSpell(dispelInfo->GetDispeller(), SPELL_PRIEST_SIN_AND_PUNISHMENT, true);
5231 }
5232
5233 void HandleApplyEffect(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) const
5234 {
5235 if (Unit* caster = GetCaster())
5236 if (caster->HasAura(SPELL_PRIEST_MISERY))
5237 caster->CastSpell(GetTarget(), SPELL_PRIEST_SHADOW_WORD_PAIN, true);
5238 }
5239
5245};
5246
5247// 390994 - Voice of Harmony
5249{
5250 bool Validate(SpellInfo const* /*spellInfo*/) override
5251 {
5252 return ValidateSpellInfo
5253 ({
5257 });
5258 }
5259
5260 static bool CheckHolyWordSanctify(AuraScript const&, AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo)
5261 {
5262 // Divine Star
5263 // Halo
5264 return eventInfo.GetSpellInfo()->IsAffected(SPELLFAMILY_PRIEST, { 0x0, 0x0, 0x0, 0x4040 });
5265 }
5266
5267 static bool CheckHolyWordSerenity(AuraScript const&, AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo)
5268 {
5269 // Power Word: Life
5270 // Prayer of Mending
5271 return eventInfo.GetSpellInfo()->IsAffected(SPELLFAMILY_PRIEST, { 0x0, 0x0, 0x8000, 0x400000 });
5272 }
5273
5274 static bool CheckHolyWordChastise(AuraScript const&, AuraEffect const* /*aurEff*/, ProcEventInfo const& eventInfo)
5275 {
5276 // Holy Fire
5277 return eventInfo.GetSpellInfo()->IsAffected(SPELLFAMILY_PRIEST, { 0x100000, 0x0, 0x0, 0x0 });
5278 }
5279
5280 template <uint32 TargetSpellId>
5281 void HandleProc(AuraEffect const* aurEff, ProcEventInfo const& /*eventInfo*/) const
5282 {
5283 SpellInfo const* targetSpellInfo = sSpellMgr->AssertSpellInfo(TargetSpellId, GetCastDifficulty());
5284 Milliseconds cdReduction = -duration_cast<Milliseconds>(FloatSeconds(aurEff->GetAmount()));
5285 spell_pri_holy_words_base::ModifyCooldown(GetTarget(), targetSpellInfo, cdReduction);
5286 }
5287
5288 void Register() override
5289 {
5293 OnEffectProc += AuraEffectProcFn(spell_pri_voice_of_harmony::HandleProc<SPELL_PRIEST_HOLY_WORD_SANCTIFY>, EFFECT_0, SPELL_AURA_DUMMY);
5294 OnEffectProc += AuraEffectProcFn(spell_pri_voice_of_harmony::HandleProc<SPELL_PRIEST_HOLY_WORD_SERENITY>, EFFECT_1, SPELL_AURA_DUMMY);
5295 OnEffectProc += AuraEffectProcFn(spell_pri_voice_of_harmony::HandleProc<SPELL_PRIEST_HOLY_WORD_CHASTISE>, EFFECT_2, SPELL_AURA_DUMMY);
5296 }
5297};
5298
5299// 1242173 - Void Volley
5301{
5302 class BoltEvent : public BasicEvent
5303 {
5304 public:
5305 static constexpr Milliseconds Period = 75ms;
5306
5307 explicit BoltEvent(Unit* caster, ObjectGuid target, ObjectGuid originalCastId, int32 count) :
5308 _caster(caster), _target(target), _originalCastId(originalCastId), _count(count) { }
5309
5310 bool Execute(uint64 time, uint32) override
5311 {
5313 if (!target)
5314 return true;
5315
5318 .OriginalCastId = _originalCastId
5319 });
5320
5321 if (--_count)
5322 {
5324 return false;
5325 }
5326 return true;
5327 }
5328
5329 private:
5334 };
5335
5336 bool Validate(SpellInfo const* spellInfo) override
5337 {
5339 && ValidateSpellEffect({ { spellInfo->Id, EFFECT_2 } });
5340 }
5341
5342 void HandleEffectHit(SpellEffIndex /*effIndex*/) const
5343 {
5344 Unit* caster = GetCaster();
5345 Unit* target = GetHitUnit();
5346
5349 .TriggeringSpell = GetSpell()
5350 });
5351
5353 if (bolts > 1)
5354 caster->m_Events.AddEventAtOffset(new BoltEvent(caster, target->GetGUID(), GetSpell()->m_originalCastId, bolts - 1), BoltEvent::Period);
5355 }
5356
5361};
5362
5363// 205385 - Shadow Crash
5382
5383// 391286 - Whispering Shadows (Dot Application)
5385{
5386 bool Validate(SpellInfo const* /*spellInfo*/) override
5387 {
5389 }
5390
5391 void FilterTargets(std::list<WorldObject*>& targets) const
5392 {
5393 if (targets.size() <= GetSpellValue()->MaxAffectedTargets)
5394 return;
5395
5396 auto getVampiricTouch = [&](WorldObject const* target)
5397 {
5398 return target->ToUnit()->GetAura(SPELL_PRIEST_VAMPIRIC_TOUCH, GetCaster()->GetGUID());
5399 };
5400
5401 // prioritize targets without Vampiric Touch
5402 targets.sort([&](WorldObject const* target1, WorldObject const* target2)
5403 {
5404 int32 duration1 = 0;
5405 if (Aura const* aura1 = getVampiricTouch(target1))
5406 duration1 = aura1->GetDuration();
5407 int32 duration2 = 0;
5408 if (Aura const* aura2 = getVampiricTouch(target2))
5409 duration2 = aura2->GetDuration();
5410 return duration1 < duration2;
5411 });
5412
5413 // remove targets that definitely will not get Vampiric Touch applied (excess targets with longest remaining duration)
5414 while (targets.size() > GetSpellValue()->MaxAffectedTargets && getVampiricTouch(targets.back()) != nullptr)
5415 targets.pop_back();
5416
5417 Trinity::Containers::RandomResize(targets, GetSpellValue()->MaxAffectedTargets);
5418 }
5419
5426
5432};
5433
5435{
5502 RegisterSpellScriptWithArgs(spell_pri_lasting_words, "spell_pri_lasting_words_serenity", EFFECT_0);
5503 RegisterSpellScriptWithArgs(spell_pri_lasting_words, "spell_pri_lasting_words_sanctify", EFFECT_1);
5576}
AreaTriggerExitReason
Definition AreaTrigger.h:69
@ IN_MILLISECONDS
Definition Common.h:38
@ DIFFICULTY_NONE
Definition DBCEnums.h:933
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:187
#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:27
@ RACE_DARK_IRON_DWARF
Definition RaceMask.h:62
@ RACE_TROLL
Definition RaceMask.h:36
@ RACE_UNDEAD_PLAYER
Definition RaceMask.h:33
@ RACE_PANDAREN_NEUTRAL
Definition RaceMask.h:52
@ RACE_ORC
Definition RaceMask.h:30
@ RACE_LIGHTFORGED_DRAENEI
Definition RaceMask.h:58
@ RACE_DRAENEI
Definition RaceMask.h:39
@ RACE_EARTHEN_DWARF_HORDE
Definition RaceMask.h:78
@ RACE_NIGHTBORNE
Definition RaceMask.h:55
@ RACE_HIGHMOUNTAIN_TAUREN
Definition RaceMask.h:56
@ RACE_HARANIR_HORDE
Definition RaceMask.h:83
@ RACE_EARTHEN_DWARF_ALLIANCE
Definition RaceMask.h:79
@ RACE_DRACTHYR_HORDE
Definition RaceMask.h:67
@ RACE_ZANDALARI_TROLL
Definition RaceMask.h:59
@ RACE_VOID_ELF
Definition RaceMask.h:57
@ RACE_NIGHTELF
Definition RaceMask.h:32
@ RACE_BLOODELF
Definition RaceMask.h:38
@ RACE_DWARF
Definition RaceMask.h:31
@ RACE_GNOME
Definition RaceMask.h:35
@ RACE_GOBLIN
Definition RaceMask.h:37
@ RACE_KUL_TIRAN
Definition RaceMask.h:60
@ RACE_HUMAN
Definition RaceMask.h:29
@ RACE_DRACTHYR_ALLIANCE
Definition RaceMask.h:66
@ RACE_WORGEN
Definition RaceMask.h:50
@ RACE_PANDAREN_ALLIANCE
Definition RaceMask.h:53
@ RACE_VULPERA
Definition RaceMask.h:63
@ RACE_MECHAGNOME
Definition RaceMask.h:65
@ RACE_HARANIR_ALLIANCE
Definition RaceMask.h:80
@ RACE_MAGHAR_ORC
Definition RaceMask.h:64
@ RACE_PANDAREN_HORDE
Definition RaceMask.h:54
@ RACE_TAUREN
Definition RaceMask.h:34
bool roll_chance(T chance)
Definition Random.h:55
#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
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
@ 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
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:345
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:447
Unit * GetAttacker() const
Definition Unit.h:446
SpellInfo const * GetSpellInfo() const
Definition Unit.h:448
SpellSchoolMask GetSchoolMask() const
Definition Unit.h:449
uint32 GetDamage() const
Definition Unit.h:452
WorldObject * GetDispeller() const
Definition Unit.h:396
void AddEvent(BasicEvent *event, Milliseconds e_time, bool set_addtime=true)
void AddEventAtOffset(BasicEvent *event, Milliseconds offset)
uint32 GetHeal() const
Definition Unit.h:482
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:2008
float GetRatingBonusValue(CombatRating cr) const
Definition Player.cpp:5240
Group * GetGroup(Optional< uint8 > partyIndex)
Definition Player.h:2796
HealInfo * GetHealInfo() const
Definition Unit.h:512
Unit * GetActionTarget() const
Definition Unit.h:500
ProcFlagsSpellType GetSpellTypeMask() const
Definition Unit.h:504
Spell const * GetProcSpell() const
Definition Unit.h:514
SpellInfo const * GetSpellInfo() const
Definition Unit.cpp:281
ProcFlagsInit GetTypeMask() const
Definition Unit.h:503
DamageInfo * GetDamageInfo() const
Definition Unit.h:511
Unit * GetProcTarget() const
Definition Unit.h:501
Unit * GetActor() const
Definition Unit.h:499
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:588
std::vector< SpellEffectInfo > const & GetEffects() const
Definition SpellInfo.h:587
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:8790
static uint32 GetSearcherTypeMask(SpellInfo const *spellInfo, SpellEffectInfo const &spellEffectInfo, SpellTargetObjectTypes objType, ConditionContainer const *condList)
Definition Spell.cpp:2113
static void SearchTargets(SEARCHER &searcher, uint32 containerMask, WorldObject *referer, Position const *pos, float radius)
Definition Spell.cpp:2151
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:635
float GetHealthPct() const
Definition Unit.h:796
uint64 CountPctFromMaxHealth(float pct) const
Definition Unit.h:797
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3828
void SetFullHealth()
Definition Unit.h:802
void SendPlaySpellVisual(Unit *target, uint32 spellVisualId, uint8 missReason, uint8 reflectStatus, float travelSpeed, bool speedAsTime=false, float launchDelay=0.0f)
Definition Unit.cpp:12305
Aura * GetOwnedAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, Aura *except=nullptr) const
Definition Unit.cpp:3812
Powers GetPowerType() const
Definition Unit.h:811
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid casterGUID=ObjectGuid::Empty) const
Definition Unit.cpp:4604
bool IsFullHealth() const
Definition Unit.h:791
TempSummon * ToTempSummon()
Definition Unit.h:1828
ControlList m_Controlled
Definition Unit.h:1232
bool IsInCombatWith(Unit const *who) const
Definition Unit.h:1059
float SpellCritChanceDone(Spell *spell, AuraEffect const *aurEff, SpellSchoolMask schoolMask, WeaponAttackType attackType=BASE_ATTACK) const
Definition Unit.cpp:7121
virtual bool HasSpell(uint32) const
Definition Unit.h:1084
Gender GetGender() const
Definition Unit.h:767
float SpellCritChanceTaken(Unit const *caster, Spell *spell, AuraEffect const *aurEff, SpellSchoolMask schoolMask, float doneChance, WeaponAttackType attackType=BASE_ATTACK) const
Definition Unit.cpp:7175
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster=ObjectGuid::Empty) const
Definition Unit.cpp:4774
Aura * GetAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4700
uint64 GetHealth() const
Definition Unit.h:788
bool HealthBelowPctDamaged(float pct, uint32 damage) const
Definition Unit.h:793
bool HealthBelowPct(float pct) const
Definition Unit.h:792
void NearTeleportTo(TeleportLocation const &target, bool casting=false)
Definition Unit.cpp:12958
bool IsInRaidWith(Unit const *unit) const
Definition Unit.cpp:12177
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition Unit.cpp:4804
SpellHistory * GetSpellHistory()
Definition Unit.h:1498
bool HasBreakableByDamageCrowdControlAura(Unit const *excludeCasterChannel=nullptr) const
Definition Unit.cpp:778
void RemoveMovementImpairingAuras(bool withRoot)
Definition Unit.cpp:4294
std::vector< AreaTrigger * > GetAreaTriggers(uint32 spellId) const
Definition Unit.cpp:5475
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const
Definition Unit.cpp:7084
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Definition Unit.cpp:3974
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:7328
ObjectGuid GetTarget() const
Definition Unit.h:1831
uint8 GetRace() const
Definition Unit.h:761
AreaTrigger * GetAreaTrigger(uint32 spellId) const
Definition Unit.cpp:5469
SpellCastResult CastSpell(CastSpellTargetArg const &targets, uint32 spellId, CastSpellExtraArgs const &args={ })
Definition Object.cpp:2217
bool IsValidAttackTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2324
PhaseShift & GetPhaseShift()
Definition Object.h:310
Unit * GetOwner() const
Definition Object.cpp:1598
bool isInFront(WorldObject const *target, float arc=float(M_PI)) const
Definition Object.cpp:670
Position GetRandomNearPosition(float radius)
Definition Object.cpp:2769
bool IsValidAssistTarget(WorldObject const *target, SpellInfo const *bySpell=nullptr) const
Definition Object.cpp:2482
EventProcessor m_Events
Definition Object.h:561
void MovePositionToFirstCollision(Position &pos, float dist, float angle) const
Definition Object.cpp:2828
float GetDistance(WorldObject const *obj) const
Definition Object.cpp:432
bool IsWithinDist(WorldObject const *obj, float dist2compare, bool is3D=true, bool incOwnRadius=true, bool incTargetRadius=true) const
Definition Object.cpp:496
bool IsFriendlyTo(WorldObject const *target) const
Definition Object.cpp:2186
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
void HandleProc(AuraEffect const *aurEff, ProcEventInfo const &eventInfo)
bool Validate(SpellInfo const *) override
void Register() override
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
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
bool CheckEffectProc(AuraEffect const *, ProcEventInfo const &eventInfo) const
void HandleEffectProc(AuraEffect const *aurEff, ProcEventInfo &) const
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 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:9577
void SortTargetsWithPriorityRules(std::list< WorldObject * > &targets, size_t maxTargets, std::span< TargetPriorityRule const > rules)
Definition Spell.cpp:9642
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_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_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:9707
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)