TrinityCore
Loading...
Searching...
No Matches
SpellHistory Class Reference

#include <SpellHistory.h>

Classes

struct  ChargeEntry
 
struct  CooldownEntry
 
struct  PersistenceHelper
 
struct  PersistenceHelper< Pet >
 
struct  PersistenceHelper< Player >
 

Public Types

using Clock = std::chrono::system_clock
 
using Duration = Milliseconds
 
using ChargeEntryCollection = std::deque< ChargeEntry >
 
using CooldownStorageType = std::unordered_map< uint32, CooldownEntry >
 
using CategoryCooldownStorageType = std::unordered_map< uint32, CooldownEntry * >
 
using ChargeStorageType = std::unordered_map< uint32, ChargeEntryCollection >
 
using GlobalCooldownStorageType = std::unordered_map< uint32, Clock::time_point >
 

Public Member Functions

 SpellHistory (Unit *owner)
 
 ~SpellHistory ()
 
 SpellHistory (SpellHistory const &)=delete
 
 SpellHistory (SpellHistory &&)=delete
 
SpellHistoryoperator= (SpellHistory const &)=delete
 
SpellHistoryoperator= (SpellHistory &&)=delete
 
template<class OwnerType >
void LoadFromDB (PreparedQueryResult cooldownsResult, PreparedQueryResult chargesResult)
 
template<class OwnerType >
void SaveToDB (CharacterDatabaseTransaction trans)
 
void Update ()
 
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 StartCooldown (SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool onHold=false, Optional< Duration > forcedCooldown={})
 
void SendCooldownEvent (SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool startCooldown=true)
 
void AddCooldown (uint32 spellId, uint32 itemId, Duration cooldownDuration)
 
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, bool withoutCategoryCooldown=false)
 
void ModifyCooldown (SpellInfo const *spellInfo, Duration cooldownMod, bool withoutCategoryCooldown=false)
 
template<typename Predicate >
void ModifyCoooldowns (Predicate &&predicate, Duration cooldownMod, bool withoutCategoryCooldown=false)
 
void ResetCooldown (uint32 spellId, bool update=false)
 
template<typename Predicate >
void ResetCooldowns (Predicate predicate, bool update=false)
 
void ResetAllCooldowns ()
 
bool HasCooldown (SpellInfo const *spellInfo, uint32 itemId=0) const
 
bool HasCooldown (uint32 spellId, uint32 itemId=0) const
 
Duration GetRemainingCooldown (SpellInfo const *spellInfo) const
 
Duration GetRemainingCategoryCooldown (uint32 categoryId) const
 
Duration GetRemainingCategoryCooldown (SpellInfo const *spellInfo) const
 
void LockSpellSchool (SpellSchoolMask schoolMask, Duration lockoutTime)
 
bool IsSchoolLocked (SpellSchoolMask schoolMask) const
 
bool ConsumeCharge (uint32 chargeCategoryId)
 
void ModifyChargeRecoveryTime (uint32 chargeCategoryId, Duration cooldownMod)
 
void RestoreCharge (uint32 chargeCategoryId)
 
void ResetCharges (uint32 chargeCategoryId)
 
void ResetAllCharges ()
 
bool HasCharge (uint32 chargeCategoryId) const
 
int32 GetMaxCharges (uint32 chargeCategoryId) const
 
int32 GetChargeRecoveryTime (uint32 chargeCategoryId) const
 
bool HasGlobalCooldown (SpellInfo const *spellInfo) const
 
void AddGlobalCooldown (SpellInfo const *spellInfo, Duration duration)
 
void CancelGlobalCooldown (SpellInfo const *spellInfo)
 
void SaveCooldownStateBeforeDuel ()
 
void RestoreCooldownStateAfterDuel ()
 
template<>
void WritePacket (WorldPackets::Spells::SendSpellHistory *sendSpellHistory) const
 
template<>
void WritePacket (WorldPackets::Spells::SendSpellCharges *sendSpellCharges) const
 
template<>
void WritePacket (WorldPackets::Pet::PetSpells *petSpells) const
 

Static Public Attributes

static Duration const InfinityCooldownDelay = Seconds(MONTH)
 

Private Member Functions

PlayerGetPlayerOwner () const
 
void ModifySpellCooldown (uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown)
 
void ModifySpellCooldown (CooldownStorageType::iterator &itr, Duration cooldownMod, bool withoutCategoryCooldown)
 
void ResetCooldown (CooldownStorageType::iterator &itr, bool update=false)
 
void SendClearCooldowns (std::vector< int32 > const &cooldowns) const
 
CooldownStorageType::iterator EraseCooldown (CooldownStorageType::iterator itr)
 
void SendSetSpellCharges (uint32 chargeCategoryId, ChargeEntryCollection const &chargeCollection)
 

Static Private Member Functions

static void GetCooldownDurations (SpellInfo const *spellInfo, uint32 itemId, Duration *cooldown, uint32 *categoryId, Duration *categoryCooldown)
 

Private Attributes

Unit_owner
 
CooldownStorageType _spellCooldowns
 
CooldownStorageType _spellCooldownsBeforeDuel
 
CategoryCooldownStorageType _categoryCooldowns
 
Clock::time_point _schoolLockouts [MAX_SPELL_SCHOOL]
 
ChargeStorageType _categoryCharges
 
GlobalCooldownStorageType _globalCooldowns
 

Detailed Description

Definition at line 46 of file SpellHistory.h.

Member Typedef Documentation

◆ CategoryCooldownStorageType

Definition at line 74 of file SpellHistory.h.

◆ ChargeEntryCollection

Definition at line 72 of file SpellHistory.h.

◆ ChargeStorageType

Definition at line 75 of file SpellHistory.h.

◆ Clock

using SpellHistory::Clock = std::chrono::system_clock

Definition at line 49 of file SpellHistory.h.

◆ CooldownStorageType

Definition at line 73 of file SpellHistory.h.

◆ Duration

Definition at line 50 of file SpellHistory.h.

◆ GlobalCooldownStorageType

using SpellHistory::GlobalCooldownStorageType = std::unordered_map<uint32 , Clock::time_point>

Definition at line 76 of file SpellHistory.h.

Constructor & Destructor Documentation

◆ SpellHistory() [1/3]

SpellHistory::SpellHistory ( Unit owner)
explicit

Definition at line 139 of file SpellHistory.cpp.

139 : _owner(owner), _schoolLockouts()
140{
141}
Clock::time_point _schoolLockouts[MAX_SPELL_SCHOOL]
Definition: SpellHistory.h:198

◆ ~SpellHistory()

SpellHistory::~SpellHistory ( )
default

◆ SpellHistory() [2/3]

SpellHistory::SpellHistory ( SpellHistory const &  )
delete

◆ SpellHistory() [3/3]

SpellHistory::SpellHistory ( SpellHistory &&  )
delete

Member Function Documentation

◆ AddCooldown() [1/2]

void SpellHistory::AddCooldown ( uint32  spellId,
uint32  itemId,
Clock::time_point  cooldownEnd,
uint32  categoryId,
Clock::time_point  categoryEnd,
bool  onHold = false 
)

Definition at line 553 of file SpellHistory.cpp.

