aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2016-07-26 20:55:24 +0200
committerShauren <shauren.trinity@gmail.com>2016-07-26 20:55:24 +0200
commit83555367a786230fcd5ed3672e1ff3eac42c6f68 (patch)
treeb199412f587a5207ea44c4d9623a4d3a5e9f6f1a
parent060256000b1a553a21581b9b65e12f7cb034e148 (diff)
Core/Auras: Visibility changes
* Changed max visible aura amount to 255 * All auras are now sent to clients, many passives that client needed to see were incorrectly hidden (also client properly filters aura bar by itself)
-rw-r--r--src/server/game/Entities/Player/Player.cpp9
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp38
-rw-r--r--src/server/game/Entities/Unit/Unit.h19
-rw-r--r--src/server/game/Server/Packets/PartyPackets.cpp64
-rw-r--r--src/server/game/Spells/Auras/SpellAuraDefines.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp98
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.h9
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;