From e75b5f9c6b8b4dcaadcbe4bd3e84f7692d7f0d7d Mon Sep 17 00:00:00 2001 From: hondacrx Date: Tue, 20 Apr 2021 13:13:49 -0400 Subject: [PATCH] Core/Spells: Implement priest holy words + modify cooldown for a charge Port From (https://github.com/TrinityCore/TrinityCore/commit/81eac826562f8e75de1842c59c8d35cf050b0f21) --- Source/Game/Spells/SpellHistory.cs | 79 ++++++++++++++----- Source/Scripts/Spells/Paladin.cs | 8 +- Source/Scripts/Spells/Priest.cs | 64 +++++++++++++++ Source/Scripts/Spells/Shaman.cs | 2 +- Source/Scripts/Spells/Warrior.cs | 2 +- .../2021_04_19_00_world_priest_holy_words.sql | 17 ++++ 6 files changed, 147 insertions(+), 25 deletions(-) create mode 100644 sql/updates/world/master/2021_04_19_00_world_priest_holy_words.sql diff --git a/Source/Game/Spells/SpellHistory.cs b/Source/Game/Spells/SpellHistory.cs index 802a34212..42884f72d 100644 --- a/Source/Game/Spells/SpellHistory.cs +++ b/Source/Game/Spells/SpellHistory.cs @@ -498,13 +498,7 @@ namespace Game.Spells _categoryCooldowns[categoryId] = cooldownEntry; } - public void ModifyCooldown(uint spellId, int cooldownModMs) - { - TimeSpan offset = TimeSpan.FromMilliseconds(cooldownModMs); - ModifyCooldown(spellId, offset); - } - - public void ModifyCooldown(uint spellId, TimeSpan offset) + public void ModifySpellCooldown(uint spellId, TimeSpan offset) { var cooldownEntry = _spellCooldowns.LookupByKey(spellId); if (offset.TotalMilliseconds == 0 || cooldownEntry == null) @@ -531,6 +525,24 @@ namespace Game.Spells } } + public void ModifyCooldown(uint spellId, TimeSpan cooldownMod) + { + SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(spellId, _owner.GetMap().GetDifficultyID()); + if (spellInfo != null) + ModifyCooldown(spellInfo, cooldownMod); + } + + public void ModifyCooldown(SpellInfo spellInfo, TimeSpan cooldownMod) + { + if (cooldownMod == TimeSpan.Zero) + return; + + if (GetChargeRecoveryTime(spellInfo.ChargeCategoryId) > 0 && GetMaxCharges(spellInfo.ChargeCategoryId) > 0) + ModifyChargeRecoveryTime(spellInfo.ChargeCategoryId, cooldownMod); + else + ModifySpellCooldown(spellInfo.Id, cooldownMod); + } + public void ResetCooldown(uint spellId, bool update = false) { var entry = _spellCooldowns.LookupByKey(spellId); @@ -723,6 +735,31 @@ namespace Game.Spells return false; } + void ModifyChargeRecoveryTime(uint chargeCategoryId, TimeSpan cooldownMod) + { + var chargeCategoryEntry = CliDB.SpellCategoryStorage.LookupByKey(chargeCategoryId); + if (chargeCategoryEntry == null) + return; + + var chargeList = _categoryCharges.LookupByKey(chargeCategoryId); + if (chargeList == null || chargeList.Empty()) + return; + + var now = GameTime.GetGameTimeSystemPoint(); + + for (var i = 0; i < chargeList.Count; ++i) + { + var entry = chargeList[i]; + entry.RechargeStart += cooldownMod; + entry.RechargeEnd += cooldownMod; + } + + while (!chargeList.Empty() && chargeList[0].RechargeEnd < now) + chargeList.RemoveAt(0); + + SendSetSpellCharges(chargeCategoryId, chargeList); + } + public void RestoreCharge(uint chargeCategoryId) { var chargeList = _categoryCharges.LookupByKey(chargeCategoryId); @@ -730,18 +767,7 @@ namespace Game.Spells { chargeList.RemoveAt(chargeList.Count - 1); - Player player = GetPlayerOwner(); - if (player) - { - SetSpellCharges setSpellCharges = new(); - setSpellCharges.Category = chargeCategoryId; - if (!chargeList.Empty()) - setSpellCharges.NextRecoveryTime = (uint)(chargeList.FirstOrDefault().RechargeEnd - GameTime.GetGameTimeSystemPoint()).TotalMilliseconds; - setSpellCharges.ConsumedCharges = (byte)chargeList.Count; - setSpellCharges.IsPet = player != _owner; - - player.SendPacket(setSpellCharges); - } + SendSetSpellCharges(chargeCategoryId, chargeList); if (chargeList.Empty()) _categoryCharges.Remove(chargeCategoryId); @@ -857,6 +883,21 @@ namespace Game.Spells } } + void SendSetSpellCharges(uint chargeCategoryId, List chargeCollection) + { + Player player = GetPlayerOwner(); + if (player != null) + { + SetSpellCharges setSpellCharges = new(); + setSpellCharges.Category = chargeCategoryId; + if (!chargeCollection.Empty()) + setSpellCharges.NextRecoveryTime = (uint)(chargeCollection[0].RechargeEnd - DateTime.Now).TotalMilliseconds; + setSpellCharges.ConsumedCharges = (byte)chargeCollection.Count; + setSpellCharges.IsPet = player != _owner; + player.SendPacket(setSpellCharges); + } + } + void GetCooldownDurations(SpellInfo spellInfo, uint itemId, ref uint categoryId) { int notUsed = 0; diff --git a/Source/Scripts/Spells/Paladin.cs b/Source/Scripts/Spells/Paladin.cs index 730d0ba53..604e8e576 100644 --- a/Source/Scripts/Spells/Paladin.cs +++ b/Source/Scripts/Spells/Paladin.cs @@ -188,7 +188,7 @@ namespace Scripts.Spells.Paladin void HandleEffectProc(AuraEffect aurEff, ProcEventInfo eventInfo) { - GetTarget().GetSpellHistory().ModifyCooldown(SpellIds.HolyShockR1, aurEff.GetAmount()); + GetTarget().GetSpellHistory().ModifyCooldown(SpellIds.HolyShockR1, TimeSpan.FromSeconds(aurEff.GetAmount())); } public override void Register() @@ -313,7 +313,7 @@ namespace Scripts.Spells.Paladin { int value = aurEff.GetAmount() / 10; - GetTarget().GetSpellHistory().ModifyCooldown(SpellIds.HammerOfJustice, -value); + GetTarget().GetSpellHistory().ModifyCooldown(SpellIds.HammerOfJustice, TimeSpan.FromSeconds(-value)); } public override void Register() @@ -682,8 +682,8 @@ namespace Scripts.Spells.Paladin { int value = aurEff.GetAmount() * 100 * _baseHolyPowerCost.Amount; - GetTarget().GetSpellHistory().ModifyCooldown(SpellIds.AvengingWrath, -value); - GetTarget().GetSpellHistory().ModifyCooldown(SpellIds.GuardianOfAcientKings, -value); + GetTarget().GetSpellHistory().ModifyCooldown(SpellIds.AvengingWrath, TimeSpan.FromSeconds(-value)); + GetTarget().GetSpellHistory().ModifyCooldown(SpellIds.GuardianOfAcientKings, TimeSpan.FromSeconds(-value)); } public override void Register() diff --git a/Source/Scripts/Spells/Priest.cs b/Source/Scripts/Spells/Priest.cs index f32677c6e..42d99029d 100644 --- a/Source/Scripts/Spells/Priest.cs +++ b/Source/Scripts/Spells/Priest.cs @@ -41,7 +41,12 @@ namespace Scripts.Spells.Priest public const uint BodyAndSoulSpeed = 65081; public const uint DivineBlessing = 40440; public const uint DivineWrath = 40441; + public const uint FlashHeal = 2061; public const uint GuardianSpiritHeal = 48153; + public const uint Heal = 2060; + public const uint HolyWordChastise = 88625; + public const uint HolyWordSanctify = 34861; + public const uint HolyWordSerenity = 2050; public const uint ItemEfficiency = 37595; public const uint LeapOfFaithEffect = 92832; public const uint LevitateEffect = 111759; @@ -52,10 +57,13 @@ namespace Scripts.Spells.Priest public const uint PrayerOfMendingAura = 41635; public const uint PrayerOfMendingHeal = 33110; public const uint PrayerOfMendingJump = 155793; + public const uint PrayerOfHealing = 596; + public const uint Renew = 139; public const uint RenewedHope = 197469; public const uint RenewedHopeEffect = 197470; public const uint ShieldDisciplineEnergize = 47755; public const uint ShieldDisciplinePassive = 197045; + public const uint Smite = 585; public const uint SpiritOfRedemption = 27827; public const uint StrengthOfSoul = 197535; public const uint StrengthOfSoulEffect = 197548; @@ -269,6 +277,62 @@ namespace Scripts.Spells.Priest } } + [Script] // 63733 - Holy Words + class spell_pri_holy_words : AuraScript + { + public override bool Validate(SpellInfo spellInfo) + { + return ValidateSpellInfo(SpellIds.Heal, SpellIds.FlashHeal, SpellIds.PrayerOfHealing, SpellIds.Renew, SpellIds.Smite, SpellIds.HolyWordChastise, SpellIds.HolyWordSanctify, SpellIds.HolyWordSerenity) + && Global.SpellMgr.GetSpellInfo(SpellIds.HolyWordSerenity, Difficulty.None).GetEffect(1) != null + && Global.SpellMgr.GetSpellInfo(SpellIds.HolyWordSanctify, Difficulty.None).GetEffect(2) != null + && Global.SpellMgr.GetSpellInfo(SpellIds.HolyWordSanctify, Difficulty.None).GetEffect(3) != null + && Global.SpellMgr.GetSpellInfo(SpellIds.HolyWordChastise, Difficulty.None).GetEffect(1) != null; + } + + void HandleProc(AuraEffect aurEff, ProcEventInfo eventInfo) + { + SpellInfo spellInfo = eventInfo.GetSpellInfo(); + if (spellInfo == null) + return; + + uint targetSpellId; + uint cdReductionEffIndex; + switch (spellInfo.Id) + { + case SpellIds.Heal: + case SpellIds.FlashHeal: // reduce Holy Word: Serenity cd by 6 seconds + targetSpellId = SpellIds.HolyWordSerenity; + cdReductionEffIndex = 1; + // cdReduction = sSpellMgr.GetSpellInfo(SPELL_PRIEST_HOLY_WORD_SERENITY, GetCastDifficulty()).GetEffect(EFFECT_1).CalcValue(player); + break; + case SpellIds.PrayerOfHealing: // reduce Holy Word: Sanctify cd by 6 seconds + targetSpellId = SpellIds.HolyWordSanctify; + cdReductionEffIndex = 2; + break; + case SpellIds.Renew: // reuce Holy Word: Sanctify cd by 2 seconds + targetSpellId = SpellIds.HolyWordSanctify; + cdReductionEffIndex = 3; + break; + case SpellIds.Smite: // reduce Holy Word: Chastise cd by 4 seconds + targetSpellId = SpellIds.HolyWordChastise; + cdReductionEffIndex = 1; + break; + default: + Log.outWarn(LogFilter.Spells, $"HolyWords aura has been proced by an unknown spell: {GetSpellInfo().Id}"); + return; + } + + SpellInfo targetSpellInfo = Global.SpellMgr.GetSpellInfo(targetSpellId, GetCastDifficulty()); + int cdReduction = targetSpellInfo.GetEffect(cdReductionEffIndex).CalcValue(GetTarget()); + GetTarget().GetSpellHistory().ModifyCooldown(targetSpellInfo, TimeSpan.FromSeconds(-cdReduction)); + } + + public override void Register() + { + OnEffectProc.Add(new EffectProcHandler(HandleProc, 0, AuraType.Dummy)); + } + } + [Script] // 40438 - Priest Tier 6 Trinket class spell_pri_item_t6_trinket : AuraScript { diff --git a/Source/Scripts/Spells/Shaman.cs b/Source/Scripts/Spells/Shaman.cs index 9e7b311b8..c71d74a64 100644 --- a/Source/Scripts/Spells/Shaman.cs +++ b/Source/Scripts/Spells/Shaman.cs @@ -626,7 +626,7 @@ namespace Scripts.Spells.Shaman PreventDefaultAction(); Player target = GetTarget().ToPlayer(); if (target) - target.GetSpellHistory().ModifyCooldown(SpellIds.ElementalMastery, -aurEff.GetAmount()); + target.GetSpellHistory().ModifyCooldown(SpellIds.ElementalMastery, TimeSpan.FromMilliseconds(-aurEff.GetAmount())); } public override void Register() diff --git a/Source/Scripts/Spells/Warrior.cs b/Source/Scripts/Spells/Warrior.cs index 2fb09d82c..0c8563df1 100644 --- a/Source/Scripts/Spells/Warrior.cs +++ b/Source/Scripts/Spells/Warrior.cs @@ -396,7 +396,7 @@ namespace Scripts.Spells.Warrior void HandleAfterCast() { if (_targetCount >= (uint)GetSpellInfo().GetEffect(0).CalcValue()) - GetCaster().ToPlayer().GetSpellHistory().ModifyCooldown(GetSpellInfo().Id, -(GetSpellInfo().GetEffect(3).CalcValue() * Time.InMilliseconds)); + GetCaster().ToPlayer().GetSpellHistory().ModifyCooldown(GetSpellInfo().Id, TimeSpan.FromSeconds(-GetSpellInfo().GetEffect(3).CalcValue())); } public override void Register() diff --git a/sql/updates/world/master/2021_04_19_00_world_priest_holy_words.sql b/sql/updates/world/master/2021_04_19_00_world_priest_holy_words.sql new file mode 100644 index 000000000..073c084fc --- /dev/null +++ b/sql/updates/world/master/2021_04_19_00_world_priest_holy_words.sql @@ -0,0 +1,17 @@ +-- Spell Proc +DELETE FROM `spell_script_names` WHERE `ScriptName` IN ('spell_pri_holy_words'); +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(63733, 'spell_pri_holy_words'); + +-- Spell Procs +-- Make holy words Proc on the following spells: +-- 2060 Heal 0x1000 +-- 2061 Flash Heal 0x0800 +-- 596 Prayer of Healing 0x0200 +-- 139 Renew 0x0040 +-- 585 Smite 0x0080 +-- 0x1AC0 + +DELETE FROM `spell_proc` WHERE `SpellId` IN (63733); -- Holy Words +INSERT INTO `spell_proc` (`SpellId`,`SchoolMask`,`SpellFamilyName`,`SpellFamilyMask0`,`SpellFamilyMask1`,`SpellFamilyMask2`,`SpellFamilyMask3`,`ProcFlags`,`SpellTypeMask`,`SpellPhaseMask`,`HitMask`,`AttributesMask`,`DisableEffectsMask`,`ProcsPerMinute`,`Chance`,`Cooldown`,`Charges`) VALUES +(63733, 0, 6, 0x1AC0, 0x0, 0x0, 0x0, 0, 7, 2, 0x403, 0x0, 0, 0, 0, 0, 0);