554{
555 CooldownEntry& cooldownEntry = _spellCooldowns[spellId];
556 // scripts can start multiple cooldowns for a given spell, only store the longest one
557 if (cooldownEnd > cooldownEntry.CooldownEnd || categoryEnd > cooldownEntry.CategoryEnd || onHold)
558 {
559 cooldownEntry.SpellId = spellId;
560 cooldownEntry.CooldownEnd = cooldownEnd;
561 cooldownEntry.ItemId = itemId;
562 cooldownEntry.CategoryId = categoryId;
563 cooldownEntry.CategoryEnd = categoryEnd;
564 cooldownEntry.OnHold = onHold;
565
566 if (categoryId)
567 _categoryCooldowns[categoryId] = &cooldownEntry;
568 }
569}
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:195
CategoryCooldownStorageType _categoryCooldowns
Definition: SpellHistory.h:197

◆ AddCooldown() [2/2]

void SpellHistory::AddCooldown ( uint32  spellId,
uint32  itemId,
Duration  cooldownDuration 
)
inline

Definition at line 107 of file SpellHistory.h.

108 {
109 Clock::time_point now = GameTime::GetTime<Clock>();
110 AddCooldown(spellId, itemId, now + cooldownDuration, 0, now);
111 }
void AddCooldown(uint32 spellId, uint32 itemId, Duration cooldownDuration)
Definition: SpellHistory.h:107
+ Here is the caller graph for this function:

◆ AddGlobalCooldown()

void SpellHistory::AddGlobalCooldown ( SpellInfo const *  spellInfo,
Duration  duration 
)

Definition at line 940 of file SpellHistory.cpp.

941{
942 _globalCooldowns[spellInfo->StartRecoveryCategory] = Clock::now() + duration;
943}
GlobalCooldownStorageType _globalCooldowns
Definition: SpellHistory.h:200
+ Here is the caller graph for this function:

◆ CancelGlobalCooldown()

void SpellHistory::CancelGlobalCooldown ( SpellInfo const *  spellInfo)

Definition at line 945 of file SpellHistory.cpp.

946{
947 _globalCooldowns[spellInfo->StartRecoveryCategory] = Clock::time_point(Clock::duration(0));
948}
+ Here is the caller graph for this function:

◆ ConsumeCharge()

bool SpellHistory::ConsumeCharge ( uint32  chargeCategoryId)

Definition at line 802 of file SpellHistory.cpp.

803{
804 if (!sSpellCategoryStore.LookupEntry(chargeCategoryId))
805 return false;
806
807 int32 chargeRecovery = GetChargeRecoveryTime(chargeCategoryId);
808 if (chargeRecovery > 0 && GetMaxCharges(chargeCategoryId) > 0)
809 {
810 Clock::time_point recoveryStart;
811 std::deque<ChargeEntry>& charges = _categoryCharges[chargeCategoryId];
812 if (charges.empty())
813 recoveryStart = GameTime::GetTime<Clock>();
814 else
815 recoveryStart = charges.back().RechargeEnd;
816
817 charges.emplace_back(recoveryStart, Milliseconds(chargeRecovery));
818 return true;
819 }
820
821 return false;
822}
DB2Storage< SpellCategoryEntry > sSpellCategoryStore("SpellCategory.db2", &SpellCategoryLoadInfo::Instance)
int32_t int32
Definition: Define.h:139
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:29
int32 GetMaxCharges(uint32 chargeCategoryId) const
int32 GetChargeRecoveryTime(uint32 chargeCategoryId) const
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:199
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ EraseCooldown()

CooldownStorageType::iterator SpellHistory::EraseCooldown ( CooldownStorageType::iterator  itr)
inlineprivate

Definition at line 184 of file SpellHistory.h.

185 {
186 _categoryCooldowns.erase(itr->second.CategoryId);
187 return _spellCooldowns.erase(itr);
188 }
+ Here is the caller graph for this function:

◆ GetChargeRecoveryTime()

int32 SpellHistory::GetChargeRecoveryTime ( uint32  chargeCategoryId) const

Definition at line 913 of file SpellHistory.cpp.

914{
915 SpellCategoryEntry const* chargeCategoryEntry = sSpellCategoryStore.LookupEntry(chargeCategoryId);
916 if (!chargeCategoryEntry)
917 return 0;
918
919 int32 recoveryTime = chargeCategoryEntry->ChargeRecoveryTime;
921
922 float recoveryTimeF = float(recoveryTime);
924
926 recoveryTimeF *= _owner->m_unitData->ModSpellHaste;
927
929 recoveryTimeF *= _owner->m_unitData->ModHasteRegen;
930
931 return int32(std::floor(recoveryTimeF));
932}
@ SPELL_AURA_CHARGE_RECOVERY_MOD
@ SPELL_AURA_CHARGE_RECOVERY_AFFECTED_BY_HASTE
@ SPELL_AURA_CHARGE_RECOVERY_MULTIPLIER
@ SPELL_AURA_CHARGE_RECOVERY_AFFECTED_BY_HASTE_REGEN
UF::UpdateField< UF::UnitData, 0, TYPEID_UNIT > m_unitData
Definition: Unit.h:1904
float GetTotalAuraMultiplierByMiscValue(AuraType auraType, int32 misc_value) const
Definition: Unit.cpp:4910
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:4585
int32 GetTotalAuraModifierByMiscValue(AuraType auraType, int32 misc_value) const
Definition: Unit.cpp:4900
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetCooldownDurations()

void SpellHistory::GetCooldownDurations ( SpellInfo const *  spellInfo,
uint32  itemId,
Duration cooldown,
uint32 categoryId,
Duration categoryCooldown 
)
staticprivate

Definition at line 980 of file SpellHistory.cpp.

981{
982 ASSERT(cooldown || categoryId || categoryCooldown);
983 Duration tmpCooldown = Duration::min();
984 uint32 tmpCategoryId = 0;
985 Duration tmpCategoryCooldown = Duration::min();
986
987 // cooldown information stored in ItemEffect.db2, overriding normal cooldown and category
988 if (itemId)
989 {
990 if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId))
991 {
992 for (ItemEffectEntry const* itemEffect : proto->Effects)
993 {
994 if (uint32(itemEffect->SpellID) == spellInfo->Id)
995 {
996 tmpCooldown = Milliseconds(itemEffect->CoolDownMSec);
997 tmpCategoryId = itemEffect->SpellCategoryID;
998 tmpCategoryCooldown = Milliseconds(itemEffect->CategoryCoolDownMSec);
999 break;
1000 }
1001 }
1002 }
1003 }
1004
1005 // if no cooldown found above then base at DBC data
1006 if (tmpCooldown < Duration::zero() && tmpCategoryCooldown < Duration::zero())
1007 {
1008 tmpCooldown = Milliseconds(spellInfo->RecoveryTime);
1009 tmpCategoryId = spellInfo->GetCategory();
1010 tmpCategoryCooldown = Milliseconds(spellInfo->CategoryRecoveryTime);
1011 }
1012
1013 if (cooldown)
1014 *cooldown = tmpCooldown;
1015 if (categoryId)
1016 *categoryId = tmpCategoryId;
1017 if (categoryCooldown)
1018 *categoryCooldown = tmpCategoryCooldown;
1019}
uint32_t uint32
Definition: Define.h:143
#define ASSERT
Definition: Errors.h:68
#define sObjectMgr
Definition: ObjectMgr.h:1972
Milliseconds Duration
Definition: SpellHistory.h:50
uint16 SpellCategoryID
int32 CategoryCoolDownMSec
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetMaxCharges()

