TrinityCore
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 "DatabaseEnvFwd.h"
22#include "Duration.h"
23#include "GameTime.h"
24#include "Optional.h"
25#include "SharedDefines.h"
26#include <deque>
27#include <unordered_map>
28#include <vector>
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 using TimePoint = std::chrono::time_point<Clock, Duration>;
52
54 {
55 uint32 SpellId = 0;
56 TimePoint CooldownEnd = TimePoint::min();
58 uint32 CategoryId = 0;
59 TimePoint CategoryEnd = TimePoint::min();
60 bool OnHold = false;
61 };
62
64 {
65 ChargeEntry() = default;
66 ChargeEntry(TimePoint startTime, Duration rechargeTime) : RechargeStart(startTime), RechargeEnd(startTime + rechargeTime) { }
67 ChargeEntry(TimePoint startTime, TimePoint endTime) : RechargeStart(startTime), RechargeEnd(endTime) { }
68
71 };
72
73 using ChargeEntryCollection = std::deque<ChargeEntry>;
74 using CooldownStorageType = std::unordered_map<uint32 /*spellId*/, CooldownEntry>;
75 using CategoryCooldownStorageType = std::unordered_map<uint32 /*categoryId*/, CooldownEntry*>;
76 using ChargeStorageType = std::unordered_map<uint32 /*categoryId*/, ChargeEntryCollection>;
77 using GlobalCooldownStorageType = std::unordered_map<uint32 /*categoryId*/, TimePoint>;
78
79 explicit SpellHistory(Unit* owner);
81
82 SpellHistory(SpellHistory const&) = delete;
84
87
88 template<class OwnerType>
89 void LoadFromDB(PreparedQueryResult cooldownsResult, PreparedQueryResult chargesResult);
90
91 template<class OwnerType>
93
94 void Update();
95
96 void HandleCooldowns(SpellInfo const* spellInfo, Item const* item, Spell* spell = nullptr);
97 void HandleCooldowns(SpellInfo const* spellInfo, uint32 itemId, Spell* spell = nullptr);
98 bool IsReady(SpellInfo const* spellInfo, uint32 itemId = 0) const;
99 template<class PacketType>
100 void WritePacket(PacketType* packet) const;
101
102 // Cooldowns
103 static Duration const InfinityCooldownDelay; // used for set "infinity cooldowns" for spells and check
104
105 void StartCooldown(SpellInfo const* spellInfo, uint32 itemId, Spell* spell = nullptr, bool onHold = false, Optional<Duration> forcedCooldown = {});
106 void SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId = 0, Spell* spell = nullptr, bool startCooldown = true);
107
108 void AddCooldown(uint32 spellId, uint32 itemId, Duration cooldownDuration)
109 {
110 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
111 AddCooldown(spellId, itemId, now + cooldownDuration, 0, now);
112 }
113
114 void AddCooldown(uint32 spellId, uint32 itemId, TimePoint cooldownEnd, uint32 categoryId, TimePoint categoryEnd, bool onHold = false);
115 void ModifyCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown = false);
116 void ModifyCooldown(SpellInfo const* spellInfo, Duration cooldownMod, bool withoutCategoryCooldown = false);
117 template<typename Predicate>
118 void ModifyCoooldowns(Predicate&& predicate, Duration cooldownMod, bool withoutCategoryCooldown = false)
119 {
120 for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end();)
121 {
122 if (predicate(itr))
123 ModifySpellCooldown(itr, cooldownMod, withoutCategoryCooldown);
124 else
125 ++itr;
126 }
127 }
128
129 void ResetCooldown(uint32 spellId, bool update = false);
130 template<typename Predicate>
131 void ResetCooldowns(Predicate predicate, bool update = false)
132 {
133 std::vector<int32> resetCooldowns;
134 resetCooldowns.reserve(_spellCooldowns.size());
135 for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end();)
136 {
137 if (predicate(itr))
138 {
139 resetCooldowns.push_back(int32(itr->first));
140 ResetCooldown(itr, false);
141 }
142 else
143 ++itr;
144 }
145
146 if (update && !resetCooldowns.empty())
147 SendClearCooldowns(resetCooldowns);
148 }
149
150 void ResetAllCooldowns();
151 bool HasCooldown(SpellInfo const* spellInfo, uint32 itemId = 0) const;
152 bool HasCooldown(uint32 spellId, uint32 itemId = 0) const;
153 Duration GetRemainingCooldown(SpellInfo const* spellInfo) const;
154 Duration GetRemainingCategoryCooldown(uint32 categoryId) const;
155 Duration GetRemainingCategoryCooldown(SpellInfo const* spellInfo) const;
156
157 // School lockouts
158 void LockSpellSchool(SpellSchoolMask schoolMask, Duration lockoutTime);
159 bool IsSchoolLocked(SpellSchoolMask schoolMask) const;
160
161 // Charges
162 bool ConsumeCharge(uint32 chargeCategoryId);
163 void ModifyChargeRecoveryTime(uint32 chargeCategoryId, Duration cooldownMod);
164 void RestoreCharge(uint32 chargeCategoryId);
165 void ResetCharges(uint32 chargeCategoryId);
166 void ResetAllCharges();
167 bool HasCharge(uint32 chargeCategoryId) const;
168 int32 GetMaxCharges(uint32 chargeCategoryId) const;
169 int32 GetChargeRecoveryTime(uint32 chargeCategoryId) const;
170
171 // Global cooldown
172 bool HasGlobalCooldown(SpellInfo const* spellInfo) const;
173 void AddGlobalCooldown(SpellInfo const* spellInfo, Duration duration);
174 void CancelGlobalCooldown(SpellInfo const* spellInfo);
175 Duration GetRemainingGlobalCooldown(SpellInfo const* spellInfo) const;
176
177 bool IsPaused() const { return _pauseTime.has_value(); }
178 void PauseCooldowns();
179 void ResumeCooldowns();
180
181 void SaveCooldownStateBeforeDuel();
182 void RestoreCooldownStateAfterDuel();
183
184private:
185 Player* GetPlayerOwner() const;
186 void ModifySpellCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown);
187 void ModifySpellCooldown(CooldownStorageType::iterator& itr, Duration cooldownMod, bool withoutCategoryCooldown);
188 void ResetCooldown(CooldownStorageType::iterator& itr, bool update = false);
189 void SendClearCooldowns(std::vector<int32> const& cooldowns) const;
190 CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr)
191 {
192 _categoryCooldowns.erase(itr->second.CategoryId);
193 return _spellCooldowns.erase(itr);
194 }
195
196 void SendSetSpellCharges(uint32 chargeCategoryId, ChargeEntryCollection const& chargeCollection);
197
198 static void GetCooldownDurations(SpellInfo const* spellInfo, uint32 itemId, Duration* cooldown, uint32* categoryId, Duration* categoryCooldown);
199
204 TimePoint _schoolLockouts[MAX_SPELL_SCHOOL];
208
209 template<class T>
211};
212
213#endif // SpellHistory_h__
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
std::shared_ptr< PreparedResultSet > PreparedQueryResult
#define TC_GAME_API
Definition: Define.h:123
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
std::chrono::steady_clock::time_point TimePoint
time_point shorthand typedefs
Definition: Duration.h:41
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:108
SpellHistory & operator=(SpellHistory const &)=delete
GlobalCooldownStorageType _globalCooldowns
Definition: SpellHistory.h:206
std::unordered_map< uint32, CooldownEntry * > CategoryCooldownStorageType
Definition: SpellHistory.h:75
std::chrono::system_clock Clock
Definition: SpellHistory.h:49
std::unordered_map< uint32, TimePoint > GlobalCooldownStorageType
Definition: SpellHistory.h:77
static Duration const InfinityCooldownDelay
Definition: SpellHistory.h:103
Optional< TimePoint > _pauseTime
Definition: SpellHistory.h:207
std::deque< ChargeEntry > ChargeEntryCollection
Definition: SpellHistory.h:73
SpellHistory(SpellHistory const &)=delete
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:201
void ModifyCoooldowns(Predicate &&predicate, Duration cooldownMod, bool withoutCategoryCooldown=false)
Definition: SpellHistory.h:118
std::unordered_map< uint32, CooldownEntry > CooldownStorageType
Definition: SpellHistory.h:74
bool IsPaused() const
Definition: SpellHistory.h:177
CooldownStorageType _spellCooldownsBeforeDuel
Definition: SpellHistory.h:202
Milliseconds Duration
Definition: SpellHistory.h:50
std::chrono::time_point< Clock, Duration > TimePoint
Definition: SpellHistory.h:51
CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr)
Definition: SpellHistory.h:190
std::unordered_map< uint32, ChargeEntryCollection > ChargeStorageType
Definition: SpellHistory.h:76
SpellHistory(SpellHistory &&)=delete
void ResetCooldowns(Predicate predicate, bool update=false)
Definition: SpellHistory.h:131
SpellHistory & operator=(SpellHistory &&)=delete
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:205
CategoryCooldownStorageType _categoryCooldowns
Definition: SpellHistory.h:203
Definition: Spell.h:255
Definition: Unit.h:627
void Update(VignetteData &vignette, WorldObject const *owner)
Definition: Vignette.cpp:90
ChargeEntry(TimePoint startTime, Duration rechargeTime)
Definition: SpellHistory.h:66
ChargeEntry(TimePoint startTime, TimePoint endTime)
Definition: SpellHistory.h:67