diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 9 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 38 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 19 | ||||
-rw-r--r-- | src/server/game/Server/Packets/PartyPackets.cpp | 64 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuraDefines.h | 2 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.cpp | 98 | ||||
-rw-r--r-- | src/server/game/Spells/Auras/SpellAuras.h | 9 |
7 files changed, 99 insertions, 140 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 0511344bdfb..ffd7740f258 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -23446,7 +23446,7 @@ void Player::LearnSkillRewardedSpells(uint32 skillId, uint32 skillValue) void Player::SendAurasForTarget(Unit* target) const { - if (!target || target->GetVisibleAuras()->empty()) // speedup things + if (!target || target->GetVisibleAuras().empty()) // speedup things return; /*! Blizz sends certain movement packets sometimes even before CreateObject @@ -23461,16 +23461,15 @@ void Player::SendAurasForTarget(Unit* target) const if (target->HasAuraType(SPELL_AURA_HOVER)) target->SetHover(true, true); - Unit::VisibleAuraMap const* visibleAuras = target->GetVisibleAuras(); + Unit::VisibleAuraContainer const& visibleAuras = target->GetVisibleAuras(); WorldPackets::Spells::AuraUpdate update; update.UpdateAll = true; update.UnitGUID = target->GetGUID(); - update.Auras.reserve(visibleAuras->size()); + update.Auras.reserve(visibleAuras.size()); - for (Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr) + for (AuraApplication* auraApp : visibleAuras) { - AuraApplication* auraApp = itr->second; WorldPackets::Spells::AuraInfo auraInfo; auraApp->BuildUpdatePacket(auraInfo, false); update.Auras.push_back(auraInfo); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 1b67b78a5f1..c8cd3645721 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -537,24 +537,18 @@ void Unit::GetRandomContactPoint(const Unit* obj, float &x, float &y, float &z, GetAngle(obj) + (attacker_number ? (static_cast<float>(M_PI/2) - static_cast<float>(M_PI) * (float)rand_norm()) * float(attacker_number) / combat_reach * 0.3f : 0)); } -AuraApplication * Unit::GetVisibleAura(uint8 slot) const +void Unit::SetVisibleAura(AuraApplication* aurApp) { - VisibleAuraMap::const_iterator itr = m_visibleAuras.find(slot); - if (itr != m_visibleAuras.end()) - return itr->second; - return 0; + m_visibleAuras.insert(aurApp); + m_visibleAurasToUpdate.insert(aurApp); + UpdateAuraForGroup(); } -void Unit::SetVisibleAura(uint8 slot, AuraApplication * aur) +void Unit::RemoveVisibleAura(AuraApplication* aurApp) { - m_visibleAuras[slot]=aur; - UpdateAuraForGroup(slot); -} - -void Unit::RemoveVisibleAura(uint8 slot) -{ - m_visibleAuras.erase(slot); - UpdateAuraForGroup(slot); + m_visibleAuras.erase(aurApp); + m_visibleAurasToUpdate.erase(aurApp); + UpdateAuraForGroup(); } void Unit::UpdateInterruptMask() @@ -2689,9 +2683,10 @@ void Unit::_UpdateSpells(uint32 time) ++i; } - for (VisibleAuraMap::iterator itr = m_visibleAuras.begin(); itr != m_visibleAuras.end(); ++itr) - if (itr->second->IsNeedClientUpdate()) - itr->second->ClientUpdate(); + for (AuraApplication* visibleAura : m_visibleAurasToUpdate) + visibleAura->ClientUpdate(); + + m_visibleAurasToUpdate.clear(); _DeleteRemovedAuras(); @@ -12547,10 +12542,8 @@ uint32 Unit::GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectTyp return CastingTime; } -void Unit::UpdateAuraForGroup(uint8 slot) +void Unit::UpdateAuraForGroup() { - if (slot >= MAX_AURAS) // slot not found, return - return; if (Player* player = ToPlayer()) { if (player->GetGroup()) @@ -16181,3 +16174,8 @@ void Unit::SendCombatLogMessage(WorldPackets::CombatLog::CombatLogServerPacket* CombatLogSender notifier(this, combatLog, GetVisibilityRange()); VisitNearbyWorldObject(GetVisibilityRange(), notifier); } + +bool Unit::VisibleAuraSlotCompare::operator()(AuraApplication* left, AuraApplication* right) const +{ + return left->GetSlot() < right->GetSlot(); +} diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 054720c2218..246a8a09818 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -28,6 +28,7 @@ #include "SpellAuraDefines.h" #include "ThreatManager.h" #include "MoveSplineInit.h" +#include <boost/container/flat_set.hpp> #define WORLD_TRIGGER 12999 @@ -1339,7 +1340,8 @@ class TC_GAME_API Unit : public WorldObject typedef std::list<AuraApplication *> AuraApplicationList; typedef std::list<DiminishingReturn> Diminishing; - typedef std::map<uint8, AuraApplication*> VisibleAuraMap; + struct VisibleAuraSlotCompare { bool operator()(AuraApplication* left, AuraApplication* right) const; }; + typedef std::set<AuraApplication*, VisibleAuraSlotCompare> VisibleAuraContainer; virtual ~Unit(); @@ -2020,10 +2022,11 @@ class TC_GAME_API Unit : public WorldObject void removeHatedBy(HostileReference* /*pHostileReference*/) { /* nothing to do yet */ } HostileRefManager& getHostileRefManager() { return m_HostileRefManager; } - VisibleAuraMap const* GetVisibleAuras() { return &m_visibleAuras; } - AuraApplication * GetVisibleAura(uint8 slot) const; - void SetVisibleAura(uint8 slot, AuraApplication * aur); - void RemoveVisibleAura(uint8 slot); + VisibleAuraContainer const& GetVisibleAuras() const { return m_visibleAuras; } + bool HasVisibleAura(AuraApplication* aurApp) const { return m_visibleAuras.count(aurApp) > 0; } + void SetVisibleAura(AuraApplication* aurApp); + void SetVisibleAuraUpdate(AuraApplication* aurApp) { m_visibleAurasToUpdate.insert(aurApp); } + void RemoveVisibleAura(AuraApplication* aurApp); uint32 GetInterruptMask() const { return m_interruptMask; } void AddInterruptMask(uint32 mask) { m_interruptMask |= mask; } @@ -2158,7 +2161,7 @@ class TC_GAME_API Unit : public WorldObject void UpdateReactives(uint32 p_time); // group updates - void UpdateAuraForGroup(uint8 slot); + void UpdateAuraForGroup(); // proc trigger system bool CanProc() const {return !m_procDeep;} @@ -2309,7 +2312,9 @@ class TC_GAME_API Unit : public WorldObject float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END]; float m_weaponDamage[MAX_ATTACK][2]; bool m_canModifyStats; - VisibleAuraMap m_visibleAuras; + + VisibleAuraContainer m_visibleAuras; + boost::container::flat_set<AuraApplication*, VisibleAuraSlotCompare> m_visibleAurasToUpdate; float m_speed_rate[MAX_MOVE_TYPE]; diff --git a/src/server/game/Server/Packets/PartyPackets.cpp b/src/server/game/Server/Packets/PartyPackets.cpp index 91b6ca4e18d..686123de4d6 100644 --- a/src/server/game/Server/Packets/PartyPackets.cpp +++ b/src/server/game/Server/Packets/PartyPackets.cpp @@ -600,30 +600,27 @@ void WorldPackets::Party::PartyMemberState::Initialize(Player const* player) MemberStats.VehicleSeat = player->GetVehicle()->GetVehicleInfo()->SeatID[player->m_movementInfo.transport.seat]; // Auras - for (uint8 i = 0; i < MAX_AURAS; ++i) + for (AuraApplication const* aurApp : player->GetVisibleAuras()) { - if (AuraApplication const* aurApp = player->GetVisibleAura(i)) - { - WorldPackets::Party::PartyMemberAuraStates aura; + WorldPackets::Party::PartyMemberAuraStates aura; - aura.SpellID = aurApp->GetBase()->GetId(); - aura.ActiveFlags = aurApp->GetEffectMask(); - aura.Flags = aurApp->GetFlags(); + aura.SpellID = aurApp->GetBase()->GetId(); + aura.ActiveFlags = aurApp->GetEffectMask(); + aura.Flags = aurApp->GetFlags(); - if (aurApp->GetFlags() & AFLAG_SCALABLE) + if (aurApp->GetFlags() & AFLAG_SCALABLE) + { + for (AuraEffect const* aurEff : aurApp->GetBase()->GetAuraEffects()) { - for (AuraEffect const* aurEff : aurApp->GetBase()->GetAuraEffects()) - { - if (!aurEff) - continue; + if (!aurEff) + continue; - if (aurApp->HasEffect(aurEff->GetEffIndex())) - aura.Points.push_back(float(aurEff->GetAmount())); - } + if (aurApp->HasEffect(aurEff->GetEffIndex())) + aura.Points.push_back(float(aurEff->GetAmount())); } - - MemberStats.Auras.push_back(aura); } + + MemberStats.Auras.push_back(aura); } // Phases @@ -652,30 +649,27 @@ void WorldPackets::Party::PartyMemberState::Initialize(Player const* player) MemberStats.PetStats->CurrentHealth = pet->GetHealth(); MemberStats.PetStats->MaxHealth = pet->GetMaxHealth(); - for (uint8 i = 0; i < MAX_AURAS; ++i) + for (AuraApplication const* aurApp : pet->GetVisibleAuras()) { - if (AuraApplication const* aurApp = pet->GetVisibleAura(i)) - { - WorldPackets::Party::PartyMemberAuraStates aura; + WorldPackets::Party::PartyMemberAuraStates aura; - aura.SpellID = aurApp->GetBase()->GetId(); - aura.ActiveFlags = aurApp->GetEffectMask(); - aura.Flags = aurApp->GetFlags(); + aura.SpellID = aurApp->GetBase()->GetId(); + aura.ActiveFlags = aurApp->GetEffectMask(); + aura.Flags = aurApp->GetFlags(); - if (aurApp->GetFlags() & AFLAG_SCALABLE) + if (aurApp->GetFlags() & AFLAG_SCALABLE) + { + for (AuraEffect const* aurEff : aurApp->GetBase()->GetAuraEffects()) { - for (AuraEffect const* aurEff : aurApp->GetBase()->GetAuraEffects()) - { - if (!aurEff) - continue; - - if (aurApp->HasEffect(aurEff->GetEffIndex())) - aura.Points.push_back(float(aurEff->GetAmount())); - } - } + if (!aurEff) + continue; - MemberStats.PetStats->Auras.push_back(aura); + if (aurApp->HasEffect(aurEff->GetEffIndex())) + aura.Points.push_back(float(aurEff->GetAmount())); + } } + + MemberStats.PetStats->Auras.push_back(aura); } } } diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h index 8a147c88f24..60953fcbf1d 100644 --- a/src/server/game/Spells/Auras/SpellAuraDefines.h +++ b/src/server/game/Spells/Auras/SpellAuraDefines.h @@ -18,7 +18,7 @@ #ifndef TRINITY_SPELLAURADEFINES_H #define TRINITY_SPELLAURADEFINES_H -#define MAX_AURAS 64 // client support up to 255, but it will cause problems with group auras updating +#define MAX_AURAS 255 enum AURA_FLAGS { diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 0aa5d752c60..fefdcc96030 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -45,72 +45,37 @@ _flags(AFLAG_NONE), _effectsToApply(effMask), _needClientUpdate(false), _effectM { ASSERT(GetTarget() && GetBase()); - if (GetBase()->CanBeSentToClient()) + // Try find slot for aura + uint8 slot = 0; + // lookup for free slots in units visibleAuras + for (AuraApplication* visibleAura : GetTarget()->GetVisibleAuras()) { - // Try find slot for aura - uint8 slot = MAX_AURAS; - // Lookup for auras already applied from spell - if (AuraApplication * foundAura = GetTarget()->GetAuraApplication(GetBase()->GetId(), GetBase()->GetCasterGUID(), GetBase()->GetCastItemGUID())) - { - // allow use single slot only by auras from same caster - slot = foundAura->GetSlot(); - } - else - { - Unit::VisibleAuraMap const* visibleAuras = GetTarget()->GetVisibleAuras(); - // lookup for free slots in units visibleAuras - Unit::VisibleAuraMap::const_iterator itr = visibleAuras->find(0); - for (uint32 freeSlot = 0; freeSlot < MAX_AURAS; ++itr, ++freeSlot) - { - if (itr == visibleAuras->end() || itr->first != freeSlot) - { - slot = freeSlot; - break; - } - } - } + if (slot < visibleAura->GetSlot()) + break; - // Register Visible Aura - if (slot < MAX_AURAS) - { - _slot = slot; - GetTarget()->SetVisibleAura(slot, this); - SetNeedClientUpdate(); - TC_LOG_DEBUG("spells", "Aura: %u Effect: %d put to unit visible auras slot: %u", GetBase()->GetId(), GetEffectMask(), slot); - } - else - TC_LOG_DEBUG("spells", "Aura: %u Effect: %d could not find empty unit visible slot", GetBase()->GetId(), GetEffectMask()); + ++slot; } + // Register Visible Aura + if (slot < MAX_AURAS) + { + _slot = slot; + GetTarget()->SetVisibleAura(this); + _needClientUpdate = true; + TC_LOG_DEBUG("spells", "Aura: %u Effect: %d put to unit visible auras slot: %u", GetBase()->GetId(), GetEffectMask(), slot); + } + else + TC_LOG_DEBUG("spells", "Aura: %u Effect: %d could not find empty unit visible slot", GetBase()->GetId(), GetEffectMask()); + _InitFlags(caster, effMask); } void AuraApplication::_Remove() { - uint8 slot = GetSlot(); - - if (slot >= MAX_AURAS) - return; - - if (AuraApplication * foundAura = _target->GetAuraApplication(GetBase()->GetId(), GetBase()->GetCasterGUID(), GetBase()->GetCastItemGUID())) - { - // Reuse visible aura slot by aura which is still applied - prevent storing dead pointers - if (slot == foundAura->GetSlot()) - { - if (GetTarget()->GetVisibleAura(slot) == this) - { - GetTarget()->SetVisibleAura(slot, foundAura); - foundAura->SetNeedClientUpdate(); - } - // set not valid slot for aura - prevent removing other visible aura - slot = MAX_AURAS; - } - } - // update for out of range group members - if (slot < MAX_AURAS) + if (GetSlot() < MAX_AURAS) { - GetTarget()->RemoveVisibleAura(slot); + GetTarget()->RemoveVisibleAura(this); ClientUpdate(true); } } @@ -190,9 +155,18 @@ void AuraApplication::_HandleEffect(uint8 effIndex, bool apply) SetNeedClientUpdate(); } -void AuraApplication::BuildUpdatePacket(WorldPackets::Spells::AuraInfo& auraInfo, bool remove) const +void AuraApplication::SetNeedClientUpdate() { - ASSERT((_target->GetVisibleAura(_slot) != nullptr) ^ remove); + if (_needClientUpdate || GetRemoveMode() != AURA_REMOVE_NONE) + return; + + _needClientUpdate = true; + _target->SetVisibleAuraUpdate(this); +} + +void AuraApplication::BuildUpdatePacket(WorldPackets::Spells::AuraInfo& auraInfo, bool remove) +{ + ASSERT(_target->HasVisibleAura(this) != remove); auraInfo.Slot = GetSlot(); if (remove) @@ -1079,16 +1053,6 @@ bool Aura::CanBeSaved() const return true; } -bool Aura::CanBeSentToClient() const -{ - return !IsPassive() || GetSpellInfo()->HasAreaAuraEffect(GetOwner() ? GetOwner()->GetMap()->GetDifficultyID() : DIFFICULTY_NONE) - || HasEffectType(SPELL_AURA_ABILITY_IGNORE_AURASTATE) - || HasEffectType(SPELL_AURA_CAST_WHILE_WALKING) - || HasEffectType(SPELL_AURA_MOD_MAX_CHARGES) - || HasEffectType(SPELL_AURA_CHARGE_RECOVERY_MOD) - || HasEffectType(SPELL_AURA_CHARGE_RECOVERY_MULTIPLIER); -} - bool Aura::IsSingleTargetWith(Aura const* aura) const { // Same spell? diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 83b6343ceef..172210a80cb 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -83,11 +83,11 @@ class TC_GAME_API AuraApplication uint32 GetEffectsToApply() const { return _effectsToApply; } void SetRemoveMode(AuraRemoveMode mode) { _removeMode = mode; } - AuraRemoveMode GetRemoveMode() const {return _removeMode;} + AuraRemoveMode GetRemoveMode() const { return _removeMode; } - void SetNeedClientUpdate() { _needClientUpdate = true;} - bool IsNeedClientUpdate() const { return _needClientUpdate;} - void BuildUpdatePacket(WorldPackets::Spells::AuraInfo& data, bool remove) const; + void SetNeedClientUpdate(); + bool IsNeedClientUpdate() const { return _needClientUpdate; } + void BuildUpdatePacket(WorldPackets::Spells::AuraInfo& auraInfo, bool remove); void ClientUpdate(bool remove = false); }; @@ -201,7 +201,6 @@ class TC_GAME_API Aura bool CanBeSaved() const; bool IsRemoved() const { return m_isRemoved; } - bool CanBeSentToClient() const; // Single cast aura helpers bool IsSingleTarget() const {return m_isSingleTarget; } bool IsSingleTargetWith(Aura const* aura) const; |