diff options
author | Shauren <shauren.trinity@gmail.com> | 2025-01-30 18:27:38 +0100 |
---|---|---|
committer | Ovahlord <dreadkiller@gmx.de> | 2025-02-01 05:36:35 +0100 |
commit | 9f084cd749c5f677392d9b5d0678285080eb5ac2 (patch) | |
tree | ae61141d56ebc52d79b33736e57cefaf3c727dc5 | |
parent | 1547fd0d8a5bb0498f344aa5e0877081aace4bd7 (diff) |
Core/Spells: Refactor SpellHistory ModifyCoooldowns and ResetCooldowns callbacks to use CooldownEntry argument instead of internal iterator
(cherry picked from commit ace6342aea9e8e3f69af88ca3963fc961ba56f1b)
# Conflicts:
# src/server/scripts/Spells/spell_dh.cpp
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Spells/SpellHistory.cpp | 171 | ||||
-rw-r--r-- | src/server/game/Spells/SpellHistory.h | 35 | ||||
-rw-r--r-- | src/server/scripts/World/duel_reset.cpp | 6 |
6 files changed, 117 insertions, 113 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index d651760572c..7c266e4593c 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -3128,12 +3128,12 @@ void Player::SetSpellFavorite(uint32 spellId, bool favorite) void Player::RemoveArenaSpellCooldowns(bool removeActivePetCooldowns) { // remove cooldowns on spells that have < 10 min CD - GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) + GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownEntry const& cooldownEntry) { - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first, DIFFICULTY_NONE); + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(cooldownEntry.SpellId, DIFFICULTY_NONE); SpellHistory::Duration cooldown = 0s; SpellHistory::Duration categoryCooldown = 0s; - SpellHistory::GetCooldownDurations(spellInfo, itr->second.ItemId, &cooldown, nullptr, &categoryCooldown); + SpellHistory::GetCooldownDurations(spellInfo, cooldownEntry.ItemId, &cooldown, nullptr, &categoryCooldown); return cooldown < 10min && categoryCooldown < 10min && !spellInfo->HasAttribute(SPELL_ATTR6_DO_NOT_RESET_COOLDOWN_IN_ARENA); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 8e3434c3242..d694b89e236 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -583,9 +583,9 @@ void Unit::AtEndOfEncounter(EncounterType type) break; } - GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownStorageType::iterator itr) + GetSpellHistory()->ResetCooldowns([](SpellHistory::CooldownEntry const& cooldown) { - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first, DIFFICULTY_NONE); + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(cooldown.SpellId, DIFFICULTY_NONE); return spellInfo->HasAttribute(SPELL_ATTR10_RESET_COOLDOWN_ON_ENCOUNTER_END); }, true); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 17638a92c08..a71e40bcb50 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -5864,9 +5864,9 @@ void Spell::EffectModifyCooldowns() if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - unitTarget->GetSpellHistory()->ModifyCoooldowns([this](SpellHistory::CooldownStorageType::iterator itr) + unitTarget->GetSpellHistory()->ModifyCoooldowns([this](SpellHistory::CooldownEntry const& cooldown) { - SpellInfo const* spellOnCooldown = sSpellMgr->AssertSpellInfo(itr->first, DIFFICULTY_NONE); + SpellInfo const* spellOnCooldown = sSpellMgr->AssertSpellInfo(cooldown.SpellId, DIFFICULTY_NONE); if (spellOnCooldown->SpellFamilyName != uint32(effectInfo->MiscValue)) return false; @@ -5885,9 +5885,9 @@ void Spell::EffectModifyCooldownsByCategory() if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; - unitTarget->GetSpellHistory()->ModifyCoooldowns([this](SpellHistory::CooldownStorageType::iterator itr) + unitTarget->GetSpellHistory()->ModifyCoooldowns([this](SpellHistory::CooldownEntry const& cooldown) { - return sSpellMgr->AssertSpellInfo(itr->first, DIFFICULTY_NONE)->CategoryId == uint32(effectInfo->MiscValue); + return sSpellMgr->AssertSpellInfo(cooldown.SpellId, DIFFICULTY_NONE)->CategoryId == uint32(effectInfo->MiscValue); }, Milliseconds(damage)); } diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index 9902266b1a1..207298a85a8 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -37,14 +37,14 @@ SpellHistory::Duration const SpellHistory::InfinityCooldownDelay = Seconds(MONTH template<> struct SpellHistory::PersistenceHelper<Player> { - static CharacterDatabaseStatements const CooldownsDeleteStatement = CHAR_DEL_CHAR_SPELL_COOLDOWNS; - static CharacterDatabaseStatements const CooldownsInsertStatement = CHAR_INS_CHAR_SPELL_COOLDOWN; - static CharacterDatabaseStatements const ChargesDeleteStatement = CHAR_DEL_CHAR_SPELL_CHARGES; - static CharacterDatabaseStatements const ChargesInsertStatement = CHAR_INS_CHAR_SPELL_CHARGES; + static constexpr CharacterDatabaseStatements CooldownsDeleteStatement = CHAR_DEL_CHAR_SPELL_COOLDOWNS; + static constexpr CharacterDatabaseStatements CooldownsInsertStatement = CHAR_INS_CHAR_SPELL_COOLDOWN; + static constexpr CharacterDatabaseStatements ChargesDeleteStatement = CHAR_DEL_CHAR_SPELL_CHARGES; + static constexpr CharacterDatabaseStatements ChargesInsertStatement = CHAR_INS_CHAR_SPELL_CHARGES; - static void SetIdentifier(PreparedStatementBase* stmt, uint8 index, Unit* owner) { stmt->setUInt64(index, owner->GetGUID().GetCounter()); } + static void SetIdentifier(PreparedStatementBase* stmt, uint8 index, Unit const* owner) { stmt->setUInt64(index, owner->GetGUID().GetCounter()); } - static bool ReadCooldown(Field* fields, uint32* spellId, CooldownEntry* cooldownEntry) + static bool ReadCooldown(Field const* fields, uint32* spellId, CooldownEntry* cooldownEntry) { *spellId = fields[0].GetUInt32(); if (!sSpellMgr->GetSpellInfo(*spellId, DIFFICULTY_NONE)) @@ -58,7 +58,7 @@ struct SpellHistory::PersistenceHelper<Player> return true; } - static bool ReadCharge(Field* fields, uint32* categoryId, ChargeEntry* chargeEntry) + static bool ReadCharge(Field const* fields, uint32* categoryId, ChargeEntry* chargeEntry) { *categoryId = fields[0].GetUInt32(); if (!sSpellCategoryStore.LookupEntry(*categoryId)) @@ -69,13 +69,13 @@ struct SpellHistory::PersistenceHelper<Player> return true; } - static void WriteCooldown(PreparedStatementBase* stmt, uint8& index, CooldownStorageType::value_type const& cooldown) + static void WriteCooldown(PreparedStatementBase* stmt, uint8& index, CooldownEntry const& cooldown) { - stmt->setUInt32(index++, cooldown.first); - stmt->setUInt32(index++, cooldown.second.ItemId); - stmt->setInt64(index++, Clock::to_time_t(cooldown.second.CooldownEnd)); - stmt->setUInt32(index++, cooldown.second.CategoryId); - stmt->setInt64(index++, Clock::to_time_t(cooldown.second.CategoryEnd)); + stmt->setUInt32(index++, cooldown.SpellId); + stmt->setUInt32(index++, cooldown.ItemId); + stmt->setInt64(index++, Clock::to_time_t(cooldown.CooldownEnd)); + stmt->setUInt32(index++, cooldown.CategoryId); + stmt->setInt64(index++, Clock::to_time_t(cooldown.CategoryEnd)); } static void WriteCharge(PreparedStatementBase* stmt, uint8& index, uint32 chargeCategory, ChargeEntry const& charge) @@ -89,14 +89,14 @@ struct SpellHistory::PersistenceHelper<Player> template<> struct SpellHistory::PersistenceHelper<Pet> { - static CharacterDatabaseStatements const CooldownsDeleteStatement = CHAR_DEL_PET_SPELL_COOLDOWNS; - static CharacterDatabaseStatements const CooldownsInsertStatement = CHAR_INS_PET_SPELL_COOLDOWN; - static CharacterDatabaseStatements const ChargesDeleteStatement = CHAR_DEL_PET_SPELL_CHARGES; - static CharacterDatabaseStatements const ChargesInsertStatement = CHAR_INS_PET_SPELL_CHARGES; + static constexpr CharacterDatabaseStatements CooldownsDeleteStatement = CHAR_DEL_PET_SPELL_COOLDOWNS; + static constexpr CharacterDatabaseStatements CooldownsInsertStatement = CHAR_INS_PET_SPELL_COOLDOWN; + static constexpr CharacterDatabaseStatements ChargesDeleteStatement = CHAR_DEL_PET_SPELL_CHARGES; + static constexpr CharacterDatabaseStatements ChargesInsertStatement = CHAR_INS_PET_SPELL_CHARGES; static void SetIdentifier(PreparedStatementBase* stmt, uint8 index, Unit* owner) { stmt->setUInt32(index, owner->GetCharmInfo()->GetPetNumber()); } - static bool ReadCooldown(Field* fields, uint32* spellId, CooldownEntry* cooldownEntry) + static bool ReadCooldown(Field const* fields, uint32* spellId, CooldownEntry* cooldownEntry) { *spellId = fields[0].GetUInt32(); if (!sSpellMgr->GetSpellInfo(*spellId, DIFFICULTY_NONE)) @@ -110,7 +110,7 @@ struct SpellHistory::PersistenceHelper<Pet> return true; } - static bool ReadCharge(Field* fields, uint32* categoryId, ChargeEntry* chargeEntry) + static bool ReadCharge(Field const* fields, uint32* categoryId, ChargeEntry* chargeEntry) { *categoryId = fields[0].GetUInt32(); if (!sSpellCategoryStore.LookupEntry(*categoryId)) @@ -121,12 +121,12 @@ struct SpellHistory::PersistenceHelper<Pet> return true; } - static void WriteCooldown(PreparedStatementBase* stmt, uint8& index, CooldownStorageType::value_type const& cooldown) + static void WriteCooldown(PreparedStatementBase* stmt, uint8& index, CooldownEntry const& cooldown) { - stmt->setUInt32(index++, cooldown.first); - stmt->setInt64(index++, Clock::to_time_t(cooldown.second.CooldownEnd)); - stmt->setUInt32(index++, cooldown.second.CategoryId); - stmt->setInt64(index++, Clock::to_time_t(cooldown.second.CategoryEnd)); + stmt->setUInt32(index++, cooldown.SpellId); + stmt->setInt64(index++, Clock::to_time_t(cooldown.CooldownEnd)); + stmt->setUInt32(index++, cooldown.CategoryId); + stmt->setInt64(index++, Clock::to_time_t(cooldown.CategoryEnd)); } static void WriteCharge(PreparedStatementBase* stmt, uint8& index, uint32 chargeCategory, ChargeEntry const& charge) @@ -188,14 +188,14 @@ void SpellHistory::SaveToDB(CharacterDatabaseTransaction trans) StatementInfo::SetIdentifier(stmt, index++, _owner); trans->Append(stmt); - for (auto const& p : _spellCooldowns) + for (auto const& [spellId, cooldown] : _spellCooldowns) { - if (!p.second.OnHold) + if (!cooldown.OnHold) { index = 0; stmt = CharacterDatabase.GetPreparedStatement(StatementInfo::CooldownsInsertStatement); StatementInfo::SetIdentifier(stmt, index++, _owner); - StatementInfo::WriteCooldown(stmt, index, p); + StatementInfo::WriteCooldown(stmt, index, cooldown); trans->Append(stmt); } } @@ -204,14 +204,14 @@ void SpellHistory::SaveToDB(CharacterDatabaseTransaction trans) StatementInfo::SetIdentifier(stmt, 0, _owner); trans->Append(stmt); - for (auto const& p : _categoryCharges) + for (auto const& [categoryId, consumedCharges] : _categoryCharges) { - for (ChargeEntry const& charge : p.second) + for (ChargeEntry const& charge : consumedCharges) { index = 0; stmt = CharacterDatabase.GetPreparedStatement(StatementInfo::ChargesInsertStatement); StatementInfo::SetIdentifier(stmt, index++, _owner); - StatementInfo::WriteCharge(stmt, index, p.first, charge); + StatementInfo::WriteCharge(stmt, index, categoryId, charge); trans->Append(stmt); } } @@ -291,36 +291,29 @@ bool SpellHistory::IsReady(SpellInfo const* spellInfo, uint32 itemId /*= 0*/) co return true; } -template<class PacketType> -void SpellHistory::WritePacket(PacketType* /*packet*/) const -{ - static_assert(!std::is_same<PacketType, PacketType>::value /*static_assert(false)*/, "This packet is not supported."); -} - -template<> void SpellHistory::WritePacket(WorldPackets::Spells::SendSpellHistory* sendSpellHistory) const { sendSpellHistory->Entries.reserve(_spellCooldowns.size()); TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); - for (auto const& p : _spellCooldowns) + for (auto const& [spellId, cooldown] : _spellCooldowns) { WorldPackets::Spells::SpellHistoryEntry historyEntry; - historyEntry.SpellID = p.first; - historyEntry.ItemID = p.second.ItemId; + historyEntry.SpellID = spellId; + historyEntry.ItemID = cooldown.ItemId; - if (p.second.OnHold) + if (cooldown.OnHold) historyEntry.OnHold = true; else { - Milliseconds cooldownDuration = duration_cast<Milliseconds>(p.second.CooldownEnd - now); + Milliseconds cooldownDuration = duration_cast<Milliseconds>(cooldown.CooldownEnd - now); if (cooldownDuration.count() <= 0) continue; - Milliseconds categoryDuration = duration_cast<Milliseconds>(p.second.CategoryEnd - now); + Milliseconds categoryDuration = duration_cast<Milliseconds>(cooldown.CategoryEnd - now); if (categoryDuration.count() > 0) { - historyEntry.Category = p.second.CategoryId; + historyEntry.Category = cooldown.CategoryId; historyEntry.CategoryRecoveryTime = uint32(categoryDuration.count()); } @@ -332,71 +325,69 @@ void SpellHistory::WritePacket(WorldPackets::Spells::SendSpellHistory* sendSpell } } -template<> void SpellHistory::WritePacket(WorldPackets::Spells::SendSpellCharges* sendSpellCharges) const { sendSpellCharges->Entries.reserve(_categoryCharges.size()); TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); - for (auto const& p : _categoryCharges) + for (auto const& [categoryId, consumedCharges] : _categoryCharges) { - if (!p.second.empty()) + if (!consumedCharges.empty()) { - Milliseconds cooldownDuration = duration_cast<Milliseconds>(p.second.front().RechargeEnd - now); + Milliseconds cooldownDuration = duration_cast<Milliseconds>(consumedCharges.front().RechargeEnd - now); if (cooldownDuration.count() <= 0) continue; WorldPackets::Spells::SpellChargeEntry chargeEntry; - chargeEntry.Category = p.first; + chargeEntry.Category = categoryId; chargeEntry.NextRecoveryTime = uint32(cooldownDuration.count()); - chargeEntry.ConsumedCharges = uint8(p.second.size()); + chargeEntry.ConsumedCharges = uint8(consumedCharges.size()); sendSpellCharges->Entries.push_back(chargeEntry); } } } -template<> void SpellHistory::WritePacket(WorldPackets::Pet::PetSpells* petSpells) const { TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); petSpells->Cooldowns.reserve(_spellCooldowns.size()); - for (auto const& p : _spellCooldowns) + for (auto const& [spellId, cooldown] : _spellCooldowns) { WorldPackets::Pet::PetSpellCooldown petSpellCooldown; - petSpellCooldown.SpellID = p.first; - petSpellCooldown.Category = p.second.CategoryId; + petSpellCooldown.SpellID = spellId; + petSpellCooldown.Category = cooldown.CategoryId; - if (!p.second.OnHold) + if (!cooldown.OnHold) { - Milliseconds cooldownDuration = duration_cast<Milliseconds>(p.second.CooldownEnd - now); + Milliseconds cooldownDuration = duration_cast<Milliseconds>(cooldown.CooldownEnd - now); if (cooldownDuration.count() <= 0) continue; petSpellCooldown.Duration = uint32(cooldownDuration.count()); - Milliseconds categoryDuration = duration_cast<Milliseconds>(p.second.CategoryEnd - now); + Milliseconds categoryDuration = duration_cast<Milliseconds>(cooldown.CategoryEnd - now); if (categoryDuration.count() > 0) petSpellCooldown.CategoryDuration = uint32(categoryDuration.count()); } else - petSpellCooldown.CategoryDuration = 0x80000000; + petSpellCooldown.CategoryDuration = std::numeric_limits<int32>::min(); petSpells->Cooldowns.push_back(petSpellCooldown); } petSpells->SpellHistory.reserve(_categoryCharges.size()); - for (auto const& p : _categoryCharges) + for (auto const& [categoryId, consumedCharges] : _categoryCharges) { - if (!p.second.empty()) + if (!consumedCharges.empty()) { - Milliseconds cooldownDuration = duration_cast<Milliseconds>(p.second.front().RechargeEnd - now); + Milliseconds cooldownDuration = duration_cast<Milliseconds>(consumedCharges.front().RechargeEnd - now); if (cooldownDuration.count() <= 0) continue; WorldPackets::Pet::PetSpellHistory petChargeEntry; - petChargeEntry.CategoryID = p.first; + petChargeEntry.CategoryID = categoryId; petChargeEntry.RecoveryTime = uint32(cooldownDuration.count()); - petChargeEntry.ConsumedCharges = int8(p.second.size()); + petChargeEntry.ConsumedCharges = int8(consumedCharges.size()); petSpells->SpellHistory.push_back(petChargeEntry); } @@ -657,8 +648,8 @@ void SpellHistory::ResetAllCooldowns() { std::vector<int32> cooldowns; cooldowns.reserve(_spellCooldowns.size()); - for (auto const& p : _spellCooldowns) - cooldowns.push_back(p.first); + for (auto const& [spellId, _] : _spellCooldowns) + cooldowns.push_back(spellId); SendClearCooldowns(cooldowns); } @@ -672,7 +663,7 @@ bool SpellHistory::HasCooldown(SpellInfo const* spellInfo, uint32 itemId /*= 0*/ if (_owner->HasAuraTypeWithAffectMask(SPELL_AURA_IGNORE_SPELL_COOLDOWN, spellInfo)) return false; - if (_spellCooldowns.count(spellInfo->Id) != 0) + if (_spellCooldowns.contains(spellInfo->Id)) return true; if (spellInfo->CooldownAuraSpellId && _owner->HasAura(spellInfo->CooldownAuraSpellId)) @@ -683,7 +674,7 @@ bool SpellHistory::HasCooldown(SpellInfo const* spellInfo, uint32 itemId /*= 0*/ if (!category) return false; - return _categoryCooldowns.count(category) != 0; + return _categoryCooldowns.contains(category); } bool SpellHistory::HasCooldown(uint32 spellId, uint32 itemId /*= 0*/) const @@ -716,12 +707,11 @@ SpellHistory::Duration SpellHistory::GetRemainingCooldown(SpellInfo const* spell SpellHistory::Duration SpellHistory::GetRemainingCategoryCooldown(uint32 categoryId) const { - TimePoint end; auto catItr = _categoryCooldowns.find(categoryId); if (catItr == _categoryCooldowns.end()) return Duration::zero(); - end = catItr->second->CategoryEnd; + TimePoint end = catItr->second->CategoryEnd; TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); if (end < now) @@ -747,15 +737,15 @@ void SpellHistory::LockSpellSchool(SpellSchoolMask schoolMask, Duration lockoutT std::set<uint32> knownSpells; if (Player* plrOwner = _owner->ToPlayer()) { - for (auto const& p : plrOwner->GetSpellMap()) - if (p.second.state != PLAYERSPELL_REMOVED) - knownSpells.insert(p.first); + for (auto const& [spellId, playerSpell] : plrOwner->GetSpellMap()) + if (playerSpell.state != PLAYERSPELL_REMOVED) + knownSpells.insert(spellId); } else if (Pet* petOwner = _owner->ToPet()) { - for (auto const& p : petOwner->m_spells) - if (p.second.state != PETSPELL_REMOVED) - knownSpells.insert(p.first); + for (auto const& [spellId, petSpell] : petOwner->m_spells) + if (petSpell.state != PETSPELL_REMOVED) + knownSpells.insert(spellId); } else { @@ -956,12 +946,11 @@ void SpellHistory::CancelGlobalCooldown(SpellInfo const* spellInfo) SpellHistory::Duration SpellHistory::GetRemainingGlobalCooldown(SpellInfo const* spellInfo) const { - TimePoint end; auto cdItr = _globalCooldowns.find(spellInfo->StartRecoveryCategory); if (cdItr == _globalCooldowns.end()) return Duration::zero(); - end = cdItr->second; + TimePoint end = cdItr->second; TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); if (end < now) return Duration::zero(); @@ -1010,7 +999,7 @@ void SpellHistory::SendClearCooldowns(std::vector<int32> const& cooldowns) const } } -void SpellHistory::SendSetSpellCharges(uint32 chargeCategoryId, ChargeEntryCollection const& chargeCollection) +void SpellHistory::SendSetSpellCharges(uint32 chargeCategoryId, ChargeEntryCollection const& chargeCollection) const { if (Player* player = GetPlayerOwner()) { @@ -1075,22 +1064,24 @@ void SpellHistory::RestoreCooldownStateAfterDuel() if (Player* player = _owner->ToPlayer()) { // add all profession CDs created while in duel (if any) - for (auto const& c : _spellCooldowns) + for (auto const& [spellId, cooldown] : _spellCooldowns) { - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(c.first, DIFFICULTY_NONE); + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(spellId, DIFFICULTY_NONE); if (spellInfo->RecoveryTime > 10 * MINUTE * IN_MILLISECONDS || spellInfo->CategoryRecoveryTime > 10 * MINUTE * IN_MILLISECONDS) - _spellCooldownsBeforeDuel[c.first] = _spellCooldowns[c.first]; + _spellCooldownsBeforeDuel[spellId] = cooldown; } // check for spell with onHold active before and during the duel - for (CooldownStorageType::value_type const& pair : _spellCooldownsBeforeDuel) + for (auto const& [spellId, cooldown] : _spellCooldownsBeforeDuel) { - if (!pair.second.OnHold && - _spellCooldowns.find(pair.first) != _spellCooldowns.end() && - !_spellCooldowns[pair.first].OnHold) - _spellCooldowns[pair.first] = _spellCooldownsBeforeDuel[pair.first]; + if (cooldown.OnHold) + continue; + + auto [itr, inserted] = _spellCooldowns.try_emplace(spellId, cooldown); + if (!inserted && !itr->second.OnHold /*don't override if pre-existing cooldown is on hold*/) + itr->second = cooldown; } // update the client: restore old cooldowns @@ -1098,16 +1089,16 @@ void SpellHistory::RestoreCooldownStateAfterDuel() spellCooldown.Caster = _owner->GetGUID(); spellCooldown.Flags = SPELL_COOLDOWN_FLAG_INCLUDE_EVENT_COOLDOWNS; - for (auto const& c : _spellCooldowns) + for (auto const& [spellId, cooldown] : _spellCooldowns) { TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); - uint32 cooldownDuration = uint32(c.second.CooldownEnd > now ? duration_cast<Milliseconds>(c.second.CooldownEnd - now).count() : 0); + uint32 cooldownDuration = uint32(cooldown.CooldownEnd > now ? duration_cast<Milliseconds>(cooldown.CooldownEnd - now).count() : 0); // cooldownDuration must be between 0 and 10 minutes in order to avoid any visual bugs - if (cooldownDuration <= 0 || cooldownDuration > 10 * MINUTE * IN_MILLISECONDS || c.second.OnHold) + if (cooldownDuration <= 0 || cooldownDuration > 10 * MINUTE * IN_MILLISECONDS || cooldown.OnHold) continue; - spellCooldown.SpellCooldowns.emplace_back(c.first, cooldownDuration); + spellCooldown.SpellCooldowns.emplace_back(spellId, cooldownDuration); } player->SendDirectMessage(spellCooldown.Write()); diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h index 25c8a53788e..536cb86ece4 100644 --- a/src/server/game/Spells/SpellHistory.h +++ b/src/server/game/Spells/SpellHistory.h @@ -15,9 +15,10 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef SpellHistory_h__ -#define SpellHistory_h__ +#ifndef TRINITYCORE_SPELL_HISTORY_H +#define TRINITYCORE_SPELL_HISTORY_H +#include "Concepts.h" #include "DatabaseEnvFwd.h" #include "Duration.h" #include "GameTime.h" @@ -33,6 +34,17 @@ class Spell; class SpellInfo; class Unit; +namespace WorldPackets::Pet +{ +class PetSpells; +} + +namespace WorldPackets::Spells +{ +class SendSpellHistory; +class SendSpellCharges; +} + /// Spell cooldown flags sent in SMSG_SPELL_COOLDOWN enum SpellCooldownFlags { @@ -96,8 +108,9 @@ public: void HandleCooldowns(SpellInfo const* spellInfo, Item const* item, Spell* spell = nullptr); void HandleCooldowns(SpellInfo const* spellInfo, uint32 itemId, Spell* spell = nullptr); bool IsReady(SpellInfo const* spellInfo, uint32 itemId = 0) const; - template<class PacketType> - void WritePacket(PacketType* packet) const; + void WritePacket(WorldPackets::Spells::SendSpellHistory* sendSpellHistory) const; + void WritePacket(WorldPackets::Spells::SendSpellCharges* sendSpellCharges) const; + void WritePacket(WorldPackets::Pet::PetSpells* petSpells) const; // Cooldowns static Duration const InfinityCooldownDelay; // used for set "infinity cooldowns" for spells and check @@ -114,12 +127,12 @@ public: void AddCooldown(uint32 spellId, uint32 itemId, TimePoint cooldownEnd, uint32 categoryId, TimePoint categoryEnd, bool onHold = false); void ModifyCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown = false); void ModifyCooldown(SpellInfo const* spellInfo, Duration cooldownMod, bool withoutCategoryCooldown = false); - template<typename Predicate> + template <Trinity::invocable_r<bool, CooldownEntry const&> Predicate> void ModifyCoooldowns(Predicate&& predicate, Duration cooldownMod, bool withoutCategoryCooldown = false) { for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end();) { - if (predicate(itr)) + if (std::forward<Predicate>(predicate)(itr->second)) ModifySpellCooldown(itr, cooldownMod, withoutCategoryCooldown); else ++itr; @@ -127,14 +140,14 @@ public: } void ResetCooldown(uint32 spellId, bool update = false); - template<typename Predicate> - void ResetCooldowns(Predicate predicate, bool update = false) + template <Trinity::invocable_r<bool, CooldownEntry const&> Predicate> + void ResetCooldowns(Predicate&& predicate, bool update = false) { std::vector<int32> resetCooldowns; resetCooldowns.reserve(_spellCooldowns.size()); for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end();) { - if (predicate(itr)) + if (std::forward<Predicate>(predicate)(itr->second)) { resetCooldowns.push_back(int32(itr->first)); ResetCooldown(itr, false); @@ -195,7 +208,7 @@ private: return _spellCooldowns.erase(itr); } - void SendSetSpellCharges(uint32 chargeCategoryId, ChargeEntryCollection const& chargeCollection); + void SendSetSpellCharges(uint32 chargeCategoryId, ChargeEntryCollection const& chargeCollection) const; Unit* _owner; CooldownStorageType _spellCooldowns; @@ -210,4 +223,4 @@ private: struct PersistenceHelper { }; }; -#endif // SpellHistory_h__ +#endif // TRINITYCORE_SPELL_HISTORY_H diff --git a/src/server/scripts/World/duel_reset.cpp b/src/server/scripts/World/duel_reset.cpp index 9f4fc5977c9..6d3dca3d16f 100644 --- a/src/server/scripts/World/duel_reset.cpp +++ b/src/server/scripts/World/duel_reset.cpp @@ -91,9 +91,9 @@ class DuelResetScript : public PlayerScript static void ResetSpellCooldowns(Player* player, bool onStartDuel) { // remove cooldowns on spells that have < 10 min CD > 30 sec and has no onHold - player->GetSpellHistory()->ResetCooldowns([player, onStartDuel](SpellHistory::CooldownStorageType::iterator itr) -> bool + player->GetSpellHistory()->ResetCooldowns([player, onStartDuel](SpellHistory::CooldownEntry const& cooldown) -> bool { - SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(itr->first, DIFFICULTY_NONE); + SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(cooldown.SpellId, DIFFICULTY_NONE); Milliseconds remainingCooldown = player->GetSpellHistory()->GetRemainingCooldown(spellInfo); Milliseconds totalCooldown = Milliseconds(spellInfo->RecoveryTime); Milliseconds categoryCooldown = Milliseconds(spellInfo->CategoryRecoveryTime); @@ -114,7 +114,7 @@ class DuelResetScript : public PlayerScript applySpellMod(categoryCooldown); return remainingCooldown > 0ms - && !itr->second.OnHold + && !cooldown.OnHold && Milliseconds(totalCooldown) < 10min && Milliseconds(categoryCooldown) < 10min && Milliseconds(remainingCooldown) < 10min |