int32 SpellHistory::GetMaxCharges ( uint32  chargeCategoryId) const

Definition at line 902 of file SpellHistory.cpp.

903{
904 SpellCategoryEntry const* chargeCategoryEntry = sSpellCategoryStore.LookupEntry(chargeCategoryId);
905 if (!chargeCategoryEntry)
906 return 0;
907
908 uint32 charges = chargeCategoryEntry->MaxCharges;
910 return charges;
911}
@ SPELL_AURA_MOD_MAX_CHARGES
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetPlayerOwner()

Player * SpellHistory::GetPlayerOwner ( ) const
private

Definition at line 950 of file SpellHistory.cpp.

951{
953}
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Object.cpp:2226
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetRemainingCategoryCooldown() [1/2]

SpellHistory::Duration SpellHistory::GetRemainingCategoryCooldown ( SpellInfo const *  spellInfo) const

Definition at line 730 of file SpellHistory.cpp.

731{
732 return GetRemainingCategoryCooldown(spellInfo->GetCategory());
733}
Duration GetRemainingCategoryCooldown(uint32 categoryId) const
+ Here is the call graph for this function:

◆ GetRemainingCategoryCooldown() [2/2]

SpellHistory::Duration SpellHistory::GetRemainingCategoryCooldown ( uint32  categoryId) const

Definition at line 713 of file SpellHistory.cpp.

714{
715 Clock::time_point end;
716 auto catItr = _categoryCooldowns.find(categoryId);
717 if (catItr == _categoryCooldowns.end())
718 return Duration::zero();
719
720 end = catItr->second->CategoryEnd;
721
722 Clock::time_point now = GameTime::GetTime<Clock>();
723 if (end < now)
724 return Duration::zero();
725
726 Clock::duration remaining = end - now;
727 return std::chrono::duration_cast<Milliseconds>(remaining);
728}
+ Here is the caller graph for this function:

◆ GetRemainingCooldown()

SpellHistory::Duration SpellHistory::GetRemainingCooldown ( SpellInfo const *  spellInfo) const

Definition at line 690 of file SpellHistory.cpp.

691{
692 Clock::time_point end;
693 auto itr = _spellCooldowns.find(spellInfo->Id);
694 if (itr != _spellCooldowns.end())
695 end = itr->second.CooldownEnd;
696 else
697 {
698 auto catItr = _categoryCooldowns.find(spellInfo->GetCategory());
699 if (catItr == _categoryCooldowns.end())
700 return Duration::zero();
701
702 end = catItr->second->CategoryEnd;
703 }
704
705 Clock::time_point now = GameTime::GetTime<Clock>();
706 if (end < now)
707 return Duration::zero();
708
709 Clock::duration remaining = end - now;
710 return std::chrono::duration_cast<Milliseconds>(remaining);
711}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HandleCooldowns() [1/2]

void SpellHistory::HandleCooldowns ( SpellInfo const *  spellInfo,
Item const *  item,
Spell spell = nullptr 
)

Definition at line 246 of file SpellHistory.cpp.

247{
248 HandleCooldowns(spellInfo, item ? item->GetEntry() : 0, spell);
249}
void HandleCooldowns(SpellInfo const *spellInfo, Item const *item, Spell *spell=nullptr)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HandleCooldowns() [2/2]

void SpellHistory::HandleCooldowns ( SpellInfo const *  spellInfo,
uint32  itemId,
Spell spell = nullptr 
)

Definition at line 251 of file SpellHistory.cpp.

252{
253 if (spell && spell->IsIgnoringCooldowns())
254 return;
255
256 if (ConsumeCharge(spellInfo->ChargeCategoryId))
257 return;
258
259 if (Player* player = _owner->ToPlayer())
260 {
261 // potions start cooldown until exiting combat
262 if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemId))
263 {
264 if (itemTemplate->IsPotion() || spellInfo->IsCooldownStartedOnEvent())
265 {
266 player->SetLastPotionId(itemId);
267 return;
268 }
269 }
270 }
271
272 if (spellInfo->IsCooldownStartedOnEvent() || spellInfo->IsPassive())
273 return;
274
275 StartCooldown(spellInfo, itemId, spell);
276}
static Player * ToPlayer(Object *o)
Definition: Object.h:199
bool ConsumeCharge(uint32 chargeCategoryId)
bool IsIgnoringCooldowns() const
Definition: Spell.cpp:7999
+ Here is the call graph for this function:

◆ HasCharge()

bool SpellHistory::HasCharge ( uint32  chargeCategoryId) const

Definition at line 888 of file SpellHistory.cpp.

889{
890 if (!sSpellCategoryStore.LookupEntry(chargeCategoryId))
891 return true;
892
893 // Check if the spell is currently using charges (untalented warlock Dark Soul)
894 int32 maxCharges = GetMaxCharges(chargeCategoryId);
895 if (maxCharges <= 0)
896 return true;
897
898 auto itr = _categoryCharges.find(chargeCategoryId);
899 return itr == _categoryCharges.end() || int32(itr->second.size()) < maxCharges;
900}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HasCooldown() [1/2]

bool SpellHistory::HasCooldown ( SpellInfo const *  spellInfo,
uint32  itemId = 0 
) const

Definition at line 669 of file SpellHistory.cpp.

670{
671 if (_spellCooldowns.count(spellInfo->Id) != 0)
672 return true;
673
674 if (spellInfo->CooldownAuraSpellId && _owner->HasAura(spellInfo->CooldownAuraSpellId))
675 return true;
676
677 uint32 category = 0;
678 GetCooldownDurations(spellInfo, itemId, nullptr, &category, nullptr);
679 if (!category)
680 return false;
681
682 return _categoryCooldowns.count(category) != 0;
683}
static void GetCooldownDurations(SpellInfo const *spellInfo, uint32 itemId, Duration *cooldown, uint32 *categoryId, Duration *categoryCooldown)
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
Definition: Unit.cpp:4575
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HasCooldown() [2/2]

bool SpellHistory::HasCooldown ( uint32  spellId,
uint32  itemId = 0 
) const

Definition at line 685 of file SpellHistory.cpp.

686{
687 return HasCooldown(sSpellMgr->AssertSpellInfo(spellId, _owner->GetMap()->GetDifficultyID()), itemId);
688}
#define sSpellMgr
Definition: SpellMgr.h:824
Difficulty GetDifficultyID() const
Definition: Map.h:307
bool HasCooldown(SpellInfo const *spellInfo, uint32 itemId=0) const
Map * GetMap() const
Definition: Object.h:611
+ Here is the call graph for this function:

◆ HasGlobalCooldown()

bool SpellHistory::HasGlobalCooldown ( SpellInfo const *  spellInfo) const

Definition at line 934 of file SpellHistory.cpp.

935{
936 auto itr = _globalCooldowns.find(spellInfo->StartRecoveryCategory);
937 return itr != _globalCooldowns.end() && itr->second > Clock::now();
938}
+ Here is the caller graph for this function:

