aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/BattlePets/BattlePetMgr.h2
-rw-r--r--src/server/game/Entities/Player/Player.cpp19
-rw-r--r--src/server/game/Entities/Player/Player.h1
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp2
-rw-r--r--src/server/game/Spells/SpellHistory.cpp53
-rw-r--r--src/server/game/Spells/SpellHistory.h8
-rw-r--r--src/server/scripts/Spells/spell_priest.cpp2
7 files changed, 74 insertions, 13 deletions
diff --git a/src/server/game/BattlePets/BattlePetMgr.h b/src/server/game/BattlePets/BattlePetMgr.h
index ddfd04f4fec..6fa7f588863 100644
--- a/src/server/game/BattlePets/BattlePetMgr.h
+++ b/src/server/game/BattlePets/BattlePetMgr.h
@@ -36,6 +36,8 @@ enum BattlePetMisc
SPELL_SUMMON_BATTLE_PET = 118301
};
+static constexpr Milliseconds REVIVE_BATTLE_PETS_COOLDOWN = 180s;
+
enum class BattlePetBreedQuality : uint8
{
Poor = 0,
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 3ad7c4efd5f..317c4ecd82d 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -23641,6 +23641,25 @@ void Player::UpdatePotionCooldown(Spell* spell)
m_lastPotionId = 0;
}
+void Player::UpdateReviveBattlePetCooldown()
+{
+ SpellInfo const* reviveBattlePetSpellInfo = sSpellMgr->GetSpellInfo(SPELL_REVIVE_BATTLE_PETS, DIFFICULTY_NONE);
+
+ if (reviveBattlePetSpellInfo && HasSpell(SPELL_REVIVE_BATTLE_PETS))
+ {
+ SpellHistory::Duration remainingCooldown = GetSpellHistory()->GetRemainingCategoryCooldown(reviveBattlePetSpellInfo);
+ if (remainingCooldown > SpellHistory::Duration::zero())
+ {
+ if (remainingCooldown < REVIVE_BATTLE_PETS_COOLDOWN)
+ GetSpellHistory()->ModifyCooldown(reviveBattlePetSpellInfo, REVIVE_BATTLE_PETS_COOLDOWN - remainingCooldown);
+ }
+ else
+ {
+ GetSpellHistory()->StartCooldown(reviveBattlePetSpellInfo, 0, nullptr, false, REVIVE_BATTLE_PETS_COOLDOWN);
+ }
+ }
+}
+
void Player::SetResurrectRequestData(WorldObject const* caster, uint32 health, uint32 mana, uint32 appliedAura)
{
ASSERT(!IsResurrectRequested());
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index ad773d6878b..f20fe6c3704 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1851,6 +1851,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
uint32 GetLastPotionId() const { return m_lastPotionId; }
void SetLastPotionId(uint32 item_id) { m_lastPotionId = item_id; }
void UpdatePotionCooldown(Spell* spell = nullptr);
+ void UpdateReviveBattlePetCooldown();
void SetResurrectRequestData(WorldObject const* caster, uint32 health, uint32 mana, uint32 appliedAura);
void ClearResurrectRequestData()
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 16aa7a09625..772f961cb95 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -1173,6 +1173,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder)
pCurrChar->SendInitialPacketsAfterAddToMap();
+ pCurrChar->UpdateReviveBattlePetCooldown();
+
CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ONLINE);
stmt->setUInt64(0, pCurrChar->GetGUID().GetCounter());
CharacterDatabase.Execute(stmt);
diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp
index caa91fd6d18..669564017ea 100644
--- a/src/server/game/Spells/SpellHistory.cpp
+++ b/src/server/game/Spells/SpellHistory.cpp
@@ -310,13 +310,15 @@ void SpellHistory::WritePacket(WorldPackets::Spells::SendSpellHistory* sendSpell
if (cooldownDuration.count() <= 0)
continue;
- historyEntry.RecoveryTime = uint32(cooldownDuration.count());
Milliseconds categoryDuration = std::chrono::duration_cast<Milliseconds>(p.second.CategoryEnd - now);
if (categoryDuration.count() > 0)
{
historyEntry.Category = p.second.CategoryId;
historyEntry.CategoryRecoveryTime = uint32(categoryDuration.count());
}
+
+ if (cooldownDuration.count() > categoryDuration.count())
+ historyEntry.RecoveryTime = uint32(cooldownDuration.count());
}
sendSpellHistory->Entries.push_back(historyEntry);
@@ -565,7 +567,7 @@ void SpellHistory::AddCooldown(uint32 spellId, uint32 itemId, Clock::time_point
}
}
-void SpellHistory::ModifySpellCooldown(uint32 spellId, Duration offset)
+void SpellHistory::ModifySpellCooldown(uint32 spellId, Duration offset, bool withoutCategoryCooldown)
{
auto itr = _spellCooldowns.find(spellId);
if (!offset.count() || itr == _spellCooldowns.end())
@@ -573,9 +575,19 @@ void SpellHistory::ModifySpellCooldown(uint32 spellId, Duration offset)
Clock::time_point now = GameTime::GetGameTimePoint<Clock>();
- if (itr->second.CooldownEnd + offset > now)
- itr->second.CooldownEnd += offset;
- else
+ itr->second.CooldownEnd += offset;
+
+ if (itr->second.CategoryId)
+ {
+ if (!withoutCategoryCooldown)
+ itr->second.CategoryEnd += offset;
+
+ // Because category cooldown existence is tied to regular cooldown, we cannot allow a situation where regular cooldown is shorter than category
+ if (itr->second.CooldownEnd < itr->second.CategoryEnd)
+ itr->second.CooldownEnd = itr->second.CategoryEnd;
+ }
+
+ if (itr->second.CooldownEnd <= now)
EraseCooldown(itr);
if (Player* playerOwner = GetPlayerOwner())
@@ -584,17 +596,18 @@ void SpellHistory::ModifySpellCooldown(uint32 spellId, Duration offset)
modifyCooldown.IsPet = _owner != playerOwner;
modifyCooldown.SpellID = spellId;
modifyCooldown.DeltaTime = std::chrono::duration_cast<Milliseconds>(offset).count();
+ modifyCooldown.WithoutCategoryCooldown = withoutCategoryCooldown;
playerOwner->SendDirectMessage(modifyCooldown.Write());
}
}
-void SpellHistory::ModifyCooldown(uint32 spellId, Duration cooldownMod)
+void SpellHistory::ModifyCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown)
{
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, _owner->GetMap()->GetDifficultyID()))
- ModifyCooldown(spellInfo, cooldownMod);
+ ModifyCooldown(spellInfo, cooldownMod, withoutCategoryCooldown);
}
-void SpellHistory::ModifyCooldown(SpellInfo const* spellInfo, Duration cooldownMod)
+void SpellHistory::ModifyCooldown(SpellInfo const* spellInfo, Duration cooldownMod, bool withoutCategoryCooldown)
{
if (!cooldownMod.count())
return;
@@ -602,7 +615,7 @@ void SpellHistory::ModifyCooldown(SpellInfo const* spellInfo, Duration cooldownM
if (GetChargeRecoveryTime(spellInfo->ChargeCategoryId) > 0 && GetMaxCharges(spellInfo->ChargeCategoryId) > 0)
ModifyChargeRecoveryTime(spellInfo->ChargeCategoryId, cooldownMod);
else
- ModifySpellCooldown(spellInfo->Id, cooldownMod);
+ ModifySpellCooldown(spellInfo->Id, cooldownMod, withoutCategoryCooldown);
}
void SpellHistory::ResetCooldown(uint32 spellId, bool update /*= false*/)
@@ -691,6 +704,28 @@ SpellHistory::Duration SpellHistory::GetRemainingCooldown(SpellInfo const* spell
return std::chrono::duration_cast<Milliseconds>(remaining);
}
+SpellHistory::Duration SpellHistory::GetRemainingCategoryCooldown(uint32 categoryId) const
+{
+ Clock::time_point end;
+ auto catItr = _categoryCooldowns.find(categoryId);
+ if (catItr == _categoryCooldowns.end())
+ return Duration::zero();
+
+ end = catItr->second->CategoryEnd;
+
+ Clock::time_point now = GameTime::GetGameTimePoint<Clock>();
+ if (end < now)
+ return Duration::zero();
+
+ Clock::duration remaining = end - now;
+ return std::chrono::duration_cast<Milliseconds>(remaining);
+}
+
+SpellHistory::Duration SpellHistory::GetRemainingCategoryCooldown(SpellInfo const* spellInfo) const
+{
+ return GetRemainingCategoryCooldown(spellInfo->GetCategory());
+}
+
void SpellHistory::LockSpellSchool(SpellSchoolMask schoolMask, Duration lockoutTime)
{
Clock::time_point now = GameTime::GetGameTimePoint<Clock>();
diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h
index 43379728167..04b5793cf20 100644
--- a/src/server/game/Spells/SpellHistory.h
+++ b/src/server/game/Spells/SpellHistory.h
@@ -104,8 +104,8 @@ public:
}
void AddCooldown(uint32 spellId, uint32 itemId, Clock::time_point cooldownEnd, uint32 categoryId, Clock::time_point categoryEnd, bool onHold = false);
- void ModifyCooldown(uint32 spellId, Duration cooldownMod);
- void ModifyCooldown(SpellInfo const* spellInfo, Duration cooldownMod);
+ void ModifyCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown = false);
+ void ModifyCooldown(SpellInfo const* spellInfo, Duration cooldownMod, bool withoutCategoryCooldown = false);
void ResetCooldown(uint32 spellId, bool update = false);
void ResetCooldown(CooldownStorageType::iterator& itr, bool update = false);
template<typename Predicate>
@@ -132,6 +132,8 @@ public:
bool HasCooldown(SpellInfo const* spellInfo, uint32 itemId = 0, bool ignoreCategoryCooldown = false) const;
bool HasCooldown(uint32 spellId, uint32 itemId = 0, bool ignoreCategoryCooldown = false) const;
Duration GetRemainingCooldown(SpellInfo const* spellInfo) const;
+ Duration GetRemainingCategoryCooldown(uint32 categoryId) const;
+ Duration GetRemainingCategoryCooldown(SpellInfo const* spellInfo) const;
// School lockouts
void LockSpellSchool(SpellSchoolMask schoolMask, Duration lockoutTime);
@@ -157,7 +159,7 @@ public:
private:
Player* GetPlayerOwner() const;
- void ModifySpellCooldown(uint32 spellId, Duration cooldownMod);
+ void ModifySpellCooldown(uint32 spellId, Duration cooldownMod, bool withoutCategoryCooldown = false);
void SendClearCooldowns(std::vector<int32> const& cooldowns) const;
CooldownStorageType::iterator EraseCooldown(CooldownStorageType::iterator itr)
{
diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp
index 199901fe175..8884a8ec8b5 100644
--- a/src/server/scripts/Spells/spell_priest.cpp
+++ b/src/server/scripts/Spells/spell_priest.cpp
@@ -425,7 +425,7 @@ class spell_pri_holy_words : public AuraScript
SpellInfo const* targetSpellInfo = sSpellMgr->AssertSpellInfo(targetSpellId, GetCastDifficulty());
int32 cdReduction = targetSpellInfo->GetEffect(cdReductionEffIndex).CalcValue(GetTarget());
- GetTarget()->GetSpellHistory()->ModifyCooldown(targetSpellInfo, Seconds(-cdReduction));
+ GetTarget()->GetSpellHistory()->ModifyCooldown(targetSpellInfo, Seconds(-cdReduction), true);
}
void Register() override