diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/BattlePets/BattlePetMgr.h | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 19 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 1 | ||||
-rw-r--r-- | src/server/game/Handlers/CharacterHandler.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Spells/SpellHistory.cpp | 53 | ||||
-rw-r--r-- | src/server/game/Spells/SpellHistory.h | 8 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_priest.cpp | 2 |
7 files changed, 74 insertions, 13 deletions
diff --git a/src/server/game/BattlePets/BattlePetMgr.h b/src/server/game/BattlePets/BattlePetMgr.h index ddfd04f4fec..6fa7f588863 100644 --- a/src/server/game/BattlePets/BattlePetMgr.h +++ b/src/server/game/BattlePets/BattlePetMgr.h @@ -36,6 +36,8 @@ enum BattlePetMisc SPELL_SUMMON_BATTLE_PET = 118301 }; +static constexpr Milliseconds REVIVE_BATTLE_PETS_COOLDOWN = 180s; + enum class BattlePetBreedQuality : uint8 { Poor = 0, diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 3ad7c4efd5f..317c4ecd82d 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -23641,6 +23641,25 @@ void Player::UpdatePotionCooldown(Spell* spell) m_lastPotionId = 0; } +void Player::UpdateReviveBattlePetCooldown() +{ + SpellInfo const* reviveBattlePetSpellInfo = sSpellMgr->GetSpellInfo(SPELL_REVIVE_BATTLE_PETS, DIFFICULTY_NONE); + + if (reviveBattlePetSpellInfo && HasSpell(SPELL_REVIVE_BATTLE_PETS)) + { + SpellHistory::Duration remainingCooldown = GetSpellHistory()->GetRemainingCategoryCooldown(reviveBattlePetSpellInfo); + if (remainingCooldown > SpellHistory::Duration::zero()) + { + if (remainingCooldown < REVIVE_BATTLE_PETS_COOLDOWN) + GetSpellHistory()->ModifyCooldown(reviveBattlePetSpellInfo, REVIVE_BATTLE_PETS_COOLDOWN - remainingCooldown); + } + else + { + GetSpellHistory()->StartCooldown(reviveBattlePetSpellInfo, 0, nullptr, false, REVIVE_BATTLE_PETS_COOLDOWN); + } + } +} + void Player::SetResurrectRequestData(WorldObject const* caster, uint32 health, uint32 mana, uint32 appliedAura) { ASSERT(!IsResurrectRequested()); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index ad773d6878b..f20fe6c3704 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1851,6 +1851,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> uint32 GetLastPotionId() const { return m_lastPotionId; } void SetLastPotionId(uint32 item_id) { m_lastPotionId = item_id; } void UpdatePotionCooldown(Spell* spell = nullptr); + void UpdateReviveBattlePetCooldown(); void SetResurrectRequestData(WorldObject const* caster, uint32 health, uint32 mana, uint32 appliedAura); void ClearResurrectRequestData() diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 16aa7a09625..772f961cb95 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1173,6 +1173,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) pCurrChar->SendInitialPacketsAfterAddToMap(); + pCurrChar->UpdateReviveBattlePetCooldown(); + CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ONLINE); stmt->setUInt64(0, pCurrChar->GetGUID().GetCounter()); CharacterDatabase.Execute(stmt); diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index caa91fd6d18..669564017ea 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -310,13 +310,15 @@ void SpellHistory::WritePacket(WorldPackets::Spells::SendSpellHistory* sendSpell if (cooldownDuration.count() <= 0) continue; - historyEntry.RecoveryTime = uint32(cooldownDuration.count()); Milliseconds categoryDuration = std::chrono::duration_cast<Milliseconds>(p.second.CategoryEnd - now); if (categoryDuration.count() > 0) { historyEntry.Category = p.second.CategoryId; historyEntry.CategoryRecoveryTime = uint32(categoryDuration.count()); } + + if (cooldownDuration.count() > categoryDuration.count()) + historyEntry.RecoveryTime = uint32(cooldownDuration.count()); } sendSpellHistory->Entries.push_back(historyEntry); @@ -565,7 +567,7 @@ void SpellHistory::AddCooldown(uint32 spellId, uint32 itemId, Clock::time_point } } -void SpellHistory::ModifySpellCooldown(uint32 spellId, Duration offset) +void SpellHistory::ModifySpellCooldown(uint32 spellId, Duration offset, bool withoutCategoryCooldown) { auto itr = _spellCooldowns.find(spellId); if (!offset.count() || itr == _spellCooldowns.end()) @@ -573,9 +575,19 @@ void SpellHistory::ModifySpellCooldown(uint32 spellId, Duration offset) Clock::time_point now = GameTime::GetGameTimePoint<Clock>(); - if (itr->second.CooldownEnd + offset > now) - itr->second.CooldownEnd += offset; - else + itr->second.CooldownEnd += offset; + + if (itr->second.CategoryId) + { + if (!withoutCategoryCooldown) + itr->second.CategoryEnd += offset; + + // Because category cooldown existence is tied to regular cooldown, we cannot allow a situation where regular cooldown is shorter than category + if (itr->second.CooldownEnd < itr->second.CategoryEnd) + itr->second.CooldownEnd = itr->second.CategoryEnd; + } + + if (itr->second.CooldownEnd <= now) EraseCooldown(itr); if (Player* playerOwner = GetPlayerOwner()) @@ -584,17 +596,18 @@ void SpellHistory::ModifySpellCooldown(uint32 spellId, Duration offset) modifyCooldown.IsPet = _owner != playerOwner; modifyCooldown.SpellID = spellId; modifyCooldown.DeltaTime = std::chrono::duration_cast<Milliseconds>(offset).count(); + modifyCooldown.WithoutCategoryCooldown = withoutCategoryCooldown; playerOwner->SendDirectMessage(modifyCooldown.Write()); } } -void SpellHistory::ModifyCooldown(uint32 spellId, Duration cooldownMod) +void SpellHistory::ModifyCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown) { if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, _owner->GetMap()->GetDifficultyID())) - ModifyCooldown(spellInfo, cooldownMod); + ModifyCooldown(spellInfo, cooldownMod, withoutCategoryCooldown); } -void SpellHistory::ModifyCooldown(SpellInfo const* spellInfo, Duration cooldownMod) +void SpellHistory::ModifyCooldown(SpellInfo const* spellInfo, Duration cooldownMod, bool withoutCategoryCooldown) { if (!cooldownMod.count()) return; @@ -602,7 +615,7 @@ void SpellHistory::ModifyCooldown(SpellInfo const* spellInfo, Duration cooldownM if (GetChargeRecoveryTime(spellInfo->ChargeCategoryId) > 0 && GetMaxCharges(spellInfo->ChargeCategoryId) > 0) ModifyChargeRecoveryTime(spellInfo->ChargeCategoryId, cooldownMod); else - ModifySpellCooldown(spellInfo->Id, cooldownMod); + ModifySpellCooldown(spellInfo->Id, cooldownMod, withoutCategoryCooldown); } void SpellHistory::ResetCooldown(uint32 spellId, bool update /*= false*/) @@ -691,6 +704,28 @@ SpellHistory::Duration SpellHistory::GetRemainingCooldown(SpellInfo const* spell return std::chrono::duration_cast<Milliseconds>(remaining); } +SpellHistory::Duration SpellHistory::GetRemainingCategoryCooldown(uint32 categoryId) const +{ + Clock::time_point end; + auto catItr = _categoryCooldowns.find(categoryId); + if (catItr == _categoryCooldowns.end()) + return Duration::zero(); + + end = catItr->second->CategoryEnd; + + Clock::time_point now = GameTime::GetGameTimePoint<Clock>(); + if (end < now) + return Duration::zero(); + + Clock::duration remaining = end - now; + return std::chrono::duration_cast<Milliseconds>(remaining); +} + +SpellHistory::Duration SpellHistory::GetRemainingCategoryCooldown(SpellInfo const* spellInfo) const +{ + return GetRemainingCategoryCooldown(spellInfo->GetCategory()); +} + void SpellHistory::LockSpellSchool(SpellSchoolMask schoolMask, Duration lockoutTime) { Clock::time_point now = GameTime::GetGameTimePoint<Clock>(); diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h index 43379728167..04b5793cf20 100644 --- a/src/server/game/Spells/SpellHistory.h +++ b/src/server/game/Spells/SpellHistory.h @@ -104,8 +104,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, Duration cooldownMod); - void ModifyCooldown(SpellInfo const* spellInfo, Duration cooldownMod); + void ModifyCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown = false); + void ModifyCooldown(SpellInfo const* spellInfo, Duration cooldownMod, bool withoutCategoryCooldown = false); void ResetCooldown(uint32 spellId, bool update = false); void ResetCooldown(CooldownStorageType::iterator& itr, bool update = false); template<typename Predicate> @@ -132,6 +132,8 @@ public: bool HasCooldown(SpellInfo const* spellInfo, uint32 itemId = 0, bool ignoreCategoryCooldown = false) const; bool HasCooldown(uint32 spellId, uint32 itemId = 0, bool ignoreCategoryCooldown = false) const; Duration GetRemainingCooldown(SpellInfo const* spellInfo) const; + Duration GetRemainingCategoryCooldown(uint32 categoryId) const; + Duration GetRemainingCategoryCooldown(SpellInfo const* spellInfo) const; // School lockouts void LockSpellSchool(SpellSchoolMask schoolMask, Duration lockoutTime); @@ -157,7 +159,7 @@ public: private: Player* GetPlayerOwner() const; - void ModifySpellCooldown(uint32 spellId, Duration cooldownMod); + void ModifySpellCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown = false); void SendClearCooldowns(std::vector<int32> const& cooldowns) const; CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr) { diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 199901fe175..8884a8ec8b5 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -425,7 +425,7 @@ class spell_pri_holy_words : public AuraScript SpellInfo const* targetSpellInfo = sSpellMgr->AssertSpellInfo(targetSpellId, GetCastDifficulty()); int32 cdReduction = targetSpellInfo->GetEffect(cdReductionEffIndex).CalcValue(GetTarget()); - GetTarget()->GetSpellHistory()->ModifyCooldown(targetSpellInfo, Seconds(-cdReduction)); + GetTarget()->GetSpellHistory()->ModifyCooldown(targetSpellInfo, Seconds(-cdReduction), true); } void Register() override |