diff options
Diffstat (limited to 'src/server')
| -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;  | 
