TrinityCore
AuraApplication Class Reference

#include <SpellAuras.h>

Public Member Functions

UnitGetTarget () const
 
AuraGetBase () const
 
uint8 GetSlot () const
 
uint16 GetFlags () const
 
uint32 GetEffectMask () const
 
bool HasEffect (uint8 effect) const
 
bool IsPositive () const
 
bool IsSelfcast () const
 
uint32 GetEffectsToApply () const
 
void UpdateApplyEffectMask (uint32 newEffMask)
 
void SetRemoveMode (AuraRemoveMode mode)
 
AuraRemoveMode GetRemoveMode () const
 
void SetNeedClientUpdate ()
 
bool IsNeedClientUpdate () const
 
void BuildUpdatePacket (WorldPackets::Spells::AuraInfo &auraInfo, bool remove)
 
void ClientUpdate (bool remove=false)
 

Private Member Functions

 AuraApplication (Unit *target, Unit *caster, Aura *base, uint32 effMask)
 
void _Remove ()
 
void _InitFlags (Unit *caster, uint32 effMask)
 
void _HandleEffect (uint8 effIndex, bool apply)
 

Private Attributes

Unit *const _target
 
Aura *const _base
 
AuraRemoveMode _removeMode:8
 
uint8 _slot
 
uint16 _flags
 
uint32 _effectsToApply
 
bool _needClientUpdate:1
 
uint32 _effectMask
 

Friends

class Unit
 

Constructor & Destructor Documentation

◆ AuraApplication()

AuraApplication::AuraApplication ( Unit target,
Unit caster,
Aura base,
uint32  effMask 
)
explicitprivate
67  :
70 {
71  ASSERT(GetTarget() && GetBase());
72 
73  // Try find slot for aura
74  uint8 slot = 0;
75  // lookup for free slots in units visibleAuras
76  for (AuraApplication* visibleAura : GetTarget()->GetVisibleAuras())
77  {
78  if (slot < visibleAura->GetSlot())
79  break;
80 
81  ++slot;
82  }
83 
84  // Register Visible Aura
85  if (slot < MAX_AURAS)
86  {
87  _slot = slot;
88  GetTarget()->SetVisibleAura(this);
89  _needClientUpdate = true;
90  TC_LOG_DEBUG("spells", "Aura: %u Effect: %d put to unit visible auras slot: %u", GetBase()->GetId(), GetEffectMask(), slot);
91  }
92  else
93  TC_LOG_ERROR("spells", "Aura: %u Effect: %d could not find empty unit visible slot", GetBase()->GetId(), GetEffectMask());
94 
95  _InitFlags(caster, effMask);
96 }
Aura *const _base
Definition: SpellAuras.h:59
uint16 _flags
Definition: SpellAuras.h:62
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:186
Definition: SpellAuras.h:53
void _InitFlags(Unit *caster, uint32 effMask)
Definition: SpellAuras.cpp:108
Unit * GetTarget() const
Definition: SpellAuras.h:74
TC_GAME_API uint32 GetId(std::string const &username)
Definition: BattlenetAccountMgr.cpp:131
uint8 _slot
Definition: SpellAuras.h:61
AuraRemoveMode _removeMode
Definition: SpellAuras.h:60
void SetVisibleAura(AuraApplication *aurApp)
Definition: Unit.cpp:598
uint32 _effectMask
Definition: SpellAuras.h:65
Unit *const _target
Definition: SpellAuras.h:58
Definition: SpellAuraDefines.h:64
uint8 GetSlot() const
Definition: SpellAuras.h:77
uint32 _effectsToApply
Definition: SpellAuras.h:63
uint32 GetEffectMask() const
Definition: SpellAuras.h:79
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:177
Definition: SpellAuraDefines.h:33
bool _needClientUpdate
Definition: SpellAuras.h:64
uint8_t uint8
Definition: Define.h:154
#define ASSERT
Definition: Errors.h:61
#define MAX_AURAS
Definition: SpellAuraDefines.h:29
Aura * GetBase() const
Definition: SpellAuras.h:75
+ Here is the call graph for this function:

Member Function Documentation

◆ _HandleEffect()

void AuraApplication::_HandleEffect ( uint8  effIndex,
bool  apply 
)
private
155 {
156  AuraEffect* aurEff = GetBase()->GetEffect(effIndex);
157  if (!aurEff)
158  {
159  TC_LOG_ERROR("spells", "Aura %u has no effect at effectIndex %u but _HandleEffect was called", GetBase()->GetSpellInfo()->Id, uint32(effIndex));
160  return;
161  }
162  ASSERT(aurEff);
163  ASSERT(HasEffect(effIndex) == (!apply));
164  ASSERT((1<<effIndex) & _effectsToApply);
165  TC_LOG_DEBUG("spells", "AuraApplication::_HandleEffect: %u, apply: %u: amount: %u", aurEff->GetAuraType(), apply, aurEff->GetAmount());
166 
167  if (apply)
168  {
169  ASSERT(!(_effectMask & (1<<effIndex)));
170  _effectMask |= 1<<effIndex;
171  aurEff->HandleEffect(this, AURA_EFFECT_HANDLE_REAL, true);
172  }
173  else
174  {
175  ASSERT(_effectMask & (1<<effIndex));
176  _effectMask &= ~(1<<effIndex);
177  aurEff->HandleEffect(this, AURA_EFFECT_HANDLE_REAL, false);
178  }
179 
181 }
Definition: SpellAuraEffects.h:28
void HandleEffect(AuraApplication *aurApp, uint8 mode, bool apply, AuraEffect const *triggeredBy=nullptr)
Definition: SpellAuraEffects.cpp:898
#define TC_LOG_ERROR(filterType__,...)
Definition: Log.h:186
R apply(R(*func)(Ts...), apply_tuple_type< Ts... > &&args)
Definition: advstd.h:37
void SetNeedClientUpdate()
Definition: SpellAuras.cpp:214
AuraEffect * GetEffect(uint32 index) const
Definition: SpellAuras.cpp:516
bool HasEffect(uint8 effect) const
Definition: SpellAuras.h:80
uint32 _effectMask
Definition: SpellAuras.h:65
uint32_t uint32
Definition: Define.h:152
Definition: SpellAuraDefines.h:50
AuraType GetAuraType() const
Definition: SpellAuraEffects.h:57
uint32 _effectsToApply
Definition: SpellAuras.h:63
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:177
#define ASSERT
Definition: Errors.h:61
int32 GetAmount() const
Definition: SpellAuraEffects.h:58
Aura * GetBase() const
Definition: SpellAuras.h:75
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _InitFlags()

