TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
SpellHistory Class Reference

#include <SpellHistory.h>

Classes

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

Public Types

typedef std::chrono::system_clock Clock
 
typedef std::unordered_map
< uint32, CooldownEntry
CooldownStorageType
 
typedef std::unordered_map
< uint32, CooldownEntry * > 
CategoryCooldownStorageType
 
typedef std::unordered_map
< uint32, std::deque
< ChargeEntry > > 
ChargeStorageType
 
typedef std::unordered_map
< uint32, Clock::time_point > 
GlobalCooldownStorageType
 

Public Member Functions

 SpellHistory (Unit *owner)
 
template<class OwnerType >
void LoadFromDB (PreparedQueryResult cooldownsResult, PreparedQueryResult chargesResult)
 
template<class OwnerType >
void SaveToDB (SQLTransaction &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, bool ignoreCategoryCooldown=false) const
 
template<class PacketType >
void WritePacket (PacketType *packet) const
 
void StartCooldown (SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool onHold=false)
 
void SendCooldownEvent (SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool startCooldown=true)
 
template<class Type , class Period >
void AddCooldown (uint32 spellId, uint32 itemId, std::chrono::duration< Type, Period > cooldownDuration)
 
void AddCooldown (uint32 spellId, uint32 itemId, Clock::time_point cooldownEnd, uint32 categoryId, Clock::time_point categoryEnd, bool onHold=false)
 
void ModifyCooldown (uint32 spellId, int32 cooldownModMs)
 
void ResetCooldown (uint32 spellId, bool update=false)
 
void ResetCooldown (CooldownStorageType::iterator &itr, bool update=false)
 
template<typename Predicate >
void ResetCooldowns (Predicate predicate, bool update=false)
 
void ResetAllCooldowns ()
 
bool HasCooldown (SpellInfo const *spellInfo, uint32 itemId=0, bool ignoreCategoryCooldown=false) const
 
bool HasCooldown (uint32 spellId, uint32 itemId=0, bool ignoreCategoryCooldown=false) const
 
uint32 GetRemainingCooldown (SpellInfo const *spellInfo) const
 
void LockSpellSchool (SpellSchoolMask schoolMask, uint32 lockoutTime)
 
bool IsSchoolLocked (SpellSchoolMask schoolMask) const
 
bool ConsumeCharge (SpellCategoryEntry const *chargeCategoryEntry)
 
void RestoreCharge (SpellCategoryEntry const *chargeCategoryEntry)
 
void ResetCharges (SpellCategoryEntry const *chargeCategoryEntry)
 
void ResetAllCharges ()
 
bool HasCharge (SpellCategoryEntry const *chargeCategoryEntry) const
 
int32 GetMaxCharges (SpellCategoryEntry const *chargeCategoryEntry) const
 
int32 GetChargeRecoveryTime (SpellCategoryEntry const *chargeCategoryEntry) const
 
bool HasGlobalCooldown (SpellInfo const *spellInfo) const
 
void AddGlobalCooldown (SpellInfo const *spellInfo, uint32 duration)
 
void CancelGlobalCooldown (SpellInfo const *spellInfo)
 
uint16 GetArenaCooldownsSize ()
 
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 Clock::duration const InfinityCooldownDelay = std::chrono::duration_cast<SpellHistory::Clock::duration>(std::chrono::seconds(MONTH))
 

Private Member Functions

PlayerGetPlayerOwner () const
 
void SendClearCooldowns (std::vector< int32 > const &cooldowns) const
 
CooldownStorageType::iterator EraseCooldown (CooldownStorageType::iterator itr)
 

Static Private Member Functions

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

Private Attributes

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

Member Typedef Documentation

typedef std::unordered_map<uint32 , std::deque<ChargeEntry> > SpellHistory::ChargeStorageType
typedef std::chrono::system_clock SpellHistory::Clock
typedef std::unordered_map<uint32 , Clock::time_point> SpellHistory::GlobalCooldownStorageType

Constructor & Destructor Documentation

SpellHistory::SpellHistory ( Unit owner)
inlineexplicit
72 : _owner(owner), _schoolLockouts() { }
Unit * _owner
Definition: SpellHistory.h:163
Clock::time_point _schoolLockouts[MAX_SPELL_SCHOOL]
Definition: SpellHistory.h:167

Member Function Documentation

template<class Type , class Period >
void SpellHistory::AddCooldown ( uint32  spellId,
uint32  itemId,
std::chrono::duration< Type, Period >  cooldownDuration 
)
inline
96  {
97  Clock::time_point now = Clock::now();
98  AddCooldown(spellId, itemId, now + std::chrono::duration_cast<Clock::duration>(cooldownDuration), 0, now);
99  }
void AddCooldown(uint32 spellId, uint32 itemId, std::chrono::duration< Type, Period > cooldownDuration)
Definition: SpellHistory.h:95

+ Here is the caller graph for this function:

void SpellHistory::AddCooldown ( uint32  spellId,
uint32  itemId,
Clock::time_point  cooldownEnd,
uint32  categoryId,
Clock::time_point  categoryEnd,
bool  onHold = false 
)
513 {
514  CooldownEntry& cooldownEntry = _spellCooldowns[spellId];
515  cooldownEntry.SpellId = spellId;
516  cooldownEntry.CooldownEnd = cooldownEnd;
517  cooldownEntry.ItemId = itemId;
518  cooldownEntry.CategoryId = categoryId;
519  cooldownEntry.CategoryEnd = categoryEnd;
520  cooldownEntry.OnHold = onHold;
521 
522  if (categoryId)
523  _categoryCooldowns[categoryId] = &cooldownEntry;
524 }
CategoryCooldownStorageType _categoryCooldowns
Definition: SpellHistory.h:166
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164
void SpellHistory::AddGlobalCooldown ( SpellInfo const spellInfo,
uint32  duration 
)
828 {
829  _globalCooldowns[spellInfo->StartRecoveryCategory] = Clock::now() + std::chrono::duration_cast<Clock::duration>(std::chrono::milliseconds(duration));
830 }
GlobalCooldownStorageType _globalCooldowns
Definition: SpellHistory.h:169
float milliseconds()
Definition: units.h:92

+ Here is the call graph for this function:

void SpellHistory::CancelGlobalCooldown ( SpellInfo const spellInfo)
833 {
834  _globalCooldowns[spellInfo->StartRecoveryCategory] = Clock::time_point(Clock::duration(0));
835 }
GlobalCooldownStorageType _globalCooldowns
Definition: SpellHistory.h:169
bool SpellHistory::ConsumeCharge ( SpellCategoryEntry const chargeCategoryEntry)
700 {
701  if (!chargeCategoryEntry)
702  return false;
703 
704  int32 chargeRecovery = GetChargeRecoveryTime(chargeCategoryEntry);
705  if (chargeRecovery > 0 && GetMaxCharges(chargeCategoryEntry) > 0)
706  {
707  Clock::time_point recoveryStart;
708  std::deque<ChargeEntry>& charges = _categoryCharges[chargeCategoryEntry->ID];
709  if (charges.empty())
710  recoveryStart = Clock::now();
711  else
712  recoveryStart = charges.back().RechargeEnd;
713 
714  charges.emplace_back(recoveryStart, std::chrono::milliseconds(chargeRecovery));
715  return true;
716  }
717 
718  return false;
719 }
int32 GetMaxCharges(SpellCategoryEntry const *chargeCategoryEntry) const
Definition: SpellHistory.cpp:791
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:168
int32 GetChargeRecoveryTime(SpellCategoryEntry const *chargeCategoryEntry) const
Definition: SpellHistory.cpp:801
int32_t int32
Definition: Define.h:146
float milliseconds()
Definition: units.h:92

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

