mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
[10526] Implement server side global cooldown check.
Signed-off-by: VladimirMangos <vladimir@getmangos.com> Also pet/controlled unit global cooldown code replaced by new placed in charmInfo structure. Thanks to nos4r2zod for testing and gcd range check implement.
This commit is contained in:
parent
cb03e5a376
commit
3a8ad26a5e
12 changed files with 142 additions and 26 deletions
|
|
@ -2669,6 +2669,8 @@ void Spell::prepare(SpellCastTargets const* targets, Aura* triggeredByAura)
|
|||
|
||||
// will show cast bar
|
||||
SendSpellStart();
|
||||
|
||||
TriggerGlobalCooldown();
|
||||
}
|
||||
// execute triggered without cast time explicitly in call point
|
||||
else if(m_timer == 0)
|
||||
|
|
@ -2690,6 +2692,9 @@ void Spell::cancel()
|
|||
switch (m_spellState)
|
||||
{
|
||||
case SPELL_STATE_PREPARING:
|
||||
CancelGlobalCooldown();
|
||||
|
||||
//(no break)
|
||||
case SPELL_STATE_DELAYED:
|
||||
{
|
||||
SendInterrupted(0);
|
||||
|
|
@ -4216,6 +4221,10 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||
return SPELL_FAILED_NOT_READY;
|
||||
}
|
||||
|
||||
// check global cooldown
|
||||
if (strict && !m_IsTriggeredSpell && HasGlobalCooldown())
|
||||
return SPELL_FAILED_NOT_READY;
|
||||
|
||||
// only allow triggered spells if at an ended battleground
|
||||
if (!m_IsTriggeredSpell && m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
if(BattleGround * bg = ((Player*)m_caster)->GetBattleGround())
|
||||
|
|
@ -6767,3 +6776,61 @@ void Spell::ClearCastItem()
|
|||
|
||||
m_CastItem = NULL;
|
||||
}
|
||||
|
||||
bool Spell::HasGlobalCooldown()
|
||||
{
|
||||
// global cooldown have only player or controlled units
|
||||
if (m_caster->GetCharmInfo())
|
||||
return m_caster->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(m_spellInfo);
|
||||
else if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
return ((Player*)m_caster)->GetGlobalCooldownMgr().HasGlobalCooldown(m_spellInfo);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void Spell::TriggerGlobalCooldown()
|
||||
{
|
||||
int32 gcd = m_spellInfo->StartRecoveryTime;
|
||||
if (!gcd)
|
||||
return;
|
||||
|
||||
// global cooldown can't leave range 1..1.5 secs (if it it)
|
||||
// exist some spells (mostly not player directly casted) that have < 1 sec and > 1.5 sec global cooldowns
|
||||
// but its as test show not affected any spell mods.
|
||||
if (m_spellInfo->StartRecoveryTime >= 1000 && m_spellInfo->StartRecoveryTime <= 1500)
|
||||
{
|
||||
// gcd modifier auras applied only to self spells and only player have mods for this
|
||||
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)m_caster)->ApplySpellMod(m_spellInfo->Id, SPELLMOD_GLOBAL_COOLDOWN, gcd, this);
|
||||
|
||||
// apply haste rating
|
||||
gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED));
|
||||
|
||||
if (gcd < 1000)
|
||||
gcd = 1000;
|
||||
else if (gcd > 1500)
|
||||
gcd = 1500;
|
||||
}
|
||||
|
||||
// global cooldown have only player or controlled units
|
||||
if (m_caster->GetCharmInfo())
|
||||
m_caster->GetCharmInfo()->GetGlobalCooldownMgr().AddGlobalCooldown(m_spellInfo, gcd);
|
||||
else if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)m_caster)->GetGlobalCooldownMgr().AddGlobalCooldown(m_spellInfo, gcd);
|
||||
}
|
||||
|
||||
void Spell::CancelGlobalCooldown()
|
||||
{
|
||||
if (!m_spellInfo->StartRecoveryTime)
|
||||
return;
|
||||
|
||||
// cancel global cooldown when interrupting current cast
|
||||
if (m_caster->GetCurrentSpell(CURRENT_GENERIC_SPELL) != this)
|
||||
return;
|
||||
|
||||
// global cooldown have only player or controlled units
|
||||
if (m_caster->GetCharmInfo())
|
||||
m_caster->GetCharmInfo()->GetGlobalCooldownMgr().CancelGlobalCooldown(m_spellInfo);
|
||||
else if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)m_caster)->GetGlobalCooldownMgr().CancelGlobalCooldown(m_spellInfo);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue