TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
SpellHistory.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
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 "QueryResult.h"
23 #include "Transaction.h"
24 #include <chrono>
25 #include <deque>
26 
27 class Item;
28 class Player;
29 class Spell;
30 class SpellInfo;
31 class Unit;
32 struct SpellCategoryEntry;
33 
36 {
40 };
41 
43 {
44 public:
45  typedef std::chrono::system_clock Clock;
46 
48  {
49  uint32 SpellId = 0;
50  Clock::time_point CooldownEnd;
51  uint32 ItemId = 0;
52  uint32 CategoryId = 0;
53  Clock::time_point CategoryEnd;
54  bool OnHold = false;
55  };
56 
57  struct ChargeEntry
58  {
60  ChargeEntry(Clock::time_point startTime, std::chrono::milliseconds rechargeTime) : RechargeStart(startTime), RechargeEnd(startTime + rechargeTime) { }
61  ChargeEntry(Clock::time_point startTime, Clock::time_point endTime) : RechargeStart(startTime), RechargeEnd(endTime) { }
62 
63  Clock::time_point RechargeStart;
64  Clock::time_point RechargeEnd;
65  };
66 
67  typedef std::unordered_map<uint32 /*spellId*/, CooldownEntry> CooldownStorageType;
68  typedef std::unordered_map<uint32 /*categoryId*/, CooldownEntry*> CategoryCooldownStorageType;
69  typedef std::unordered_map<uint32 /*categoryId*/, std::deque<ChargeEntry>> ChargeStorageType;
70  typedef std::unordered_map<uint32 /*categoryId*/, Clock::time_point> GlobalCooldownStorageType;
71 
72  explicit SpellHistory(Unit* owner) : _owner(owner), _schoolLockouts() { }
73 
74  template<class OwnerType>
75  void LoadFromDB(PreparedQueryResult cooldownsResult, PreparedQueryResult chargesResult);
76 
77  template<class OwnerType>
78  void SaveToDB(SQLTransaction& trans);
79 
80  void Update();
81 
82  void HandleCooldowns(SpellInfo const* spellInfo, Item const* item, Spell* spell = nullptr);
83  void HandleCooldowns(SpellInfo const* spellInfo, uint32 itemID, Spell* spell = nullptr);
84  bool IsReady(SpellInfo const* spellInfo, uint32 itemId = 0, bool ignoreCategoryCooldown = false) const;
85  template<class PacketType>
86  void WritePacket(PacketType* packet) const;
87 
88  // Cooldowns
89  static Clock::duration const InfinityCooldownDelay; // used for set "infinity cooldowns" for spells and check
90 
91  void StartCooldown(SpellInfo const* spellInfo, uint32 itemId, Spell* spell = nullptr, bool onHold = false);
92  void SendCooldownEvent(SpellInfo const* spellInfo, uint32 itemId = 0, Spell* spell = nullptr, bool startCooldown = true);
93 
94  template<class Type, class Period>
95  void AddCooldown(uint32 spellId, uint32 itemId, std::chrono::duration<Type, Period> cooldownDuration)
96  {
97  Clock::time_point now = Clock::now();
98  AddCooldown(spellId, itemId, now + std::chrono::duration_cast<Clock::duration>(cooldownDuration), 0, now);
99  }
100 
101  void AddCooldown(uint32 spellId, uint32 itemId, Clock::time_point cooldownEnd, uint32 categoryId, Clock::time_point categoryEnd, bool onHold = false);
102  void ModifyCooldown(uint32 spellId, int32 cooldownModMs);
103  void ResetCooldown(uint32 spellId, bool update = false);
104  void ResetCooldown(CooldownStorageType::iterator& itr, bool update = false);
105  template<typename Predicate>
106  void ResetCooldowns(Predicate predicate, bool update = false)
107  {
108  std::vector<int32> resetCooldowns;
109  resetCooldowns.reserve(_spellCooldowns.size());
110  for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end();)
111  {
112  if (predicate(itr))
113  {
114  resetCooldowns.push_back(int32(itr->first));
115  ResetCooldown(itr, false);
116  }
117  else
118  ++itr;
119  }
120 
121  if (update && !resetCooldowns.empty())
122  SendClearCooldowns(resetCooldowns);
123  }
124 
125  void ResetAllCooldowns();
126  bool HasCooldown(SpellInfo const* spellInfo, uint32 itemId = 0, bool ignoreCategoryCooldown = false) const;
127  bool HasCooldown(uint32 spellId, uint32 itemId = 0, bool ignoreCategoryCooldown = false) const;
128  uint32 GetRemainingCooldown(SpellInfo const* spellInfo) const;
129 
130  // School lockouts
131  void LockSpellSchool(SpellSchoolMask schoolMask, uint32 lockoutTime);
132  bool IsSchoolLocked(SpellSchoolMask schoolMask) const;
133 
134  // Charges
135  bool ConsumeCharge(SpellCategoryEntry const* chargeCategoryEntry);
136  void RestoreCharge(SpellCategoryEntry const* chargeCategoryEntry);
137  void ResetCharges(SpellCategoryEntry const* chargeCategoryEntry);
138  void ResetAllCharges();
139  bool HasCharge(SpellCategoryEntry const* chargeCategoryEntry) const;
140  int32 GetMaxCharges(SpellCategoryEntry const* chargeCategoryEntry) const;
141  int32 GetChargeRecoveryTime(SpellCategoryEntry const* chargeCategoryEntry) const;
142 
143  // Global cooldown
144  bool HasGlobalCooldown(SpellInfo const* spellInfo) const;
145  void AddGlobalCooldown(SpellInfo const* spellInfo, uint32 duration);
146  void CancelGlobalCooldown(SpellInfo const* spellInfo);
147 
148  uint16 GetArenaCooldownsSize();
149  void SaveCooldownStateBeforeDuel();
150  void RestoreCooldownStateAfterDuel();
151 
152 private:
153  Player* GetPlayerOwner() const;
154  void SendClearCooldowns(std::vector<int32> const& cooldowns) const;
155  CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr)
156  {
157  _categoryCooldowns.erase(itr->second.CategoryId);
158  return _spellCooldowns.erase(itr);
159  }
160 
161  static void GetCooldownDurations(SpellInfo const* spellInfo, uint32 itemId, int32* cooldown, uint32* categoryId, int32* categoryCooldown);
162 
164  CooldownStorageType _spellCooldowns;
165  CooldownStorageType _spellCooldownsBeforeDuel;
166  CategoryCooldownStorageType _categoryCooldowns;
167  Clock::time_point _schoolLockouts[MAX_SPELL_SCHOOL];
168  ChargeStorageType _categoryCharges;
169  GlobalCooldownStorageType _globalCooldowns;
170 
171  template<class T>
172  struct PersistenceHelper { };
173 };
174 
175 #endif // SpellHistory_h__
ChargeEntry(Clock::time_point startTime, Clock::time_point endTime)
Definition: SpellHistory.h:61
Definition: SpellHistory.h:172
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:168
std::shared_ptr< PreparedResultSet > PreparedQueryResult
Definition: QueryResult.h:107
void AddCooldown(uint32 spellId, uint32 itemId, std::chrono::duration< Type, Period > cooldownDuration)
Definition: SpellHistory.h:95
Unit * _owner
Definition: SpellHistory.h:163
Definition: SpellHistory.h:57
SpellSchoolMask
Definition: SharedDefines.h:285
Definition: SpellInfo.h:326
CategoryCooldownStorageType _categoryCooldowns
Definition: SpellHistory.h:166
void LoadFromDB()
Definition: AddonMgr.cpp:40
GlobalCooldownStorageType _globalCooldowns
Definition: SpellHistory.h:169
#define MAX_SPELL_SCHOOL
Definition: SharedDefines.h:283
Definition: SpellHistory.h:47
Clock::time_point RechargeEnd
Definition: SpellHistory.h:64
Definition: SpellHistory.h:42
std::unordered_map< uint32, CooldownEntry * > CategoryCooldownStorageType
Definition: SpellHistory.h:68
std::unordered_map< uint32, std::deque< ChargeEntry > > ChargeStorageType
Definition: SpellHistory.h:69
ChargeEntry(Clock::time_point startTime, std::chrono::milliseconds rechargeTime)
Definition: SpellHistory.h:60
Clock::time_point RechargeStart
Definition: SpellHistory.h:63
Clock::time_point CategoryEnd
Definition: SpellHistory.h:53
Definition: Item.h:259
Definition: DBCStructure.h:1097
int32_t int32
Definition: Define.h:146
std::unordered_map< uint32, CooldownEntry > CooldownStorageType
Definition: SpellHistory.h:67
SpellCooldownFlags
Spell cooldown flags sent in SMSG_SPELL_COOLDOWN.
Definition: SpellHistory.h:35
uint32_t uint32
Definition: Define.h:150
Starts GCD for spells that should start their cooldown on events, requires SPELL_COOLDOWN_FLAG_INCLUD...
Definition: SpellHistory.h:39
uint16_t uint16
Definition: Define.h:151
ChargeEntry()
Definition: SpellHistory.h:59
float milliseconds()
Definition: units.h:92
std::unordered_map< uint32, Clock::time_point > GlobalCooldownStorageType
Definition: SpellHistory.h:70
Definition: SpellHistory.h:37
Starts GCD in addition to normal cooldown specified in the packet.
Definition: SpellHistory.h:38
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164
CooldownStorageType _spellCooldownsBeforeDuel
Definition: SpellHistory.h:165
SpellHistory(Unit *owner)
Definition: SpellHistory.h:72
#define TC_GAME_API
Definition: Define.h:134
static Clock::duration const InfinityCooldownDelay
Definition: SpellHistory.h:89
int32_t int32
Definition: g3dmath.h:167
void ResetCooldowns(Predicate predicate, bool update=false)
Definition: SpellHistory.h:106
Clock::time_point CooldownEnd
Definition: SpellHistory.h:50
std::chrono::system_clock Clock
Definition: SpellHistory.h:45
Definition: Unit.h:1305
void Update(uint32 diff)
Definition: WeatherMgr.cpp:150
CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr)
Definition: SpellHistory.h:155
std::shared_ptr< Transaction > SQLTransaction
Definition: Transaction.h:58
Definition: Spell.h:294