CooldownStorageType::iterator SpellHistory::EraseCooldown ( CooldownStorageType::iterator  itr)
inlineprivate
156  {
157  _categoryCooldowns.erase(itr->second.CategoryId);
158  return _spellCooldowns.erase(itr);
159  }
CategoryCooldownStorageType _categoryCooldowns
Definition: SpellHistory.h:166
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164

+ Here is the caller graph for this function:

uint16 SpellHistory::GetArenaCooldownsSize ( )
int32 SpellHistory::GetChargeRecoveryTime ( SpellCategoryEntry const chargeCategoryEntry) const
802 {
803  if (!chargeCategoryEntry)
804  return 0;
805 
806  int32 recoveryTime = chargeCategoryEntry->ChargeRecoveryTime;
807  recoveryTime += _owner->GetTotalAuraModifierByMiscValue(SPELL_AURA_CHARGE_RECOVERY_MOD, chargeCategoryEntry->ID);
808 
809  float recoveryTimeF = recoveryTime;
810  recoveryTimeF *= _owner->GetTotalAuraMultiplierByMiscValue(SPELL_AURA_CHARGE_RECOVERY_MULTIPLIER, chargeCategoryEntry->ID);
811 
813  recoveryTimeF *= _owner->GetFloatValue(UNIT_MOD_CAST_HASTE);
814 
817 
818  return int32(std::floor(recoveryTimeF));
819 }
int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
Definition: Unit.cpp:4521
Unit * _owner
Definition: SpellHistory.h:163
static Vector3int16 floor(const Vector3 &v)
float GetTotalAuraMultiplierByMiscValue(AuraType auratype, int32 misc_value) const
Definition: Unit.cpp:4540
Definition: UpdateFields.h:133
Definition: SpellAuraDefines.h:516
Definition: SpellAuraDefines.h:514
Definition: UpdateFields.h:130
float GetFloatValue(uint16 index) const
Definition: Object.cpp:312
int32_t int32
Definition: Define.h:146
Definition: SpellAuraDefines.h:513
int32_t int32
Definition: g3dmath.h:167
Definition: SpellAuraDefines.h:517
bool HasAuraType(AuraType auraType) const
Definition: Unit.cpp:4247

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SpellHistory::GetCooldownDurations ( SpellInfo const spellInfo,
uint32  itemId,
int32 cooldown,
uint32 categoryId,
int32 categoryCooldown 
)
staticprivate
854 {
855  ASSERT(cooldown || categoryId || categoryCooldown);
856  int32 tmpCooldown = -1;
857  uint32 tmpCategoryId = 0;
858  int32 tmpCategoryCooldown = -1;
859 
860  // cooldown information stored in ItemEffect.db2, overriding normal cooldown and category
861  if (itemId)
862  {
863  if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId))
864  {
865  for (ItemEffectEntry const* itemEffect : proto->Effects)
866  {
867  if (itemEffect->SpellID == spellInfo->Id)
868  {
869  tmpCooldown = itemEffect->Cooldown;
870  tmpCategoryId = itemEffect->Category;
871  tmpCategoryCooldown = itemEffect->CategoryCooldown;
872  break;
873  }
874  }
875  }
876  }
877 
878  // if no cooldown found above then base at DBC data
879  if (tmpCooldown < 0 && tmpCategoryCooldown < 0)
880  {
881  tmpCooldown = spellInfo->RecoveryTime;
882  tmpCategoryId = spellInfo->GetCategory();
883  tmpCategoryCooldown = spellInfo->CategoryRecoveryTime;
884  }
885 
886  if (cooldown)
887  *cooldown = tmpCooldown;
888  if (categoryId)
889  *categoryId = tmpCategoryId;
890  if (categoryCooldown)
891  *categoryCooldown = tmpCategoryCooldown;
892 }
Definition: DB2Structure.h:696
uint32 SpellID
Definition: DB2Structure.h:701
int32 CategoryCooldown
Definition: DB2Structure.h:706
#define sObjectMgr
Definition: ObjectMgr.h:1567
int32 Cooldown
Definition: DB2Structure.h:704
int32_t int32
Definition: Define.h:146
uint32_t uint32
Definition: Define.h:150
uint32 Category
Definition: DB2Structure.h:705
Definition: ItemTemplate.h:647
#define ASSERT
Definition: Errors.h:55

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

int32 SpellHistory::GetMaxCharges ( SpellCategoryEntry const chargeCategoryEntry) const
792 {
793  if (!chargeCategoryEntry)
794  return 0;
795 
796  uint32 charges = chargeCategoryEntry->MaxCharges;
797  charges += _owner->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_MAX_CHARGES, chargeCategoryEntry->ID);
798  return charges;
799 }
int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
Definition: Unit.cpp:4521
Unit * _owner
Definition: SpellHistory.h:163
Definition: SpellAuraDefines.h:471
uint32_t uint32
Definition: Define.h:150

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Player * SpellHistory::GetPlayerOwner ( ) const
private
838 {
840 }
Unit * _owner
Definition: SpellHistory.h:163
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition: Unit.cpp:7560

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

uint32 SpellHistory::GetRemainingCooldown ( SpellInfo const spellInfo) const
613 {
614  Clock::time_point end;
615  auto itr = _spellCooldowns.find(spellInfo->Id);
616  if (itr != _spellCooldowns.end())
617  end = itr->second.CooldownEnd;
618  else
619  {
620  auto catItr = _categoryCooldowns.find(spellInfo->GetCategory());
621  if (catItr == _categoryCooldowns.end())
622  return 0;
623 
624  end = catItr->second->CategoryEnd;
625  }
626 
627  Clock::time_point now = Clock::now();
628  if (end < now)
629  return 0;
630 
631  Clock::duration remaining = end - now;
632  return uint32(std::chrono::duration_cast<std::chrono::milliseconds>(remaining).count());
633 }
CategoryCooldownStorageType _categoryCooldowns
Definition: SpellHistory.h:166
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164
uint32_t uint32
Definition: g3dmath.h:168

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SpellHistory::HandleCooldowns ( SpellInfo const spellInfo,
Item const item,
Spell spell = nullptr 
)
234 {
235  HandleCooldowns(spellInfo, item ? item->GetEntry() : 0, spell);
236 }
void HandleCooldowns(SpellInfo const *spellInfo, Item const *item, Spell *spell=nullptr)
Definition: SpellHistory.cpp:233

