diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/server/game/Spells/SpellHistory.cpp | 75 | ||||
| -rw-r--r-- | src/server/game/Spells/SpellHistory.h | 10 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_paladin.cpp | 8 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_priest.cpp | 83 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_shaman.cpp | 2 | ||||
| -rw-r--r-- | src/server/scripts/Spells/spell_warrior.cpp | 2 |
6 files changed, 151 insertions, 29 deletions
diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index 95eff17a30e..01ba9da7739 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -545,13 +545,7 @@ void SpellHistory::AddCooldown(uint32 spellId, uint32 itemId, Clock::time_point _categoryCooldowns[categoryId] = &cooldownEntry; } -void SpellHistory::ModifyCooldown(uint32 spellId, int32 cooldownModMs) -{ - Clock::duration offset = std::chrono::duration_cast<Clock::duration>(std::chrono::milliseconds(cooldownModMs)); - ModifyCooldown(spellId, offset); -} - -void SpellHistory::ModifyCooldown(uint32 spellId, Clock::duration offset) +void SpellHistory::ModifySpellCooldown(uint32 spellId, Clock::duration offset) { auto itr = _spellCooldowns.find(spellId); if (!offset.count() || itr == _spellCooldowns.end()) @@ -574,6 +568,23 @@ void SpellHistory::ModifyCooldown(uint32 spellId, Clock::duration offset) } } +void SpellHistory::ModifyCooldown(uint32 spellId, Clock::duration cooldownMod) +{ + if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, _owner->GetMap()->GetDifficultyID())) + ModifyCooldown(spellInfo, cooldownMod); +} + +void SpellHistory::ModifyCooldown(SpellInfo const* spellInfo, Clock::duration cooldownMod) +{ + if (!cooldownMod.count()) + return; + + if (GetChargeRecoveryTime(spellInfo->ChargeCategoryId) > 0 && GetMaxCharges(spellInfo->ChargeCategoryId) > 0) + ModifyChargeRecoveryTime(spellInfo->ChargeCategoryId, cooldownMod); + else + ModifySpellCooldown(spellInfo->Id, cooldownMod); +} + void SpellHistory::ResetCooldown(uint32 spellId, bool update /*= false*/) { auto itr = _spellCooldowns.find(spellId); @@ -746,6 +757,30 @@ bool SpellHistory::ConsumeCharge(uint32 chargeCategoryId) return false; } +void SpellHistory::ModifyChargeRecoveryTime(uint32 chargeCategoryId, Clock::duration cooldownMod) +{ + SpellCategoryEntry const* chargeCategoryEntry = sSpellCategoryStore.LookupEntry(chargeCategoryId); + if (!chargeCategoryEntry) + return; + + auto itr = _categoryCharges.find(chargeCategoryId); + if (itr == _categoryCharges.end() || itr->second.empty()) + return; + + Clock::time_point now = GameTime::GetGameTimeSystemPoint(); + + for (ChargeEntry& entry : itr->second) + { + entry.RechargeStart += cooldownMod; + entry.RechargeEnd += cooldownMod; + } + + while (!itr->second.empty() && itr->second.front().RechargeEnd < now) + itr->second.pop_front(); + + SendSetSpellCharges(chargeCategoryId, itr->second); +} + void SpellHistory::RestoreCharge(uint32 chargeCategoryId) { auto itr = _categoryCharges.find(chargeCategoryId); @@ -753,17 +788,7 @@ void SpellHistory::RestoreCharge(uint32 chargeCategoryId) { itr->second.pop_back(); - if (Player* player = GetPlayerOwner()) - { - WorldPackets::Spells::SetSpellCharges setSpellCharges; - setSpellCharges.Category = chargeCategoryId; - if (!itr->second.empty()) - setSpellCharges.NextRecoveryTime = uint32(std::chrono::duration_cast<std::chrono::milliseconds>(itr->second.front().RechargeEnd - Clock::now()).count()); - setSpellCharges.ConsumedCharges = uint8(itr->second.size()); - setSpellCharges.IsPet = player != _owner; - - player->SendDirectMessage(setSpellCharges.Write()); - } + SendSetSpellCharges(chargeCategoryId, itr->second); } } @@ -874,6 +899,20 @@ void SpellHistory::SendClearCooldowns(std::vector<int32> const& cooldowns) const } } +void SpellHistory::SendSetSpellCharges(uint32 chargeCategoryId, ChargeEntryCollection const& chargeCollection) +{ + if (Player* player = GetPlayerOwner()) + { + WorldPackets::Spells::SetSpellCharges setSpellCharges; + setSpellCharges.Category = chargeCategoryId; + if (!chargeCollection.empty()) + setSpellCharges.NextRecoveryTime = uint32(std::chrono::duration_cast<std::chrono::milliseconds>(chargeCollection.front().RechargeEnd - Clock::now()).count()); + setSpellCharges.ConsumedCharges = uint8(chargeCollection.size()); + setSpellCharges.IsPet = player != _owner; + player->SendDirectMessage(setSpellCharges.Write()); + } +} + void SpellHistory::GetCooldownDurations(SpellInfo const* spellInfo, uint32 itemId, int32* cooldown, uint32* categoryId, int32* categoryCooldown) { ASSERT(cooldown || categoryId || categoryCooldown); diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h index 2532da00139..a6bf6bab3a2 100644 --- a/src/server/game/Spells/SpellHistory.h +++ b/src/server/game/Spells/SpellHistory.h @@ -31,7 +31,6 @@ class Player; class Spell; class SpellInfo; class Unit; -struct SpellCategoryEntry; /// Spell cooldown flags sent in SMSG_SPELL_COOLDOWN enum SpellCooldownFlags @@ -66,9 +65,10 @@ public: Clock::time_point RechargeEnd; }; + typedef std::deque<ChargeEntry> ChargeEntryCollection; typedef std::unordered_map<uint32 /*spellId*/, CooldownEntry> CooldownStorageType; typedef std::unordered_map<uint32 /*categoryId*/, CooldownEntry*> CategoryCooldownStorageType; - typedef std::unordered_map<uint32 /*categoryId*/, std::deque<ChargeEntry>> ChargeStorageType; + typedef std::unordered_map<uint32 /*categoryId*/, ChargeEntryCollection> ChargeStorageType; typedef std::unordered_map<uint32 /*categoryId*/, Clock::time_point> GlobalCooldownStorageType; explicit SpellHistory(Unit* owner) : _owner(owner), _schoolLockouts() { } @@ -101,8 +101,8 @@ public: } void AddCooldown(uint32 spellId, uint32 itemId, Clock::time_point cooldownEnd, uint32 categoryId, Clock::time_point categoryEnd, bool onHold = false); - void ModifyCooldown(uint32 spellId, int32 cooldownModMs); void ModifyCooldown(uint32 spellId, Clock::duration cooldownMod); + void ModifyCooldown(SpellInfo const* spellInfo, Clock::duration cooldownMod); void ResetCooldown(uint32 spellId, bool update = false); void ResetCooldown(CooldownStorageType::iterator& itr, bool update = false); template<typename Predicate> @@ -136,6 +136,7 @@ public: // Charges bool ConsumeCharge(uint32 chargeCategoryId); + void ModifyChargeRecoveryTime(uint32 chargeCategoryId, Clock::duration cooldownMod); void RestoreCharge(uint32 chargeCategoryId); void ResetCharges(uint32 chargeCategoryId); void ResetAllCharges(); @@ -153,6 +154,7 @@ public: private: Player* GetPlayerOwner() const; + void ModifySpellCooldown(uint32 spellId, Clock::duration cooldownMod); void SendClearCooldowns(std::vector<int32> const& cooldowns) const; CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr) { @@ -160,6 +162,8 @@ private: return _spellCooldowns.erase(itr); } + void SendSetSpellCharges(uint32 chargeCategoryId, ChargeEntryCollection const& chargeCollection); + static void GetCooldownDurations(SpellInfo const* spellInfo, uint32 itemId, int32* cooldown, uint32* categoryId, int32* categoryCooldown); Unit* _owner; diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 3aba1eff8ae..9a91831da93 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -290,7 +290,7 @@ class spell_pal_crusader_might : public AuraScript void HandleEffectProc(AuraEffect* aurEff, ProcEventInfo& /*eventInfo*/) { - GetTarget()->GetSpellHistory()->ModifyCooldown(SPELL_PALADIN_HOLY_SHOCK_R1, aurEff->GetAmount()); + GetTarget()->GetSpellHistory()->ModifyCooldown(SPELL_PALADIN_HOLY_SHOCK_R1, Seconds(aurEff->GetAmount())); } void Register() override @@ -437,7 +437,7 @@ class spell_pal_fist_of_justice : public AuraScript { int32 value = aurEff->GetAmount() / 10; - GetTarget()->GetSpellHistory()->ModifyCooldown(SPELL_PALADIN_HAMMER_OF_JUSTICE, -value); + GetTarget()->GetSpellHistory()->ModifyCooldown(SPELL_PALADIN_HAMMER_OF_JUSTICE, Seconds(-value)); } void Register() override @@ -863,8 +863,8 @@ class spell_pal_righteous_protector : public AuraScript { int32 value = aurEff->GetAmount() * 100 * _baseHolyPowerCost->Amount; - GetTarget()->GetSpellHistory()->ModifyCooldown(SPELL_PALADIN_AVENGING_WRATH, -value); - GetTarget()->GetSpellHistory()->ModifyCooldown(SPELL_PALADIN_GUARDIAN_OF_ANCIENT_KINGS, -value); + GetTarget()->GetSpellHistory()->ModifyCooldown(SPELL_PALADIN_AVENGING_WRATH, Seconds(-value)); + GetTarget()->GetSpellHistory()->ModifyCooldown(SPELL_PALADIN_GUARDIAN_OF_ANCIENT_KINGS, Seconds(-value)); } void Register() override diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 8a0995098af..d94b5cdef2a 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -25,8 +25,10 @@ #include "AreaTriggerAI.h" #include "GridNotifiers.h" #include "ObjectAccessor.h" +#include "Log.h" #include "Player.h" #include "SpellAuraEffects.h" +#include "SpellHistory.h" #include "SpellMgr.h" #include "SpellScript.h" @@ -43,7 +45,12 @@ enum PriestSpells SPELL_PRIEST_BODY_AND_SOUL_SPEED = 65081, SPELL_PRIEST_DIVINE_BLESSING = 40440, SPELL_PRIEST_DIVINE_WRATH = 40441, + SPELL_PRIEST_FLASH_HEAL = 2061, SPELL_PRIEST_GUARDIAN_SPIRIT_HEAL = 48153, + SPELL_PRIEST_HEAL = 2060, + SPELL_PRIEST_HOLY_WORD_CHASTISE = 88625, + SPELL_PRIEST_HOLY_WORD_SANCTIFY = 34861, + SPELL_PRIEST_HOLY_WORD_SERENITY = 2050, SPELL_PRIEST_ITEM_EFFICIENCY = 37595, SPELL_PRIEST_LEAP_OF_FAITH_EFFECT = 92832, SPELL_PRIEST_LEVITATE_EFFECT = 111759, @@ -51,10 +58,13 @@ enum PriestSpells SPELL_PRIEST_PENANCE_R1 = 47540, SPELL_PRIEST_PENANCE_R1_DAMAGE = 47758, SPELL_PRIEST_PENANCE_R1_HEAL = 47757, + SPELL_PRIEST_PRAYER_OF_HEALING = 596, + SPELL_PRIEST_RENEW = 139, SPELL_PRIEST_RENEWED_HOPE = 197469, SPELL_PRIEST_RENEWED_HOPE_EFFECT = 197470, SPELL_PRIEST_SHIELD_DISCIPLINE_ENERGIZE = 47755, SPELL_PRIEST_SHIELD_DISCIPLINE_PASSIVE = 197045, + SPELL_PRIEST_SMITE = 585, SPELL_PRIEST_SPIRIT_OF_REDEMPTION = 27827, SPELL_PRIEST_STRENGTH_OF_SOUL = 197535, SPELL_PRIEST_STRENGTH_OF_SOUL_EFFECT = 197548, @@ -358,6 +368,74 @@ class spell_pri_guardian_spirit : public SpellScriptLoader } }; +// 63733 - Holy Words +class spell_pri_holy_words : public AuraScript +{ + PrepareAuraScript(spell_pri_holy_words); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo + ({ + SPELL_PRIEST_HEAL, + SPELL_PRIEST_FLASH_HEAL, + SPELL_PRIEST_PRAYER_OF_HEALING, + SPELL_PRIEST_RENEW, + SPELL_PRIEST_SMITE, + SPELL_PRIEST_HOLY_WORD_CHASTISE, + SPELL_PRIEST_HOLY_WORD_SANCTIFY, + SPELL_PRIEST_HOLY_WORD_SERENITY + }) + && sSpellMgr->AssertSpellInfo(SPELL_PRIEST_HOLY_WORD_SERENITY, DIFFICULTY_NONE)->GetEffect(EFFECT_1) + && sSpellMgr->AssertSpellInfo(SPELL_PRIEST_HOLY_WORD_SANCTIFY, DIFFICULTY_NONE)->GetEffect(EFFECT_2) + && sSpellMgr->AssertSpellInfo(SPELL_PRIEST_HOLY_WORD_SANCTIFY, DIFFICULTY_NONE)->GetEffect(EFFECT_3) + && sSpellMgr->AssertSpellInfo(SPELL_PRIEST_HOLY_WORD_CHASTISE, DIFFICULTY_NONE)->GetEffect(EFFECT_1); + } + + void HandleProc(AuraEffect* /*aurEff*/, ProcEventInfo& eventInfo) + { + SpellInfo const* spellInfo = eventInfo.GetSpellInfo(); + if (!spellInfo) + return; + + uint32 targetSpellId; + SpellEffIndex cdReductionEffIndex; + switch (spellInfo->Id) + { + case SPELL_PRIEST_HEAL: + case SPELL_PRIEST_FLASH_HEAL: // reduce Holy Word: Serenity cd by 6 seconds + targetSpellId = SPELL_PRIEST_HOLY_WORD_SERENITY; + cdReductionEffIndex = EFFECT_1; + // cdReduction = sSpellMgr->GetSpellInfo(SPELL_PRIEST_HOLY_WORD_SERENITY, GetCastDifficulty())->GetEffect(EFFECT_1)->CalcValue(player); + break; + case SPELL_PRIEST_PRAYER_OF_HEALING: // reduce Holy Word: Sanctify cd by 6 seconds + targetSpellId = SPELL_PRIEST_HOLY_WORD_SANCTIFY; + cdReductionEffIndex = EFFECT_2; + break; + case SPELL_PRIEST_RENEW: // reuce Holy Word: Sanctify cd by 2 seconds + targetSpellId = SPELL_PRIEST_HOLY_WORD_SANCTIFY; + cdReductionEffIndex = EFFECT_3; + break; + case SPELL_PRIEST_SMITE: // reduce Holy Word: Chastise cd by 4 seconds + targetSpellId = SPELL_PRIEST_HOLY_WORD_CHASTISE; + cdReductionEffIndex = EFFECT_1; + break; + default: + TC_LOG_WARN("spells.priest", "HolyWords aura has been proced by an unknown spell: %u", GetSpellInfo()->Id); + return; + } + + SpellInfo const* targetSpellInfo = sSpellMgr->AssertSpellInfo(targetSpellId, GetCastDifficulty()); + int32 cdReduction = targetSpellInfo->GetEffect(cdReductionEffIndex)->CalcValue(GetTarget()); + GetTarget()->GetSpellHistory()->ModifyCooldown(targetSpellInfo, Seconds(-cdReduction)); + } + + void Register() override + { + OnEffectProc += AuraEffectProcFn(spell_pri_holy_words::HandleProc, EFFECT_0, SPELL_AURA_DUMMY); + } +}; + // 40438 - Priest Tier 6 Trinket class spell_pri_item_t6_trinket : public SpellScriptLoader { @@ -459,9 +537,9 @@ public: } }; - SpellScript* GetSpellScript() const + SpellScript* GetSpellScript() const override { - return new spell_pri_levitate_SpellScript; + return new spell_pri_levitate_SpellScript(); } }; @@ -1134,6 +1212,7 @@ void AddSC_priest_spell_scripts() new spell_pri_atonement_triggered(); new spell_pri_divine_hymn(); new spell_pri_guardian_spirit(); + RegisterAuraScript(spell_pri_holy_words); new spell_pri_item_t6_trinket(); new spell_pri_leap_of_faith_effect_trigger(); new spell_pri_levitate(); diff --git a/src/server/scripts/Spells/spell_shaman.cpp b/src/server/scripts/Spells/spell_shaman.cpp index 618cb45e30f..cdef3647137 100644 --- a/src/server/scripts/Spells/spell_shaman.cpp +++ b/src/server/scripts/Spells/spell_shaman.cpp @@ -850,7 +850,7 @@ class spell_sha_item_t10_elemental_2p_bonus : public SpellScriptLoader { PreventDefaultAction(); if (Player* target = GetTarget()->ToPlayer()) - target->GetSpellHistory()->ModifyCooldown(SPELL_SHAMAN_ELEMENTAL_MASTERY, -aurEff->GetAmount()); + target->GetSpellHistory()->ModifyCooldown(SPELL_SHAMAN_ELEMENTAL_MASTERY, Milliseconds(-aurEff->GetAmount())); } void Register() override diff --git a/src/server/scripts/Spells/spell_warrior.cpp b/src/server/scripts/Spells/spell_warrior.cpp index 3e9d168ed12..555748be8ab 100644 --- a/src/server/scripts/Spells/spell_warrior.cpp +++ b/src/server/scripts/Spells/spell_warrior.cpp @@ -571,7 +571,7 @@ public: void HandleAfterCast() { if (_targetCount >= uint32(GetSpellInfo()->GetEffect(EFFECT_0)->CalcValue())) - GetCaster()->ToPlayer()->GetSpellHistory()->ModifyCooldown(GetSpellInfo()->Id, -(GetSpellInfo()->GetEffect(EFFECT_3)->CalcValue() * IN_MILLISECONDS)); + GetCaster()->ToPlayer()->GetSpellHistory()->ModifyCooldown(GetSpellInfo()->Id, Seconds(-GetSpellInfo()->GetEffect(EFFECT_3)->CalcValue())); } void Register() override |
