diff options
author | megamage <none@none> | 2009-03-02 16:55:41 -0600 |
---|---|---|
committer | megamage <none@none> | 2009-03-02 16:55:41 -0600 |
commit | c6fc7f7bca19eb9acf52a6abac55df84e66ade08 (patch) | |
tree | b5457ff7776c5933130944b50e319441ed3462a9 /src/game/Player.cpp | |
parent | b1677c901d8d45e60947e30ff98d7ac5d01bd685 (diff) |
[7363] Propertly set cooldown at server side for category spells at cooldown event send to client. Author: VladimirMangos
Also support item dependent cooldown set propetly at cooldown event send to client.
Last will used in follow potion cooldown delay in combat patch.
--HG--
branch : trunk
Diffstat (limited to 'src/game/Player.cpp')
-rw-r--r-- | src/game/Player.cpp | 98 |
1 files changed, 86 insertions, 12 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 4587d8f1d3f..a2f5f05b83e 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -18030,6 +18030,88 @@ void Player::UpdatePvP(bool state, bool ovrride) } } +void Player::AddSpellAndCategoryCooldowns(SpellEntry const* spellInfo, uint32 itemId, Spell* spell) +{ + // init cooldown values + uint32 cat = 0; + int32 rec = -1; + int32 catrec = -1; + + // some special item spells without correct cooldown in SpellInfo + // cooldown information stored in item prototype + // This used in same way in WorldSession::HandleItemQuerySingleOpcode data sending to client. + + if(itemId) + { + if(ItemPrototype const* proto = ObjectMgr::GetItemPrototype(itemId)) + { + for(int idx = 0; idx < 5; ++idx) + { + if(proto->Spells[idx].SpellId == spellInfo->Id) + { + cat = proto->Spells[idx].SpellCategory; + rec = proto->Spells[idx].SpellCooldown; + catrec = proto->Spells[idx].SpellCategoryCooldown; + break; + } + } + } + } + + // if no cooldown found above then base at DBC data + if(rec < 0 && catrec < 0) + { + cat = spellInfo->Category; + rec = spellInfo->RecoveryTime; + catrec = spellInfo->CategoryRecoveryTime; + } + + // shoot spells used equipped item cooldown values already assigned in GetAttackTime(RANGED_ATTACK) + // prevent 0 cooldowns set by another way + if (rec <= 0 && catrec <= 0 && (cat == 76 || IsAutoRepeatRangedSpell(spellInfo) && spellInfo->Id != SPELL_ID_AUTOSHOT)) + rec = GetAttackTime(RANGED_ATTACK); + + // Now we have cooldown data (if found any), time to apply mods + if(rec > 0) + ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, rec, spell); + + if(catrec > 0) + ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, catrec, spell); + + // replace negative cooldowns by 0 + if (rec < 0) rec = 0; + if (catrec < 0) catrec = 0; + + // no cooldown after applying spell mods + if( rec == 0 && catrec == 0) + return; + + time_t curTime = time(NULL); + + time_t catrecTime = catrec ? curTime+catrec/IN_MILISECONDS : 0; // in secs + time_t recTime = rec ? curTime+rec/IN_MILISECONDS : catrecTime;// in secs + + // self spell cooldown + if(recTime > 0) + AddSpellCooldown(spellInfo->Id, itemId, recTime); + + // category spells + if (catrec > 0) + { + SpellCategoryStore::const_iterator i_scstore = sSpellCategoryStore.find(cat); + if(i_scstore != sSpellCategoryStore.end()) + { + for(SpellCategorySet::const_iterator i_scset = i_scstore->second.begin(); i_scset != i_scstore->second.end(); ++i_scset) + { + if(*i_scset == spellInfo->Id) // skip main spell, already handled above + continue; + + AddSpellCooldown(*i_scset, itemId, catrecTime); + } + } + } +} + void Player::AddSpellCooldown(uint32 spellid, uint32 itemid, time_t end_time) { SpellCooldown sc; @@ -18038,20 +18120,12 @@ void Player::AddSpellCooldown(uint32 spellid, uint32 itemid, time_t end_time) m_spellCooldowns[spellid] = sc; } -void Player::SendCooldownEvent(SpellEntry const *spellInfo) +void Player::SendCooldownEvent(SpellEntry const *spellInfo, uint32 itemId, Spell* spell) { - if ( !(spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE) ) - return; + // start cooldowns at server side, if any + AddSpellAndCategoryCooldowns(spellInfo,itemId,spell); - // Get spell cooldown - int32 cooldown = GetSpellRecoveryTime(spellInfo); - // Apply spellmods - ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, cooldown); - if (cooldown < 0) - cooldown = 0; - // Add cooldown - AddSpellCooldown(spellInfo->Id, 0, time(NULL) + cooldown / IN_MILISECONDS); - // Send activate + // Send activate cooldown timer (possible 0) at client side WorldPacket data(SMSG_COOLDOWN_EVENT, (4+8)); data << spellInfo->Id; data << GetGUID(); |