+ Here is the call graph for this function:

void SpellHistory::HandleCooldowns ( SpellInfo const spellInfo,
uint32  itemID,
Spell spell = nullptr 
)
239 {
240  if (ConsumeCharge(spellInfo->ChargeCategoryEntry))
241  return;
242 
243  if (Player* player = _owner->ToPlayer())
244  {
245  // potions start cooldown until exiting combat
246  if (ItemTemplate const* itemTemplate = sObjectMgr->GetItemTemplate(itemID))
247  {
248  if (itemTemplate->IsPotion() || spellInfo->IsCooldownStartedOnEvent())
249  {
250  player->SetLastPotionId(itemID);
251  return;
252  }
253  }
254  }
255 
256  if (spellInfo->IsCooldownStartedOnEvent() || spellInfo->IsPassive() || (spell && spell->IsIgnoringCooldowns()))
257  return;
258 
259  StartCooldown(spellInfo, itemID, spell);
260 }
Unit * _owner
Definition: SpellHistory.h:163
bool ConsumeCharge(SpellCategoryEntry const *chargeCategoryEntry)
Definition: SpellHistory.cpp:699
#define sObjectMgr
Definition: ObjectMgr.h:1567
Player * ToPlayer()
Definition: Object.h:191
Definition: ItemTemplate.h:647
void StartCooldown(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool onHold=false)
Definition: SpellHistory.cpp:386
bool IsIgnoringCooldowns() const
Definition: Spell.h:596

+ Here is the call graph for this function:

bool SpellHistory::HasCharge ( SpellCategoryEntry const chargeCategoryEntry) const
778 {
779  if (!chargeCategoryEntry)
780  return true;
781 
782  // Check if the spell is currently using charges (untalented warlock Dark Soul)
783  int32 maxCharges = GetMaxCharges(chargeCategoryEntry);
784  if (maxCharges <= 0)
785  return true;
786 
787  auto itr = _categoryCharges.find(chargeCategoryEntry->ID);
788  return itr == _categoryCharges.end() || int32(itr->second.size()) < maxCharges;
789 }
int32 GetMaxCharges(SpellCategoryEntry const *chargeCategoryEntry) const
Definition: SpellHistory.cpp:791
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:168
int32_t int32
Definition: Define.h:146
int32_t int32
Definition: g3dmath.h:167

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool SpellHistory::HasCooldown ( SpellInfo const spellInfo,
uint32  itemId = 0,
bool  ignoreCategoryCooldown = false 
) const
592 {
593  if (_spellCooldowns.count(spellInfo->Id) != 0)
594  return true;
595 
596  if (ignoreCategoryCooldown)
597  return false;
598 
599  uint32 category = 0;
600  GetCooldownDurations(spellInfo, itemId, nullptr, &category, nullptr);
601  if (!category)
602  return false;
603 
604  return _categoryCooldowns.count(category) != 0;
605 }
CategoryCooldownStorageType _categoryCooldowns
Definition: SpellHistory.h:166
uint32_t uint32
Definition: Define.h:150
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164
static void GetCooldownDurations(SpellInfo const *spellInfo, uint32 itemId, int32 *cooldown, uint32 *categoryId, int32 *categoryCooldown)
Definition: SpellHistory.cpp:853

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool SpellHistory::HasCooldown ( uint32  spellId,
uint32  itemId = 0,
bool  ignoreCategoryCooldown = false 
) const
608 {
609  return HasCooldown(sSpellMgr->AssertSpellInfo(spellId), itemId, ignoreCategoryCooldown);
610 }
#define sSpellMgr
Definition: SpellMgr.h:756
bool HasCooldown(SpellInfo const *spellInfo, uint32 itemId=0, bool ignoreCategoryCooldown=false) const
Definition: SpellHistory.cpp:591

+ Here is the call graph for this function:

bool SpellHistory::HasGlobalCooldown ( SpellInfo const spellInfo) const
822 {
823  auto itr = _globalCooldowns.find(spellInfo->StartRecoveryCategory);
824  return itr != _globalCooldowns.end() && itr->second > Clock::now();
825 }
GlobalCooldownStorageType _globalCooldowns
Definition: SpellHistory.h:169

+ Here is the caller graph for this function:

