diff options
author | Shauren <shauren.trinity@gmail.com> | 2024-03-01 00:23:09 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2024-03-01 00:23:09 +0100 |
commit | ede97a52e9077cca59e1dffbc83fbce83fedd031 (patch) | |
tree | 63330ebb20494c304bb3e6be3277f964785a3641 | |
parent | 70121171beca7a0851d534237aa259a83ae9cdf1 (diff) |
Core/Spells: Store truncated (only up to millisecond precision) cooldown times
-rw-r--r-- | src/server/game/Spells/SpellHistory.cpp | 96 | ||||
-rw-r--r-- | src/server/game/Spells/SpellHistory.h | 25 |
2 files changed, 61 insertions, 60 deletions
diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index 4f8fc96e378..6a53ca3452b 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -17,8 +17,8 @@ #include "SpellHistory.h" #include "CharmInfo.h" -#include "DatabaseEnv.h" #include "DB2Stores.h" +#include "DatabaseEnv.h" #include "Duration.h" #include "Item.h" #include "Map.h" @@ -51,10 +51,10 @@ struct SpellHistory::PersistenceHelper<Player> return false; cooldownEntry->SpellId = *spellId; - cooldownEntry->CooldownEnd = Clock::from_time_t(fields[2].GetInt64()); + cooldownEntry->CooldownEnd = time_point_cast<Duration>(Clock::from_time_t(fields[2].GetInt64())); cooldownEntry->ItemId = fields[1].GetUInt32(); cooldownEntry->CategoryId = fields[3].GetUInt32(); - cooldownEntry->CategoryEnd = Clock::from_time_t(fields[4].GetInt64()); + cooldownEntry->CategoryEnd = time_point_cast<Duration>(Clock::from_time_t(fields[4].GetInt64())); return true; } @@ -64,8 +64,8 @@ struct SpellHistory::PersistenceHelper<Player> if (!sSpellCategoryStore.LookupEntry(*categoryId)) return false; - chargeEntry->RechargeStart = Clock::from_time_t(fields[1].GetInt64()); - chargeEntry->RechargeEnd = Clock::from_time_t(fields[2].GetInt64()); + chargeEntry->RechargeStart = time_point_cast<Duration>(Clock::from_time_t(fields[1].GetInt64())); + chargeEntry->RechargeEnd = time_point_cast<Duration>(Clock::from_time_t(fields[2].GetInt64())); return true; } @@ -103,10 +103,10 @@ struct SpellHistory::PersistenceHelper<Pet> return false; cooldownEntry->SpellId = *spellId; - cooldownEntry->CooldownEnd = Clock::from_time_t(fields[1].GetInt64()); + cooldownEntry->CooldownEnd = time_point_cast<Duration>(Clock::from_time_t(fields[1].GetInt64())); cooldownEntry->ItemId = 0; cooldownEntry->CategoryId = fields[2].GetUInt32(); - cooldownEntry->CategoryEnd = Clock::from_time_t(fields[3].GetInt64()); + cooldownEntry->CategoryEnd = time_point_cast<Duration>(Clock::from_time_t(fields[3].GetInt64())); return true; } @@ -116,8 +116,8 @@ struct SpellHistory::PersistenceHelper<Pet> if (!sSpellCategoryStore.LookupEntry(*categoryId)) return false; - chargeEntry->RechargeStart = Clock::from_time_t(fields[1].GetInt64()); - chargeEntry->RechargeEnd = Clock::from_time_t(fields[2].GetInt64()); + chargeEntry->RechargeStart = time_point_cast<Duration>(Clock::from_time_t(fields[1].GetInt64())); + chargeEntry->RechargeEnd = time_point_cast<Duration>(Clock::from_time_t(fields[2].GetInt64())); return true; } @@ -219,7 +219,7 @@ void SpellHistory::SaveToDB(CharacterDatabaseTransaction trans) void SpellHistory::Update() { - Clock::time_point now = GameTime::GetTime<Clock>(); + TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); for (auto itr = _categoryCooldowns.begin(); itr != _categoryCooldowns.end();) { if (itr->second->CategoryEnd < now) @@ -302,7 +302,7 @@ void SpellHistory::WritePacket(WorldPackets::Spells::SendSpellHistory* sendSpell { sendSpellHistory->Entries.reserve(_spellCooldowns.size()); - Clock::time_point now = GameTime::GetTime<Clock>(); + TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); for (auto const& p : _spellCooldowns) { WorldPackets::Spells::SpellHistoryEntry historyEntry; @@ -313,11 +313,11 @@ void SpellHistory::WritePacket(WorldPackets::Spells::SendSpellHistory* sendSpell historyEntry.OnHold = true; else { - Milliseconds cooldownDuration = std::chrono::duration_cast<Milliseconds>(p.second.CooldownEnd - now); + Milliseconds cooldownDuration = duration_cast<Milliseconds>(p.second.CooldownEnd - now); if (cooldownDuration.count() <= 0) continue; - Milliseconds categoryDuration = std::chrono::duration_cast<Milliseconds>(p.second.CategoryEnd - now); + Milliseconds categoryDuration = duration_cast<Milliseconds>(p.second.CategoryEnd - now); if (categoryDuration.count() > 0) { historyEntry.Category = p.second.CategoryId; @@ -337,12 +337,12 @@ void SpellHistory::WritePacket(WorldPackets::Spells::SendSpellCharges* sendSpell { sendSpellCharges->Entries.reserve(_categoryCharges.size()); - Clock::time_point now = GameTime::GetTime<Clock>(); + TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); for (auto const& p : _categoryCharges) { if (!p.second.empty()) { - Milliseconds cooldownDuration = std::chrono::duration_cast<Milliseconds>(p.second.front().RechargeEnd - now); + Milliseconds cooldownDuration = duration_cast<Milliseconds>(p.second.front().RechargeEnd - now); if (cooldownDuration.count() <= 0) continue; @@ -358,7 +358,7 @@ void SpellHistory::WritePacket(WorldPackets::Spells::SendSpellCharges* sendSpell template<> void SpellHistory::WritePacket(WorldPackets::Pet::PetSpells* petSpells) const { - Clock::time_point now = GameTime::GetTime<Clock>(); + TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); petSpells->Cooldowns.reserve(_spellCooldowns.size()); for (auto const& p : _spellCooldowns) @@ -369,12 +369,12 @@ void SpellHistory::WritePacket(WorldPackets::Pet::PetSpells* petSpells) const if (!p.second.OnHold) { - Milliseconds cooldownDuration = std::chrono::duration_cast<Milliseconds>(p.second.CooldownEnd - now); + Milliseconds cooldownDuration = duration_cast<Milliseconds>(p.second.CooldownEnd - now); if (cooldownDuration.count() <= 0) continue; petSpellCooldown.Duration = uint32(cooldownDuration.count()); - Milliseconds categoryDuration = std::chrono::duration_cast<Milliseconds>(p.second.CategoryEnd - now); + Milliseconds categoryDuration = duration_cast<Milliseconds>(p.second.CategoryEnd - now); if (categoryDuration.count() > 0) petSpellCooldown.CategoryDuration = uint32(categoryDuration.count()); } @@ -389,7 +389,7 @@ void SpellHistory::WritePacket(WorldPackets::Pet::PetSpells* petSpells) const { if (!p.second.empty()) { - Milliseconds cooldownDuration = std::chrono::duration_cast<Milliseconds>(p.second.front().RechargeEnd - now); + Milliseconds cooldownDuration = duration_cast<Milliseconds>(p.second.front().RechargeEnd - now); if (cooldownDuration.count() <= 0) continue; @@ -410,9 +410,9 @@ void SpellHistory::StartCooldown(SpellInfo const* spellInfo, uint32 itemId, Spel Duration cooldown = Duration::zero(); Duration categoryCooldown = Duration::zero(); - Clock::time_point curTime = GameTime::GetTime<Clock>(); - Clock::time_point catrecTime; - Clock::time_point recTime; + TimePoint curTime = time_point_cast<Duration>(GameTime::GetTime<Clock>()); + TimePoint catrecTime; + TimePoint recTime; bool needsCooldownPacket = false; if (!forcedCooldown) @@ -486,7 +486,7 @@ void SpellHistory::StartCooldown(SpellInfo const* spellInfo, uint32 itemId, Spel SpellCategoryEntry const* categoryEntry = sSpellCategoryStore.AssertEntry(categoryId); if (categoryEntry->Flags & SPELL_CATEGORY_FLAG_COOLDOWN_EXPIRES_AT_DAILY_RESET) - categoryCooldown = std::chrono::duration_cast<Milliseconds>(Clock::from_time_t(sWorld->GetNextDailyQuestsResetTime()) - Clock::now()); + categoryCooldown = duration_cast<Milliseconds>(Clock::from_time_t(sWorld->GetNextDailyQuestsResetTime()) - GameTime::GetTime<Clock>()); } } else @@ -503,8 +503,8 @@ void SpellHistory::StartCooldown(SpellInfo const* spellInfo, uint32 itemId, Spel if (cooldown == Duration::zero() && categoryCooldown == Duration::zero()) return; - catrecTime = categoryCooldown != Duration::zero() ? curTime + std::chrono::duration_cast<Clock::duration>(Milliseconds(categoryCooldown)) : curTime; - recTime = cooldown != Duration::zero() ? curTime + std::chrono::duration_cast<Clock::duration>(Milliseconds(cooldown)) : catrecTime; + catrecTime = categoryCooldown != Duration::zero() ? curTime + categoryCooldown : curTime; + recTime = cooldown != Duration::zero() ? curTime + cooldown : catrecTime; } // self spell cooldown @@ -551,7 +551,7 @@ void SpellHistory::SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId / StartCooldown(spellInfo, itemId, spell); } -void SpellHistory::AddCooldown(uint32 spellId, uint32 itemId, Clock::time_point cooldownEnd, uint32 categoryId, Clock::time_point categoryEnd, bool onHold /*= false*/) +void SpellHistory::AddCooldown(uint32 spellId, uint32 itemId, TimePoint cooldownEnd, uint32 categoryId, TimePoint categoryEnd, bool onHold /*= false*/) { CooldownEntry& cooldownEntry = _spellCooldowns[spellId]; // scripts can start multiple cooldowns for a given spell, only store the longest one @@ -580,7 +580,7 @@ void SpellHistory::ModifySpellCooldown(uint32 spellId, Duration cooldownMod, boo void SpellHistory::ModifySpellCooldown(CooldownStorageType::iterator& itr, Duration cooldownMod, bool withoutCategoryCooldown) { - Clock::time_point now = GameTime::GetTime<Clock>(); + TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); itr->second.CooldownEnd += cooldownMod; @@ -599,7 +599,7 @@ void SpellHistory::ModifySpellCooldown(CooldownStorageType::iterator& itr, Durat WorldPackets::Spells::ModifyCooldown modifyCooldown; modifyCooldown.IsPet = _owner != playerOwner; modifyCooldown.SpellID = itr->second.SpellId; - modifyCooldown.DeltaTime = std::chrono::duration_cast<Milliseconds>(cooldownMod).count(); + modifyCooldown.DeltaTime = duration_cast<Milliseconds>(cooldownMod).count(); modifyCooldown.WithoutCategoryCooldown = withoutCategoryCooldown; playerOwner->SendDirectMessage(modifyCooldown.Write()); } @@ -693,7 +693,7 @@ bool SpellHistory::HasCooldown(uint32 spellId, uint32 itemId /*= 0*/) const SpellHistory::Duration SpellHistory::GetRemainingCooldown(SpellInfo const* spellInfo) const { - Clock::time_point end; + TimePoint end; auto itr = _spellCooldowns.find(spellInfo->Id); if (itr != _spellCooldowns.end()) end = itr->second.CooldownEnd; @@ -706,29 +706,29 @@ SpellHistory::Duration SpellHistory::GetRemainingCooldown(SpellInfo const* spell end = catItr->second->CategoryEnd; } - Clock::time_point now = GameTime::GetTime<Clock>(); + TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); if (end < now) return Duration::zero(); Clock::duration remaining = end - now; - return std::chrono::duration_cast<Milliseconds>(remaining); + return duration_cast<Milliseconds>(remaining); } SpellHistory::Duration SpellHistory::GetRemainingCategoryCooldown(uint32 categoryId) const { - Clock::time_point end; + TimePoint end; auto catItr = _categoryCooldowns.find(categoryId); if (catItr == _categoryCooldowns.end()) return Duration::zero(); end = catItr->second->CategoryEnd; - Clock::time_point now = GameTime::GetTime<Clock>(); + TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); if (end < now) return Duration::zero(); Clock::duration remaining = end - now; - return std::chrono::duration_cast<Milliseconds>(remaining); + return duration_cast<Milliseconds>(remaining); } SpellHistory::Duration SpellHistory::GetRemainingCategoryCooldown(SpellInfo const* spellInfo) const @@ -738,8 +738,8 @@ SpellHistory::Duration SpellHistory::GetRemainingCategoryCooldown(SpellInfo cons void SpellHistory::LockSpellSchool(SpellSchoolMask schoolMask, Duration lockoutTime) { - Clock::time_point now = GameTime::GetTime<Clock>(); - Clock::time_point lockoutEnd = now + lockoutTime; + TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); + TimePoint lockoutEnd = now + lockoutTime; for (uint32 i = 0; i < MAX_SPELL_SCHOOL; ++i) if (SpellSchoolMask(1 << i) & schoolMask) _schoolLockouts[i] = lockoutEnd; @@ -794,7 +794,7 @@ void SpellHistory::LockSpellSchool(SpellSchoolMask schoolMask, Duration lockoutT bool SpellHistory::IsSchoolLocked(SpellSchoolMask schoolMask) const { - Clock::time_point now = GameTime::GetTime<Clock>(); + TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); for (uint32 i = 0; i < MAX_SPELL_SCHOOL; ++i) if (SpellSchoolMask(1 << i) & schoolMask) if (_schoolLockouts[i] > now) @@ -811,10 +811,10 @@ bool SpellHistory::ConsumeCharge(uint32 chargeCategoryId) int32 chargeRecovery = GetChargeRecoveryTime(chargeCategoryId); if (chargeRecovery > 0 && GetMaxCharges(chargeCategoryId) > 0) { - Clock::time_point recoveryStart; + TimePoint recoveryStart; std::deque<ChargeEntry>& charges = _categoryCharges[chargeCategoryId]; if (charges.empty()) - recoveryStart = GameTime::GetTime<Clock>(); + recoveryStart = time_point_cast<Duration>(GameTime::GetTime<Clock>()); else recoveryStart = charges.back().RechargeEnd; @@ -835,7 +835,7 @@ void SpellHistory::ModifyChargeRecoveryTime(uint32 chargeCategoryId, Duration co if (itr == _categoryCharges.end() || itr->second.empty()) return; - Clock::time_point now = GameTime::GetTime<Clock>(); + TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); for (ChargeEntry& entry : itr->second) { @@ -943,28 +943,28 @@ bool SpellHistory::HasGlobalCooldown(SpellInfo const* spellInfo) const void SpellHistory::AddGlobalCooldown(SpellInfo const* spellInfo, Duration duration) { - _globalCooldowns[spellInfo->StartRecoveryCategory] = Clock::now() + duration; + _globalCooldowns[spellInfo->StartRecoveryCategory] = time_point_cast<Duration>(Clock::now() + duration); } void SpellHistory::CancelGlobalCooldown(SpellInfo const* spellInfo) { - _globalCooldowns[spellInfo->StartRecoveryCategory] = Clock::time_point(Clock::duration(0)); + _globalCooldowns[spellInfo->StartRecoveryCategory] = TimePoint(Duration(0)); } SpellHistory::Duration SpellHistory::GetRemainingGlobalCooldown(SpellInfo const* spellInfo) const { - Clock::time_point end; + TimePoint end; auto cdItr = _globalCooldowns.find(spellInfo->StartRecoveryCategory); if (cdItr == _globalCooldowns.end()) return Duration::zero(); end = cdItr->second; - Clock::time_point now = GameTime::GetTime<Clock>(); + TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); if (end < now) return Duration::zero(); Clock::duration remaining = end - now; - return std::chrono::duration_cast<std::chrono::milliseconds>(remaining); + return duration_cast<Milliseconds>(remaining); } Player* SpellHistory::GetPlayerOwner() const @@ -990,7 +990,7 @@ void SpellHistory::SendSetSpellCharges(uint32 chargeCategoryId, ChargeEntryColle WorldPackets::Spells::SetSpellCharges setSpellCharges; setSpellCharges.Category = chargeCategoryId; if (!chargeCollection.empty()) - setSpellCharges.NextRecoveryTime = uint32(std::chrono::duration_cast<Milliseconds>(chargeCollection.front().RechargeEnd - Clock::now()).count()); + setSpellCharges.NextRecoveryTime = uint32(duration_cast<Milliseconds>(chargeCollection.front().RechargeEnd - GameTime::GetTime<Clock>()).count()); setSpellCharges.ConsumedCharges = uint8(chargeCollection.size()); setSpellCharges.IsPet = player != _owner; player->SendDirectMessage(setSpellCharges.Write()); @@ -1073,8 +1073,8 @@ void SpellHistory::RestoreCooldownStateAfterDuel() for (auto const& c : _spellCooldowns) { - Clock::time_point now = GameTime::GetTime<Clock>(); - uint32 cooldownDuration = uint32(c.second.CooldownEnd > now ? std::chrono::duration_cast<Milliseconds>(c.second.CooldownEnd - now).count() : 0); + 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); // 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) diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h index 0e86193ef02..b2df3f803b9 100644 --- a/src/server/game/Spells/SpellHistory.h +++ b/src/server/game/Spells/SpellHistory.h @@ -18,14 +18,14 @@ #ifndef SpellHistory_h__ #define SpellHistory_h__ -#include "SharedDefines.h" #include "DatabaseEnvFwd.h" #include "Duration.h" #include "GameTime.h" #include "Optional.h" +#include "SharedDefines.h" #include <deque> -#include <vector> #include <unordered_map> +#include <vector> class Item; class Player; @@ -48,32 +48,33 @@ class TC_GAME_API SpellHistory public: using Clock = std::chrono::system_clock; using Duration = Milliseconds; // Cooldowns are stored only with millisecond precision, not whatever Clock's precision is + using TimePoint = std::chrono::time_point<Clock, Duration>; struct CooldownEntry { uint32 SpellId = 0; - Clock::time_point CooldownEnd = Clock::time_point::min(); + TimePoint CooldownEnd = TimePoint::min(); uint32 ItemId = 0; uint32 CategoryId = 0; - Clock::time_point CategoryEnd = Clock::time_point::min(); + TimePoint CategoryEnd = TimePoint::min(); bool OnHold = false; }; struct ChargeEntry { ChargeEntry() = default; - ChargeEntry(Clock::time_point startTime, Duration rechargeTime) : RechargeStart(startTime), RechargeEnd(startTime + rechargeTime) { } - ChargeEntry(Clock::time_point startTime, Clock::time_point endTime) : RechargeStart(startTime), RechargeEnd(endTime) { } + ChargeEntry(TimePoint startTime, Duration rechargeTime) : RechargeStart(startTime), RechargeEnd(startTime + rechargeTime) { } + ChargeEntry(TimePoint startTime, TimePoint endTime) : RechargeStart(startTime), RechargeEnd(endTime) { } - Clock::time_point RechargeStart; - Clock::time_point RechargeEnd; + TimePoint RechargeStart; + TimePoint RechargeEnd; }; using ChargeEntryCollection = std::deque<ChargeEntry>; using CooldownStorageType = std::unordered_map<uint32 /*spellId*/, CooldownEntry>; using CategoryCooldownStorageType = std::unordered_map<uint32 /*categoryId*/, CooldownEntry*>; using ChargeStorageType = std::unordered_map<uint32 /*categoryId*/, ChargeEntryCollection>; - using GlobalCooldownStorageType = std::unordered_map<uint32 /*categoryId*/, Clock::time_point>; + using GlobalCooldownStorageType = std::unordered_map<uint32 /*categoryId*/, TimePoint>; explicit SpellHistory(Unit* owner); ~SpellHistory(); @@ -106,11 +107,11 @@ public: void AddCooldown(uint32 spellId, uint32 itemId, Duration cooldownDuration) { - Clock::time_point now = GameTime::GetTime<Clock>(); + TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>()); AddCooldown(spellId, itemId, now + cooldownDuration, 0, now); } - void AddCooldown(uint32 spellId, uint32 itemId, Clock::time_point cooldownEnd, uint32 categoryId, Clock::time_point categoryEnd, bool onHold = false); + 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> @@ -196,7 +197,7 @@ private: CooldownStorageType _spellCooldowns; CooldownStorageType _spellCooldownsBeforeDuel; CategoryCooldownStorageType _categoryCooldowns; - Clock::time_point _schoolLockouts[MAX_SPELL_SCHOOL]; + TimePoint _schoolLockouts[MAX_SPELL_SCHOOL]; ChargeStorageType _categoryCharges; GlobalCooldownStorageType _globalCooldowns; |