TrinityCore
Loading...
Searching...
No Matches
SpellHistory.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef SpellHistory_h__
19#define SpellHistory_h__
20
21#include "SharedDefines.h"
22#include "DatabaseEnvFwd.h"
23#include "Duration.h"
24#include "GameTime.h"
25#include "Optional.h"
26#include <deque>
27#include <vector>
28#include <unordered_map>
29
30class Item;
31class Player;
32class Spell;
33class SpellInfo;
34class Unit;
35
38{
44};
45
47{
48public:
49 using Clock = std::chrono::system_clock;
50 using Duration = Milliseconds; // Cooldowns are stored only with millisecond precision, not whatever Clock's precision is
51
53 {
54 uint32 SpellId = 0;
55 Clock::time_point CooldownEnd = Clock::time_point::min();
57 uint32 CategoryId = 0;
58 Clock::time_point CategoryEnd = Clock::time_point::min();
59 bool OnHold = false;
60 };
61
63 {
64 ChargeEntry() = default;
65 ChargeEntry(Clock::time_point startTime, Duration rechargeTime) : RechargeStart(startTime), RechargeEnd(startTime + rechargeTime) { }
66 ChargeEntry(Clock::time_point startTime, Clock::time_point endTime) : RechargeStart(startTime), RechargeEnd(endTime) { }
67
68 Clock::time_point RechargeStart;
69 Clock::time_point RechargeEnd;
70 };
71
72 using ChargeEntryCollection = std::deque<ChargeEntry>;
73 using CooldownStorageType = std::unordered_map<uint32 /*spellId*/, CooldownEntry>;
74 using CategoryCooldownStorageType = std::unordered_map<uint32 /*categoryId*/, CooldownEntry*>;
75 using ChargeStorageType = std::unordered_map<uint32 /*categoryId*/, ChargeEntryCollection>;
76 using GlobalCooldownStorageType = std::unordered_map<uint32 /*categoryId*/, Clock::time_point>;
77
78 explicit SpellHistory(Unit* owner);
80
81 SpellHistory(SpellHistory const&) = delete;
83
86
87 template<class OwnerType>
88 void LoadFromDB(PreparedQueryResult cooldownsResult, PreparedQueryResult chargesResult);
89
90 template<class OwnerType>
92
93 void Update();
94
95 void HandleCooldowns(SpellInfo const* spellInfo, Item const* item, Spell* spell = nullptr);
96 void HandleCooldowns(SpellInfo const* spellInfo, uint32 itemId, Spell* spell = nullptr);
97 bool IsReady(SpellInfo const* spellInfo, uint32 itemId = 0) const;
98 template<class PacketType>
99 void WritePacket(PacketType* packet) const;
100
101 // Cooldowns
102 static Duration const InfinityCooldownDelay; // used for set "infinity cooldowns" for spells and check
103
104 void StartCooldown(SpellInfo const* spellInfo, uint32 itemId, Spell* spell = nullptr, bool onHold = false, Optional<Duration> forcedCooldown = {});
105 void SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId = 0, Spell* spell = nullptr, bool startCooldown = true);
106
107 void AddCooldown(uint32 spellId, uint32 itemId, Duration cooldownDuration)
108 {
109 Clock::time_point now = GameTime::GetTime<Clock>();
110 AddCooldown(spellId, itemId, now + cooldownDuration, 0, now);
111 }
112
113 void AddCooldown(uint32 spellId, uint32 itemId, Clock::time_point cooldownEnd, uint32 categoryId, Clock::time_point categoryEnd, bool onHold = false);
114 void ModifyCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown = false);
115 void ModifyCooldown(SpellInfo const* spellInfo, Duration cooldownMod, bool withoutCategoryCooldown = false);
116 template<typename Predicate>
117 void ModifyCoooldowns(Predicate&& predicate, Duration cooldownMod, bool withoutCategoryCooldown = false)
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 }
127
128 void ResetCooldown(uint32 spellId, bool update = false);
129 template<typename Predicate>
130 void ResetCooldowns(Predicate predicate, bool update = false)
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 }
148
149 void ResetAllCooldowns();
150 bool HasCooldown(SpellInfo const* spellInfo, uint32 itemId = 0) const;
151 bool HasCooldown(uint32 spellId, uint32 itemId = 0) const;
152 Duration GetRemainingCooldown(SpellInfo const* spellInfo) const;
153 Duration GetRemainingCategoryCooldown(uint32 categoryId) const;
154 Duration GetRemainingCategoryCooldown(SpellInfo const* spellInfo) const;
155
156 // School lockouts
157 void LockSpellSchool(SpellSchoolMask schoolMask, Duration lockoutTime);
158 bool IsSchoolLocked(SpellSchoolMask schoolMask) const;
159
160 // Charges
161 bool ConsumeCharge(uint32 chargeCategoryId);
162 void ModifyChargeRecoveryTime(uint32 chargeCategoryId, Duration cooldownMod);
163 void RestoreCharge(uint32 chargeCategoryId);
164 void ResetCharges(uint32 chargeCategoryId);
165 void ResetAllCharges();
166 bool HasCharge(uint32 chargeCategoryId) const;
167 int32 GetMaxCharges(uint32 chargeCategoryId) const;
168 int32 GetChargeRecoveryTime(uint32 chargeCategoryId) const;
169
170 // Global cooldown
171 bool HasGlobalCooldown(SpellInfo const* spellInfo) const;
172 void AddGlobalCooldown(SpellInfo const* spellInfo, Duration duration);
173 void CancelGlobalCooldown(SpellInfo const* spellInfo);
174
175 void SaveCooldownStateBeforeDuel();
176 void RestoreCooldownStateAfterDuel();
177
178private:
179 Player* GetPlayerOwner() const;
180 void ModifySpellCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown);
181 void ModifySpellCooldown(CooldownStorageType::iterator& itr, Duration cooldownMod, bool withoutCategoryCooldown);
182 void ResetCooldown(CooldownStorageType::iterator& itr, bool update = false);
183 void SendClearCooldowns(std::vector<int32> const& cooldowns) const;
184 CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr)
185 {
186 _categoryCooldowns.erase(itr->second.CategoryId);
187 return _spellCooldowns.erase(itr);
188 }
189
190 void SendSetSpellCharges(uint32 chargeCategoryId, ChargeEntryCollection const& chargeCollection);
191
192 static void GetCooldownDurations(SpellInfo const* spellInfo, uint32 itemId, Duration* cooldown, uint32* categoryId, Duration* categoryCooldown);
193
198 Clock::time_point _schoolLockouts[MAX_SPELL_SCHOOL];
201
202 template<class T>
204};
205
206#endif // SpellHistory_h__
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
std::shared_ptr< PreparedResultSet > PreparedQueryResult
#define TC_GAME_API
Definition: Define.h:124
int32_t int32
Definition: Define.h:139
uint32_t uint32
Definition: Define.h:143
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:29
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
static void SaveToDB(QuestPool const &pool, CharacterDatabaseTransaction trans)
Definition: QuestPools.cpp:50
SpellSchoolMask
@ MAX_SPELL_SCHOOL
SpellCooldownFlags
Spell cooldown flags sent in SMSG_SPELL_COOLDOWN.
Definition: SpellHistory.h:38
@ 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
@ SPELL_COOLDOWN_FLAG_INCLUDE_GCD
Starts GCD in addition to normal cooldown specified in the packet.
Definition: SpellHistory.h:40
@ SPELL_COOLDOWN_FLAG_LOSS_OF_CONTROL_UI
Shows interrupt cooldown in loss of control ui.
Definition: SpellHistory.h:42
@ SPELL_COOLDOWN_FLAG_NONE
Definition: SpellHistory.h:39
@ SPELL_COOLDOWN_FLAG_ON_HOLD
Forces cooldown to behave as if SpellInfo::IsCooldownStartedOnEvent was true.
Definition: SpellHistory.h:43
Definition: Item.h:170
void AddCooldown(uint32 spellId, uint32 itemId, Duration cooldownDuration)
Definition: SpellHistory.h:107
SpellHistory & operator=(SpellHistory const &)=delete
GlobalCooldownStorageType _globalCooldowns
Definition: SpellHistory.h:200
std::unordered_map< uint32, CooldownEntry * > CategoryCooldownStorageType
Definition: SpellHistory.h:74
std::chrono::system_clock Clock
Definition: SpellHistory.h:49
static Duration const InfinityCooldownDelay
Definition: SpellHistory.h:102
std::deque< ChargeEntry > ChargeEntryCollection
Definition: SpellHistory.h:72
SpellHistory(SpellHistory const &)=delete
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:195
void ModifyCoooldowns(Predicate &&predicate, Duration cooldownMod, bool withoutCategoryCooldown=false)
Definition: SpellHistory.h:117
std::unordered_map< uint32, CooldownEntry > CooldownStorageType
Definition: SpellHistory.h:73
std::unordered_map< uint32, Clock::time_point > GlobalCooldownStorageType
Definition: SpellHistory.h:76
CooldownStorageType _spellCooldownsBeforeDuel
Definition: SpellHistory.h:196
Milliseconds Duration
Definition: SpellHistory.h:50
CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr)
Definition: SpellHistory.h:184
std::unordered_map< uint32, ChargeEntryCollection > ChargeStorageType
Definition: SpellHistory.h:75
SpellHistory(SpellHistory &&)=delete
void ResetCooldowns(Predicate predicate, bool update=false)
Definition: SpellHistory.h:130
SpellHistory & operator=(SpellHistory &&)=delete
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:199
CategoryCooldownStorageType _categoryCooldowns
Definition: SpellHistory.h:197
Definition: Spell.h:239
Definition: Unit.h:745
Clock::time_point RechargeStart
Definition: SpellHistory.h:68
Clock::time_point RechargeEnd
Definition: SpellHistory.h:69
ChargeEntry(Clock::time_point startTime, Duration rechargeTime)
Definition: SpellHistory.h:65
ChargeEntry(Clock::time_point startTime, Clock::time_point endTime)
Definition: SpellHistory.h:66
eventMap Update(1s)