◆ IsReady()

bool SpellHistory::IsReady ( SpellInfo const *  spellInfo,
uint32  itemId = 0 
) const

Definition at line 278 of file SpellHistory.cpp.

279{
280 if (spellInfo->PreventionType & SPELL_PREVENTION_TYPE_SILENCE)
281 if (IsSchoolLocked(spellInfo->GetSchoolMask()))
282 return false;
283
284 if (HasCooldown(spellInfo, itemId))
285 return false;
286
287 if (!HasCharge(spellInfo->ChargeCategoryId))
288 return false;
289
290 return true;
291}
@ SPELL_PREVENTION_TYPE_SILENCE
bool HasCharge(uint32 chargeCategoryId) const
bool IsSchoolLocked(SpellSchoolMask schoolMask) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ IsSchoolLocked()

bool SpellHistory::IsSchoolLocked ( SpellSchoolMask  schoolMask) const

Definition at line 791 of file SpellHistory.cpp.

792{
793 Clock::time_point now = GameTime::GetTime<Clock>();
794 for (uint32 i = 0; i < MAX_SPELL_SCHOOL; ++i)
795 if (SpellSchoolMask(1 << i) & schoolMask)
796 if (_schoolLockouts[i] > now)
797 return true;
798
799 return false;
800}
SpellSchoolMask
@ MAX_SPELL_SCHOOL
+ Here is the caller graph for this function:

◆ LoadFromDB()

template<class OwnerType >
template void SpellHistory::LoadFromDB< Pet > ( PreparedQueryResult  cooldownsResult,
PreparedQueryResult  chargesResult 
)

Definition at line 146 of file SpellHistory.cpp.

147{
148 using StatementInfo = PersistenceHelper<OwnerType>;
149
150 if (cooldownsResult)
151 {
152 do
153 {
154 uint32 spellId;
155 CooldownEntry cooldown;
156 if (StatementInfo::ReadCooldown(cooldownsResult->Fetch(), &spellId, &cooldown))
157 {
158 _spellCooldowns[spellId] = cooldown;
159 if (cooldown.CategoryId)
160 _categoryCooldowns[cooldown.CategoryId] = &_spellCooldowns[spellId];
161 }
162
163 } while (cooldownsResult->NextRow());
164 }
165
166 if (chargesResult)
167 {
168 do
169 {
170 Field* fields = chargesResult->Fetch();
171 uint32 categoryId = 0;
172 ChargeEntry charges;
173 if (StatementInfo::ReadCharge(fields, &categoryId, &charges))
174 _categoryCharges[categoryId].push_back(charges);
175
176 } while (chargesResult->NextRow());
177 }
178}
Class used to access individual fields of database query result.
Definition: Field.h:84
+ Here is the caller graph for this function:

◆ LockSpellSchool()

void SpellHistory::LockSpellSchool ( SpellSchoolMask  schoolMask,
Duration  lockoutTime 
)

Definition at line 735 of file SpellHistory.cpp.

736{
737 Clock::time_point now = GameTime::GetTime<Clock>();
738 Clock::time_point lockoutEnd = now + lockoutTime;
739 for (uint32 i = 0; i < MAX_SPELL_SCHOOL; ++i)
740 if (SpellSchoolMask(1 << i) & schoolMask)
741 _schoolLockouts[i] = lockoutEnd;
742
743 std::set<uint32> knownSpells;
744 if (Player* plrOwner = _owner->ToPlayer())
745 {
746 for (auto const& p : plrOwner->GetSpellMap())
747 if (p.second.state != PLAYERSPELL_REMOVED)
748 knownSpells.insert(p.first);
749 }
750 else if (Pet* petOwner = _owner->ToPet())
751 {
752 for (auto const& p : petOwner->m_spells)
753 if (p.second.state != PETSPELL_REMOVED)
754 knownSpells.insert(p.first);
755 }
756 else
757 {
758 Creature* creatureOwner = _owner->ToCreature();
759 for (uint32 spell : creatureOwner->m_spells)
760 if (spell)
761 knownSpells.insert(spell);
762 }
763
765 spellCooldown.Caster = _owner->GetGUID();
767 for (uint32 spellId : knownSpells)
768 {
769 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(spellId, _owner->GetMap()->GetDifficultyID());
770 if (spellInfo->IsCooldownStartedOnEvent())
771 continue;
772
774 continue;
775
776 if (!(schoolMask & spellInfo->GetSchoolMask()))
777 continue;
778
779 if (GetRemainingCooldown(spellInfo) < lockoutTime)
780 AddCooldown(spellId, 0, lockoutEnd, 0, now);
781
782 // always send cooldown, even if it will be shorter than already existing cooldown for LossOfControl UI
783 spellCooldown.SpellCooldowns.emplace_back(spellId, lockoutTime.count());
784 }
785
786 if (Player* player = GetPlayerOwner())
787 if (!spellCooldown.SpellCooldowns.empty())
788 player->SendDirectMessage(spellCooldown.Write());
789}
@ PETSPELL_REMOVED
Definition: PetDefines.h:66
@ PLAYERSPELL_REMOVED
Definition: Player.h:181
@ SPELL_COOLDOWN_FLAG_LOSS_OF_CONTROL_UI
Shows interrupt cooldown in loss of control ui.
Definition: SpellHistory.h:42
uint32 m_spells[MAX_CREATURE_SPELLS]
Definition: Creature.h:266
static Creature * ToCreature(Object *o)
Definition: Object.h:205
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:157
Definition: Pet.h:46
Duration GetRemainingCooldown(SpellInfo const *spellInfo) const
Player * GetPlayerOwner() const
uint32 PreventionType
Definition: SpellInfo.h:412
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1626
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:2414
Pet * ToPet()
Definition: Unit.h:1850
WorldPacket const * Write() override
std::vector< SpellCooldownStruct > SpellCooldowns
Definition: SpellPackets.h:590
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ModifyChargeRecoveryTime()

void SpellHistory::ModifyChargeRecoveryTime ( uint32  chargeCategoryId,
Duration  cooldownMod 
)

Definition at line 824 of file SpellHistory.cpp.

825{
826 SpellCategoryEntry const* chargeCategoryEntry = sSpellCategoryStore.LookupEntry(chargeCategoryId);
827 if (!chargeCategoryEntry)
828 return;
829
830 auto itr = _categoryCharges.find(chargeCategoryId);
831 if (itr == _categoryCharges.end() || itr->second.empty())
832 return;
833
834 Clock::time_point now = GameTime::GetTime<Clock>();
835
836 for (ChargeEntry& entry : itr->second)
837 {
838 entry.RechargeStart += cooldownMod;
839 entry.RechargeEnd += cooldownMod;
840 }
841
842 while (!itr->second.empty() && itr->second.front().RechargeEnd < now)
843 itr->second.pop_front();
844
845 SendSetSpellCharges(chargeCategoryId, itr->second);
846}
void SendSetSpellCharges(uint32 chargeCategoryId, ChargeEntryCollection const &chargeCollection)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ModifyCooldown() [1/2]

void SpellHistory::ModifyCooldown ( SpellInfo const *  spellInfo,
Duration  cooldownMod,
bool  withoutCategoryCooldown = false 
)