bool SpellHistory::IsReady ( SpellInfo const spellInfo,
uint32  itemId = 0,
bool  ignoreCategoryCooldown = false 
) const
263 {
264  if (spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
265  if (IsSchoolLocked(spellInfo->GetSchoolMask()))
266  return false;
267 
268  if (HasCooldown(spellInfo->Id, itemId, ignoreCategoryCooldown))
269  return false;
270 
271  if (!HasCharge(spellInfo->ChargeCategoryEntry))
272  return false;
273 
274  return true;
275 }
Definition: SharedDefines.h:2058
bool HasCharge(SpellCategoryEntry const *chargeCategoryEntry) const
Definition: SpellHistory.cpp:777
bool HasCooldown(SpellInfo const *spellInfo, uint32 itemId=0, bool ignoreCategoryCooldown=false) const
Definition: SpellHistory.cpp:591
bool IsSchoolLocked(SpellSchoolMask schoolMask) const
Definition: SpellHistory.cpp:688

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool SpellHistory::IsSchoolLocked ( SpellSchoolMask  schoolMask) const
689 {
690  Clock::time_point now = Clock::now();
691  for (uint32 i = 0; i < MAX_SPELL_SCHOOL; ++i)
692  if (SpellSchoolMask(1 << i) & schoolMask)
693  if (_schoolLockouts[i] > now)
694  return true;
695 
696  return false;
697 }
SpellSchoolMask
Definition: SharedDefines.h:285
#define MAX_SPELL_SCHOOL
Definition: SharedDefines.h:283
Clock::time_point _schoolLockouts[MAX_SPELL_SCHOOL]
Definition: SpellHistory.h:167
uint32_t uint32
Definition: Define.h:150

+ Here is the caller graph for this function:

template<class OwnerType >
template void SpellHistory::LoadFromDB< Pet > ( PreparedQueryResult  cooldownsResult,
PreparedQueryResult  chargesResult 
)
133 {
134  typedef PersistenceHelper<OwnerType> StatementInfo;
135 
136  if (cooldownsResult)
137  {
138  do
139  {
140  uint32 spellId;
141  CooldownEntry cooldown;
142  if (StatementInfo::ReadCooldown(cooldownsResult->Fetch(), &spellId, &cooldown))
143  {
144  _spellCooldowns[spellId] = cooldown;
145  if (cooldown.CategoryId)
146  _categoryCooldowns[cooldown.CategoryId] = &_spellCooldowns[spellId];
147  }
148 
149  } while (cooldownsResult->NextRow());
150  }
151 
152  if (chargesResult)
153  {
154  do
155  {
156  Field* fields = chargesResult->Fetch();
157  uint32 categoryId = 0;
158  ChargeEntry charges;
159  if (StatementInfo::ReadCharge(fields, &categoryId, &charges))
160  _categoryCharges[categoryId].push_back(charges);
161 
162  } while (chargesResult->NextRow());
163  }
164 }
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:168
CategoryCooldownStorageType _categoryCooldowns
Definition: SpellHistory.h:166
Class used to access individual fields of database query result.
Definition: Field.h:56
uint32_t uint32
Definition: Define.h:150
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164

+ Here is the caller graph for this function:

void SpellHistory::LockSpellSchool ( SpellSchoolMask  schoolMask,
uint32  lockoutTime 
)
636 {
637  Clock::time_point now = Clock::now();
638  Clock::time_point lockoutEnd = now + std::chrono::duration_cast<Clock::duration>(std::chrono::milliseconds(lockoutTime));
639  for (uint32 i = 0; i < MAX_SPELL_SCHOOL; ++i)
640  if (SpellSchoolMask(1 << i) & schoolMask)
641  _schoolLockouts[i] = lockoutEnd;
642 
643  std::set<uint32> knownSpells;
644  if (Player* plrOwner = _owner->ToPlayer())
645  {
646  for (auto const& p : plrOwner->GetSpellMap())
647  if (p.second->state != PLAYERSPELL_REMOVED)
648  knownSpells.insert(p.first);
649  }
650  else if (Pet* petOwner = _owner->ToPet())
651  {
652  for (auto const& p : petOwner->m_spells)
653  if (p.second.state != PETSPELL_REMOVED)
654  knownSpells.insert(p.first);
655  }
656  else
657  {
658  Creature* creatureOwner = _owner->ToCreature();
659  for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
660  if (creatureOwner->m_spells[i])
661  knownSpells.insert(creatureOwner->m_spells[i]);
662  }
663 
665  spellCooldown.Caster = _owner->GetGUID();
666  spellCooldown.Flags = SPELL_COOLDOWN_FLAG_NONE;
667  for (uint32 spellId : knownSpells)
668  {
669  SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(spellId);
670  if (spellInfo->IsCooldownStartedOnEvent())
671  continue;
672 
674  continue;
675 
676  if ((schoolMask & spellInfo->GetSchoolMask()) && GetRemainingCooldown(spellInfo) < lockoutTime)
677  {
678  spellCooldown.SpellCooldowns.emplace_back(spellId, lockoutTime);
679  AddCooldown(spellId, 0, lockoutEnd, 0, now);
680  }
681  }
682 
683  if (Player* player = GetPlayerOwner())
684  if (!spellCooldown.SpellCooldowns.empty())
685  player->SendDirectMessage(spellCooldown.Write());
686 }
WorldPacket const * Write() override
Definition: SpellPackets.cpp:550
std::vector< SpellCooldownStruct > SpellCooldowns
Definition: SpellPackets.h:532
ObjectGuid Caster
Definition: SpellPackets.h:533
Definition: Player.h:106
void AddCooldown(uint32 spellId, uint32 itemId, std::chrono::duration< Type, Period > cooldownDuration)
Definition: SpellHistory.h:95
Definition: SharedDefines.h:2058
#define CREATURE_MAX_SPELLS
Definition: Creature.h:75
Unit * _owner
Definition: SpellHistory.h:163
SpellSchoolMask
Definition: SharedDefines.h:285
Definition: SpellInfo.h:326
Pet * ToPet()
Definition: Unit.h:2200
Definition: Creature.h:467
#define MAX_SPELL_SCHOOL
Definition: SharedDefines.h:283
Clock::time_point _schoolLockouts[MAX_SPELL_SCHOOL]
Definition: SpellHistory.h:167
Player * ToPlayer()
Definition: Object.h:191
uint32 m_spells[CREATURE_MAX_SPELLS]
Definition: Creature.h:602
#define sSpellMgr
Definition: SpellMgr.h:756
uint32_t uint32
Definition: Define.h:150
float milliseconds()
Definition: units.h:92
Definition: PetDefines.h:53
uint32 PreventionType
Definition: SpellInfo.h:399
Definition: SpellHistory.h:37
ObjectGuid const & GetGUID() const
Definition: Object.h:105
Creature * ToCreature()
Definition: Object.h:194
SpellSchoolMask GetSchoolMask() const
Definition: SpellInfo.cpp:2131
Player * GetPlayerOwner() const
Definition: SpellHistory.cpp:837
uint32 GetRemainingCooldown(SpellInfo const *spellInfo) const
Definition: SpellHistory.cpp:612
uint8_t uint8
Definition: Define.h:152
Definition: SpellPackets.h:525
uint8 Flags
Definition: SpellPackets.h:534
Definition: Pet.h:46
bool IsCooldownStartedOnEvent() const
Definition: SpellInfo.cpp:1470

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SpellHistory::ModifyCooldown ( uint32  spellId,
int32  cooldownModMs 
)
527 {
528  auto itr = _spellCooldowns.find(spellId);
529  if (!cooldownModMs || itr == _spellCooldowns.end())
530  return;
531 
532  Clock::time_point now = Clock::now();
533  Clock::duration offset = std::chrono::duration_cast<Clock::duration>(std::chrono::milliseconds(cooldownModMs));
534  if (itr->second.CooldownEnd + offset > now)
535  itr->second.CooldownEnd += offset;
536  else
537  EraseCooldown(itr);
538 
539  if (Player* playerOwner = GetPlayerOwner())
540  {
542  modifyCooldown.IsPet = _owner != playerOwner;
543  modifyCooldown.SpellID = spellId;
544  modifyCooldown.DeltaTime = cooldownModMs;
545  playerOwner->SendDirectMessage(modifyCooldown.Write());
546  }
547 }
Unit * _owner
Definition: SpellHistory.h:163
WorldPacket const * Write() override
Definition: SpellPackets.cpp:533
int32 DeltaTime
Definition: SpellPackets.h:512
bool IsPet
Definition: SpellPackets.h:511
Definition: SpellPackets.h:504
int32 SpellID
Definition: SpellPackets.h:513
float milliseconds()
Definition: units.h:92
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164
Player * GetPlayerOwner() const
Definition: SpellHistory.cpp:837
CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr)
Definition: SpellHistory.h:155

+ Here is the call graph for this function:

void SpellHistory::ResetAllCharges ( )
766 {
767  _categoryCharges.clear();
768 
769  if (Player* player = GetPlayerOwner())
770  {
771  WorldPackets::Spells::ClearAllSpellCharges clearAllSpellCharges;
772  clearAllSpellCharges.IsPet = _owner != player;
773  player->SendDirectMessage(clearAllSpellCharges.Write());
774  }
775 }
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:168
Unit * _owner
Definition: SpellHistory.h:163
WorldPacket const * Write() override
Definition: SpellPackets.cpp:589
Definition: SpellPackets.h:559
bool IsPet
Definition: SpellPackets.h:566
Player * GetPlayerOwner() const
Definition: SpellHistory.cpp:837