void AuraApplication::_InitFlags ( Unit caster,
uint32  effMask 
)
private
109 {
110  // mark as selfcast if needed
112 
113  // aura is cast by self or an enemy
114  // one negative effect and we know aura is negative
115  if (IsSelfcast() || !caster || !caster->IsFriendlyTo(GetTarget()))
116  {
117  bool negativeFound = false;
118  for (uint8 i = 0; i < GetBase()->GetSpellInfo()->GetEffects().size(); ++i)
119  {
120  if (((1 << i) & effMask) && !GetBase()->GetSpellInfo()->IsPositiveEffect(i))
121  {
122  negativeFound = true;
123  break;
124  }
125  }
126  _flags |= negativeFound ? AFLAG_NEGATIVE : AFLAG_POSITIVE;
127  }
128  // aura is cast by friend
129  // one positive effect and we know aura is positive
130  else
131  {
132  bool positiveFound = false;
133  for (uint8 i = 0; i < GetBase()->GetSpellInfo()->GetEffects().size(); ++i)
134  {
135  if (((1 << i) & effMask) && GetBase()->GetSpellInfo()->IsPositiveEffect(i))
136  {
137  positiveFound = true;
138  break;
139  }
140  }
141  _flags |= positiveFound ? AFLAG_POSITIVE : AFLAG_NEGATIVE;
142  }
143 
144  auto effectNeedsAmount = [this](AuraEffect const* effect)
145  {
146  return effect && (GetEffectsToApply() & (1 << effect->GetEffIndex())) && Aura::EffectTypeNeedsSendingAmount(effect->GetAuraType());
147  };
148 
150  || std::find_if(GetBase()->GetAuraEffects().begin(), GetBase()->GetAuraEffects().end(), std::cref(effectNeedsAmount)) != GetBase()->GetAuraEffects().end())
152 }
Definition: SpellAuraEffects.h:28
bool IsSelfcast() const
Definition: SpellAuras.h:82
SpellInfo const * GetSpellInfo() const
Definition: SpellAuras.h:134
uint32 GetEffectsToApply() const
Definition: SpellAuras.h:84
Definition: SpellAuraDefines.h:35
uint16 _flags
Definition: SpellAuras.h:62
bool IsPositiveEffect(uint8 effIndex) const
Definition: SpellInfo.cpp:1613
Unit * GetTarget() const
Definition: SpellAuras.h:74
static bool EffectTypeNeedsSendingAmount(AuraType type)
Definition: SpellAuras.cpp:1253
ObjectGuid const & GetGUID() const
Definition: Object.h:154
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:449
Definition: SpellAuraDefines.h:37
Definition: SpellAuraDefines.h:34
AuraEffectVector const & GetAuraEffects() const
Definition: SpellAuras.h:302
Definition: SpellAuraDefines.h:38
std::vector< SpellEffectInfo > const & GetEffects() const
Definition: SpellInfo.h:579
bool IsFriendlyTo(WorldObject const *target) const
Definition: Object.cpp:2602
ObjectGuid GetCasterGUID() const
Definition: SpellAuras.h:139
Definition: SpellAuraDefines.h:33
Definition: SharedDefines.h:682
uint8_t uint8
Definition: Define.h:154
Aura * GetBase() const
Definition: SpellAuras.h:75
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ _Remove()

void AuraApplication::_Remove ( )
private
99 {
100  // update for out of range group members
101  if (GetSlot() < MAX_AURAS)
102  {
103  GetTarget()->RemoveVisibleAura(this);
104  ClientUpdate(true);
105  }
106 }
Unit * GetTarget() const
Definition: SpellAuras.h:74
uint8 GetSlot() const
Definition: SpellAuras.h:77
void RemoveVisibleAura(AuraApplication *aurApp)
Definition: Unit.cpp:605
void ClientUpdate(bool remove=false)
Definition: SpellAuras.cpp:279
#define MAX_AURAS
Definition: SpellAuraDefines.h:29
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ BuildUpdatePacket()