Definition at line 616 of file SpellHistory.cpp.

617{
618 if (!cooldownMod.count())
619 return;
620
621 if (GetChargeRecoveryTime(spellInfo->ChargeCategoryId) > 0 && GetMaxCharges(spellInfo->ChargeCategoryId) > 0)
622 ModifyChargeRecoveryTime(spellInfo->ChargeCategoryId, cooldownMod);
623 else
624 ModifySpellCooldown(spellInfo->Id, cooldownMod, withoutCategoryCooldown);
625}
void ModifyChargeRecoveryTime(uint32 chargeCategoryId, Duration cooldownMod)
void ModifySpellCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown)
+ Here is the call graph for this function:

◆ ModifyCooldown() [2/2]

void SpellHistory::ModifyCooldown ( uint32  spellId,
Duration  cooldownMod,
bool  withoutCategoryCooldown = false 
)

Definition at line 610 of file SpellHistory.cpp.

611{
612 if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, _owner->GetMap()->GetDifficultyID()))
613 ModifyCooldown(spellInfo, cooldownMod, withoutCategoryCooldown);
614}
void ModifyCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown=false)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ModifyCoooldowns()

template<typename Predicate >
void SpellHistory::ModifyCoooldowns ( Predicate &&  predicate,
Duration  cooldownMod,
bool  withoutCategoryCooldown = false 
)
inline

Definition at line 117 of file SpellHistory.h.

118 {
119 for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end();)
120 {
121 if (predicate(itr))
122 ModifySpellCooldown(itr, cooldownMod, withoutCategoryCooldown);
123 else
124 ++itr;
125 }
126 }
+ Here is the caller graph for this function:

◆ ModifySpellCooldown() [1/2]

void SpellHistory::ModifySpellCooldown ( CooldownStorageType::iterator &  itr,
Duration  cooldownMod,
bool  withoutCategoryCooldown 
)
private

Definition at line 580 of file SpellHistory.cpp.

581{
582 Clock::time_point now = GameTime::GetTime<Clock>();
583
584 itr->second.CooldownEnd += cooldownMod;
585
586 if (itr->second.CategoryId)
587 {
588 if (!withoutCategoryCooldown)
589 itr->second.CategoryEnd += cooldownMod;
590
591 // Because category cooldown existence is tied to regular cooldown, we cannot allow a situation where regular cooldown is shorter than category
592 if (itr->second.CooldownEnd < itr->second.CategoryEnd)
593 itr->second.CooldownEnd = itr->second.CategoryEnd;
594 }
595
596 if (Player* playerOwner = GetPlayerOwner())
597 {
599 modifyCooldown.IsPet = _owner != playerOwner;
600 modifyCooldown.SpellID = itr->second.SpellId;
601 modifyCooldown.DeltaTime = std::chrono::duration_cast<Milliseconds>(cooldownMod).count();
602 modifyCooldown.WithoutCategoryCooldown = withoutCategoryCooldown;
603 playerOwner->SendDirectMessage(modifyCooldown.Write());
604 }
605
606 if (itr->second.CooldownEnd <= now)
607 itr = EraseCooldown(itr);
608}
CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr)
Definition: SpellHistory.h:184
WorldPacket const * Write() override
+ Here is the call graph for this function:

◆ ModifySpellCooldown() [2/2]

void SpellHistory::ModifySpellCooldown ( uint32  spellId,
Duration  cooldownMod,
bool  withoutCategoryCooldown 
)
private

Definition at line 571 of file SpellHistory.cpp.

572{
573 auto itr = _spellCooldowns.find(spellId);
574 if (!cooldownMod.count() || itr == _spellCooldowns.end())
575 return;
576
577 ModifySpellCooldown(itr, cooldownMod, withoutCategoryCooldown);
578}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ operator=() [1/2]

SpellHistory & SpellHistory::operator= ( SpellHistory &&  )
delete

◆ operator=() [2/2]

SpellHistory & SpellHistory::operator= ( SpellHistory const &  )
delete

◆ ResetAllCharges()

void SpellHistory::ResetAllCharges ( )

Definition at line 876 of file SpellHistory.cpp.

877{
878 _categoryCharges.clear();
879
880 if (Player* player = GetPlayerOwner())
881 {
883 clearAllSpellCharges.IsPet = _owner != player;
884 player->SendDirectMessage(clearAllSpellCharges.Write());
885 }
886}
WorldPacket const * Write() override
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ResetAllCooldowns()

void SpellHistory::ResetAllCooldowns ( )

Definition at line 653 of file SpellHistory.cpp.

654{
655 if (GetPlayerOwner())
656 {
657 std::vector<int32> cooldowns;
658 cooldowns.reserve(_spellCooldowns.size());
659 for (auto const& p : _spellCooldowns)
660 cooldowns.push_back(p.first);
661
662 SendClearCooldowns(cooldowns);
663 }
664
665 _categoryCooldowns.clear();
666 _spellCooldowns.clear();
667}
void SendClearCooldowns(std::vector< int32 > const &cooldowns) const
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ResetCharges()

void SpellHistory::ResetCharges ( uint32  chargeCategoryId)

Definition at line 859 of file SpellHistory.cpp.

860{
861 auto itr = _categoryCharges.find(chargeCategoryId);
862 if (itr != _categoryCharges.end())
863 {
864 _categoryCharges.erase(itr);
865
866 if (Player* player = GetPlayerOwner())
867 {
869 clearSpellCharges.IsPet = _owner != player;
870 clearSpellCharges.Category = chargeCategoryId;
871 player->SendDirectMessage(clearSpellCharges.Write());
872 }
873 }
874}
WorldPacket const * Write() override
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ResetCooldown() [1/2]

void SpellHistory::ResetCooldown ( CooldownStorageType::iterator &  itr,
bool  update = false 
)
private

Definition at line 636 of file SpellHistory.cpp.

637{
638 if (update)
639 {
640 if (Player* playerOwner = GetPlayerOwner())
641 {
643 clearCooldown.IsPet = _owner != playerOwner;
644 clearCooldown.SpellID = itr->first;
645 clearCooldown.ClearOnHold = false;
646 playerOwner->SendDirectMessage(clearCooldown.Write());
647 }
648 }
649
650 itr = EraseCooldown(itr);
651}
WorldPacket const * Write() override
+ Here is the call graph for this function:

◆ ResetCooldown() [2/2]

void SpellHistory::ResetCooldown ( uint32  spellId,
bool  update = false 
)

Definition at line 627 of file SpellHistory.cpp.

628{
629 auto itr = _spellCooldowns.find(spellId);
630 if (itr == _spellCooldowns.end())
631 return;
632
633 ResetCooldown(itr, update);
634}
void ResetCooldown(uint32 spellId, bool update=false)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ResetCooldowns()

template<typename Predicate >
void SpellHistory::ResetCooldowns ( Predicate  predicate,
bool  update = false 
)
inline

Definition at line 130 of file SpellHistory.h.