+ Here is the call graph for this function:

void SpellHistory::ResetAllCooldowns ( )
576 {
577  if (GetPlayerOwner())
578  {
579  std::vector<int32> cooldowns;
580  cooldowns.reserve(_spellCooldowns.size());
581  for (auto const& p : _spellCooldowns)
582  cooldowns.push_back(p.first);
583 
584  SendClearCooldowns(cooldowns);
585  }
586 
587  _categoryCooldowns.clear();
588  _spellCooldowns.clear();
589 }
void SendClearCooldowns(std::vector< int32 > const &cooldowns) const
Definition: SpellHistory.cpp:842
CategoryCooldownStorageType _categoryCooldowns
Definition: SpellHistory.h:166
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164
Player * GetPlayerOwner() const
Definition: SpellHistory.cpp:837

+ Here is the call graph for this function:

void SpellHistory::ResetCharges ( SpellCategoryEntry const chargeCategoryEntry)
746 {
747  if (!chargeCategoryEntry)
748  return;
749 
750  auto itr = _categoryCharges.find(chargeCategoryEntry->ID);
751  if (itr != _categoryCharges.end())
752  {
753  _categoryCharges.erase(itr);
754 
755  if (Player* player = GetPlayerOwner())
756  {
757  WorldPackets::Spells::ClearSpellCharges clearSpellCharges;
758  clearSpellCharges.IsPet = _owner != player;
759  clearSpellCharges.Category = chargeCategoryEntry->ID;
760  player->SendDirectMessage(clearSpellCharges.Write());
761  }
762  }
763 }
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:168
Unit * _owner
Definition: SpellHistory.h:163
WorldPacket const * Write() override
Definition: SpellPackets.cpp:597
int32 Category
Definition: SpellPackets.h:577
bool IsPet
Definition: SpellPackets.h:576
Definition: SpellPackets.h:569
Player * GetPlayerOwner() const
Definition: SpellHistory.cpp:837

+ Here is the call graph for this function:

void SpellHistory::ResetCooldown ( uint32  spellId,
bool  update = false 
)
550 {
551  auto itr = _spellCooldowns.find(spellId);
552  if (itr == _spellCooldowns.end())
553  return;
554 
555  ResetCooldown(itr, update);
556 }
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164
void ResetCooldown(uint32 spellId, bool update=false)
Definition: SpellHistory.cpp:549

+ Here is the caller graph for this function:

void SpellHistory::ResetCooldown ( CooldownStorageType::iterator &  itr,
bool  update = false 
)
559 {
560  if (update)
561  {
562  if (Player* playerOwner = GetPlayerOwner())
563  {
565  clearCooldown.IsPet = _owner != playerOwner;
566  clearCooldown.SpellID = itr->first;
567  clearCooldown.ClearOnHold = false;
568  playerOwner->SendDirectMessage(clearCooldown.Write());
569  }
570  }
571 
572  itr = EraseCooldown(itr);
573 }
bool IsPet
Definition: SpellPackets.h:499
Unit * _owner
Definition: SpellHistory.h:163
bool ClearOnHold
Definition: SpellPackets.h:501
WorldPacket const * Write() override
Definition: SpellPackets.cpp:523
Definition: SpellPackets.h:492
Player * GetPlayerOwner() const
Definition: SpellHistory.cpp:837
int32 SpellID
Definition: SpellPackets.h:500
CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr)
Definition: SpellHistory.h:155

+ Here is the call graph for this function:

template<typename Predicate >
void SpellHistory::ResetCooldowns ( Predicate  predicate,
bool  update = false 
)
inline
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  }
void SendClearCooldowns(std::vector< int32 > const &cooldowns) const
Definition: SpellHistory.cpp:842
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164
void ResetCooldown(uint32 spellId, bool update=false)
Definition: SpellHistory.cpp:549
int32_t int32
Definition: g3dmath.h:167

+ Here is the caller graph for this function:

void SpellHistory::RestoreCharge ( SpellCategoryEntry const chargeCategoryEntry)
722 {
723  if (!chargeCategoryEntry)
724  return;
725 
726  auto itr = _categoryCharges.find(chargeCategoryEntry->ID);
727  if (itr != _categoryCharges.end() && !itr->second.empty())
728  {
729  itr->second.pop_back();
730 
731  if (Player* player = GetPlayerOwner())
732  {
734  setSpellCharges.Category = chargeCategoryEntry->ID;
735  if (!itr->second.empty())
736  setSpellCharges.NextRecoveryTime = uint32(std::chrono::duration_cast<std::chrono::milliseconds>(itr->second.front().RechargeEnd - Clock::now()).count());
737  setSpellCharges.ConsumedCharges = itr->second.size();
738  setSpellCharges.IsPet = player != _owner;
739 
740  player->SendDirectMessage(setSpellCharges.Write());
741  }
742  }
743 }
WorldPacket const * Write() override
Definition: SpellPackets.cpp:606
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:168
Unit * _owner
Definition: SpellHistory.h:163
Definition: SpellPackets.h:580
bool IsPet
Definition: SpellPackets.h:587
uint32_t uint32
Definition: Define.h:150
uint8 ConsumedCharges
Definition: SpellPackets.h:590
uint32 NextRecoveryTime
Definition: SpellPackets.h:589
Player * GetPlayerOwner() const
Definition: SpellHistory.cpp:837
uint32 Category
Definition: SpellPackets.h:588

+ Here is the call graph for this function:

void SpellHistory::RestoreCooldownStateAfterDuel ( )
900 {
901  if (Player* player = _owner->ToPlayer())
902  {
903  // add all profession CDs created while in duel (if any)
904  for (auto const& c : _spellCooldowns)
905  {
906  SpellInfo const* spellInfo = sSpellMgr->AssertSpellInfo(c.first);
907 
908  if (spellInfo->RecoveryTime > 10 * MINUTE * IN_MILLISECONDS ||
909  spellInfo->CategoryRecoveryTime > 10 * MINUTE * IN_MILLISECONDS)
910  _spellCooldownsBeforeDuel[c.first] = _spellCooldowns[c.first];
911  }
912 
913  // check for spell with onHold active before and during the duel
914  for (auto itr = _spellCooldownsBeforeDuel.begin(); itr != _spellCooldownsBeforeDuel.end(); ++itr)
915  {
916  if (!itr->second.OnHold &&
917  _spellCooldowns.find(itr->first) != _spellCooldowns.end() &&
918  !_spellCooldowns[itr->first].OnHold)
919  _spellCooldowns[itr->first] = _spellCooldownsBeforeDuel[itr->first];
920  }
921 
922  // update the client: restore old cooldowns
924  spellCooldown.Caster = _owner->GetGUID();
926 
927  for (auto const& c : _spellCooldowns)
928  {
929  Clock::time_point now = Clock::now();
930  uint32 cooldownDuration = c.second.CooldownEnd > now ? std::chrono::duration_cast<std::chrono::milliseconds>(c.second.CooldownEnd - now).count() : 0;
931 
932  // cooldownDuration must be between 0 and 10 minutes in order to avoid any visual bugs
933  if (cooldownDuration <= 0 || cooldownDuration > 10 * MINUTE * IN_MILLISECONDS || c.second.OnHold)
934  continue;
935 
936  spellCooldown.SpellCooldowns.emplace_back(c.first, cooldownDuration);
937  }
938 
939  player->SendDirectMessage(spellCooldown.Write());
940  }
941 }
WorldPacket const * Write() override
Definition: SpellPackets.cpp:550
std::vector< SpellCooldownStruct > SpellCooldowns
Definition: SpellPackets.h:532
ObjectGuid Caster
Definition: SpellPackets.h:533
Unit * _owner
Definition: SpellHistory.h:163
Definition: SpellInfo.h:326
Definition: Common.h:97
Player * ToPlayer()
Definition: Object.h:191
uint32 RecoveryTime
Definition: SpellInfo.h:363
#define sSpellMgr
Definition: SpellMgr.h:756
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
float milliseconds()
Definition: units.h:92
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164
CooldownStorageType _spellCooldownsBeforeDuel
Definition: SpellHistory.h:165
ObjectGuid const & GetGUID() const
Definition: Object.h:105
Definition: Common.h:103
uint32 CategoryRecoveryTime
Definition: SpellInfo.h:364
Definition: SpellPackets.h:525
uint8 Flags
Definition: SpellPackets.h:534

