aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2024-03-01 00:23:09 +0100
committerShauren <shauren.trinity@gmail.com>2024-03-01 00:23:09 +0100
commitede97a52e9077cca59e1dffbc83fbce83fedd031 (patch)
tree63330ebb20494c304bb3e6be3277f964785a3641
parent70121171beca7a0851d534237aa259a83ae9cdf1 (diff)
Core/Spells: Store truncated (only up to millisecond precision) cooldown times
-rw-r--r--src/server/game/Spells/SpellHistory.cpp96
-rw-r--r--src/server/game/Spells/SpellHistory.h25
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;