131 {
132 std::vector<int32> resetCooldowns;
133 resetCooldowns.reserve(_spellCooldowns.size());
134 for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end();)
135 {
136 if (predicate(itr))
137 {
138 resetCooldowns.push_back(int32(itr->first));
139 ResetCooldown(itr, false);
140 }
141 else
142 ++itr;
143 }
144
145 if (update && !resetCooldowns.empty())
146 SendClearCooldowns(resetCooldowns);
147 }
+ Here is the caller graph for this function:

◆ RestoreCharge()

void SpellHistory::RestoreCharge ( uint32  chargeCategoryId)

Definition at line 848 of file SpellHistory.cpp.

849{
850 auto itr = _categoryCharges.find(chargeCategoryId);
851 if (itr != _categoryCharges.end() && !itr->second.empty())
852 {
853 itr->second.pop_back();
854
855 SendSetSpellCharges(chargeCategoryId, itr->second);
856 }
857}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ RestoreCooldownStateAfterDuel()

void SpellHistory::RestoreCooldownStateAfterDuel ( )

Definition at line 1026 of file SpellHistory.cpp.

1027{
1028 if (Player* player = _owner->ToPlayer())
1029 {
1030 // add all profession CDs created while in duel (if any)
1031 for (auto const& c : _spellCooldowns)
1032 {
1033 SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(c.first, DIFFICULTY_NONE);
1034
1035 if (spellInfo->RecoveryTime > 10 * MINUTE * IN_MILLISECONDS ||
1036 spellInfo->CategoryRecoveryTime > 10 * MINUTE * IN_MILLISECONDS)
1037 _spellCooldownsBeforeDuel[c.first] = _spellCooldowns[c.first];
1038 }
1039
1040 // check for spell with onHold active before and during the duel
1041 for (CooldownStorageType::value_type const& pair : _spellCooldownsBeforeDuel)
1042 {
1043 if (!pair.second.OnHold &&
1044 _spellCooldowns.find(pair.first) != _spellCooldowns.end() &&
1045 !_spellCooldowns[pair.first].OnHold)
1046 _spellCooldowns[pair.first] = _spellCooldownsBeforeDuel[pair.first];
1047 }
1048
1049 // update the client: restore old cooldowns
1051 spellCooldown.Caster = _owner->GetGUID();
1053
1054 for (auto const& c : _spellCooldowns)
1055 {
1056 Clock::time_point now = GameTime::GetTime<Clock>();
1057 uint32 cooldownDuration = uint32(c.second.CooldownEnd > now ? std::chrono::duration_cast<Milliseconds>(c.second.CooldownEnd - now).count() : 0);
1058
1059 // cooldownDuration must be between 0 and 10 minutes in order to avoid any visual bugs
1060 if (cooldownDuration <= 0 || cooldownDuration > 10 * MINUTE * IN_MILLISECONDS || c.second.OnHold)
1061 continue;
1062
1063 spellCooldown.SpellCooldowns.emplace_back(c.first, cooldownDuration);
1064 }
1065
1066 player->SendDirectMessage(spellCooldown.Write());
1067 }
1068}
@ IN_MILLISECONDS
Definition: Common.h:51
@ MINUTE
Definition: Common.h:45
@ DIFFICULTY_NONE
Definition: DBCEnums.h:733
@ SPELL_COOLDOWN_FLAG_INCLUDE_EVENT_COOLDOWNS
Starts GCD for spells that should start their cooldown on events, requires SPELL_COOLDOWN_FLAG_INCLUD...
Definition: SpellHistory.h:41
CooldownStorageType _spellCooldownsBeforeDuel
Definition: SpellHistory.h:196
uint32 RecoveryTime
Definition: SpellInfo.h:367
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:368
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SaveCooldownStateBeforeDuel()

void SpellHistory::SaveCooldownStateBeforeDuel ( )

Definition at line 1021 of file SpellHistory.cpp.

+ Here is the caller graph for this function:

◆ SaveToDB()

template<class OwnerType >
template void SpellHistory::SaveToDB< Pet > ( CharacterDatabaseTransaction  trans)

Definition at line 181 of file SpellHistory.cpp.

182{
183 using StatementInfo = PersistenceHelper<OwnerType>;
184
185 uint8 index = 0;
186 CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(StatementInfo::CooldownsDeleteStatement);
187 StatementInfo::SetIdentifier(stmt, index++, _owner);
188 trans->Append(stmt);
189
190 for (auto const& p : _spellCooldowns)
191 {
192 if (!p.second.OnHold)
193 {
194 index = 0;
195 stmt = CharacterDatabase.GetPreparedStatement(StatementInfo::CooldownsInsertStatement);
196 StatementInfo::SetIdentifier(stmt, index++, _owner);
197 StatementInfo::WriteCooldown(stmt, index, p);
198 trans->Append(stmt);
199 }
200 }
201
202 stmt = CharacterDatabase.GetPreparedStatement(StatementInfo::ChargesDeleteStatement);
203 StatementInfo::SetIdentifier(stmt, 0, _owner);
204 trans->Append(stmt);
205
206 for (auto const& p : _categoryCharges)
207 {
208 for (ChargeEntry const& charge : p.second)
209 {
210 index = 0;
211 stmt = CharacterDatabase.GetPreparedStatement(StatementInfo::ChargesInsertStatement);
212 StatementInfo::SetIdentifier(stmt, index++, _owner);
213 StatementInfo::WriteCharge(stmt, index, p.first, charge);
214 trans->Append(stmt);
215 }
216 }
217}
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21
uint8_t uint8
Definition: Define.h:145
+ Here is the caller graph for this function:

◆ SendClearCooldowns()

void SpellHistory::SendClearCooldowns ( std::vector< int32 > const &  cooldowns) const
private

Definition at line 955 of file SpellHistory.cpp.

956{
957 if (Player const* playerOwner = GetPlayerOwner())
958 {
960 clearCooldowns.IsPet = _owner != playerOwner;
961 clearCooldowns.SpellID = cooldowns;
962 playerOwner->SendDirectMessage(clearCooldowns.Write());
963 }
964}
WorldPacket const * Write() override
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SendCooldownEvent()

void SpellHistory::SendCooldownEvent ( SpellInfo const *  spellInfo,
uint32  itemId = 0,
Spell spell = nullptr,
bool  startCooldown = true 
)

Definition at line 528 of file SpellHistory.cpp.

529{
530 // Send activate cooldown timer (possible 0) at client side
531 if (Player* player = GetPlayerOwner())
532 {
533 uint32 category = spellInfo->GetCategory();
534 GetCooldownDurations(spellInfo, itemId, nullptr, &category, nullptr);
535
536 auto categoryItr = _categoryCooldowns.find(category);
537 if (categoryItr != _categoryCooldowns.end() && categoryItr->second->SpellId != spellInfo->Id)
538 {
539 player->SendDirectMessage(WorldPackets::Spells::CooldownEvent(player != _owner, categoryItr->second->SpellId).Write());
540
541 if (startCooldown)
542 StartCooldown(sSpellMgr->AssertSpellInfo(categoryItr->second->SpellId, _owner->GetMap()->GetDifficultyID()), itemId, spell);
543 }
544
545 player->SendDirectMessage(WorldPackets::Spells::CooldownEvent(player != _owner, spellInfo->Id).Write());
546 }
547
548 // start cooldowns at server side, if any
549 if (startCooldown)
550 StartCooldown(spellInfo, itemId, spell);
551}
WorldPacket const * Write() override
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SendSetSpellCharges()

void SpellHistory::SendSetSpellCharges ( uint32  chargeCategoryId,
ChargeEntryCollection const &  chargeCollection 
)
private

Definition at line 966 of file SpellHistory.cpp.

967{
968 if (Player* player = GetPlayerOwner())
969 {
971 setSpellCharges.Category = chargeCategoryId;
972 if (!chargeCollection.empty())
973 setSpellCharges.NextRecoveryTime = uint32(std::chrono::duration_cast<Milliseconds>(chargeCollection.front().RechargeEnd - Clock::now()).count());
974 setSpellCharges.ConsumedCharges = uint8(chargeCollection.size());
975 setSpellCharges.IsPet = player != _owner;
976 player->SendDirectMessage(setSpellCharges.Write());
977 }
978}
WorldPacket const * Write() override
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ StartCooldown()

void SpellHistory::StartCooldown ( SpellInfo const *  spellInfo,
uint32  itemId,
Spell spell = nullptr,
bool  onHold = false,
Optional< Duration forcedCooldown = {} 
)

Definition at line 405 of file SpellHistory.cpp.

406{
407 // init cooldown values
408 uint32 categoryId = 0;
409 Duration cooldown = Duration::zero();
410 Duration categoryCooldown = Duration::zero();
411
412 Clock::time_point curTime = GameTime::GetTime<Clock>();
413 Clock::time_point catrecTime;
414 Clock::time_point recTime;
415 bool needsCooldownPacket = false;
416
417 if (!forcedCooldown)
418 GetCooldownDurations(spellInfo, itemId, &cooldown, &categoryId, &categoryCooldown);
419 else
420 cooldown = *forcedCooldown;
421
422 // overwrite time for selected category
423 if (onHold)
424 {
425 // use +MONTH as infinite cooldown marker
426 catrecTime = categoryCooldown > Duration::zero() ? (curTime + InfinityCooldownDelay) : curTime;
427 recTime = cooldown > Duration::zero() ? (curTime + InfinityCooldownDelay) : catrecTime;
428 }
429 else
430 {
431 if (!forcedCooldown)
432 {
433 // Now we have cooldown data (if found any), time to apply mods
434 if (Player* modOwner = _owner->GetSpellModOwner())
435 {
436 auto applySpellMod = [&](Milliseconds& value)
437 {
438 int32 intValue = value.count();
439 modOwner->ApplySpellMod(spellInfo, SpellModOp::Cooldown, intValue, spell);
440 value = Milliseconds(intValue);
441 };
442
443 if (cooldown >= Duration::zero())
444 applySpellMod(cooldown);
445
446 if (categoryCooldown >= Clock::duration::zero() && !spellInfo->HasAttribute(SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS))
447 applySpellMod(categoryCooldown);
448 }
449
451 {
452 cooldown = Duration(int64(cooldown.count() * _owner->m_unitData->ModSpellHaste));
453 categoryCooldown = Duration(int64(categoryCooldown.count() * _owner->m_unitData->ModSpellHaste));
454 }
455
457 {
458 cooldown = Duration(int64(cooldown.count() * _owner->m_unitData->ModHasteRegen));
459 categoryCooldown = Duration(int64(categoryCooldown.count() * _owner->m_unitData->ModHasteRegen));
460 }
461
463 {
464 // Apply SPELL_AURA_MOD_COOLDOWN only to own spells
465 Player* playerOwner = GetPlayerOwner();
466 if (!playerOwner || playerOwner->HasSpell(spellInfo->Id))
467 {
468 needsCooldownPacket = true;
469 cooldown += Milliseconds(cooldownMod); // SPELL_AURA_MOD_COOLDOWN does not affect category cooldows, verified with shaman shocks
470 }
471 }
472
473 // Apply SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN modifiers
474 // Note: This aura applies its modifiers to all cooldowns of spells with set category, not to category cooldown only
475 if (categoryId)
476 {
478 {
479 if (cooldown > Duration::zero())
480 cooldown += Milliseconds(categoryModifier);
481
482 if (categoryCooldown > Duration::zero())
483 categoryCooldown += Milliseconds(categoryModifier);
484 }
485
486 SpellCategoryEntry const* categoryEntry = sSpellCategoryStore.AssertEntry(categoryId);
488 categoryCooldown = std::chrono::duration_cast<Milliseconds>(Clock::from_time_t(sWorld->GetNextDailyQuestsResetTime()) - Clock::now());
489 }
490 }
491 else
492 needsCooldownPacket = true;
493
494 // replace negative cooldowns by 0
495 if (cooldown < Duration::zero())
496 cooldown = Duration::zero();
497
498 if (categoryCooldown < Duration::zero())
499 categoryCooldown = Duration::zero();
500
501 // no cooldown after applying spell mods
502 if (cooldown == Duration::zero() && categoryCooldown == Duration::zero())
503 return;
504
505 catrecTime = categoryCooldown != Duration::zero() ? curTime + std::chrono::duration_cast<Clock::duration>(Milliseconds(categoryCooldown)) : curTime;
506 recTime = cooldown != Duration::zero() ? curTime + std::chrono::duration_cast<Clock::duration>(Milliseconds(cooldown)) : catrecTime;
507 }
508
509 // self spell cooldown
510 if (recTime != curTime)
511 {
512 AddCooldown(spellInfo->Id, itemId, recTime, categoryId, catrecTime, onHold);
513
514 if (needsCooldownPacket)
515 {
516 if (Player* playerOwner = GetPlayerOwner())
517 {
519 spellCooldown.Caster = _owner->GetGUID();
520 spellCooldown.Flags = SPELL_COOLDOWN_FLAG_NONE;
521 spellCooldown.SpellCooldowns.emplace_back(spellInfo->Id, uint32(cooldown.count()));
522 playerOwner->SendDirectMessage(spellCooldown.Write());
523 }
524 }
525 }
526}
@ SPELL_CATEGORY_FLAG_COOLDOWN_EXPIRES_AT_DAILY_RESET
Definition: DBCEnums.h:1736
int64_t int64
Definition: Define.h:138
@ SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS
@ SPELL_AURA_MOD_COOLDOWN_BY_HASTE_REGEN
@ SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN
@ SPELL_AURA_MOD_COOLDOWN
@ SPELL_AURA_MOD_SPELL_COOLDOWN_BY_HASTE
@ SPELL_COOLDOWN_FLAG_NONE
Definition: SpellHistory.h:39
void SendDirectMessage(WorldPacket const *data) const
Definition: Player.cpp:6288
bool HasSpell(uint32 spell) const override
Definition: Player.cpp:3765
static Duration const InfinityCooldownDelay
Definition: SpellHistory.h:102
int32 GetTotalAuraModifier(AuraType auraType) const
Definition: Unit.cpp:4840
bool HasAuraTypeWithAffectMask(AuraType auraType, SpellInfo const *affectedSpell) const
Definition: Unit.cpp:4607
Player * GetSpellModOwner() const
Definition: Object.cpp:2246
#define sWorld
Definition: World.h:961
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Update()

void SpellHistory::Update ( )

Definition at line 219 of file SpellHistory.cpp.

