diff options
| author | Shauren <shauren.trinity@gmail.com> | 2011-02-22 21:51:38 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2011-02-22 21:51:38 +0100 |
| commit | a8f9936bea6d114de585ab393020c0324c075c8b (patch) | |
| tree | 8e77e86f1835f74730592211e4f1f27621e50aa8 /src/server/game/Spells/Spell.cpp | |
| parent | a267e3ade7516a9e73b308af198e8b080af32888 (diff) | |
| parent | bde5adf9bdf77b94757d87aed6f4ba2107f88860 (diff) | |
Merge branch 'master' of github.com:TrinityCore/TrinityCore
Diffstat (limited to 'src/server/game/Spells/Spell.cpp')
| -rwxr-xr-x | src/server/game/Spells/Spell.cpp | 72 |
1 files changed, 70 insertions, 2 deletions
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 95769040dde..4d6459bc66d 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -3001,8 +3001,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const * triggere m_caster->SetCurrentCastedSpell(this); SendSpellStart(); - if (m_caster->GetTypeId() == TYPEID_PLAYER) - m_caster->ToPlayer()->AddGlobalCooldown(m_spellInfo,this); + TriggerGlobalCooldown(); if (!m_casttime && !m_spellInfo->StartRecoveryTime && !m_castItemGUID //item: first cast may destroy item and second cast causes crash @@ -3027,6 +3026,7 @@ void Spell::cancel() switch (oldState) { case SPELL_STATE_PREPARING: + CancelGlobalCooldown(); case SPELL_STATE_DELAYED: SendInterrupted(0); SendCastResult(SPELL_FAILED_INTERRUPTED); @@ -4680,6 +4680,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 +7289,67 @@ void Spell::CallScriptAfterUnitTargetSelectHandlers(std::list<Unit*>& unitTarget (*scritr)->_FinishScriptCall(); } } + +// Global cooldowns management +enum GCDLimits +{ + 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); +} |
