[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:
darkstalker 2010-09-24 04:46:50 +04:00 committed by VladimirMangos
parent cb03e5a376
commit 3a8ad26a5e
12 changed files with 142 additions and 26 deletions

View file

@ -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);
}