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 "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 
30 class Item;
31 class Player;
32 class Spell;
33 class SpellInfo;
34 class Unit;
35 
38 {
44 };
45 
47 {
48 public:
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 
62  struct ChargeEntry
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);
79  ~SpellHistory();
80 
81  SpellHistory(SpellHistory const&) = delete;
82  SpellHistory(SpellHistory&&) = delete;
83 
84  SpellHistory& operator=(SpellHistory const&) = delete;
85  SpellHistory& operator=(SpellHistory&&) = delete;
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  void ResetCooldown(uint32 spellId, bool update = false);
117  void ResetCooldown(CooldownStorageType::iterator& itr, bool update = false);
118  template<typename Predicate>
119  void ResetCooldowns(Predicate predicate, bool update = false)
120  {
121  std::vector<int32> resetCooldowns;
122  resetCooldowns.reserve(_spellCooldowns.size());
123  for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end();)
124  {
125  if (predicate(itr))
126  {
127  resetCooldowns.push_back(int32(itr->first));
128  ResetCooldown(itr, false);
129  }
130  else
131  ++itr;
132  }
133 
134  if (update && !resetCooldowns.empty())
135  SendClearCooldowns(resetCooldowns);
136  }
137 
138  void ResetAllCooldowns();
139  bool HasCooldown(SpellInfo const* spellInfo, uint32 itemId = 0) const;
140  bool HasCooldown(uint32 spellId, uint32 itemId = 0) const;
141  Duration GetRemainingCooldown(SpellInfo const* spellInfo) const;
142  Duration GetRemainingCategoryCooldown(uint32 categoryId) const;
143  Duration GetRemainingCategoryCooldown(SpellInfo const* spellInfo) const;
144 
145  // School lockouts
146  void LockSpellSchool(SpellSchoolMask schoolMask, Duration lockoutTime);
147  bool IsSchoolLocked(SpellSchoolMask schoolMask) const;
148 
149  // Charges
150  bool ConsumeCharge(uint32 chargeCategoryId);
151  void ModifyChargeRecoveryTime(uint32 chargeCategoryId, Duration cooldownMod);
152  void RestoreCharge(uint32 chargeCategoryId);
153  void ResetCharges(uint32 chargeCategoryId);
154  void ResetAllCharges();
155  bool HasCharge(uint32 chargeCategoryId) const;
156  int32 GetMaxCharges(uint32 chargeCategoryId) const;
157  int32 GetChargeRecoveryTime(uint32 chargeCategoryId) const;
158 
159  // Global cooldown
160  bool HasGlobalCooldown(SpellInfo const* spellInfo) const;
161  void AddGlobalCooldown(SpellInfo const* spellInfo, Duration duration);
162  void CancelGlobalCooldown(SpellInfo const* spellInfo);
163 
164  void SaveCooldownStateBeforeDuel();
165  void RestoreCooldownStateAfterDuel();
166 
167 private:
168  Player* GetPlayerOwner() const;
169  void ModifySpellCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown = false);
170  void SendClearCooldowns(std::vector<int32> const& cooldowns) const;
171  CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr)
172  {
173  _categoryCooldowns.erase(itr->second.CategoryId);
174  return _spellCooldowns.erase(itr);
175  }
176 
177  void SendSetSpellCharges(uint32 chargeCategoryId, ChargeEntryCollection const& chargeCollection);
178 
179  static void GetCooldownDurations(SpellInfo const* spellInfo, uint32 itemId, Duration* cooldown, uint32* categoryId, Duration* categoryCooldown);
180 
185  Clock::time_point _schoolLockouts[MAX_SPELL_SCHOOL];
188 
189  template<class T>
190  struct PersistenceHelper { };
191 };
192 
193 #endif // SpellHistory_h__
ChargeEntry(Clock::time_point startTime, Clock::time_point endTime)
Definition: SpellHistory.h:66
Definition: SpellHistory.h:190
std::chrono::system_clock Clock
Definition: SpellHistory.h:49
std::unordered_map< uint32, ChargeEntryCollection > ChargeStorageType
Definition: SpellHistory.h:75
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:186
Unit * _owner
Definition: SpellHistory.h:181
Definition: SpellHistory.h:62
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition: DatabaseEnvFwd.h:48
Definition: SpellInfo.h:342
CategoryCooldownStorageType _categoryCooldowns
Definition: SpellHistory.h:184
std::unordered_map< uint32, CooldownEntry * > CategoryCooldownStorageType
Definition: SpellHistory.h:74
std::unordered_map< uint32, Clock::time_point > GlobalCooldownStorageType
Definition: SpellHistory.h:76
GlobalCooldownStorageType _globalCooldowns
Definition: SpellHistory.h:187
void AddCooldown(uint32 spellId, uint32 itemId, Duration cooldownDuration)
Definition: SpellHistory.h:107
std::deque< ChargeEntry > ChargeEntryCollection
Definition: SpellHistory.h:72
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
Definition: Duration.h:24
Definition: SpellHistory.h:52
SpellSchoolMask
Definition: SharedDefines.h:310
Shows interrupt cooldown in loss of control ui.
Definition: SpellHistory.h:42
Clock::time_point RechargeEnd
Definition: SpellHistory.h:69
Definition: SpellHistory.h:46
Definition: SharedDefines.h:307
Clock::time_point RechargeStart
Definition: SpellHistory.h:68
eventMap Update(1s)
std::unordered_map< uint32, CooldownEntry > CooldownStorageType
Definition: SpellHistory.h:73
Definition: Item.h:169
int32_t int32
Definition: Define.h:139
Milliseconds Duration
Definition: SpellHistory.h:50
SpellCooldownFlags
Spell cooldown flags sent in SMSG_SPELL_COOLDOWN.
Definition: SpellHistory.h:37
uint32_t uint32
Definition: Define.h:143
Starts GCD for spells that should start their cooldown on events, requires SPELL_COOLDOWN_FLAG_INCLUD...
Definition: SpellHistory.h:41
static void SaveToDB(QuestPool const &pool, CharacterDatabaseTransaction trans)
Definition: QuestPools.cpp:50
Definition: SpellHistory.h:39
Starts GCD in addition to normal cooldown specified in the packet.
Definition: SpellHistory.h:40
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:182
CooldownStorageType _spellCooldownsBeforeDuel
Definition: SpellHistory.h:183
ChargeEntry(Clock::time_point startTime, Duration rechargeTime)
Definition: SpellHistory.h:65
static Duration const InfinityCooldownDelay
Definition: SpellHistory.h:102
#define TC_GAME_API
Definition: Define.h:124
Forces cooldown to behave as if SpellInfo::IsCooldownStartedOnEvent was true.
Definition: SpellHistory.h:43
void ResetCooldowns(Predicate predicate, bool update=false)
Definition: SpellHistory.h:119
std::optional< T > Optional
Optional helper class to wrap optional values within.
Definition: Optional.h:25
Definition: Unit.h:746
Definition: Player.h:1131
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
Definition: DatabaseEnvFwd.h:72
CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr)
Definition: SpellHistory.h:171
Definition: Spell.h:238