diff options
author | Shauren <shauren.trinity@gmail.com> | 2014-02-05 13:00:42 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2014-02-05 13:00:42 +0100 |
commit | 0d51fd55a177b54f94e00c38895e27c7eb318f66 (patch) | |
tree | 0001ac7e138571f6a30f808105b45d3cb8f7e0a6 /src | |
parent | 30924211a35f292fa98cf70d1157c8d75074123e (diff) |
Core/Auras: Implemented SPELL_AURA_MOD_COOLDOWN
Closes #9671
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Pet/Pet.cpp | 37 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 44 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 28 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 12 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 7 |
5 files changed, 91 insertions, 37 deletions
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index c218c3c645f..a887e85e77e 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -1122,9 +1122,8 @@ void Pet::_LoadSpellCooldowns() { time_t curTime = time(NULL); - WorldPacket data(SMSG_SPELL_COOLDOWN, size_t(8+1+result->GetRowCount()*8)); - data << GetGUID(); - data << uint8(0x0); // flags (0x1, 0x2) + PacketCooldowns cooldowns; + WorldPacket data; do { @@ -1143,8 +1142,7 @@ void Pet::_LoadSpellCooldowns() if (db_time <= curTime) continue; - data << uint32(spell_id); - data << uint32(uint32(db_time-curTime)*IN_MILLISECONDS); + cooldowns[spell_id] = uint32(db_time - curTime)*IN_MILLISECONDS; _AddCreatureSpellCooldown(spell_id, db_time); @@ -1152,8 +1150,11 @@ void Pet::_LoadSpellCooldowns() } while (result->NextRow()); - if (!m_CreatureSpellCooldowns.empty() && GetOwner()) + if (!cooldowns.empty() && GetOwner()) + { + BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, cooldowns); GetOwner()->GetSession()->SendPacket(&data); + } } } @@ -2050,21 +2051,17 @@ void Pet::SynchronizeLevelWithOwner() void Pet::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) { - WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+m_spells.size()*8); - data << uint64(GetGUID()); - data << uint8(0x0); // flags (0x1, 0x2) + PacketCooldowns cooldowns; + WorldPacket data; time_t curTime = time(NULL); for (PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) { if (itr->second.state == PETSPELL_REMOVED) continue; + uint32 unSpellId = itr->first; SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(unSpellId); - if (!spellInfo) - { - ASSERT(spellInfo); - continue; - } + ASSERT(spellInfo); // Not send cooldown for this spells if (spellInfo->IsCooldownStartedOnEvent()) @@ -2075,14 +2072,18 @@ void Pet::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) if ((idSchoolMask & spellInfo->GetSchoolMask()) && GetCreatureSpellCooldownDelay(unSpellId) < unTimeMs) { - data << uint32(unSpellId); - data << uint32(unTimeMs); // in m.secs + cooldowns[unSpellId] = unTimeMs; _AddCreatureSpellCooldown(unSpellId, curTime + unTimeMs/IN_MILLISECONDS); } } - if (Player* owner = GetOwner()) - owner->GetSession()->SendPacket(&data); + if (!cooldowns.empty()) + { + BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, cooldowns); + + if (Player* owner = GetOwner()) + owner->GetSession()->SendPacket(&data); + } } Player* Pet::GetOwner() const diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 9ea9c153f36..603a4654697 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -12350,11 +12350,8 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update) GetGlobalCooldownMgr().AddGlobalCooldown(spellProto, m_weaponChangeTimer); - WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4); - data << uint64(GetGUID()); - data << uint8(1); - data << uint32(cooldownSpell); - data << uint32(0); + WorldPacket data; + BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_INCLUDE_GCD, cooldownSpell, 0); GetSession()->SendPacket(&data); } } @@ -21291,10 +21288,8 @@ void Player::ContinueTaxiFlight() void Player::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) { - // last check 2.0.10 - WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+m_spells.size()*8); - data << uint64(GetGUID()); - data << uint8(0x0); // flags (0x1, 0x2) + PacketCooldowns cooldowns; + WorldPacket data; time_t curTime = time(NULL); for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) { @@ -21317,12 +21312,16 @@ void Player::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs) if ((idSchoolMask & spellInfo->GetSchoolMask()) && GetSpellCooldownDelay(unSpellId) < unTimeMs) { - data << uint32(unSpellId); - data << uint32(unTimeMs); // in m.secs + cooldowns[unSpellId] = unTimeMs; AddSpellCooldown(unSpellId, 0, curTime + unTimeMs/IN_MILLISECONDS); } } - GetSession()->SendPacket(&data); + + if (!cooldowns.empty()) + { + BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, cooldowns); + GetSession()->SendPacket(&data); + } } void Player::InitDataForForm(bool reapplyMods) @@ -21799,6 +21798,8 @@ void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 ite time_t catrecTime; time_t recTime; + bool needsCooldownPacket = false; + // overwrite time for selected category if (infinityCooldown) { @@ -21821,6 +21822,16 @@ void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 ite if (catrec > 0 && !(spellInfo->AttributesEx6 & SPELL_ATTR6_IGNORE_CATEGORY_COOLDOWN_MODS)) ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, catrec, spell); + if (int32 cooldownMod = GetTotalAuraModifier(SPELL_AURA_MOD_COOLDOWN)) + { + // Apply SPELL_AURA_MOD_COOLDOWN only to own spells + if (HasSpell(spellInfo->Id)) + { + needsCooldownPacket = true; + rec += cooldownMod * IN_MILLISECONDS; // SPELL_AURA_MOD_COOLDOWN does not affect category cooldows, verified with shaman shocks + } + } + // replace negative cooldowns by 0 if (rec < 0) rec = 0; if (catrec < 0) catrec = 0; @@ -21835,8 +21846,17 @@ void Player::AddSpellAndCategoryCooldowns(SpellInfo const* spellInfo, uint32 ite // self spell cooldown if (recTime > 0) + { AddSpellCooldown(spellInfo->Id, itemId, recTime); + if (needsCooldownPacket) + { + WorldPacket data; + BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, spellInfo->Id, rec); + SendDirectMessage(&data); + } + } + // category spells if (cat && catrec > 0) { diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index ff402488c2c..52565a2eaa5 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -4484,10 +4484,13 @@ uint32 Unit::GetDoTsByCaster(uint64 casterGUID) const int32 Unit::GetTotalAuraModifier(AuraType auratype) const { + AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype); + if (mTotalAuraList.empty()) + return 0; + std::map<SpellGroup, int32> SameEffectSpellGroup; int32 modifier = 0; - AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype); for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i) if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup)) modifier += (*i)->GetAmount(); @@ -8720,7 +8723,7 @@ ReputationRank Unit::GetReactionTo(Unit const* target) const Player const* targetPlayerOwner = target->GetAffectingPlayer(); // check forced reputation to support SPELL_AURA_FORCE_REACTION - if (selfPlayerOwner) + if (selfPlayerOwner) { if (FactionTemplateEntry const* targetFactionTemplateEntry = target->GetFactionTemplateEntry()) if (ReputationRank const* repRank = selfPlayerOwner->GetReputationMgr().GetForcedRankIfAny(targetFactionTemplateEntry)) @@ -17656,3 +17659,24 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) updateMask.AppendToPacket(data); data->append(fieldBuffer); } + +void Unit::BuildCooldownPacket(WorldPacket& data, uint8 flags, uint32 spellId, uint32 cooldown) +{ + data.Initialize(SMSG_SPELL_COOLDOWN, 8 + 1 + 4 + 4); + data << uint64(GetGUID()); + data << uint8(flags); + data << uint32(spellId); + data << uint32(cooldown); +} + +void Unit::BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCooldowns const& cooldowns) +{ + data.Initialize(SMSG_SPELL_COOLDOWN, 8 + 1 + (4 + 4) * cooldowns.size()); + data << uint64(GetGUID()); + data << uint8(flags); + for (UNORDERED_MAP<uint32, uint32>::const_iterator itr = cooldowns.begin(); itr != cooldowns.end(); ++itr) + { + data << uint32(itr->first); + data << uint32(itr->second); + } +} diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 41b181e54f8..751bfcb8126 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1233,6 +1233,16 @@ enum PlayerTotemType SUMMON_TYPE_TOTEM_AIR = 83 }; +/// Spell cooldown flags sent in SMSG_SPELL_COOLDOWN +enum SpellCooldownFlags +{ + SPELL_COOLDOWN_FLAG_NONE = 0x0, + SPELL_COOLDOWN_FLAG_INCLUDE_GCD = 0x1, ///< Starts GCD in addition to normal cooldown specified in the packet + SPELL_COOLDOWN_FLAG_INCLUDE_EVENT_COOLDOWNS = 0x2 ///< Starts GCD for spells that should start their cooldown on events, requires SPELL_COOLDOWN_FLAG_INCLUDE_GCD set +}; + +typedef UNORDERED_MAP<uint32, uint32> PacketCooldowns; + // delay time next attack to prevent client attack animation problems #define ATTACK_DISPLAY_DELAY 200 #define MAX_PLAYER_STEALTH_DETECT_RANGE 30.0f // max distance for detection targets by player @@ -1565,6 +1575,8 @@ class Unit : public WorldObject void SetAuraStack(uint32 spellId, Unit* target, uint32 stack); void SendPlaySpellVisual(uint32 id); void SendPlaySpellImpact(uint64 guid, uint32 id); + void BuildCooldownPacket(WorldPacket& data, uint8 flags, uint32 spellId, uint32 cooldown); + void BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCooldowns const& cooldowns); void DeMorph(); diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 9c7fff612b7..8e7edfc5355 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1525,11 +1525,8 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b player->RemoveSpellCooldown(GetSpellInfo()->Id, true); player->AddSpellCooldown(GetSpellInfo()->Id, 0, uint32(time(NULL) + aurEff->GetAmount())); - WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4+4); - data << uint64(player->GetGUID()); - data << uint8(0x0); // flags (0x1, 0x2) - data << uint32(GetSpellInfo()->Id); - data << uint32(aurEff->GetAmount()*IN_MILLISECONDS); + WorldPacket data; + player->BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_NONE, GetSpellInfo()->Id, aurEff->GetAmount()*IN_MILLISECONDS); player->SendDirectMessage(&data); } break; |