54 cooldownEntry->
SpellId = *spellId;
55 cooldownEntry->
CooldownEnd = time_point_cast<Duration>(Clock::from_time_t(fields[2].GetInt64()));
58 cooldownEntry->
CategoryEnd = time_point_cast<Duration>(Clock::from_time_t(fields[4].GetInt64()));
68 chargeEntry->
RechargeStart = time_point_cast<Duration>(Clock::from_time_t(fields[1].GetInt64()));
69 chargeEntry->
RechargeEnd = time_point_cast<Duration>(Clock::from_time_t(fields[2].GetInt64()));
106 cooldownEntry->
SpellId = *spellId;
107 cooldownEntry->
CooldownEnd = time_point_cast<Duration>(Clock::from_time_t(fields[1].GetInt64()));
108 cooldownEntry->
ItemId = 0;
110 cooldownEntry->
CategoryEnd = time_point_cast<Duration>(Clock::from_time_t(fields[3].GetInt64()));
120 chargeEntry->
RechargeStart = time_point_cast<Duration>(Clock::from_time_t(fields[1].GetInt64()));
121 chargeEntry->
RechargeEnd = time_point_cast<Duration>(Clock::from_time_t(fields[2].GetInt64()));
135 stmt->
setUInt32(index++, chargeCategory);
147template<
class OwnerType>
158 if (StatementInfo::ReadCooldown(cooldownsResult->Fetch(), &spellId, &cooldown))
165 }
while (cooldownsResult->NextRow());
172 Field* fields = chargesResult->Fetch();
175 if (StatementInfo::ReadCharge(fields, &categoryId, &charges))
178 }
while (chargesResult->NextRow());
182template<
class OwnerType>
189 StatementInfo::SetIdentifier(stmt, index++,
_owner);
194 if (!cooldown.OnHold)
197 stmt =
CharacterDatabase.GetPreparedStatement(StatementInfo::CooldownsInsertStatement);
198 StatementInfo::SetIdentifier(stmt, index++,
_owner);
199 StatementInfo::WriteCooldown(stmt, index, cooldown);
204 stmt =
CharacterDatabase.GetPreparedStatement(StatementInfo::ChargesDeleteStatement);
205 StatementInfo::SetIdentifier(stmt, 0,
_owner);
213 stmt =
CharacterDatabase.GetPreparedStatement(StatementInfo::ChargesInsertStatement);
214 StatementInfo::SetIdentifier(stmt, index++,
_owner);
215 StatementInfo::WriteCharge(stmt, index, categoryId, charge);
223 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
226 if (itr->second->CategoryEnd < now)
234 if (itr->second.CooldownEnd < now)
241 while (!chargeRefreshTimes.empty() && chargeRefreshTimes.front().RechargeEnd <= now)
242 chargeRefreshTimes.pop_front();
267 player->SetLastPotionId(itemId);
298 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
302 historyEntry.
SpellID = spellId;
303 historyEntry.
ItemID = cooldown.ItemId;
306 historyEntry.
OnHold =
true;
309 Milliseconds cooldownDuration = duration_cast<Milliseconds>(cooldown.CooldownEnd - now);
310 if (cooldownDuration.count() <= 0)
313 Milliseconds categoryDuration = duration_cast<Milliseconds>(cooldown.CategoryEnd - now);
314 if (categoryDuration.count() > 0)
316 historyEntry.
Category = cooldown.CategoryId;
320 if (cooldownDuration.count() > categoryDuration.count())
324 sendSpellHistory->
Entries.push_back(historyEntry);
332 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
335 if (!consumedCharges.empty())
337 Milliseconds cooldownDuration = duration_cast<Milliseconds>(consumedCharges.front().RechargeEnd - now);
338 if (cooldownDuration.count() <= 0)
345 sendSpellCharges->
Entries.push_back(chargeEntry);
352 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
358 petSpellCooldown.
SpellID = spellId;
359 petSpellCooldown.
Category = cooldown.CategoryId;
361 if (!cooldown.OnHold)
363 Milliseconds cooldownDuration = duration_cast<Milliseconds>(cooldown.CooldownEnd - now);
364 if (cooldownDuration.count() <= 0)
368 Milliseconds categoryDuration = duration_cast<Milliseconds>(cooldown.CategoryEnd - now);
369 if (categoryDuration.count() > 0)
375 petSpells->
Cooldowns.push_back(petSpellCooldown);
381 if (!consumedCharges.empty())
383 Milliseconds cooldownDuration = duration_cast<Milliseconds>(consumedCharges.front().RechargeEnd - now);
384 if (cooldownDuration.count() <= 0)
401 Duration cooldown = Duration::zero();
402 Duration categoryCooldown = Duration::zero();
404 TimePoint curTime = time_point_cast<Duration>(GameTime::GetTime<Clock>());
407 bool needsCooldownPacket =
false;
412 cooldown = *forcedCooldown;
432 int32 intValue = value.count();
437 if (cooldown >= Duration::zero())
438 applySpellMod(cooldown);
441 applySpellMod(categoryCooldown);
457 auto calcRecoveryRate = [&](
AuraEffect const* modRecoveryRate)
459 double rate = 100.0 / (std::max(modRecoveryRate->GetAmount(), -99.0) + 100.0);
460 if (baseCooldown <= 1h
468 double recoveryRate = 1.0;
470 if (modRecoveryRate->IsAffectingSpell(spellInfo))
471 recoveryRate *= calcRecoveryRate(modRecoveryRate);
474 if (spellInfo->
HasLabel(modRecoveryRate->GetMiscValue()) || (modRecoveryRate->GetMiscValueB() && spellInfo->
HasLabel(modRecoveryRate->GetMiscValueB())))
475 recoveryRate *= calcRecoveryRate(modRecoveryRate);
477 if (recoveryRate > 0.0)
480 categoryCooldown =
Duration(
int64(categoryCooldown.count() * recoveryRate));
488 if (!playerOwner || playerOwner->
HasSpell(spellInfo->
Id))
490 needsCooldownPacket =
true;
501 if (cooldown > Duration::zero())
504 if (categoryCooldown > Duration::zero())
510 categoryCooldown = duration_cast<Milliseconds>(Clock::from_time_t(
sWorld->GetNextDailyQuestsResetTime()) - GameTime::GetTime<Clock>());
514 needsCooldownPacket =
true;
517 if (cooldown < Duration::zero())
518 cooldown = Duration::zero();
520 if (categoryCooldown < Duration::zero())
521 categoryCooldown = Duration::zero();
524 if (cooldown == Duration::zero() && categoryCooldown == Duration::zero())
527 catrecTime = categoryCooldown != Duration::zero() ? curTime + categoryCooldown : curTime;
528 recTime = cooldown != Duration::zero() ? curTime + cooldown : catrecTime;
532 if (recTime != curTime)
534 AddCooldown(spellInfo->
Id, itemId, recTime, categoryId, catrecTime, onHold);
536 if (needsCooldownPacket)
544 playerOwner->SendDirectMessage(spellCooldown.
Write());
581 cooldownEntry.
SpellId = spellId;
583 cooldownEntry.
ItemId = itemId;
586 cooldownEntry.
OnHold = onHold;
604 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
606 itr->second.CooldownEnd += cooldownMod;
608 if (itr->second.CategoryId)
610 if (!withoutCategoryCooldown)
611 itr->second.CategoryEnd += cooldownMod;
614 if (itr->second.CooldownEnd < itr->second.CategoryEnd)
615 itr->second.CooldownEnd = itr->second.CategoryEnd;
622 modifyCooldown.
SpellID = itr->second.SpellId;
623 modifyCooldown.
DeltaTime = duration_cast<Milliseconds>(cooldownMod).count();
625 playerOwner->SendDirectMessage(modifyCooldown.
Write());
628 if (itr->second.CooldownEnd <= now)
634 if (modChange <= 0.0f)
638 modChange = 1.0f / modChange;
640 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
642 itr->second.CooldownEnd = now + duration_cast<Duration>((itr->second.CooldownEnd - now) * modChange);
644 if (itr->second.CategoryId)
645 itr->second.CategoryEnd = now + duration_cast<Duration>((itr->second.CategoryEnd - now) * modChange);
650 updateCooldown.
SpellID = itr->second.SpellId;
652 playerOwner->SendDirectMessage(updateCooldown.
Write());
664 if (!cooldownMod.count())
688 clearCooldown.
SpellID = itr->first;
690 playerOwner->SendDirectMessage(clearCooldown.
Write());
701 std::vector<int32> cooldowns;
704 cooldowns.push_back(spellId);
742 end = itr->second.CooldownEnd;
747 return Duration::zero();
749 end = catItr->second->CategoryEnd;
752 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
754 return Duration::zero();
756 Clock::duration remaining = end - now;
757 return duration_cast<Milliseconds>(remaining);
764 return Duration::zero();
766 TimePoint end = catItr->second->CategoryEnd;
768 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
770 return Duration::zero();
772 Clock::duration remaining = end - now;
773 return duration_cast<Milliseconds>(remaining);
783 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
784 TimePoint lockoutEnd = now + lockoutTime;
789 std::set<uint32> knownSpells;
792 for (
auto const& [spellId, playerSpell] : plrOwner->GetSpellMap())
794 knownSpells.insert(spellId);
798 for (
auto const& [spellId, petSpell] : petOwner->m_spells)
800 knownSpells.insert(spellId);
807 knownSpells.insert(spell);
813 for (
uint32 spellId : knownSpells)
832 spellCooldown.
SpellCooldowns.emplace_back(spellId, lockoutTime.count());
837 player->SendDirectMessage(spellCooldown.
Write());
842 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
857 if (chargeRecovery <= 0 ||
GetMaxCharges(chargeCategoryId) <= 0)
866 recoveryStart = time_point_cast<Duration>(GameTime::GetTime<Clock>());
868 recoveryStart = charges.back().RechargeEnd;
870 charges.emplace_back(recoveryStart,
Milliseconds(chargeRecovery));
876 if (!chargeCategoryEntry)
883 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
887 entry.RechargeStart += cooldownMod;
888 entry.RechargeEnd += cooldownMod;
891 while (!itr->second.empty() && itr->second.front().RechargeEnd < now)
892 itr->second.pop_front();
903 if (modChange <= 0.0f)
907 modChange = 1.0f / modChange;
909 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
911 auto chargeItr = itr->second.begin();
913 chargeItr->RechargeEnd = now + duration_cast<Duration>((chargeItr->RechargeEnd - now) * modChange);
915 TimePoint prevEnd = chargeItr->RechargeEnd;
917 while (++chargeItr != itr->second.end())
919 Duration rechargeTime = duration_cast<Duration>((chargeItr->RechargeEnd - chargeItr->RechargeStart) * modChange);
920 chargeItr->RechargeStart = prevEnd;
921 chargeItr->RechargeEnd = prevEnd + rechargeTime;
922 prevEnd = chargeItr->RechargeEnd;
928 updateChargeCategoryCooldown.
Category = chargeCategoryId;
929 updateChargeCategoryCooldown.
ModChange = modChange;
930 playerOwner->SendDirectMessage(updateChargeCategoryCooldown.
Write());
939 itr->second.pop_back();
956 clearSpellCharges.
Category = chargeCategoryId;
957 player->SendDirectMessage(clearSpellCharges.
Write());
970 player->SendDirectMessage(clearAllSpellCharges.
Write());
991 if (!chargeCategoryEntry)
1002 if (!chargeCategoryEntry)
1009 if (modRecoveryRate->GetMiscValue() & chargeCategoryEntry->
TypeMask)
1010 recoveryTime += modRecoveryRate->GetAmount();
1021 if (modRecoveryRate->GetMiscValue() ==
int32(chargeCategoryId))
1022 recoveryTime *= 100.0 / (std::max(modRecoveryRate->GetAmount(), -99.0) + 100.0);
1025 if (modRecoveryRate->GetMiscValue() & chargeCategoryEntry->
TypeMask)
1026 recoveryTime *= 100.0 / (std::max(modRecoveryRate->GetAmount(), -99.0) + 100.0);
1033 return int32(std::floor(recoveryTime));
1056 return Duration::zero();
1059 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
1061 return Duration::zero();
1063 Clock::duration remaining = end - now;
1064 return duration_cast<Milliseconds>(remaining);
1069 _pauseTime = time_point_cast<Duration>(GameTime::GetTime<Clock>());
1077 Duration pausedDuration = time_point_cast<Duration>(GameTime::GetTime<Clock>()) - *
_pauseTime;
1080 itr->second.CooldownEnd += pausedDuration;
1083 for (
ChargeEntry& chargeEntry : chargeRefreshTimes)
1084 chargeEntry.RechargeEnd += pausedDuration;
1102 clearCooldowns.
SpellID = cooldowns;
1103 playerOwner->SendDirectMessage(clearCooldowns.
Write());
1118 setSpellCharges.
Category = chargeCategoryId;
1119 if (!chargeCollection.empty())
1120 setSpellCharges.
NextRecoveryTime =
uint32(duration_cast<Milliseconds>(chargeCollection.front().RechargeEnd - GameTime::GetTime<Clock>()).count());
1123 player->SendDirectMessage(setSpellCharges.
Write());
1129 ASSERT(cooldown || categoryId || categoryCooldown);
1130 Duration tmpCooldown = Duration::min();
1131 uint32 tmpCategoryId = 0;
1132 Duration tmpCategoryCooldown = Duration::min();
1141 if (
uint32(itemEffect->SpellID) == spellInfo->
Id)
1144 tmpCategoryId = itemEffect->SpellCategoryID;
1145 tmpCategoryCooldown =
Milliseconds(itemEffect->CategoryCoolDownMSec);
1153 if (tmpCooldown < Duration::zero() && tmpCategoryCooldown < Duration::zero())
1161 *cooldown = tmpCooldown;
1163 *categoryId = tmpCategoryId;
1164 if (categoryCooldown)
1165 *categoryCooldown = tmpCategoryCooldown;
1190 if (cooldown.OnHold)
1193 auto [itr, inserted] =
_spellCooldowns.try_emplace(spellId, cooldown);
1194 if (!inserted && !itr->second.OnHold )
1195 itr->second = cooldown;
1205 TimePoint now = time_point_cast<Duration>(GameTime::GetTime<Clock>());
1206 uint32 cooldownDuration =
uint32(cooldown.CooldownEnd > now ? duration_cast<Milliseconds>(cooldown.CooldownEnd - now).count() : 0);
1212 spellCooldown.
SpellCooldowns.emplace_back(spellId, cooldownDuration);
1215 player->SendDirectMessage(spellCooldown.
Write());
CharacterDatabaseStatements
@ CHAR_DEL_PET_SPELL_CHARGES
@ CHAR_INS_PET_SPELL_CHARGES
@ CHAR_INS_PET_SPELL_COOLDOWN
@ CHAR_DEL_CHAR_SPELL_COOLDOWNS
@ CHAR_INS_CHAR_SPELL_COOLDOWN
@ CHAR_INS_CHAR_SPELL_CHARGES
@ CHAR_DEL_PET_SPELL_COOLDOWNS
@ CHAR_DEL_CHAR_SPELL_CHARGES
DB2Storage< SpellCategoryEntry > sSpellCategoryStore("SpellCategory.db2", &SpellCategoryLoadInfo::Instance)
@ IgnoreDuringCooldownTimeRateCalculation
SQLTransaction< CharacterDatabaseConnection > CharacterDatabaseTransaction
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< CharacterDatabaseConnection > CharacterDatabase
Accessor to the character database.
std::chrono::milliseconds Milliseconds
Milliseconds shorthand typedef.
std::chrono::seconds Seconds
Seconds shorthand typedef.
std::optional< T > Optional
Optional helper class to wrap optional values within.
@ SPELL_ATTR9_IGNORE_SCHOOL_LOCKOUT
@ SPELL_PREVENTION_TYPE_SILENCE
@ SPELL_ATTR6_IGNORE_FOR_MOD_TIME_RATE
@ SPELL_ATTR6_NO_CATEGORY_COOLDOWN_MODS
@ SPELL_AURA_MOD_RECOVERY_RATE_BY_SPELL_LABEL
@ SPELL_AURA_MOD_CHARGE_RECOVERY_BY_TYPE_MASK
@ SPELL_AURA_MOD_CHARGE_RECOVERY_RATE_BY_TYPE_MASK
@ SPELL_AURA_MOD_COOLDOWN_BY_HASTE_REGEN
@ SPELL_AURA_CHARGE_RECOVERY_MOD
@ SPELL_AURA_CHARGE_RECOVERY_AFFECTED_BY_HASTE
@ SPELL_AURA_MOD_RECOVERY_RATE
@ SPELL_AURA_IGNORE_SPELL_COOLDOWN
@ SPELL_AURA_MOD_SPELL_CATEGORY_COOLDOWN
@ SPELL_AURA_MOD_CHARGE_RECOVERY_RATE
@ SPELL_AURA_CHARGE_RECOVERY_MULTIPLIER
@ SPELL_AURA_MOD_COOLDOWN
@ SPELL_AURA_CHARGE_RECOVERY_AFFECTED_BY_HASTE_REGEN
@ SPELL_AURA_MOD_SPELL_COOLDOWN_BY_HASTE
@ SPELL_AURA_MOD_MAX_CHARGES
@ SPELL_AURA_IGNORE_SPELL_CHARGE_COOLDOWN
double SpellEffectValue
This is a double instead of float to be able to store full range of int32.
@ SPELL_COOLDOWN_FLAG_INCLUDE_EVENT_COOLDOWNS
Starts GCD for spells that should start their cooldown on events, requires SPELL_COOLDOWN_FLAG_INCLUD...
@ SPELL_COOLDOWN_FLAG_LOSS_OF_CONTROL_UI
Shows interrupt cooldown in loss of control ui.
@ SPELL_COOLDOWN_FLAG_NONE
ObjectGuid const & GetGUID() const
uint32 m_spells[MAX_CREATURE_SPELLS]
Class used to access individual fields of database query result.
uint32 GetUInt32() const noexcept
Difficulty GetDifficultyID() const
LowType GetCounter() const
bool HasSpell(uint32 spell) const override
void setUInt32(uint8 index, uint32 value)
void setInt64(uint8 index, int64 value)
void setUInt64(uint8 index, uint64 value)
void AddCooldown(uint32 spellId, uint32 itemId, Duration cooldownDuration)
void UpdateCooldownRecoveryRate(Predicate &&predicate, float modChange, bool apply)
Duration GetRemainingGlobalCooldown(SpellInfo const *spellInfo) const
void ConsumeCharge(uint32 chargeCategoryId)
GlobalCooldownStorageType _globalCooldowns
void LoadFromDB(PreparedQueryResult cooldownsResult, PreparedQueryResult chargesResult)
TimePoint _schoolLockouts[MAX_SPELL_SCHOOL]
bool HasGlobalCooldown(SpellInfo const *spellInfo) const
Duration GetRemainingCategoryCooldown(uint32 categoryId) const
int32 GetMaxCharges(uint32 chargeCategoryId) const
CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr)
void ModifyChargeRecoveryTime(uint32 chargeCategoryId, Duration cooldownMod)
void SendCooldownEvent(SpellInfo const *spellInfo, uint32 itemId=0, Spell *spell=nullptr, bool startCooldown=true)
void ResetCooldown(uint32 spellId, bool update=false)
bool IsReady(SpellInfo const *spellInfo, uint32 itemId=0) const
void AddGlobalCooldown(SpellInfo const *spellInfo, Duration duration)
void SaveToDB(CharacterDatabaseTransaction trans)
void SendClearCooldowns(std::vector< int32 > const &cooldowns) const
void RestoreCharge(uint32 chargeCategoryId)
static Duration const InfinityCooldownDelay
Optional< TimePoint > _pauseTime
void LockSpellSchool(SpellSchoolMask schoolMask, Duration lockoutTime)
std::deque< ChargeEntry > ChargeEntryCollection
Duration GetRemainingCooldown(SpellInfo const *spellInfo) const
SpellHistory(Unit *owner)
CooldownStorageType _spellCooldowns
void WritePacket(WorldPackets::Spells::SendSpellHistory *sendSpellHistory) const
void ResetCharges(uint32 chargeCategoryId)
static void GetCooldownDurations(SpellInfo const *spellInfo, uint32 itemId, Duration *cooldown, uint32 *categoryId, Duration *categoryCooldown)
void SendSetSpellCharges(uint32 chargeCategoryId, ChargeEntryCollection const &chargeCollection) const
void CancelGlobalCooldown(SpellInfo const *spellInfo)
void RestoreCooldownStateAfterDuel()
void UpdateChargeRecoveryRate(uint32 chargeCategoryId, float modChange, bool apply)
void ModifyCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown=false)
CooldownStorageType _spellCooldownsBeforeDuel
bool HasCharge(uint32 chargeCategoryId) const
void SaveCooldownStateBeforeDuel()
std::chrono::time_point< Clock, Duration > TimePoint
void HandleCooldowns(SpellInfo const *spellInfo, Item const *item, Spell *spell=nullptr)
void ModifySpellCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown)
void StartCooldown(SpellInfo const *spellInfo, uint32 itemId, Spell *spell=nullptr, bool onHold=false, Optional< Duration > forcedCooldown={})
Player * GetPlayerOwner() const
int32 GetChargeRecoveryTime(uint32 chargeCategoryId) const
ChargeStorageType _categoryCharges
bool IsSchoolLocked(SpellSchoolMask schoolMask) const
CategoryCooldownStorageType _categoryCooldowns
bool HasCooldown(SpellInfo const *spellInfo, uint32 itemId=0) const
uint32 GetCategory() const
bool IsCooldownStartedOnEvent() const
uint32 CooldownAuraSpellId
uint32 CategoryRecoveryTime
SpellSchoolMask GetSchoolMask() const
bool HasAttribute(SpellAttr0 attribute) const
uint32 StartRecoveryCategory
bool HasLabel(uint32 labelId) const
bool IsIgnoringCooldowns() const
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
bool HasAuraTypeWithMiscvalue(AuraType auraType, int32 miscValue) const
CharmInfo * GetCharmInfo()
float GetTotalAuraMultiplierByMiscValue(AuraType auraType, int32 misc_value) const
float GetTotalAuraModifier(AuraType auraType) const
bool HasAuraType(AuraType auraType) const
float GetTotalAuraModifierByMiscValue(AuraType auraType, int32 misc_value) const
UF::UpdateField< UF::UnitData, int32(WowCS::EntityFragment::CGObject), TYPEID_UNIT > m_unitData
bool HasAura(uint32 spellId, ObjectGuid casterGUID=ObjectGuid::Empty, ObjectGuid itemCasterGUID=ObjectGuid::Empty, uint32 reqEffMask=0) const
bool HasAuraTypeWithAffectMask(AuraType auraType, SpellInfo const *affectedSpell) const
Player * GetSpellModOwner() const
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
std::vector< PetSpellCooldown > Cooldowns
std::vector< PetSpellHistory > SpellHistory
WorldPacket const * Write() override
WorldPacket const * Write() override
std::vector< int32 > SpellID
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
WorldPacket const * Write() override
std::vector< SpellChargeEntry > Entries
std::vector< SpellHistoryEntry > Entries
WorldPacket const * Write() override
WorldPacket const * Write() override
std::vector< SpellCooldownStruct > SpellCooldowns
WorldPacket const * Write() override
WorldPacket const * Write() override
uint32 GetPetNumber() const
EnumFlag< SpellCategoryFlags > GetFlags() const
static bool ReadCooldown(Field const *fields, uint32 *spellId, CooldownEntry *cooldownEntry)
static void WriteCooldown(PreparedStatementBase *stmt, uint8 &index, CooldownEntry const &cooldown)
static bool ReadCharge(Field const *fields, uint32 *categoryId, ChargeEntry *chargeEntry)
static void SetIdentifier(PreparedStatementBase *stmt, uint8 index, Unit *owner)
static void WriteCharge(PreparedStatementBase *stmt, uint8 &index, uint32 chargeCategory, ChargeEntry const &charge)
static bool ReadCooldown(Field const *fields, uint32 *spellId, CooldownEntry *cooldownEntry)
static void WriteCharge(PreparedStatementBase *stmt, uint8 &index, uint32 chargeCategory, ChargeEntry const &charge)
static bool ReadCharge(Field const *fields, uint32 *categoryId, ChargeEntry *chargeEntry)
static void SetIdentifier(PreparedStatementBase *stmt, uint8 index, Unit const *owner)
static void WriteCooldown(PreparedStatementBase *stmt, uint8 &index, CooldownEntry const &cooldown)
int32 CategoryRecoveryTime