+ Here is the call graph for this function:

void SpellHistory::SaveCooldownStateBeforeDuel ( )
895 {
897 }
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164
CooldownStorageType _spellCooldownsBeforeDuel
Definition: SpellHistory.h:165
template<class OwnerType >
template void SpellHistory::SaveToDB< Pet > ( SQLTransaction trans)
168 {
169  typedef PersistenceHelper<OwnerType> StatementInfo;
170 
171  uint8 index = 0;
172  PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(StatementInfo::CooldownsDeleteStatement);
173  StatementInfo::SetIdentifier(stmt, index++, _owner);
174  trans->Append(stmt);
175 
176  for (auto const& p : _spellCooldowns)
177  {
178  if (!p.second.OnHold)
179  {
180  index = 0;
181  stmt = CharacterDatabase.GetPreparedStatement(StatementInfo::CooldownsInsertStatement);
182  StatementInfo::SetIdentifier(stmt, index++, _owner);
183  StatementInfo::WriteCooldown(stmt, index, p);
184  trans->Append(stmt);
185  }
186  }
187 
188  stmt = CharacterDatabase.GetPreparedStatement(StatementInfo::ChargesDeleteStatement);
189  StatementInfo::SetIdentifier(stmt, 0, _owner);
190  trans->Append(stmt);
191 
192  for (auto const& p : _categoryCharges)
193  {
194  for (ChargeEntry const& charge : p.second)
195  {
196  index = 0;
197  stmt = CharacterDatabase.GetPreparedStatement(StatementInfo::ChargesInsertStatement);
198  StatementInfo::SetIdentifier(stmt, index++, _owner);
199  StatementInfo::WriteCharge(stmt, index, p.first, charge);
200  trans->Append(stmt);
201  }
202  }
203 }
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:168
Unit * _owner
Definition: SpellHistory.h:163
Definition: PreparedStatement.h:74
PreparedStatement * GetPreparedStatement(PreparedStatementIndex index)
Definition: DatabaseWorkerPool.h:263
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164
uint8_t uint8
Definition: Define.h:152
CharacterDatabaseWorkerPool CharacterDatabase
Accessor to the character database.
Definition: DatabaseEnv.cpp:21

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SpellHistory::SendClearCooldowns ( std::vector< int32 > const cooldowns) const
private
843 {
844  if (Player const* playerOwner = GetPlayerOwner())
845  {
847  clearCooldowns.IsPet = _owner != playerOwner;
848  clearCooldowns.SpellID = cooldowns;
849  playerOwner->SendDirectMessage(clearCooldowns.Write());
850  }
851 }
WorldPacket const * Write() override
Definition: SpellPackets.cpp:511
Unit * _owner
Definition: SpellHistory.h:163
std::vector< int32 > SpellID
Definition: SpellPackets.h:488
bool IsPet
Definition: SpellPackets.h:489
Player * GetPlayerOwner() const
Definition: SpellHistory.cpp:837
Definition: SpellPackets.h:481

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SpellHistory::SendCooldownEvent ( SpellInfo const spellInfo,
uint32  itemId = 0,
Spell spell = nullptr,
bool  startCooldown = true 
)
488 {
489  // Send activate cooldown timer (possible 0) at client side
490  if (Player* player = GetPlayerOwner())
491  {
492  uint32 category = spellInfo->GetCategory();
493  GetCooldownDurations(spellInfo, itemId, nullptr, &category, nullptr);
494 
495  auto categoryItr = _categoryCooldowns.find(category);
496  if (categoryItr != _categoryCooldowns.end() && categoryItr->second->SpellId != spellInfo->Id)
497  {
498  player->SendDirectMessage(WorldPackets::Spells::CooldownEvent(player != _owner, categoryItr->second->SpellId).Write());
499 
500  if (startCooldown)
501  StartCooldown(sSpellMgr->AssertSpellInfo(categoryItr->second->SpellId), itemId, spell);
502  }
503 
504  player->SendDirectMessage(WorldPackets::Spells::CooldownEvent(player != _owner, spellInfo->Id).Write());
505  }
506 
507  // start cooldowns at server side, if any
508  if (startCooldown)
509  StartCooldown(spellInfo, itemId, spell);
510 }
Unit * _owner
Definition: SpellHistory.h:163
CategoryCooldownStorageType _categoryCooldowns
Definition: SpellHistory.h:166
WorldPacket const * Write() override
Definition: SpellPackets.cpp:502
Definition: SpellPackets.h:469
#define sSpellMgr
Definition: SpellMgr.h:756
uint32_t uint32
Definition: Define.h:150
void StartCooldown(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool onHold=false)
Definition: SpellHistory.cpp:386
Player * GetPlayerOwner() const
Definition: SpellHistory.cpp:837
static void GetCooldownDurations(SpellInfo const *spellInfo, uint32 itemId, int32 *cooldown, uint32 *categoryId, int32 *categoryCooldown)
Definition: SpellHistory.cpp:853

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SpellHistory::StartCooldown ( SpellInfo const spellInfo,
uint32  itemId,
Spell spell = nullptr,
bool  onHold = false 
)
387 {
388  // init cooldown values
389  uint32 categoryId = 0;
390  int32 cooldown = -1;
391  int32 categoryCooldown = -1;
392 
393  GetCooldownDurations(spellInfo, itemId, &cooldown, &categoryId, &categoryCooldown);
394 
395  Clock::time_point curTime = Clock::now();
396  Clock::time_point catrecTime;
397  Clock::time_point recTime;
398  bool needsCooldownPacket = false;
399 
400  // overwrite time for selected category
401  if (onHold)
402  {
403  // use +MONTH as infinite cooldown marker
404  catrecTime = categoryCooldown > 0 ? (curTime + InfinityCooldownDelay) : curTime;
405  recTime = cooldown > 0 ? (curTime + InfinityCooldownDelay) : catrecTime;
406  }
407  else
408  {
409  // shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK)
410  // prevent 0 cooldowns set by another way
411  if (cooldown <= 0 && categoryCooldown <= 0 && (categoryId == 76 || (spellInfo->IsAutoRepeatRangedSpell() && spellInfo->Id != 75)))
412  cooldown = _owner->GetAttackTime(RANGED_ATTACK);
413 
414  // Now we have cooldown data (if found any), time to apply mods
415  if (Player* modOwner = _owner->GetSpellModOwner())
416  {
417  if (cooldown > 0)
418  modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, cooldown, spell);
419 
420  if (categoryCooldown > 0 && !spellInfo->HasAttribute(SPELL_ATTR6_IGNORE_CATEGORY_COOLDOWN_MODS))
421  modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, categoryCooldown, spell);
422  }
423 
425  {
426  // Apply SPELL_AURA_MOD_COOLDOWN only to own spells
427  Player* playerOwner = GetPlayerOwner();
428  if (!playerOwner || playerOwner->HasSpell(spellInfo->Id))
429  {
430  needsCooldownPacket = true;
431  cooldown += cooldownMod * IN_MILLISECONDS; // SPELL_AURA_MOD_COOLDOWN does not affect category cooldows, verified with shaman shocks
432  }
433  }
434 
435  // Apply SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN modifiers
436  // Note: This aura applies its modifiers to all cooldowns of spells with set category, not to category cooldown only
437  if (categoryId)
438  {
440  {
441  if (cooldown > 0)
442  cooldown += categoryModifier;
443 
444  if (categoryCooldown > 0)
445  categoryCooldown += categoryModifier;
446  }
447 
448  SpellCategoryEntry const* categoryEntry = sSpellCategoryStore.AssertEntry(categoryId);
450  categoryCooldown = int32(std::chrono::duration_cast<std::chrono::milliseconds>(Clock::from_time_t(sWorld->GetNextDailyQuestsResetTime()) - Clock::now()).count());
451  }
452 
453  // replace negative cooldowns by 0
454  if (cooldown < 0)
455  cooldown = 0;
456 
457  if (categoryCooldown < 0)
458  categoryCooldown = 0;
459 
460  // no cooldown after applying spell mods
461  if (cooldown == 0 && categoryCooldown == 0)
462  return;
463 
464  catrecTime = categoryCooldown ? curTime + std::chrono::duration_cast<Clock::duration>(std::chrono::milliseconds(categoryCooldown)) : curTime;
465  recTime = cooldown ? curTime + std::chrono::duration_cast<Clock::duration>(std::chrono::milliseconds(cooldown)) : catrecTime;
466  }
467 
468  // self spell cooldown
469  if (recTime != curTime)
470  {
471  AddCooldown(spellInfo->Id, itemId, recTime, categoryId, catrecTime, onHold);
472 
473  if (needsCooldownPacket)
474  {
475  if (Player* playerOwner = GetPlayerOwner())
476  {
478  spellCooldown.Caster = _owner->GetGUID();
479  spellCooldown.Flags = SPELL_COOLDOWN_FLAG_NONE;
480  spellCooldown.SpellCooldowns.emplace_back(spellInfo->Id, uint32(cooldown));
481  playerOwner->SendDirectMessage(spellCooldown.Write());
482  }
483  }
484  }
485 }
WorldPacket const * Write() override
Definition: SpellPackets.cpp:550
std::vector< SpellCooldownStruct > SpellCooldowns
Definition: SpellPackets.h:532
int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
Definition: Unit.cpp:4521
ObjectGuid Caster
Definition: SpellPackets.h:533
void AddCooldown(uint32 spellId, uint32 itemId, std::chrono::duration< Type, Period > cooldownDuration)
Definition: SpellHistory.h:95
Unit * _owner
Definition: SpellHistory.h:163
int32 GetTotalAuraModifier(AuraType auratype) const
Definition: Unit.cpp:4396
Definition: Unit.h:619
Definition: SharedDefines.h:603
uint32 Flags
Definition: DBCStructure.h:1100
#define sWorld
Definition: World.h:887
Definition: SpellAuraDefines.h:401
uint32 GetAttackTime(WeaponAttackType att) const
Definition: Unit.cpp:10326
DBCStorage< SpellCategoryEntry > sSpellCategoryStore(SpellCategoryfmt)
Definition: DBCStructure.h:1097
int32_t int32
Definition: Define.h:146
uint32_t uint32
Definition: Define.h:150
float milliseconds()
Definition: units.h:92
Definition: Unit.h:97
Definition: SpellHistory.h:37
ObjectGuid const & GetGUID() const
Definition: Object.h:105
Player * GetSpellModOwner() const
Definition: Unit.cpp:12691
Definition: Common.h:103
Player * GetPlayerOwner() const
Definition: SpellHistory.cpp:837
static Clock::duration const InfinityCooldownDelay
Definition: SpellHistory.h:89
int32_t int32
Definition: g3dmath.h:167
Definition: SpellAuraDefines.h:256
Definition: SpellPackets.h:525
uint8 Flags
Definition: SpellPackets.h:534
static void GetCooldownDurations(SpellInfo const *spellInfo, uint32 itemId, int32 *cooldown, uint32 *categoryId, int32 *categoryCooldown)
Definition: SpellHistory.cpp:853

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void SpellHistory::Update ( )
206 {
207  SQLTransaction t;
208  Clock::time_point now = Clock::now();
209  for (auto itr = _categoryCooldowns.begin(); itr != _categoryCooldowns.end();)
210  {
211  if (itr->second->CategoryEnd < now)
212  itr = _categoryCooldowns.erase(itr);
213  else
214  ++itr;
215  }
216 
217  for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end();)
218  {
219  if (itr->second.CooldownEnd < now)
220  itr = EraseCooldown(itr);
221  else
222  ++itr;
223  }
224 
225  for (auto& p : _categoryCharges)
226  {
227  std::deque<ChargeEntry>& chargeRefreshTimes = p.second;
228  while (!chargeRefreshTimes.empty() && chargeRefreshTimes.front().RechargeEnd <= now)
229  chargeRefreshTimes.pop_front();
230  }
231 }
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:168
CategoryCooldownStorageType _categoryCooldowns
Definition: SpellHistory.h:166
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164
CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr)
Definition: SpellHistory.h:155
std::shared_ptr< Transaction > SQLTransaction
Definition: Transaction.h:58

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

template<class PacketType >
void SpellHistory::WritePacket ( PacketType *  packet) const
279 {
280  static_assert(!std::is_same<PacketType, PacketType>::value /*static_assert(false)*/, "This packet is not supported.");
281 }
const FieldDescriptor value
Definition: descriptor.h:1522
template<>
void SpellHistory::WritePacket ( WorldPackets::Spells::SendSpellHistory sendSpellHistory) const
285 {
286  sendSpellHistory->Entries.reserve(_spellCooldowns.size());
287 
288  Clock::time_point now = Clock::now();
289  for (auto const& p : _spellCooldowns)
290  {
292  historyEntry.SpellID = p.first;
293  historyEntry.ItemID = p.second.ItemId;
294 
295  if (p.second.OnHold)
296  historyEntry.OnHold = true;
297  else
298  {
299  std::chrono::milliseconds cooldownDuration = std::chrono::duration_cast<std::chrono::milliseconds>(p.second.CooldownEnd - now);
300  if (cooldownDuration.count() <= 0)
301  continue;
302 
303  historyEntry.RecoveryTime = uint32(cooldownDuration.count());
304  std::chrono::milliseconds categoryDuration = std::chrono::duration_cast<std::chrono::milliseconds>(p.second.CategoryEnd - now);
305  if (categoryDuration.count() > 0)
306  {
307  historyEntry.Category = p.second.CategoryId;
308  historyEntry.CategoryRecoveryTime = uint32(categoryDuration.count());
309  }
310  }
311 
312  sendSpellHistory->Entries.push_back(historyEntry);
313  }
314 }
bool OnHold
Definition: SpellPackets.h:544
uint32 SpellID
Definition: SpellPackets.h:539
int32 CategoryRecoveryTime
Definition: SpellPackets.h:543
uint32 ItemID
Definition: SpellPackets.h:540
Definition: SpellPackets.h:537
int32 RecoveryTime
Definition: SpellPackets.h:542
float milliseconds()
Definition: units.h:92
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164
uint32_t uint32
Definition: g3dmath.h:168
std::vector< SpellHistoryEntry > Entries
Definition: SpellPackets.h:556
uint32 Category
Definition: SpellPackets.h:541

+ Here is the call graph for this function:

template<>
void SpellHistory::WritePacket ( WorldPackets::Spells::SendSpellCharges sendSpellCharges) const
318 {
319  sendSpellCharges->Entries.reserve(_categoryCharges.size());
320 
321  Clock::time_point now = Clock::now();
322  for (auto const& p : _categoryCharges)
323  {
324  if (!p.second.empty())
325  {
326  std::chrono::milliseconds cooldownDuration = std::chrono::duration_cast<std::chrono::milliseconds>(p.second.front().RechargeEnd - now);
327  if (cooldownDuration.count() <= 0)
328  continue;
329 
331  chargeEntry.Category = p.first;
332  chargeEntry.NextRecoveryTime = uint32(cooldownDuration.count());
333  chargeEntry.ConsumedCharges = p.second.size();
334  sendSpellCharges->Entries.push_back(chargeEntry);
335  }
336  }
337 }
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:168
uint32 Category
Definition: SpellPackets.h:595
Definition: SpellPackets.h:593
uint8 ConsumedCharges
Definition: SpellPackets.h:597
float milliseconds()
Definition: units.h:92
std::vector< SpellChargeEntry > Entries
Definition: SpellPackets.h:607
uint32 NextRecoveryTime
Definition: SpellPackets.h:596
uint32_t uint32
Definition: g3dmath.h:168

+ Here is the call graph for this function:

template<>
void SpellHistory::WritePacket ( WorldPackets::Pet::PetSpells petSpells) const
341 {
342  Clock::time_point now = Clock::now();
343 
344  petSpells->Cooldowns.reserve(_spellCooldowns.size());
345  for (auto const& p : _spellCooldowns)
346  {
347  WorldPackets::Pet::PetSpellCooldown petSpellCooldown;
348  petSpellCooldown.SpellID = p.first;
349  petSpellCooldown.Category = p.second.CategoryId;
350 
351  if (!p.second.OnHold)
352  {
353  std::chrono::milliseconds cooldownDuration = std::chrono::duration_cast<std::chrono::milliseconds>(p.second.CooldownEnd - now);
354  if (cooldownDuration.count() <= 0)
355  continue;
356 
357  petSpellCooldown.Duration = uint32(cooldownDuration.count());
358  std::chrono::milliseconds categoryDuration = std::chrono::duration_cast<std::chrono::milliseconds>(p.second.CategoryEnd - now);
359  if (categoryDuration.count() > 0)
360  petSpellCooldown.CategoryDuration = uint32(categoryDuration.count());
361  }
362 
363  petSpells->Cooldowns.push_back(petSpellCooldown);
364  }
365 
366  petSpells->SpellHistory.reserve(_categoryCharges.size());
367  for (auto const& p : _categoryCharges)
368  {
369  if (!p.second.empty())
370  {
371  std::chrono::milliseconds cooldownDuration = std::chrono::duration_cast<std::chrono::milliseconds>(p.second.front().RechargeEnd - now);
372  if (cooldownDuration.count() <= 0)
373  continue;
374 
375  WorldPackets::Pet::PetSpellHistory petChargeEntry;
376  petChargeEntry.CategoryID = p.first;
377  petChargeEntry.RecoveryTime = uint32(cooldownDuration.count());
378  petChargeEntry.ConsumedCharges = p.second.size();
379 
380  petSpells->SpellHistory.push_back(petChargeEntry);
381  }
382  }
383 }
Definition: PetPackets.h:89
int32 CategoryID
Definition: PetPackets.h:91
ChargeStorageType _categoryCharges
Definition: SpellHistory.h:168
int32 SpellID
Definition: PetPackets.h:83
int8 ConsumedCharges
Definition: PetPackets.h:93
int32 Duration
Definition: PetPackets.h:84
int32 CategoryDuration
Definition: PetPackets.h:85
int Category
Definition: PetPackets.h:86
uint32_t uint32
Definition: Define.h:150
float milliseconds()
Definition: units.h:92
CooldownStorageType _spellCooldowns
Definition: SpellHistory.h:164
int32 RecoveryTime
Definition: PetPackets.h:92
Definition: PetPackets.h:81
std::vector< PetSpellHistory > SpellHistory
Definition: PetPackets.h:115
uint32_t uint32
Definition: g3dmath.h:168
std::vector< PetSpellCooldown > Cooldowns
Definition: PetPackets.h:114

+ Here is the call graph for this function:

Member Data Documentation

ChargeStorageType SpellHistory::_categoryCharges
private
CategoryCooldownStorageType SpellHistory::_categoryCooldowns
private
GlobalCooldownStorageType SpellHistory::_globalCooldowns
private
Unit* SpellHistory::_owner
private
Clock::time_point SpellHistory::_schoolLockouts[MAX_SPELL_SCHOOL]
private
CooldownStorageType SpellHistory::_spellCooldowns
private
CooldownStorageType SpellHistory::_spellCooldownsBeforeDuel
private
SpellHistory::Clock::duration const SpellHistory::InfinityCooldownDelay = std::chrono::duration_cast<SpellHistory::Clock::duration>(std::chrono::seconds(MONTH))
static

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