220{
221 Clock::time_point now = GameTime::GetTime<Clock>();
222 for (auto itr = _categoryCooldowns.begin(); itr != _categoryCooldowns.end();)
223 {
224 if (itr->second->CategoryEnd < now)
225 itr = _categoryCooldowns.erase(itr);
226 else
227 ++itr;
228 }
229
230 for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end();)
231 {
232 if (itr->second.CooldownEnd < now)
233 itr = EraseCooldown(itr);
234 else
235 ++itr;
236 }
237
238 for (auto& p : _categoryCharges)
239 {
240 std::deque<ChargeEntry>& chargeRefreshTimes = p.second;
241 while (!chargeRefreshTimes.empty() && chargeRefreshTimes.front().RechargeEnd <= now)
242 chargeRefreshTimes.pop_front();
243 }
244}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ WritePacket() [1/4]

template<class PacketType >
void SpellHistory::WritePacket ( PacketType *  packet) const

Definition at line 294 of file SpellHistory.cpp.

295{
296 static_assert(!std::is_same<PacketType, PacketType>::value /*static_assert(false)*/, "This packet is not supported.");
297}
+ Here is the caller graph for this function:

◆ WritePacket() [2/4]

template<>
void SpellHistory::WritePacket ( WorldPackets::Pet::PetSpells petSpells) const

Definition at line 358 of file SpellHistory.cpp.

359{
360 Clock::time_point now = GameTime::GetTime<Clock>();
361
362 petSpells->Cooldowns.reserve(_spellCooldowns.size());
363 for (auto const& p : _spellCooldowns)
364 {
366 petSpellCooldown.SpellID = p.first;
367 petSpellCooldown.Category = p.second.CategoryId;
368
369 if (!p.second.OnHold)
370 {
371 Milliseconds cooldownDuration = std::chrono::duration_cast<Milliseconds>(p.second.CooldownEnd - now);
372 if (cooldownDuration.count() <= 0)
373 continue;
374
375 petSpellCooldown.Duration = uint32(cooldownDuration.count());
376 Milliseconds categoryDuration = std::chrono::duration_cast<Milliseconds>(p.second.CategoryEnd - now);
377 if (categoryDuration.count() > 0)
378 petSpellCooldown.CategoryDuration = uint32(categoryDuration.count());
379 }
380 else
381 petSpellCooldown.CategoryDuration = 0x80000000;
382
383 petSpells->Cooldowns.push_back(petSpellCooldown);
384 }
385
386 petSpells->SpellHistory.reserve(_categoryCharges.size());
387 for (auto const& p : _categoryCharges)
388 {
389 if (!p.second.empty())
390 {
391 Milliseconds cooldownDuration = std::chrono::duration_cast<Milliseconds>(p.second.front().RechargeEnd - now);
392 if (cooldownDuration.count() <= 0)
393 continue;
394
396 petChargeEntry.CategoryID = p.first;
397 petChargeEntry.RecoveryTime = uint32(cooldownDuration.count());
398 petChargeEntry.ConsumedCharges = int8(p.second.size());
399
400 petSpells->SpellHistory.push_back(petChargeEntry);
401 }
402 }
403}
int8_t int8
Definition: Define.h:141
std::vector< PetSpellCooldown > Cooldowns
Definition: PetPackets.h:118
std::vector< PetSpellHistory > SpellHistory
Definition: PetPackets.h:119

◆ WritePacket() [3/4]

template<>
void SpellHistory::WritePacket ( WorldPackets::Spells::SendSpellCharges sendSpellCharges) const

Definition at line 335 of file SpellHistory.cpp.

336{
337 sendSpellCharges->Entries.reserve(_categoryCharges.size());
338
339 Clock::time_point now = GameTime::GetTime<Clock>();
340 for (auto const& p : _categoryCharges)
341 {
342 if (!p.second.empty())
343 {
344 Milliseconds cooldownDuration = std::chrono::duration_cast<Milliseconds>(p.second.front().RechargeEnd - now);
345 if (cooldownDuration.count() <= 0)
346 continue;
347
349 chargeEntry.Category = p.first;
350 chargeEntry.NextRecoveryTime = uint32(cooldownDuration.count());
351 chargeEntry.ConsumedCharges = uint8(p.second.size());
352 sendSpellCharges->Entries.push_back(chargeEntry);
353 }
354 }
355}
std::vector< SpellChargeEntry > Entries
Definition: SpellPackets.h:668

◆ WritePacket() [4/4]

template<>
void SpellHistory::WritePacket ( WorldPackets::Spells::SendSpellHistory sendSpellHistory) const

Definition at line 300 of file SpellHistory.cpp.

301{
302 sendSpellHistory->Entries.reserve(_spellCooldowns.size());
303
304 Clock::time_point now = GameTime::GetTime<Clock>();
305 for (auto const& p : _spellCooldowns)
306 {
308 historyEntry.SpellID = p.first;
309 historyEntry.ItemID = p.second.ItemId;
310
311 if (p.second.OnHold)
312 historyEntry.OnHold = true;
313 else
314 {
315 Milliseconds cooldownDuration = std::chrono::duration_cast<Milliseconds>(p.second.CooldownEnd - now);
316 if (cooldownDuration.count() <= 0)
317 continue;
318
319 Milliseconds categoryDuration = std::chrono::duration_cast<Milliseconds>(p.second.CategoryEnd - now);
320 if (categoryDuration.count() > 0)
321 {
322 historyEntry.Category = p.second.CategoryId;
323 historyEntry.CategoryRecoveryTime = uint32(categoryDuration.count());
324 }
325
326 if (cooldownDuration.count() > categoryDuration.count())
327 historyEntry.RecoveryTime = uint32(cooldownDuration.count());
328 }
329
330 sendSpellHistory->Entries.push_back(historyEntry);
331 }
332}
std::vector< SpellHistoryEntry > Entries
Definition: SpellPackets.h:615

Member Data Documentation

◆ _categoryCharges

ChargeStorageType SpellHistory::_categoryCharges
private

Definition at line 199 of file SpellHistory.h.

◆ _categoryCooldowns

CategoryCooldownStorageType SpellHistory::_categoryCooldowns
private

Definition at line 197 of file SpellHistory.h.

◆ _globalCooldowns

GlobalCooldownStorageType SpellHistory::_globalCooldowns
private

Definition at line 200 of file SpellHistory.h.

◆ _owner

Unit* SpellHistory::_owner
private

Definition at line 194 of file SpellHistory.h.

◆ _schoolLockouts

Clock::time_point SpellHistory::_schoolLockouts[MAX_SPELL_SCHOOL]
private

Definition at line 198 of file SpellHistory.h.

◆ _spellCooldowns

CooldownStorageType SpellHistory::_spellCooldowns
private

Definition at line 195 of file SpellHistory.h.

◆ _spellCooldownsBeforeDuel

CooldownStorageType SpellHistory::_spellCooldownsBeforeDuel
private

Definition at line 196 of file SpellHistory.h.

◆ InfinityCooldownDelay

SpellHistory::Duration const SpellHistory::InfinityCooldownDelay = Seconds(MONTH)
static

Definition at line 102 of file SpellHistory.h.


The documentation for this class was generated from the following files: