diff options
-rw-r--r-- | src/game/Player.cpp | 98 | ||||
-rw-r--r-- | src/game/Player.h | 3 | ||||
-rw-r--r-- | src/game/Spell.cpp | 80 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 1 | ||||
-rw-r--r-- | src/game/Unit.cpp | 1 | ||||
-rw-r--r-- | src/shared/revision_nr.h | 2 |
6 files changed, 92 insertions, 93 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(); diff --git a/src/game/Player.h b/src/game/Player.h index 952eaf19c02..55f789848da 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1491,8 +1491,9 @@ class TRINITY_DLL_SPEC Player : public Unit time_t t = time(NULL); return itr != m_spellCooldowns.end() && itr->second.end > t ? itr->second.end - t : 0; } + void AddSpellAndCategoryCooldowns(SpellEntry const* spellInfo, uint32 itemId, Spell* spell = NULL); void AddSpellCooldown(uint32 spell_id, uint32 itemid, time_t end_time); - void SendCooldownEvent(SpellEntry const *spellInfo); + void SendCooldownEvent(SpellEntry const *spellInfo, uint32 itemId = 0, Spell* spell = NULL); void ProhibitSpellScholl(SpellSchoolMask idSchoolMask, uint32 unTimeMs ); void RemoveSpellCooldown(uint32 spell_id) { m_spellCooldowns.erase(spell_id); } void RemoveArenaSpellCooldowns(); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 0672b759548..c70dd4c2c08 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2440,85 +2440,7 @@ void Spell::SendSpellCooldown() return; } - // 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(m_CastItem) - { - ItemPrototype const* proto = m_CastItem->GetProto(); - if(proto) - { - for(int idx = 0; idx < MAX_ITEM_PROTO_SPELLS; ++idx) - { - if(proto->Spells[idx].SpellId == m_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 = m_spellInfo->Category; - rec = m_spellInfo->RecoveryTime; - catrec = m_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(m_spellInfo) && m_spellInfo->Id != SPELL_ID_AUTOSHOT)) - rec = _player->GetAttackTime(RANGED_ATTACK); - - // Now we have cooldown data (if found any), time to apply mods - if(rec > 0) - _player->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COOLDOWN, rec, this); - - if(catrec > 0) - _player->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COOLDOWN, catrec, this); - - // 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; - time_t recTime = rec ? curTime+rec/IN_MILISECONDS : catrecTime; - - // self spell cooldown - if(recTime > 0) - _player->AddSpellCooldown(m_spellInfo->Id, m_CastItem ? m_CastItem->GetEntry() : 0, 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 == m_spellInfo->Id) // skip main spell, already handled above - continue; - - _player->AddSpellCooldown(*i_scset, m_CastItem ? m_CastItem->GetEntry() : 0, catrecTime); - } - } - } + _player->AddSpellAndCategoryCooldowns(m_spellInfo,m_CastItem ? m_CastItem->GetEntry() : 0, this); } void Spell::update(uint32 difftime) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 3dcf984086e..eb5157b28c0 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -976,6 +976,7 @@ void Aura::_RemoveAura() if(caster && caster->GetTypeId() == TYPEID_PLAYER) { if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE ) + // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases) ((Player*)caster)->SendCooldownEvent(GetSpellProto()); } } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index bad51ab1779..64daa48d612 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -4457,6 +4457,7 @@ void Unit::RemoveGameObject(GameObject* gameObj, bool del) SpellEntry const* createBySpell = sSpellStore.LookupEntry(gameObj->GetSpellId()); // Need activate spell use for owner if (createBySpell && createBySpell->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE) + // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases) ((Player*)this)->SendCooldownEvent(createBySpell); } gameObj->SetOwnerGUID(0); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e4c8695c263..ee63de4fc22 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "7362" + #define REVISION_NR "7363" #endif // __REVISION_NR_H__ |