void AuraApplication::BuildUpdatePacket ( WorldPackets::Spells::AuraInfo auraInfo,
bool  remove 
)
224 {
225  ASSERT(_target->HasVisibleAura(this) != remove);
226 
227  auraInfo.Slot = GetSlot();
228  if (remove)
229  return;
230 
231  auraInfo.AuraData = boost::in_place();
232 
233  Aura const* aura = GetBase();
234 
235  WorldPackets::Spells::AuraDataInfo& auraData = auraInfo.AuraData.get();
236  auraData.CastID = aura->GetCastId();
237  auraData.SpellID = aura->GetId();
238  auraData.Visual = aura->GetSpellVisual();
239  auraData.Flags = GetFlags();
241  auraData.Flags |= AFLAG_DURATION;
242 
243  auraData.ActiveFlags = GetEffectMask();
245  auraData.CastLevel = aura->GetCasterLevel();
246  else
247  auraData.CastLevel = uint16(aura->GetCastItemLevel());
248 
249  // send stack amount for aura which could be stacked (never 0 - causes incorrect display) or charges
250  // stack amount has priority over charges (checked on retail with spell 50262)
251  auraData.Applications = aura->IsUsingStacks() ? aura->GetStackAmount() : aura->GetCharges();
252  if (!(auraData.Flags & AFLAG_NOCASTER))
253  auraData.CastUnit = aura->GetCasterGUID();
254 
255  if (auraData.Flags & AFLAG_DURATION)
256  {
257  auraData.Duration = aura->GetMaxDuration();
258  auraData.Remaining = aura->GetDuration();
259  }
260 
261  if (auraData.Flags & AFLAG_SCALABLE)
262  {
263  auraData.Points.reserve(aura->GetAuraEffects().size());
264  auraData.EstimatedPoints.reserve(aura->GetAuraEffects().size());
265  for (AuraEffect const* effect : GetBase()->GetAuraEffects())
266  {
267  if (effect && HasEffect(effect->GetEffIndex())) // Not all of aura's effects have to be applied on every target
268  {
269  Trinity::Containers::EnsureWritableVectorIndex(auraData.Points, effect->GetEffIndex()) = float(effect->GetAmount());
270  if (effect->GetEstimatedAmount())
271  Trinity::Containers::EnsureWritableVectorIndex(auraData.EstimatedPoints, effect->GetEffIndex()) = *effect->GetEstimatedAmount();
272  }
273  }
274  if (!auraData.EstimatedPoints.empty())
275  auraData.EstimatedPoints.resize(auraData.Points.size()); // pad to equal sizes
276  }
277 }
Definition: SpellAuraEffects.h:28
Optional< AuraDataInfo > AuraData
Definition: SpellPackets.h:197
decltype(auto) EnsureWritableVectorIndex(std::vector< T > &vec, typename std::vector< T >::size_type i)
Definition: Containers.h:254
SpellInfo const * GetSpellInfo() const
Definition: SpellAuras.h:134
bool IsUsingStacks() const
Definition: SpellAuras.cpp:1023
ObjectGuid GetCastId() const
Definition: SpellAuras.h:138
int32 GetDuration() const
Definition: SpellAuras.h:172
Optional< int32 > Remaining
Definition: SpellPackets.h:188
uint8 GetStackAmount() const
Definition: SpellAuras.h:188
uint16 Flags
Definition: SpellPackets.h:180
uint32 GetId() const
Definition: SpellAuras.h:135
uint32 ActiveFlags
Definition: SpellPackets.h:181
ObjectGuid CastID
Definition: SpellPackets.h:177
Optional< int32 > Duration
Definition: SpellPackets.h:187
uint8 Slot
Definition: SpellPackets.h:196
Definition: SharedDefines.h:572
bool HasAttribute(SpellAttr0 attribute) const
Definition: SpellInfo.h:449
std::vector< float > EstimatedPoints
Definition: SpellPackets.h:191
bool HasVisibleAura(AuraApplication *aurApp) const
Definition: Unit.h:1599
Definition: SpellAuraDefines.h:37
uint16 CastLevel
Definition: SpellPackets.h:182
bool HasEffect(uint8 effect) const
Definition: SpellAuras.h:80
SpellCastVisual Visual
Definition: SpellPackets.h:179
SpellCastVisual GetSpellVisual() const
Definition: SpellAuras.h:143
Optional< ObjectGuid > CastUnit
Definition: SpellPackets.h:186
Definition: SpellAuraDefines.h:34
uint16 GetFlags() const
Definition: SpellAuras.h:78
AuraEffectVector const & GetAuraEffects() const
Definition: SpellAuras.h:302
uint8 GetCasterLevel() const
Definition: SpellAuras.h:194
uint16_t uint16
Definition: Define.h:153
Unit *const _target
Definition: SpellAuras.h:58
uint8 GetCharges() const
Definition: SpellAuras.h:179
uint8 GetSlot() const
Definition: SpellAuras.h:77
int32 GetCastItemLevel() const
Definition: SpellAuras.h:142
ObjectGuid GetCasterGUID() const
Definition: SpellAuras.h:139
int32 SpellID
Definition: SpellPackets.h:178
uint32 GetEffectMask() const
Definition: SpellAuras.h:79
Definition: SharedDefines.h:780
#define ASSERT
Definition: Errors.h:61
Definition: SpellPackets.h:175
int32 GetMaxDuration() const
Definition: SpellAuras.h:167
uint8 Applications
Definition: SpellPackets.h:183
Definition: SpellAuras.h:118
Definition: SpellAuraDefines.h:36
Aura * GetBase() const
Definition: SpellAuras.h:75
std::vector< float > Points
Definition: SpellPackets.h:190
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ClientUpdate()

