Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
SpellAuraApplication.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "CellImpl.h"
7#include "Common.h"
8#include "DynamicObject.h"
9#include "GridNotifiers.h"
10#include "GridNotifiersImpl.h"
11#include "Log.h"
12#include "ObjectAccessor.h"
13#include "ObjectMgr.h"
14#include "Opcodes.h"
15#include "Player.h"
16#include "ScriptMgr.h"
17#include "Spell.h"
18#include "SpellAuraEffects.h"
19#include "SpellMgr.h"
20#include "SpellScript.h"
21#include "Unit.h"
22#include "Util.h"
23#include "Vehicle.h"
24#include "WorldPacket.h"
25
27{
28 uint8 slot = GetSlot();
29
30 if (slot >= MAX_AURAS)
31 return;
32
33 if (AuraApplication* foundAura = _target->GetAuraApplication(GetBase()->GetId(), GetBase()->GetCasterGUID(), GetBase()->GetCastItemGUID()))
34 {
35 // Reuse visible aura slot by aura which is still applied - prevent storing dead pointers
36 if (slot == foundAura->GetSlot())
37 {
38 if (GetTarget()->GetVisibleAura(slot) == this)
39 {
40 GetTarget()->SetVisibleAura(slot, foundAura);
41 foundAura->SetNeedClientUpdate();
42 }
43 // set not valid slot for aura - prevent removing other visible aura
44 slot = MAX_AURAS;
45 }
46 }
47
48 // update for out of range group members
49 if (slot < MAX_AURAS)
50 {
52 ClientUpdate(true);
53 }
54}
55
57{
58 // mark as selfcasted if needed
60
61 // aura is casted by self or an enemy
62 // one negative effect and we know aura is negative
63 if (IsSelfcasted() || !caster || !caster->IsFriendlyTo(GetTarget()))
64 {
65 bool negativeFound = false;
66 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
67 {
68 if (((1 << i) & effMask) && !GetBase()->GetSpellInfo()->IsPositiveEffect(i))
69 {
70 negativeFound = true;
71 break;
72 }
73 }
74 _flags |= negativeFound ? AFLAG_NEGATIVE : AFLAG_POSITIVE;
75 }
76 // aura is casted by friend
77 // one positive effect and we know aura is positive
78 else
79 {
80 bool positiveFound = false;
81 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
82 {
83 if (((1 << i) & effMask) && GetBase()->GetSpellInfo()->IsPositiveEffect(i))
84 {
85 positiveFound = true;
86 break;
87 }
88 }
89 _flags |= positiveFound ? AFLAG_POSITIVE : AFLAG_NEGATIVE;
90 }
91
92 if (GetBase()->GetSpellInfo()->AttributesEx8 & SPELL_ATTR8_AURA_SEND_AMOUNT)
94}
95
96void AuraApplication::_HandleEffect(uint8 effIndex, bool apply)
97{
98 AuraEffect* aurEff = GetBase()->GetEffect(effIndex);
99 ASSERT(aurEff);
100 ASSERT(HasEffect(effIndex) == (!apply));
101 ASSERT((1 << effIndex) & _effectsToApply);
102 SF_LOG_DEBUG("spells", "AuraApplication::_HandleEffect: %u, apply: %u: amount: %u", aurEff->GetAuraType(), apply, aurEff->GetAmount());
103
104 if (apply)
105 {
106 ASSERT(!(_effMask & (1 << effIndex)));
107 _effMask |= 1 << effIndex;
108 aurEff->HandleEffect(this, AURA_EFFECT_HANDLE_REAL, true);
109 }
110 else
111 {
112 ASSERT(_effMask & (1 << effIndex));
113 _effMask &= ~(1 << effIndex);
114 aurEff->HandleEffect(this, AURA_EFFECT_HANDLE_REAL, false);
115
116 // Remove all triggered by aura spells vs unlimited duration
118 }
120}
121
123{
124 _needClientUpdate = false;
125
126 ObjectGuid targetGuid = _target->GetGUID();
127 Aura const* aura = GetBase();
128 uint32 flags = _flags;
129
131 flags |= AFLAG_DURATION;
132
134 data.WriteBit(targetGuid[7]);
135 data.WriteBit(0); // Is AURA_UPDATE_ALL
136 data.WriteBits(1, 24); // Aura Count
137 data.WriteBit(targetGuid[6]);
138 data.WriteBit(targetGuid[1]);
139 data.WriteBit(targetGuid[3]);
140 data.WriteBit(targetGuid[0]);
141 data.WriteBit(targetGuid[4]);
142 data.WriteBit(targetGuid[2]);
143 data.WriteBit(targetGuid[5]);
144 data.WriteBit(!remove); // Not remove
145
146 if (!remove)
147 {
149 {
150 uint8 effCount = 0;
151 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
152 if (HasEffect(i))
153 effCount++;
154
155 data.WriteBits(effCount, 22); // Effect Count
156 }
157 else
158 data.WriteBits(0, 22); // Effect Count
159
160 data.WriteBit(!(flags & AFLAG_CASTER)); // HasCasterGuid
161
162 if (!(flags & AFLAG_CASTER))
163 {
164 ObjectGuid casterGuid = aura->GetCasterGUID();
165 data.WriteBit(casterGuid[3]);
166 data.WriteBit(casterGuid[4]);
167 data.WriteBit(casterGuid[6]);
168 data.WriteBit(casterGuid[1]);
169 data.WriteBit(casterGuid[5]);
170 data.WriteBit(casterGuid[2]);
171 data.WriteBit(casterGuid[0]);
172 data.WriteBit(casterGuid[7]);
173 }
174
175 data.WriteBits(0, 22); // Unk effect count
176 data.WriteBit(flags & AFLAG_DURATION); // HasDuration
177 data.WriteBit(flags & AFLAG_DURATION); // HasMaxDuration
178 }
179
180 data.FlushBits();
181
182 if (!remove)
183 {
184 if (!(flags & AFLAG_CASTER))
185 {
186 ObjectGuid casterGuid = aura->GetCasterGUID();
187 data.WriteByteSeq(casterGuid[3]);
188 data.WriteByteSeq(casterGuid[2]);
189 data.WriteByteSeq(casterGuid[1]);
190 data.WriteByteSeq(casterGuid[6]);
191 data.WriteByteSeq(casterGuid[4]);
192 data.WriteByteSeq(casterGuid[0]);
193 data.WriteByteSeq(casterGuid[5]);
194 data.WriteByteSeq(casterGuid[7]);
195 }
196
197 data << uint8(flags);
198 data << uint16(aura->GetCasterLevel());
199 data << uint32(aura->GetId());
200
201 if (flags & AFLAG_DURATION)
202 data << uint32(aura->GetMaxDuration());
203
204 if (flags & AFLAG_DURATION)
205 data << uint32(aura->GetDuration());
206
207 // send stack amount for aura which could be stacked (never 0 - causes incorrect display) or charges
208 // stack amount has priority over charges (checked on retail with spell 50262)
209 data << uint8(aura->GetSpellInfo()->StackAmount ? aura->GetStackAmount() : aura->GetCharges());
210 data << uint32(GetEffectMask());
211
213 {
214 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
215 {
216 if (HasEffect(i))
217 {
218 if (AuraEffect const* eff = aura->GetEffect(i))
219 data << float(eff->GetAmount());
220 else
221 data << float(0.f);
222 }
223 }
224 }
225 }
226
227 data << uint8(GetSlot());
228
229 data.WriteByteSeq(targetGuid[2]);
230 data.WriteByteSeq(targetGuid[6]);
231 data.WriteByteSeq(targetGuid[7]);
232 data.WriteByteSeq(targetGuid[1]);
233 data.WriteByteSeq(targetGuid[3]);
234 data.WriteByteSeq(targetGuid[4]);
235 data.WriteByteSeq(targetGuid[0]);
236 data.WriteByteSeq(targetGuid[5]);
237
238 _target->SendMessageToSet(&data, true);
239}
#define MAX_SPELL_EFFECTS
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint16_t uint16
Definition Define.h:78
#define ASSERT
Definition Errors.h:29
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
@ SPELL_ATTR5_HIDE_DURATION
@ SPELL_ATTR8_AURA_SEND_AMOUNT
#define MAX_AURAS
@ AURA_EFFECT_HANDLE_REAL
@ AFLAG_POSITIVE
@ AFLAG_ANY_EFFECT_AMOUNT_SENT
@ AFLAG_NONE
@ AFLAG_NEGATIVE
@ AFLAG_CASTER
@ AFLAG_DURATION
Unit * GetTarget() const
Definition SpellAuras.h:54
uint32 _effectsToApply
Definition SpellAuras.h:41
void ClientUpdate(bool remove=false)
bool _needClientUpdate
Definition SpellAuras.h:44
void _HandleEffect(uint8 effIndex, bool apply)
void _InitFlags(Unit *caster, uint32 effMask)
AuraApplication(Unit *target, Unit *caster, Aura *base, uint32 effMask)
Aura * GetBase() const
Definition SpellAuras.h:55
bool IsSelfcasted() const
Definition SpellAuras.h:62
bool HasEffect(uint32 effect) const
Definition SpellAuras.h:60
uint8 GetSlot() const
Definition SpellAuras.h:57
void SetNeedClientUpdate()
Definition SpellAuras.h:68
uint32 GetEffectMask() const
Definition SpellAuras.h:59
Unit *const _target
Definition SpellAuras.h:36
AuraType GetAuraType() const
void HandleEffect(AuraApplication *aurApp, uint8 mode, bool apply)
void CleanupTriggeredSpells(Unit *target)
int32 GetAmount() const
uint64 GetCasterGUID() const
Definition SpellAuras.h:91
int32 GetMaxDuration() const
Definition SpellAuras.h:115
uint8 GetCasterLevel() const
Definition SpellAuras.h:139
uint32 GetId() const
Definition SpellAuras.h:88
int32 GetDuration() const
Definition SpellAuras.h:119
AuraEffect * GetEffect(uint8 effIndex) const
Definition SpellAuras.h:168
uint8 GetStackAmount() const
Definition SpellAuras.h:133
uint8 GetCharges() const
Definition SpellAuras.h:126
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:87
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void WriteBits(T value, size_t bits)
Definition ByteBuffer.h:192
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
uint64 GetGUID() const
Definition Object.h:119
uint32 StackAmount
Definition SpellInfo.h:211
uint32 AttributesEx5
Definition SpellInfo.h:169
Definition Unit.h:1367
void RemoveVisibleAura(uint8 slot)
Definition Unit.cpp:506
void SetVisibleAura(uint8 slot, AuraApplication *aur)
Definition Unit.cpp:500
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:2283
@ SMSG_AURA_UPDATE
Definition Opcodes.h:532