Core/Spell Mechanics: introduce global cooldown manager for server-side checks for GCD (ported from mangos)

This commit is contained in:
darkstalker
2011-02-22 17:02:47 +06:00
committed by Azazel
parent 401ec2180f
commit 1646f9d91c
9 changed files with 130 additions and 18 deletions
+69
View File
@@ -3001,6 +3001,8 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const * triggere
m_caster->SetCurrentCastedSpell(this);
SendSpellStart();
TriggerGlobalCooldown();
if (m_caster->GetTypeId() == TYPEID_PLAYER)
m_caster->ToPlayer()->AddGlobalCooldown(m_spellInfo,this);
@@ -3027,6 +3029,7 @@ void Spell::cancel()
switch (oldState)
{
case SPELL_STATE_PREPARING:
CancelGlobalCooldown();
case SPELL_STATE_DELAYED:
SendInterrupted(0);
SendCastResult(SPELL_FAILED_INTERRUPTED);
@@ -4680,6 +4683,10 @@ SpellCastResult Spell::CheckCast(bool strict)
}
}
// 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 = m_caster->ToPlayer()->GetBattleground())
@@ -7285,3 +7292,65 @@ void Spell::CallScriptAfterUnitTargetSelectHandlers(std::list<Unit*>& unitTarget
(*scritr)->_FinishScriptCall();
}
}
enum eGCD {
MIN_GCD = 1000,
MAX_GCD = 1500
};
bool Spell::HasGlobalCooldown()
{
// Only player or controlled units have global cooldown
if (m_caster->GetCharmInfo())
return m_caster->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(m_spellInfo);
else if (m_caster->GetTypeId() == TYPEID_PLAYER)
return m_caster->ToPlayer()->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
// There are some spells (mostly not casted directly by player) that have < 1 sec and > 1.5 sec global cooldowns
// but as tests show are not affected by any spell mods.
if (m_spellInfo->StartRecoveryTime >= MIN_GCD && m_spellInfo->StartRecoveryTime <= MAX_GCD)
{
// gcd modifier auras are applied only to own spells and only players have such mods
if (m_caster->GetTypeId() == TYPEID_PLAYER)
m_caster->ToPlayer()->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 < MIN_GCD)
gcd = MIN_GCD;
else if (gcd > MAX_GCD)
gcd = MAX_GCD;
}
// Only players or controlled units have global cooldown
if (m_caster->GetCharmInfo())
m_caster->GetCharmInfo()->GetGlobalCooldownMgr().AddGlobalCooldown(m_spellInfo, gcd);
else if (m_caster->GetTypeId() == TYPEID_PLAYER)
m_caster->ToPlayer()->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;
// Only players or controlled units have global cooldown
if (m_caster->GetCharmInfo())
m_caster->GetCharmInfo()->GetGlobalCooldownMgr().CancelGlobalCooldown(m_spellInfo);
else if (m_caster->GetTypeId() == TYPEID_PLAYER)
m_caster->ToPlayer()->GetGlobalCooldownMgr().CancelGlobalCooldown(m_spellInfo);
}
+3
View File
@@ -543,6 +543,9 @@ class Spell
void SetSpellValue(SpellValueMod mod, int32 value);
protected:
bool HasGlobalCooldown();
void TriggerGlobalCooldown();
void CancelGlobalCooldown();
void SendLoot(uint64 guid, LootType loottype);