void AuraApplication::ClientUpdate ( bool  remove = false)
280 {
281  _needClientUpdate = false;
282 
284  update.UpdateAll = false;
285  update.UnitGUID = GetTarget()->GetGUID();
286 
288  BuildUpdatePacket(auraInfo, remove);
289  update.Auras.push_back(auraInfo);
290 
291  _target->SendMessageToSet(update.Write(), true);
292 }
Definition: SpellPackets.h:194
Unit * GetTarget() const
Definition: SpellAuras.h:74
ObjectGuid const & GetGUID() const
Definition: Object.h:154
std::vector< AuraInfo > Auras
Definition: SpellPackets.h:209
Unit *const _target
Definition: SpellAuras.h:58
void BuildUpdatePacket(WorldPackets::Spells::AuraInfo &auraInfo, bool remove)
Definition: SpellAuras.cpp:223
bool UpdateAll
Definition: SpellPackets.h:207
WorldPacket const * Write() override
Definition: SpellPackets.cpp:148
ObjectGuid UnitGUID
Definition: SpellPackets.h:208
bool _needClientUpdate
Definition: SpellAuras.h:64
Definition: SpellPackets.h:200
virtual void SendMessageToSet(WorldPacket const *data, bool self) const
Definition: Object.cpp:1646
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GetBase()

Aura* AuraApplication::GetBase ( ) const
inline
75 { return _base; }
Aura *const _base
Definition: SpellAuras.h:59
+ Here is the caller graph for this function:

◆ GetEffectMask()

uint32 AuraApplication::GetEffectMask ( ) const
inline
79 { return _effectMask; }
uint32 _effectMask
Definition: SpellAuras.h:65
+ Here is the caller graph for this function:

◆ GetEffectsToApply()

uint32 AuraApplication::GetEffectsToApply ( ) const
inline
84 { return _effectsToApply; }
uint32 _effectsToApply
Definition: SpellAuras.h:63
+ Here is the caller graph for this function:

◆ GetFlags()

uint16 AuraApplication::GetFlags ( ) const
inline
78 { return _flags; }
uint16 _flags
Definition: SpellAuras.h:62
+ Here is the caller graph for this function:

◆ GetRemoveMode()

AuraRemoveMode AuraApplication::GetRemoveMode ( ) const
inline
88 { return _removeMode; }
AuraRemoveMode _removeMode
Definition: SpellAuras.h:60
+ Here is the caller graph for this function:

◆ GetSlot()

uint8 AuraApplication::GetSlot ( ) const
inline
77 { return _slot; }
uint8 _slot
Definition: SpellAuras.h:61
+ Here is the caller graph for this function:

◆ GetTarget()

Unit* AuraApplication::GetTarget ( ) const
inline
74 { return _target; }
Unit *const _target
Definition: SpellAuras.h:58

◆ HasEffect()

bool AuraApplication::HasEffect ( uint8  effect) const
inline
80 { ASSERT(effect < MAX_SPELL_EFFECTS); return (_effectMask & (1 << effect)) != 0; }
#define MAX_SPELL_EFFECTS
Definition: DBCEnums.h:1445
uint32 _effectMask
Definition: SpellAuras.h:65
#define ASSERT
Definition: Errors.h:61
+ Here is the caller graph for this function:

◆ IsNeedClientUpdate()

bool AuraApplication::IsNeedClientUpdate ( ) const
inline
91 { return _needClientUpdate; }
bool _needClientUpdate
Definition: SpellAuras.h:64

◆ IsPositive()

bool AuraApplication::IsPositive ( ) const
inline
81 { return (_flags & AFLAG_POSITIVE) != 0; }
Definition: SpellAuraDefines.h:35
uint16 _flags
Definition: SpellAuras.h:62
+ Here is the caller graph for this function:

◆ IsSelfcast()

bool AuraApplication::IsSelfcast ( ) const
inline
82 { return (_flags & AFLAG_NOCASTER) != 0; }
uint16 _flags
Definition: SpellAuras.h:62
Definition: SpellAuraDefines.h:34
+ Here is the caller graph for this function:

◆ SetNeedClientUpdate()

void AuraApplication::SetNeedClientUpdate ( )
215 {
217  return;
218 
219  _needClientUpdate = true;
221 }
void SetVisibleAuraUpdate(AuraApplication *aurApp)
Definition: Unit.h:1601
AuraRemoveMode GetRemoveMode() const
Definition: SpellAuras.h:88
Unit *const _target
Definition: SpellAuras.h:58
Definition: SpellAuraDefines.h:64
bool _needClientUpdate
Definition: SpellAuras.h:64
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SetRemoveMode()

void AuraApplication::SetRemoveMode ( AuraRemoveMode  mode)
inline
87 { _removeMode = mode; }
AuraRemoveMode _removeMode
Definition: SpellAuras.h:60
+ Here is the caller graph for this function:

◆ UpdateApplyEffectMask()

void AuraApplication::UpdateApplyEffectMask ( uint32  newEffMask)
184 {
185  if (_effectsToApply == newEffMask)
186  return;
187 
188  uint32 removeEffMask = (_effectsToApply ^ newEffMask) & (~newEffMask);
189  uint32 addEffMask = (_effectsToApply ^ newEffMask) & (~_effectsToApply);
190 
191  // quick check, removes application completely
192  if (removeEffMask == _effectsToApply && !addEffMask)
193  {
195  return;
196  }
197 
198  for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
199  {
200  // update real effects only if they were applied already
201  if (!(_effectMask & (1 << i)))
202  continue;
203 
204  if (removeEffMask & (1 << i))
205  _HandleEffect(i, false);
206 
207  if (addEffMask & (1 << i))
208  _HandleEffect(i, true);
209  }
210 
211  _effectsToApply = newEffMask;
212 }
#define MAX_SPELL_EFFECTS
Definition: DBCEnums.h:1445
void _HandleEffect(uint8 effIndex, bool apply)
Definition: SpellAuras.cpp:154
uint32 _effectMask
Definition: SpellAuras.h:65
uint32_t uint32
Definition: Define.h:152
Unit *const _target
Definition: SpellAuras.h:58
uint32 _effectsToApply
Definition: SpellAuras.h:63
uint8_t uint8
Definition: Define.h:154
Definition: SpellAuraDefines.h:65
void _UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode)
Definition: Unit.cpp:3272
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Friends And Related Function Documentation

◆ Unit

friend class Unit
friend

Member Data Documentation

◆ _base

Aura* const AuraApplication::_base
private

◆ _effectMask

uint32 AuraApplication::_effectMask
private

◆ _effectsToApply

uint32 AuraApplication::_effectsToApply
private

◆ _flags

uint16 AuraApplication::_flags
private

◆ _needClientUpdate

bool AuraApplication::_needClientUpdate
private

◆ _removeMode

AuraRemoveMode AuraApplication::_removeMode
private

◆ _slot

uint8 AuraApplication::_slot
private

◆ _target

Unit* const AuraApplication::_target
private

The documentation for this class was generated from the following files: