Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
UnitAuraState.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 "Battlefield.h"
7#include "BattlefieldMgr.h"
8#include "Battleground.h"
9#include "CellImpl.h"
10#include "Common.h"
11#include "ConditionMgr.h"
12#include "Creature.h"
13#include "CreatureAI.h"
14#include "CreatureAIImpl.h"
15#include "CreatureGroups.h"
16#include "Formulas.h"
17#include "GridNotifiersImpl.h"
18#include "Group.h"
19#include "InstanceSaveMgr.h"
20#include "InstanceScript.h"
21#include "Log.h"
22#include "MapManager.h"
23#include "MovementStructures.h"
24#include "MoveSpline.h"
25#include "ObjectAccessor.h"
26#include "ObjectMgr.h"
27#include "Opcodes.h"
28#include "OutdoorPvP.h"
29#include "PassiveAI.h"
30#include "Pet.h"
31#include "PetAI.h"
32#include "Player.h"
33#include "QuestDef.h"
34#include "ReputationMgr.h"
35#include "Spell.h"
36#include "SpellAuraEffects.h"
37#include "SpellAuraMetadata.h"
38#include "SpellAuras.h"
39#include "SpellInfo.h"
40#include "SpellMgr.h"
41#include "TemporarySummon.h"
42#include "Totem.h"
43#include "Transport.h"
44#include "Unit.h"
45#include "UpdateFieldFlags.h"
46#include "Util.h"
47#include "Vehicle.h"
48#include "World.h"
49#include "WorldPacket.h"
50#include "WorldSession.h"
51
52#include <math.h>
53
55{
56 while (!m_removedAuras.empty())
57 {
58 delete m_removedAuras.front();
59 m_removedAuras.pop_front();
60 }
61}
62
63Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellInfo const* newAura, uint32 effMask, Unit* caster, int32* baseAmount /*= NULL*/, Item* castItem /*= NULL*/, uint64 casterGUID /*= 0*/)
64{
65 ASSERT(casterGUID || caster);
66
67 // Player-controlled stacked auras must remain caster-bound. Otherwise raid members
68 // can repeatedly refresh the same owned aura and inflate its stack count.
71 caster->GetTypeId() == TypeID::TYPEID_UNIT,
72 caster->IsSummon(),
73 IsSummon());
74
75 if (!casterGUID && bindStackToCaster)
76 casterGUID = caster->GetGUID();
77
78 // passive and Incanter's Absorption and auras with different type can stack with themselves any number of times
79 if (!newAura->IsMultiSlotAura())
80 {
81 // check if cast item changed
82 uint64 castItemGUID = 0;
83 if (castItem)
84 castItemGUID = castItem->GetGUID();
85
86 // find current aura from spell and change it's stackamount, or refresh it's duration
87 if (Aura* foundAura = GetOwnedAura(newAura->Id, casterGUID, (newAura->AttributesCu & SPELL_ATTR0_CU_ENCHANT_PROC) ? castItemGUID : 0, 0))
88 {
89 // effect masks do not match
90 // extremely rare case
91 // let's just recreate aura
92 if (effMask != foundAura->GetEffectMask())
93 return NULL;
94
95 // update basepoints with new values - effect amount will be recalculated in ModStackAmount
96 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
97 {
98 if (!foundAura->HasEffect(i))
99 continue;
100
101 int bp;
102 if (baseAmount)
103 bp = *(baseAmount + i);
104 else
105 bp = foundAura->GetSpellInfo()->Effects[i].BasePoints;
106
107 int32* oldBP = const_cast<int32*>(&(foundAura->GetEffect(i)->m_baseAmount));
108 *oldBP = bp;
109 }
110
111 // correct cast item guid if needed
112 if (castItemGUID != foundAura->GetCastItemGUID())
113 {
114 uint64* oldGUID = const_cast<uint64*>(&foundAura->m_castItemGuid);
115 *oldGUID = castItemGUID;
116 }
117
118 // try to increase stack amount
119 foundAura->ModStackAmount(1);
120 return foundAura;
121 }
122 }
123
124 return NULL;
125}
126
127void Unit::_AddAura(UnitAura* aura, Unit* caster)
128{
130 m_ownedAuras.insert(AuraMap::value_type(aura->GetId(), aura));
131
133
134 if (aura->IsRemoved())
135 return;
136
138 if (aura->IsSingleTarget())
139 {
140 ASSERT((IsInWorld() && !IsDuringRemoveFromWorld()) || (aura->GetCasterGUID() == GetGUID()) ||
142 /* @HACK: Player is not in world during loading auras.
143 * Single target auras are not saved or loaded from database
144 * but may be created as a result of aura links (player mounts with passengers)
145 */
146
147 // register single target aura
148 caster->GetSingleCastAuras().push_back(aura);
149 // remove other single target auras
150 Unit::AuraList& scAuras = caster->GetSingleCastAuras();
151 for (Unit::AuraList::iterator itr = scAuras.begin(); itr != scAuras.end();)
152 {
153 if ((*itr) != aura &&
154 (*itr)->IsSingleTargetWith(aura))
155 {
156 (*itr)->Remove();
157 itr = scAuras.begin();
158 }
159 else
160 ++itr;
161 }
162 }
163}
164
165// creates aura application instance and registers it in lists
166// aura application effects are handled separately to prevent aura list corruption
168{
169 // can't apply aura on unit which is going to be deleted - to not create a memory leak
171 // aura musn't be removed
172 ASSERT(!aura->IsRemoved());
173
174 // aura mustn't be already applied on target
175 ASSERT(!aura->IsAppliedOnTarget(GetGUID()) && "Unit::_CreateAuraApplication: aura musn't be applied on target");
176
177 SpellInfo const* aurSpellInfo = aura->GetSpellInfo();
178 uint32 aurId = aurSpellInfo->Id;
179
180 // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
181 if (!IsAlive() && !aurSpellInfo->IsDeathPersistent() &&
182 (GetTypeId() != TypeID::TYPEID_PLAYER || !ToPlayer()->GetSession()->PlayerLoading()))
183 return NULL;
184
185 Unit* caster = aura->GetCaster();
186
187 AuraApplication* aurApp = new AuraApplication(this, caster, aura, effMask);
188 m_appliedAuras.insert(AuraApplicationMap::value_type(aurId, aurApp));
189
190 if (aurSpellInfo->AuraInterruptFlags)
191 {
192 m_interruptableAuras.push_back(aurApp);
194 }
195
196 if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState())
197 m_auraStateAuras.insert(AuraStateAurasMap::value_type(aState, aurApp));
198
199 aura->_ApplyForTarget(this, caster, aurApp);
200 return aurApp;
201}
202
203void Unit::_ApplyAuraEffect(Aura* aura, uint8 effIndex)
204{
205 ASSERT(aura);
206 ASSERT(aura->HasEffect(effIndex));
208 ASSERT(aurApp);
209 if (!aurApp->GetEffectMask())
210 _ApplyAura(aurApp, 1 << effIndex);
211 else
212 aurApp->_HandleEffect(effIndex, true);
213}
214
215// handles effects of aura application
216// should be done after registering aura in lists
218{
219 Aura* aura = aurApp->GetBase();
220
222
223 if (aurApp->GetRemoveMode())
224 return;
225
226 // Update target aura state flag
227 if (AuraStateType aState = aura->GetSpellInfo()->GetAuraState())
228 ModifyAuraState(aState, true);
229
230 if (aurApp->GetRemoveMode())
231 return;
232
233 // Sitdown on apply aura req seated
236
237 Unit* caster = aura->GetCaster();
238
239 if (aurApp->GetRemoveMode())
240 return;
241
242 aura->HandleAuraSpecificMods(aurApp, caster, true, false);
243
244 // apply effects of the aura
245 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
246 {
247 if (effMask & 1 << i && (!aurApp->GetRemoveMode()))
248 aurApp->_HandleEffect(i, true);
249 }
250}
251
252// removes aura application from lists and unapplies effects
253void Unit::_UnapplyAura(AuraApplicationMap::iterator& i, AuraRemoveMode removeMode)
254{
255 AuraApplication* aurApp = i->second;
256 ASSERT(aurApp);
257 ASSERT(!aurApp->GetRemoveMode());
258 ASSERT(aurApp->GetTarget() == this);
259
260 aurApp->SetRemoveMode(removeMode);
261 Aura* aura = aurApp->GetBase();
262 SF_LOG_DEBUG("spells", "Aura %u now is remove mode %d", aura->GetId(), removeMode);
263
264 // dead loop is killing the server probably
265 ASSERT(m_removedAurasCount < 0xFFFFFFFF);
266
268
269 Unit* caster = aura->GetCaster();
270
271 // Remove all pointers from lists here to prevent possible pointer invalidation on spellcast/auraapply/auraremove
272 m_appliedAuras.erase(i);
273
274 if (aura->GetSpellInfo()->AuraInterruptFlags)
275 {
276 m_interruptableAuras.remove(aurApp);
278 }
279
280 bool auraStateFound = false;
281 AuraStateType auraState = aura->GetSpellInfo()->GetAuraState();
282 if (auraState)
283 {
284 bool canBreak = false;
285 // Get mask of all aurastates from remaining auras
286 for (AuraStateAurasMap::iterator itr = m_auraStateAuras.lower_bound(auraState); itr != m_auraStateAuras.upper_bound(auraState) && !(auraStateFound && canBreak);)
287 {
288 if (itr->second == aurApp)
289 {
290 m_auraStateAuras.erase(itr);
291 itr = m_auraStateAuras.lower_bound(auraState);
292 canBreak = true;
293 continue;
294 }
295 auraStateFound = true;
296 ++itr;
297 }
298 }
299
300 aurApp->_Remove();
301 aura->_UnapplyForTarget(this, caster, aurApp);
302
303 // remove effects of the spell - needs to be done after removing aura from lists
304 for (uint32 itr = 0; itr < MAX_SPELL_EFFECTS; ++itr)
305 {
306 if (aurApp->HasEffect(itr))
307 aurApp->_HandleEffect(itr, false);
308 }
309
310 // all effect mustn't be applied
311 ASSERT(!aurApp->GetEffectMask());
312
313 // Remove totem at next update if totem loses its aura
314 if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE && GetTypeId() == TypeID::TYPEID_UNIT && ToCreature()->IsTotem() && ToTotem()->GetSummonerGUID() == aura->GetCasterGUID())
315 {
316 if (ToTotem()->GetSpell() == aura->GetId() && ToTotem()->GetTotemType() == TOTEM_PASSIVE)
318 }
319
320 // Remove aurastates only if were not found
321 if (!auraStateFound)
322 ModifyAuraState(auraState, false);
323
324 aura->HandleAuraSpecificMods(aurApp, caster, false, false);
325
326 // only way correctly remove all auras from list
327 //if (removedAuras != m_removedAurasCount) new aura may be added
328 i = m_appliedAuras.begin();
329}
330
332{
333 // aura can be removed from unit only if it's applied on it, shouldn't happen
334 ASSERT(aurApp->GetBase()->GetApplicationOfTarget(GetGUID()) == aurApp);
335
336 uint32 spellId = aurApp->GetBase()->GetId();
337 AuraApplicationMapBoundsNonConst range = m_appliedAuras.equal_range(spellId);
338
339 for (AuraApplicationMap::iterator iter = range.first; iter != range.second;)
340 {
341 if (iter->second == aurApp)
342 {
343 _UnapplyAura(iter, removeMode);
344 return;
345 }
346 else
347 ++iter;
348 }
349 ASSERT(false);
350}
351
353{
354 SpellInfo const* spellProto = aura->GetSpellInfo();
355
356 // passive spell special case (only non stackable with ranks)
357 if (spellProto->IsPassiveStackableWithRanks())
358 return;
359
360 bool remove = false;
361 for (AuraApplicationMap::iterator i = m_appliedAuras.begin(); i != m_appliedAuras.end(); ++i)
362 {
363 if (remove)
364 {
365 remove = false;
366 i = m_appliedAuras.begin();
367 }
368
369 if (aura->CanStackWith(i->second->GetBase()))
370 continue;
371
373 if (i == m_appliedAuras.end())
374 break;
375 remove = true;
376 }
377}
378
379void Unit::_RegisterAuraEffect(AuraEffect* aurEff, bool apply)
380{
381 if (apply)
382 m_modAuras[aurEff->GetAuraType()].push_back(aurEff);
383 else
384 m_modAuras[aurEff->GetAuraType()].remove(aurEff);
385}
386
387// All aura base removes should go threw this function!
388void Unit::RemoveOwnedAura(AuraMap::iterator& i, AuraRemoveMode removeMode)
389{
390 Aura* aura = i->second;
391 ASSERT(!aura->IsRemoved());
392
393 // if unit currently update aura list then make safe update iterator shift to next
394 if (m_auraUpdateIterator == i)
396
397 m_ownedAuras.erase(i);
398 m_removedAuras.push_back(aura);
399
400 // Unregister single target aura
401 if (aura->IsSingleTarget())
403
404 aura->_Remove(removeMode);
405
406 i = m_ownedAuras.begin();
407}
408
409void Unit::RemoveOwnedAura(uint32 spellId, uint64 casterGUID, uint32 reqEffMask, AuraRemoveMode removeMode)
410{
411 for (AuraMap::iterator itr = m_ownedAuras.lower_bound(spellId); itr != m_ownedAuras.upper_bound(spellId);)
412 if (((itr->second->GetEffectMask() & reqEffMask) == reqEffMask) && (!casterGUID || itr->second->GetCasterGUID() == casterGUID))
413 {
414 RemoveOwnedAura(itr, removeMode);
415 itr = m_ownedAuras.lower_bound(spellId);
416 }
417 else
418 ++itr;
419}
420
422{
423 if (aura->IsRemoved())
424 return;
425
426 ASSERT(aura->GetOwner() == this);
427
428 uint32 spellId = aura->GetId();
429 AuraMapBoundsNonConst range = m_ownedAuras.equal_range(spellId);
430
431 for (AuraMap::iterator itr = range.first; itr != range.second; ++itr)
432 {
433 if (itr->second == aura)
434 {
435 RemoveOwnedAura(itr, removeMode);
436 return;
437 }
438 }
439
440 ASSERT(false);
441}
442
443Aura* Unit::GetOwnedAura(uint32 spellId, uint64 casterGUID, uint64 itemCasterGUID, uint32 reqEffMask, Aura* except) const
444{
445 AuraMapBounds range = m_ownedAuras.equal_range(spellId);
446 for (AuraMap::const_iterator itr = range.first; itr != range.second; ++itr)
447 {
448 if (((itr->second->GetEffectMask() & reqEffMask) == reqEffMask)
449 && (!casterGUID || itr->second->GetCasterGUID() == casterGUID)
450 && (!itemCasterGUID || itr->second->GetCastItemGUID() == itemCasterGUID)
451 && (!except || except != itr->second))
452 {
453 return itr->second;
454 }
455 }
456 return NULL;
457}
458
459void Unit::RemoveAura(AuraApplicationMap::iterator& i, AuraRemoveMode mode)
460{
461 AuraApplication* aurApp = i->second;
462 // Do not remove aura which is already being removed
463 if (aurApp->GetRemoveMode())
464 return;
465 Aura* aura = aurApp->GetBase();
466 _UnapplyAura(i, mode);
467 // Remove aura - for Area and Target auras
468 if (aura->GetOwner() == this)
469 aura->Remove(mode);
470}
471
472void Unit::RemoveAura(uint32 spellId, uint64 caster, uint32 reqEffMask, AuraRemoveMode removeMode)
473{
474 AuraApplicationMapBoundsNonConst range = m_appliedAuras.equal_range(spellId);
475 for (AuraApplicationMap::iterator iter = range.first; iter != range.second;)
476 {
477 Aura const* aura = iter->second->GetBase();
478 if (((aura->GetEffectMask() & reqEffMask) == reqEffMask)
479 && (!caster || aura->GetCasterGUID() == caster))
480 {
481 RemoveAura(iter, removeMode);
482 return;
483 }
484 else
485 ++iter;
486 }
487}
488
490{
491 // we've special situation here, RemoveAura called while during aura removal
492 // this kind of call is needed only when aura effect removal handler
493 // or event triggered by it expects to remove
494 // not yet removed effects of an aura
495 if (aurApp->GetRemoveMode())
496 {
497 // remove remaining effects of an aura
498 for (uint32 itr = 0; itr < MAX_SPELL_EFFECTS; ++itr)
499 {
500 if (aurApp->HasEffect(itr))
501 aurApp->_HandleEffect(itr, false);
502 }
503 return;
504 }
505 // no need to remove
506 if (aurApp->GetBase()->GetApplicationOfTarget(GetGUID()) != aurApp || aurApp->GetBase()->IsRemoved())
507 return;
508
509 uint32 spellId = aurApp->GetBase()->GetId();
510 AuraApplicationMapBoundsNonConst range = m_appliedAuras.equal_range(spellId);
511
512 for (AuraApplicationMap::iterator iter = range.first; iter != range.second;)
513 {
514 if (aurApp == iter->second)
515 {
516 RemoveAura(iter, mode);
517 return;
518 }
519 else
520 ++iter;
521 }
522}
523
525{
526 if (aura->IsRemoved())
527 return;
528 if (AuraApplication* aurApp = aura->GetApplicationOfTarget(GetGUID()))
529 RemoveAura(aurApp, mode);
530}
531
532void Unit::RemoveAurasDueToSpell(uint32 spellId, uint64 casterGUID, uint32 reqEffMask, AuraRemoveMode removeMode)
533{
534 for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
535 {
536 Aura const* aura = iter->second->GetBase();
537 if (((aura->GetEffectMask() & reqEffMask) == reqEffMask)
538 && (!casterGUID || aura->GetCasterGUID() == casterGUID))
539 {
540 RemoveAura(iter, removeMode);
541 iter = m_appliedAuras.lower_bound(spellId);
542 }
543 else
544 ++iter;
545 }
546}
547
548void Unit::RemoveAuraFromStack(uint32 spellId, uint64 casterGUID, AuraRemoveMode removeMode)
549{
550 AuraMapBoundsNonConst range = m_ownedAuras.equal_range(spellId);
551 for (AuraMap::iterator iter = range.first; iter != range.second;)
552 {
553 Aura* aura = iter->second;
554 if ((aura->GetType() == UNIT_AURA_TYPE)
555 && (!casterGUID || aura->GetCasterGUID() == casterGUID))
556 {
557 aura->ModStackAmount(-1, removeMode);
558 return;
559 }
560 else
561 ++iter;
562 }
563}
564
565void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, uint64 casterGUID, Unit* dispeller, uint8 chargesRemoved/*= 1*/)
566{
567 AuraMapBoundsNonConst range = m_ownedAuras.equal_range(spellId);
568 for (AuraMap::iterator iter = range.first; iter != range.second;)
569 {
570 Aura* aura = iter->second;
571 if (aura->GetCasterGUID() == casterGUID)
572 {
573 DispelInfo dispelInfo(dispeller, dispellerSpellId, chargesRemoved);
574
575 // Call OnDispel hook on AuraScript
576 aura->CallScriptDispel(&dispelInfo);
577
580 else
582
583 // Call AfterDispel hook on AuraScript
584 aura->CallScriptAfterDispel(&dispelInfo);
585
586 return;
587 }
588 else
589 ++iter;
590 }
591}
592
593void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit* stealer)
594{
595 AuraMapBoundsNonConst range = m_ownedAuras.equal_range(spellId);
596 for (AuraMap::iterator iter = range.first; iter != range.second;)
597 {
598 Aura* aura = iter->second;
599 if (aura->GetCasterGUID() == casterGUID)
600 {
601 int32 damage[MAX_SPELL_EFFECTS] = { };
602 int32 baseDamage[MAX_SPELL_EFFECTS] = { };
603 uint32 effMask = 0;
604 uint32 recalculateMask = 0;
605 Unit* caster = aura->GetCaster();
606 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
607 {
608 if (aura->GetEffect(i))
609 {
610 baseDamage[i] = aura->GetEffect(i)->GetBaseAmount();
611 damage[i] = aura->GetEffect(i)->GetAmount();
612 effMask |= (1 << i);
613 if (aura->GetEffect(i)->CanBeRecalculated())
614 recalculateMask |= (1 << i);
615 }
616 else
617 {
618 baseDamage[i] = 0;
619 damage[i] = 0;
620 }
621 }
622
623 bool stealCharge = aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES;
624 // Cast duration to unsigned to prevent permanent aura's such as Righteous Fury being permanently added to caster
625 uint32 dur = std::min(2u * MINUTE * IN_MILLISECONDS, uint32(aura->GetDuration()));
626
627 if (Aura* oldAura = stealer->GetAura(aura->GetId(), aura->GetCasterGUID()))
628 {
629 if (stealCharge)
630 oldAura->ModCharges(1);
631 else
632 oldAura->ModStackAmount(1);
633 oldAura->SetDuration(int32(dur));
634 }
635 else
636 {
637 // single target state must be removed before aura creation to preserve existing single target aura
638 if (aura->IsSingleTarget())
640
641 if (Aura* newAura = Aura::TryRefreshStackOrCreate(aura->GetSpellInfo(), effMask, stealer, NULL, &baseDamage[0], NULL, aura->GetCasterGUID()))
642 {
643 // created aura must not be single target aura,, so stealer won't loose it on recast
644 if (newAura->IsSingleTarget())
645 {
646 newAura->UnregisterSingleTarget();
647 // bring back single target aura status to the old aura
648 aura->SetIsSingleTarget(true);
649 caster->GetSingleCastAuras().push_back(aura);
650 }
651 // FIXME: using aura->GetMaxDuration() maybe not blizzlike but it fixes stealing of spells like Innervate
652 newAura->SetLoadedState(aura->GetMaxDuration(), int32(dur), stealCharge ? 1 : aura->GetCharges(), 1, recalculateMask, &damage[0]);
653 newAura->ApplyForTargets();
654 }
655 }
656
657 if (stealCharge)
659 else
661
662 return;
663 }
664 else
665 ++iter;
666 }
667}
668
670{
671 for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
672 {
673 if (iter->second->GetBase()->GetCastItemGUID() == castItemGuid)
674 {
675 RemoveAura(iter);
676 iter = m_appliedAuras.lower_bound(spellId);
677 }
678 else
679 ++iter;
680 }
681}
682
683void Unit::RemoveAurasByType(AuraType auraType, uint64 casterGUID, Aura* except, bool negative, bool positive)
684{
685 for (AuraEffectList::iterator iter = m_modAuras[auraType].begin(); iter != m_modAuras[auraType].end();)
686 {
687 Aura* aura = (*iter)->GetBase();
689
690 ++iter;
691 if (aura != except && (!casterGUID || aura->GetCasterGUID() == casterGUID)
692 && ((negative && !aurApp->IsPositive()) || (positive && aurApp->IsPositive())))
693 {
694 uint32 removedAuras = m_removedAurasCount;
695 RemoveAura(aurApp);
696 if (m_removedAurasCount > removedAuras + 1)
697 iter = m_modAuras[auraType].begin();
698 }
699 }
700}
701
703{
704 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
705 {
706 SpellInfo const* spell = iter->second->GetBase()->GetSpellInfo();
707 if (spell->Attributes & flags)
708 RemoveAura(iter);
709 else
710 ++iter;
711 }
712}
713
714void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase, bool phaseid)
715{
716 // single target auras from other casters
717 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
718 {
719 AuraApplication const* aurApp = iter->second;
720 Aura const* aura = aurApp->GetBase();
721
722 if (aura->GetCasterGUID() != GetGUID() && aura->GetSpellInfo()->IsSingleTarget())
723 {
724 if (!newPhase && !phaseid)
725 RemoveAura(iter);
726 else
727 {
728 Unit* caster = aura->GetCaster();
729 if (!caster || (newPhase && !caster->InSamePhase(newPhase)) || (!newPhase && !caster->IsPhased(this)))
730 RemoveAura(iter);
731 else
732 ++iter;
733 }
734 }
735 else
736 ++iter;
737 }
738
739 // single target auras at other targets
740 AuraList& scAuras = GetSingleCastAuras();
741 for (AuraList::iterator iter = scAuras.begin(); iter != scAuras.end();)
742 {
743 Aura* aura = *iter;
744 if (aura->GetUnitOwner() != this && !aura->GetUnitOwner()->InSamePhase(newPhase))
745 {
746 aura->Remove();
747 iter = scAuras.begin();
748 }
749 else
750 ++iter;
751 }
752}
753
755{
756 if (!(m_interruptMask & flag))
757 return;
758
759 // interrupt auras
760 for (AuraApplicationList::iterator iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end();)
761 {
762 Aura* aura = (*iter)->GetBase();
763 ++iter;
764 if ((aura->GetSpellInfo()->AuraInterruptFlags & flag) && (!except || aura->GetId() != except)
766 {
767 uint32 removedAuras = m_removedAurasCount;
768 RemoveAura(aura);
769 if (m_removedAurasCount > removedAuras + 1)
770 iter = m_interruptableAuras.begin();
771 }
772 }
773
774 // interrupt channeled spell
776 if (spell->getState() == SPELL_STATE_CASTING
777 && (spell->m_spellInfo->ChannelInterruptFlags & flag)
778 && spell->m_spellInfo->Id != except
781
783}
784
785void Unit::RemoveAurasWithFamily(SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID)
786{
787 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
788 {
789 Aura const* aura = iter->second->GetBase();
790 if (!casterGUID || aura->GetCasterGUID() == casterGUID)
791 {
792 SpellInfo const* spell = aura->GetSpellInfo();
793 if (spell->SpellFamilyName == uint32(family) && spell->SpellFamilyFlags.HasFlag(familyFlag1, familyFlag2, familyFlag3))
794 {
795 RemoveAura(iter);
796 continue;
797 }
798 }
799 ++iter;
800 }
801}
802
807
808void Unit::RemoveAurasWithMechanic(uint32 mechanic_mask, AuraRemoveMode removemode, uint32 except)
809{
810 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
811 {
812 Aura const* aura = iter->second->GetBase();
813 if (!except || aura->GetId() != except)
814 {
815 if (aura->GetSpellInfo()->GetAllEffectsMechanicMask() & mechanic_mask)
816 {
817 RemoveAura(iter, removemode);
818 continue;
819 }
820 }
821 ++iter;
822 }
823}
824
826{
827 // make sure that all area auras not applied on self are removed - prevent access to deleted pointer later
828 for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
829 {
830 Aura* aura = iter->second;
831 ++iter;
832 Aura::ApplicationMap const& appMap = aura->GetApplicationMap();
833 for (Aura::ApplicationMap::const_iterator itr = appMap.begin(); itr != appMap.end();)
834 {
835 AuraApplication* aurApp = itr->second;
836 ++itr;
837 Unit* target = aurApp->GetTarget();
838 if (target == this)
839 continue;
840 target->RemoveAura(aurApp);
841 // things linked on aura remove may apply new area aura - so start from the beginning
842 iter = m_ownedAuras.begin();
843 }
844 }
845
846 // remove area auras owned by others
847 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
848 {
849 if (iter->second->GetBase()->GetOwner() != this)
850 {
851 RemoveAura(iter);
852 }
853 else
854 ++iter;
855 }
856}
857
859{
860 // this may be a dead loop if some events on aura remove will continiously apply aura on remove
861 // we want to have all auras removed, so use your brain when linking events
862 while (!m_appliedAuras.empty() || !m_ownedAuras.empty())
863 {
864 AuraApplicationMap::iterator aurAppIter;
865 for (aurAppIter = m_appliedAuras.begin(); aurAppIter != m_appliedAuras.end();)
867
868 AuraMap::iterator aurIter;
869 for (aurIter = m_ownedAuras.begin(); aurIter != m_ownedAuras.end();)
870 RemoveOwnedAura(aurIter);
871 }
872}
873
875{
876 // in join, remove positive buffs, on end, remove negative
877 // used to remove positive visible auras in arenas
878 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
879 {
880 AuraApplication const* aurApp = iter->second;
881 Aura const* aura = aurApp->GetBase();
882 if (!(aura->GetSpellInfo()->AttributesEx4 & SPELL_ATTR4_UNK21) // don't remove stances, shadowform, pally/hunter auras
883 && !aura->IsPassive() // don't remove passive auras
884 && (aurApp->IsPositive() || !(aura->GetSpellInfo()->AttributesEx3 & SPELL_ATTR3_DEATH_PERSISTENT))) // not negative death persistent auras
885 RemoveAura(iter);
886 else
887 ++iter;
888 }
889}
890
892{
893 // used just after dieing to remove all visible auras
894 // and disable the mods for the passive ones
895 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
896 {
897 Aura const* aura = iter->second->GetBase();
898 if (!aura->IsPassive() && !aura->IsDeathPersistent())
900 else
901 ++iter;
902 }
903
904 for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
905 {
906 Aura* aura = iter->second;
907 if (!aura->IsPassive() && !aura->IsDeathPersistent())
909 else
910 ++iter;
911 }
912}
913
915{
916 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
917 {
918 Aura const* aura = iter->second->GetBase();
919 if (!aura->IsPassive() && aura->GetSpellInfo()->IsRequiringDeadTarget())
921 else
922 ++iter;
923 }
924
925 for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
926 {
927 Aura* aura = iter->second;
928 if (!aura->IsPassive() && aura->GetSpellInfo()->IsRequiringDeadTarget())
930 else
931 ++iter;
932 }
933}
934
936{
937 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
938 {
939 Aura const* aura = iter->second->GetBase();
940 if (aura->GetSpellInfo()->HasAura(type))
941 ++iter;
942 else
944 }
945
946 for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
947 {
948 Aura* aura = iter->second;
949 if (aura->GetSpellInfo()->HasAura(type))
950 ++iter;
951 else
953 }
954}
955
957{
958 for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
959 {
960 Aura const* aura = iter->second->GetBase();
961 if (aura->GetSpellInfo()->HasAura(type1) || aura->GetSpellInfo()->HasAura(type2))
962 ++iter;
963 else
965 }
966
967 for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
968 {
969 Aura* aura = iter->second;
970 if (aura->GetSpellInfo()->HasAura(type1) || aura->GetSpellInfo()->HasAura(type2))
971 ++iter;
972 else
974 }
975}
976
977void Unit::DelayOwnedAuras(uint32 spellId, uint64 caster, int32 delaytime)
978{
979 AuraMapBoundsNonConst range = m_ownedAuras.equal_range(spellId);
980 for (; range.first != range.second; ++range.first)
981 {
982 Aura* aura = range.first->second;
983 if (!caster || aura->GetCasterGUID() == caster)
984 {
985 if (aura->GetDuration() < delaytime)
986 aura->SetDuration(0);
987 else
988 aura->SetDuration(aura->GetDuration() - delaytime);
989
990 // update for out of range group members (on 1 slot use)
992 SF_LOG_DEBUG("spells", "Aura %u partially interrupted on unit %u, new duration: %u ms", aura->GetId(), GetGUIDLow(), aura->GetDuration());
993 }
994 }
995}
996
998{
999 for (AuraApplicationMap::iterator i = m_appliedAuras.begin(); i != m_appliedAuras.end(); ++i)
1000 (*i).second->GetBase()->HandleAllEffects(i->second, AURA_EFFECT_HANDLE_STAT, false);
1001}
1002
1004{
1005 for (AuraApplicationMap::iterator i = m_appliedAuras.begin(); i != m_appliedAuras.end(); ++i)
1006 (*i).second->GetBase()->HandleAllEffects(i->second, AURA_EFFECT_HANDLE_STAT, true);
1007}
1008
1009AuraEffect* Unit::GetAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster) const
1010{
1011 AuraApplicationMapBounds range = m_appliedAuras.equal_range(spellId);
1012 for (AuraApplicationMap::const_iterator itr = range.first; itr != range.second; ++itr)
1013 {
1014 if (itr->second->HasEffect(effIndex)
1015 && (!caster || itr->second->GetBase()->GetCasterGUID() == caster))
1016 {
1017 return itr->second->GetBase()->GetEffect(effIndex);
1018 }
1019 }
1020 return NULL;
1021}
1022
1024{
1025 uint32 rankSpell = sSpellMgr->GetFirstSpellInChain(spellId);
1026 while (rankSpell)
1027 {
1028 if (AuraEffect* aurEff = GetAuraEffect(rankSpell, effIndex, caster))
1029 return aurEff;
1030 rankSpell = sSpellMgr->GetNextSpellInChain(rankSpell);
1031 }
1032 return NULL;
1033}
1034
1036{
1037 AuraEffectList const& auras = GetAuraEffectsByType(type);
1038 for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
1039 {
1040 if (effIndex != (*itr)->GetEffIndex())
1041 continue;
1042 SpellInfo const* spell = (*itr)->GetSpellInfo();
1043 if (spell->SpellIconID == iconId && spell->SpellFamilyName == uint32(name) && !spell->SpellFamilyFlags)
1044 return *itr;
1045 }
1046 return NULL;
1047}
1048
1049AuraEffect* Unit::GetAuraEffect(AuraType type, SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID) const
1050{
1051 AuraEffectList const& auras = GetAuraEffectsByType(type);
1052 for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
1053 {
1054 SpellInfo const* spell = (*i)->GetSpellInfo();
1055 if (spell->SpellFamilyName == uint32(family) && spell->SpellFamilyFlags.HasFlag(familyFlag1, familyFlag2, familyFlag3))
1056 {
1057 if (casterGUID && (*i)->GetCasterGUID() != casterGUID)
1058 continue;
1059 return (*i);
1060 }
1061 }
1062 return NULL;
1063}
1064
1066{
1067 return GetAuraEffect(SPELL_AURA_DUMMY, name, iconId, effIndex);
1068}
1069
1070AuraApplication* Unit::GetAuraApplication(uint32 spellId, uint64 casterGUID, uint64 itemCasterGUID, uint32 reqEffMask, AuraApplication* except) const
1071{
1072 AuraApplicationMapBounds range = m_appliedAuras.equal_range(spellId);
1073 for (; range.first != range.second; ++range.first)
1074 {
1075 AuraApplication* app = range.first->second;
1076 Aura const* aura = app->GetBase();
1077
1078 if (((aura->GetEffectMask() & reqEffMask) == reqEffMask)
1079 && (!casterGUID || aura->GetCasterGUID() == casterGUID)
1080 && (!itemCasterGUID || aura->GetCastItemGUID() == itemCasterGUID)
1081 && (!except || except != app))
1082 {
1083 return app;
1084 }
1085 }
1086 return NULL;
1087}
1088
1089Aura* Unit::GetAura(uint32 spellId, uint64 casterGUID, uint64 itemCasterGUID, uint32 reqEffMask) const
1090{
1091 AuraApplication* aurApp = GetAuraApplication(spellId, casterGUID, itemCasterGUID, reqEffMask);
1092 return aurApp ? aurApp->GetBase() : NULL;
1093}
1094
1095AuraApplication* Unit::GetAuraApplicationOfRankedSpell(uint32 spellId, uint64 casterGUID, uint64 itemCasterGUID, uint32 reqEffMask, AuraApplication* except) const
1096{
1097 uint32 rankSpell = sSpellMgr->GetFirstSpellInChain(spellId);
1098 while (rankSpell)
1099 {
1100 if (AuraApplication* aurApp = GetAuraApplication(rankSpell, casterGUID, itemCasterGUID, reqEffMask, except))
1101 return aurApp;
1102 rankSpell = sSpellMgr->GetNextSpellInChain(rankSpell);
1103 }
1104 return NULL;
1105}
1106
1107Aura* Unit::GetAuraOfRankedSpell(uint32 spellId, uint64 casterGUID, uint64 itemCasterGUID, uint32 reqEffMask) const
1108{
1109 AuraApplication* aurApp = GetAuraApplicationOfRankedSpell(spellId, casterGUID, itemCasterGUID, reqEffMask);
1110 return aurApp ? aurApp->GetBase() : NULL;
1111}
1112
1113void Unit::GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList)
1114{
1115 // we should not be able to dispel diseases if the target is affected by unholy blight
1116 if (dispelMask & (1 << DISPEL_DISEASE) && HasAura(50536))
1117 dispelMask &= ~(1 << DISPEL_DISEASE);
1118
1119 AuraMap const& auras = GetOwnedAuras();
1120 for (AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
1121 {
1122 Aura* aura = itr->second;
1124 if (!aurApp)
1125 continue;
1126
1127 // don't try to remove passive auras
1128 if (aura->IsPassive())
1129 continue;
1130
1131 if (aura->GetSpellInfo()->GetDispelMask() & dispelMask)
1132 {
1133 if (aura->GetSpellInfo()->Dispel == DISPEL_MAGIC)
1134 {
1135 // do not remove positive auras if friendly target
1136 // negative auras if non-friendly target
1137 if (aurApp->IsPositive() == IsFriendlyTo(caster))
1138 continue;
1139 }
1140
1141 // The charges / stack amounts don't count towards the total number of auras that can be dispelled.
1142 // Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
1143 // Polymorph instead of 1 / (5 + 1) -> 16%.
1144 bool dispel_charges = aura->GetSpellInfo()->AttributesEx7 & SPELL_ATTR7_DISPEL_CHARGES;
1145 uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
1146 if (charges > 0)
1147 dispelList.push_back(std::make_pair(aura, charges));
1148 }
1149 }
1150}
1151
1152bool Unit::HasAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster) const
1153{
1154 AuraApplicationMapBounds range = m_appliedAuras.equal_range(spellId);
1155 for (AuraApplicationMap::const_iterator itr = range.first; itr != range.second; ++itr)
1156 {
1157 if (itr->second->HasEffect(effIndex)
1158 && (!caster || itr->second->GetBase()->GetCasterGUID() == caster))
1159 {
1160 return true;
1161 }
1162 }
1163 return false;
1164}
1165
1167{
1168 uint32 count = 0;
1169 AuraApplicationMapBounds range = m_appliedAuras.equal_range(spellId);
1170
1171 for (AuraApplicationMap::const_iterator itr = range.first; itr != range.second; ++itr)
1172 {
1173 if (itr->second->GetBase()->GetStackAmount() == 0)
1174 ++count;
1175 else
1176 count += (uint32)itr->second->GetBase()->GetStackAmount();
1177 }
1178
1179 return count;
1180}
1181
1182bool Unit::HasAura(uint32 spellId, uint64 casterGUID, uint64 itemCasterGUID, uint32 reqEffMask) const
1183{
1184 if (GetAuraApplication(spellId, casterGUID, itemCasterGUID, reqEffMask))
1185 return true;
1186 return false;
1187}
1188
1189bool Unit::HasAuraType(AuraType auraType) const
1190{
1191 return (!m_modAuras[auraType].empty());
1192}
1193
1194bool Unit::HasAuraTypeWithCaster(AuraType auratype, uint64 caster) const
1195{
1196 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1197 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1198 if (caster == (*i)->GetCasterGUID())
1199 return true;
1200 return false;
1201}
1202
1203bool Unit::HasAuraTypeWithMiscvalue(AuraType auratype, int32 miscvalue) const
1204{
1205 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1206 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1207 if (miscvalue == (*i)->GetMiscValue())
1208 return true;
1209 return false;
1210}
1211
1212bool Unit::HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const* affectedSpell) const
1213{
1214 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1215 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1216 if ((*i)->IsAffectingSpell(affectedSpell))
1217 return true;
1218 return false;
1219}
1220
1221bool Unit::HasAuraTypeWithValue(AuraType auratype, int32 value) const
1222{
1223 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1224 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1225 if (value == (*i)->GetAmount())
1226 return true;
1227 return false;
1228}
1229
1231{
1232 if (!(m_interruptMask & flag))
1233 return false;
1234 for (AuraApplicationList::const_iterator iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end(); ++iter)
1235 {
1236 if (!(*iter)->IsPositive() && (*iter)->GetBase()->GetSpellInfo()->AuraInterruptFlags & flag && (!guid || (*iter)->GetBase()->GetCasterGUID() == guid))
1237 return true;
1238 }
1239 return false;
1240}
1241
1243{
1244 for (AuraApplicationMap::const_iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end(); ++iter)
1245 {
1246 Aura const* aura = iter->second->GetBase();
1247 if (!iter->second->IsPositive() && aura->GetSpellInfo()->Attributes & flag && (!guid || aura->GetCasterGUID() == guid))
1248 return true;
1249 }
1250 return false;
1251}
1252
1253bool Unit::HasAuraWithMechanic(uint32 mechanicMask) const
1254{
1255 for (AuraApplicationMap::const_iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end(); ++iter)
1256 {
1257 SpellInfo const* spellInfo = iter->second->GetBase()->GetSpellInfo();
1258 if (spellInfo->Mechanic && (mechanicMask & (1 << spellInfo->Mechanic)))
1259 return true;
1260
1261 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1262 if (iter->second->HasEffect(i) && spellInfo->Effects[i].Effect && spellInfo->Effects[i].Mechanic)
1263 if (mechanicMask & (1 << spellInfo->Effects[i].Mechanic))
1264 return true;
1265 }
1266
1267 return false;
1268}
1269
1271{
1273 for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
1274 {
1275 if ((*i)->GetMiscValue() == script)
1276 if ((*i)->IsAffectingSpell(spell))
1277 return (*i);
1278 }
1279 return NULL;
1280}
1281
1283{
1284 static const AuraType diseaseAuraTypes[] =
1285 {
1286 SPELL_AURA_PERIODIC_DAMAGE, // Frost Fever and Blood Plague
1287 SPELL_AURA_LINKED, // Crypt Fever and Ebon Plague
1289 };
1290
1291 uint32 diseases = 0;
1292 for (AuraType const* itr = diseaseAuraTypes; *itr != SPELL_AURA_NONE; ++itr)
1293 {
1294 for (AuraEffectList::iterator i = m_modAuras[*itr].begin(); i != m_modAuras[*itr].end();)
1295 {
1296 // Get auras with disease dispel type by caster
1297 if ((*i)->GetSpellInfo()->Dispel == DISPEL_DISEASE
1298 && (*i)->GetCasterGUID() == casterGUID)
1299 {
1300 ++diseases;
1301
1302 if (remove)
1303 {
1304 RemoveAura((*i)->GetId(), (*i)->GetCasterGUID());
1305 i = m_modAuras[*itr].begin();
1306 continue;
1307 }
1308 }
1309 ++i;
1310 }
1311 }
1312 return diseases;
1313}
1314
1316{
1317 static const AuraType diseaseAuraTypes[] =
1318 {
1322 };
1323
1324 uint32 dots = 0;
1325 for (AuraType const* itr = &diseaseAuraTypes[0]; itr && itr[0] != SPELL_AURA_NONE; ++itr)
1326 {
1327 Unit::AuraEffectList const& auras = GetAuraEffectsByType(*itr);
1328 for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
1329 {
1330 // Get auras by caster
1331 if ((*i)->GetCasterGUID() == casterGUID)
1332 ++dots;
1333 }
1334 }
1335 return dots;
1336}
1337
1339{
1340 std::map<SpellGroup, int32> SameEffectSpellGroup;
1341 int32 modifier = 0;
1342
1343 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1344 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1345 if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup))
1346 modifier += (*i)->GetAmount();
1347
1348 for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr)
1349 modifier += itr->second;
1350
1351 return modifier;
1352}
1353
1355{
1356 float multiplier = 1.0f;
1357
1358 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1359 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1360 AddPct(multiplier, (*i)->GetAmount());
1361
1362 return multiplier;
1363}
1364
1366{
1367 int32 modifier = 0;
1368
1369 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1370 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1371 {
1372 if ((*i)->GetAmount() > modifier)
1373 modifier = (*i)->GetAmount();
1374 }
1375
1376 return modifier;
1377}
1378
1380{
1381 int32 modifier = 0;
1382
1383 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1384 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1385 if ((*i)->GetAmount() < modifier)
1386 modifier = (*i)->GetAmount();
1387
1388 return modifier;
1389}
1390
1392{
1393 std::map<SpellGroup, int32> SameEffectSpellGroup;
1394 int32 modifier = 0;
1395
1396 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1397
1398 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1399 if ((*i)->GetMiscValue() & miscMask)
1400 if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup))
1401 modifier += (*i)->GetAmount();
1402
1403 for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr)
1404 modifier += itr->second;
1405
1406 return modifier;
1407}
1408
1410{
1411 std::map<SpellGroup, int32> SameEffectSpellGroup;
1412 float multiplier = 1.0f;
1413
1414 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1415 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1416 {
1417 if (((*i)->GetMiscValue() & miscMask))
1418 {
1419 // Check if the Aura Effect has a the Same Effect Stack Rule and if so, use the highest amount of that SpellGroup
1420 // If the Aura Effect does not have this Stack Rule, it returns false so we can add to the multiplier as usual
1421 if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup))
1422 AddPct(multiplier, (*i)->GetAmount());
1423 }
1424 }
1425 // Add the highest of the Same Effect Stack Rule SpellGroups to the multiplier
1426 for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr)
1427 AddPct(multiplier, itr->second);
1428
1429 return multiplier;
1430}
1431
1433{
1434 int32 modifier = 0;
1435
1436 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1437 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1438 {
1439 if (except != (*i) && (*i)->GetMiscValue() & miscMask && (*i)->GetAmount() > modifier)
1440 modifier = (*i)->GetAmount();
1441 }
1442
1443 return modifier;
1444}
1445
1447{
1448 int32 modifier = 0;
1449
1450 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1451 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1452 {
1453 if ((*i)->GetMiscValue() & miscMask && (*i)->GetAmount() < modifier)
1454 modifier = (*i)->GetAmount();
1455 }
1456
1457 return modifier;
1458}
1459
1461{
1462 std::map<SpellGroup, int32> SameEffectSpellGroup;
1463 int32 modifier = 0;
1464
1465 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1466 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1467 {
1468 if ((*i)->GetMiscValue() == miscValue)
1469 if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup))
1470 modifier += (*i)->GetAmount();
1471 }
1472
1473 for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr)
1474 modifier += itr->second;
1475
1476 return modifier;
1477}
1478
1480{
1481 std::map<SpellGroup, int32> SameEffectSpellGroup;
1482 float multiplier = 1.0f;
1483
1484 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1485 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1486 {
1487 if ((*i)->GetMiscValue() == miscValue)
1488 if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup))
1489 AddPct(multiplier, (*i)->GetAmount());
1490 }
1491
1492 for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr)
1493 AddPct(multiplier, itr->second);
1494
1495 return multiplier;
1496}
1497
1499{
1500 int32 modifier = 0;
1501
1502 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1503 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1504 {
1505 if ((*i)->GetMiscValue() == miscValue && (*i)->GetAmount() > modifier)
1506 modifier = (*i)->GetAmount();
1507 }
1508
1509 return modifier;
1510}
1511
1513{
1514 int32 modifier = 0;
1515
1516 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1517 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1518 {
1519 if ((*i)->GetMiscValue() == miscValue && (*i)->GetAmount() < modifier)
1520 modifier = (*i)->GetAmount();
1521 }
1522
1523 return modifier;
1524}
1525
1527{
1528 std::map<SpellGroup, int32> SameEffectSpellGroup;
1529 int32 modifier = 0;
1530
1531 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1532 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1533 {
1534 if ((*i)->IsAffectingSpell(affectedSpell))
1535 if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup))
1536 modifier += (*i)->GetAmount();
1537 }
1538
1539 for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr)
1540 modifier += itr->second;
1541
1542 return modifier;
1543}
1544
1545float Unit::GetTotalAuraMultiplierByAffectMask(AuraType auratype, SpellInfo const* affectedSpell) const
1546{
1547 std::map<SpellGroup, int32> SameEffectSpellGroup;
1548 float multiplier = 1.0f;
1549
1550 AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
1551 for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
1552 {
1553 if ((*i)->IsAffectingSpell(affectedSpell))
1554 if (!sSpellMgr->AddSameEffectStackRuleSpellGroups((*i)->GetSpellInfo(), (*i)->GetAmount(), SameEffectSpellGroup))
1555 AddPct(multiplier, (*i)->GetAmount());
1556 }
1557
1558 for (std::map<SpellGroup, int32>::const_iterator itr = SameEffectSpellGroup.begin(); itr != SameEffectSpellGroup.end(); ++itr)
1559 AddPct(multiplier, itr->second);
1560
1561 return multiplier;
1562}
1563
1565{
1566 if (apply)
1567 {
1568 if (!HasFlag(UNIT_FIELD_AURA_STATE, 1 << (flag - 1)))
1569 {
1570 SetFlag(UNIT_FIELD_AURA_STATE, 1 << (flag - 1));
1572 {
1573 PlayerSpellMap const& sp_list = ToPlayer()->GetSpellMap();
1574 for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
1575 {
1576 if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->disabled)
1577 continue;
1578 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
1579 if (!spellInfo || !spellInfo->IsPassive())
1580 continue;
1581 if (spellInfo->CasterAuraState == uint32(flag))
1582 CastSpell(this, itr->first, true, NULL);
1583 }
1584 }
1585 else if (Pet* pet = ToCreature()->ToPet())
1586 {
1587 for (PetSpellMap::const_iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr)
1588 {
1589 if (itr->second.state == PETSPELL_REMOVED)
1590 continue;
1591 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(itr->first);
1592 if (!spellInfo || !spellInfo->IsPassive())
1593 continue;
1594 if (spellInfo->CasterAuraState == uint32(flag))
1595 CastSpell(this, itr->first, true, NULL);
1596 }
1597 }
1598 }
1599 }
1600 else
1601 {
1602 if (HasFlag(UNIT_FIELD_AURA_STATE, 1 << (flag - 1)))
1603 {
1604 RemoveFlag(UNIT_FIELD_AURA_STATE, 1 << (flag - 1));
1605
1606 if (flag != AURA_STATE_ENRAGE) // enrage aura state triggering continues auras
1607 {
1609 for (Unit::AuraApplicationMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
1610 {
1611 SpellInfo const* spellProto = (*itr).second->GetBase()->GetSpellInfo();
1612 if (spellProto->CasterAuraState == uint32(flag))
1613 RemoveAura(itr);
1614 else
1615 ++itr;
1616 }
1617 }
1618 }
1619 }
1620}
1621
1623{
1625 for (AuraStateAurasMap::const_iterator itr = m_auraStateAuras.begin(); itr != m_auraStateAuras.end(); ++itr)
1626 if ((1 << (itr->first - 1)) & PER_CASTER_AURA_STATE_MASK)
1627 if (itr->second->GetBase()->GetCasterGUID() == target->GetGUID())
1628 auraStates |= (1 << (itr->first - 1));
1629
1630 return auraStates;
1631}
1632
1633bool Unit::HasAuraState(AuraStateType flag, SpellInfo const* spellProto, Unit const* Caster) const
1634{
1635 if (Caster)
1636 {
1637 if (spellProto)
1638 {
1640 for (AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
1641 if ((*j)->IsAffectingSpell(spellProto))
1642 return true;
1643 }
1644 // Check per caster aura state
1645 // If aura with aurastate by caster not found return false
1646 if ((1 << (flag - 1)) & PER_CASTER_AURA_STATE_MASK)
1647 {
1648 AuraStateAurasMapBounds range = m_auraStateAuras.equal_range(flag);
1649 for (AuraStateAurasMap::const_iterator itr = range.first; itr != range.second; ++itr)
1650 if (itr->second->GetBase()->GetCasterGUID() == Caster->GetGUID())
1651 return true;
1652 return false;
1653 }
1654 }
1655
1656 return HasFlag(UNIT_FIELD_AURA_STATE, 1 << (flag - 1));
1657}
1658
1659float Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32& duration, Unit* caster, DiminishingLevels Level, int32 limitduration)
1660{
1661 if (duration == -1 || group == DiminishingGroup::DIMINISHING_NONE)
1662 return 1.0f;
1663
1664 // test pet/charm masters instead pets/charmeds
1665 Unit const* tarGetOwner = GetCharmerOrOwner();
1666 Unit const* casterOwner = caster->GetCharmerOrOwner();
1667
1668 // Duration of crowd control abilities on pvp target is limited by 10 sec. (2.2.0)
1669 if (limitduration > 0 && duration > limitduration)
1670 {
1671 Unit const* target = tarGetOwner ? tarGetOwner : this;
1672 Unit const* source = casterOwner ? casterOwner : caster;
1673
1674 if ((target->GetTypeId() == TypeID::TYPEID_PLAYER
1675 || ((Creature*)target)->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH)
1676 && source->GetTypeId() == TypeID::TYPEID_PLAYER)
1677 duration = limitduration;
1678 }
1679
1680 float mod = 1.0f;
1681
1683 {
1684 if (GetTypeId() == TypeID::TYPEID_UNIT && (ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_TAUNT_DIMINISH))
1685 {
1686 DiminishingLevels diminish = Level;
1687 switch (diminish)
1688 {
1689 case DIMINISHING_LEVEL_1: break;
1690 case DIMINISHING_LEVEL_2: mod = 0.65f; break;
1691 case DIMINISHING_LEVEL_3: mod = 0.4225f; break;
1692 case DIMINISHING_LEVEL_4: mod = 0.274625f; break;
1693 case DIMINISHING_LEVEL_TAUNT_IMMUNE: mod = 0.0f; break;
1694 default: break;
1695 }
1696 }
1697 }
1698 // Some diminishings applies to mobs too (for example, Stun)
1700 && ((tarGetOwner ? (tarGetOwner->GetTypeId() == TypeID::TYPEID_PLAYER) : (GetTypeId() == TypeID::TYPEID_PLAYER))
1701 || (GetTypeId() == TypeID::TYPEID_UNIT && ToCreature()->GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_ALL_DIMINISH)))
1703 {
1704 DiminishingLevels diminish = Level;
1705 switch (diminish)
1706 {
1707 case DIMINISHING_LEVEL_1: break;
1708 case DIMINISHING_LEVEL_2: mod = 0.5f; break;
1709 case DIMINISHING_LEVEL_3: mod = 0.25f; break;
1710 case DIMINISHING_LEVEL_IMMUNE: mod = 0.0f; break;
1711 default: break;
1712 }
1713 }
1714
1715 duration = int32(duration * mod);
1716 return mod;
1717}
1718
1720{
1721 // Checking for existing in the table
1722 for (Diminishing::iterator i = m_Diminishing.begin(); i != m_Diminishing.end(); ++i)
1723 {
1724 if (i->DRGroup != group)
1725 continue;
1726
1727 if (apply)
1728 i->stack += 1;
1729 else if (i->stack)
1730 {
1731 i->stack -= 1;
1732 // Remember time after last aura from group removed
1733 if (i->stack == 0)
1734 i->hitTime = getMSTime();
1735 }
1736 break;
1737 }
1738}
1739
1741{
1742 if (unitMod >= UNIT_MOD_END)
1743 {
1744 SF_LOG_ERROR("entities.unit", "attempt to access non-existing UnitMods in GetTotalAuraModValue()!");
1745 return 0.0f;
1746 }
1747
1748 if (m_auraModifiersGroup[unitMod][TOTAL_PCT] <= 0.0f)
1749 return 0.0f;
1750
1751 float value = m_auraModifiersGroup[unitMod][BASE_VALUE];
1752 value *= m_auraModifiersGroup[unitMod][BASE_PCT];
1753 value += m_auraModifiersGroup[unitMod][TOTAL_VALUE];
1754 value *= m_auraModifiersGroup[unitMod][TOTAL_PCT];
1755
1756 return value;
1757}
1758
1760{
1761 if (slot >= MAX_AURAS) // slot not found, return
1762 return;
1763 if (Player* player = ToPlayer())
1764 {
1765 if (player->GetGroup())
1766 {
1767 player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_AURAS);
1768 player->SetAuraUpdateMaskForRaid(slot);
1769 }
1770 }
1771 else if (GetTypeId() == TypeID::TYPEID_UNIT && ToCreature()->IsPet())
1772 {
1773 Pet* pet = ((Pet*)this);
1774 if (pet->isControlled())
1775 {
1776 Unit* owner = GetOwner();
1777 if (owner && (owner->GetTypeId() == TypeID::TYPEID_PLAYER) && owner->ToPlayer()->GetGroup())
1778 {
1780 pet->SetAuraUpdateMaskForRaid(slot);
1781 }
1782 }
1783 }
1784}
1785
1786Aura* Unit::AddAura(uint32 spellId, Unit* target)
1787{
1788 if (!target)
1789 return NULL;
1790
1791 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
1792 if (!spellInfo)
1793 return NULL;
1794
1795 if (!target->IsAlive() && !(spellInfo->Attributes & SPELL_ATTR0_PASSIVE) && !(spellInfo->AttributesEx2 & SPELL_ATTR2_CAN_TARGET_DEAD))
1796 return NULL;
1797
1798 return AddAura(spellInfo, MAX_EFFECT_MASK, target);
1799}
1800
1801Aura* Unit::AddAura(SpellInfo const* spellInfo, uint32 effMask, Unit* target)
1802{
1803 if (!spellInfo)
1804 return NULL;
1805
1806 if (target->IsImmunedToSpell(spellInfo))
1807 return NULL;
1808
1809 for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
1810 {
1811 if (!(effMask & (1 << i)))
1812 continue;
1813
1814 if (target->IsImmunedToSpellEffect(spellInfo, i))
1815 effMask &= ~(1 << i);
1816 }
1817
1818 if (Aura* aura = Aura::TryRefreshStackOrCreate(spellInfo, effMask, target, this))
1819 {
1820 aura->ApplyForTargets();
1821 return aura;
1822 }
1823 return NULL;
1824}
1825
1826void Unit::SetAuraStack(uint32 spellId, Unit* target, uint32 stack)
1827{
1828 Aura* aura = target->GetAura(spellId, GetGUID());
1829 if (!aura)
1830 aura = AddAura(spellId, target);
1831 if (aura && stack)
1832 aura->SetStackAmount(stack);
1833}
@ IN_MILLISECONDS
Definition Common.h:125
@ MINUTE
Definition Common.h:119
@ CREATURE_FLAG_EXTRA_TAUNT_DIMINISH
Definition Creature.h:42
@ CREATURE_FLAG_EXTRA_ALL_DIMINISH
Definition Creature.h:43
#define MAX_EFFECT_MASK
#define MAX_SPELL_EFFECTS
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
std::uint64_t uint64
Definition Define.h:76
#define ASSERT
Definition Errors.h:29
@ GROUP_UPDATE_FLAG_PET_AURAS
Definition Group.h:97
@ GROUP_UPDATE_FLAG_AURAS
Definition Group.h:87
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
@ TYPEID_PLAYER
Definition Object.h:55
@ TYPEID_UNIT
Definition Object.h:54
@ PETSPELL_REMOVED
Definition PetDefines.h:33
UNORDERED_MAP< uint32, PlayerSpell * > PlayerSpellMap
Definition Player.h:199
@ PLAYERSPELL_REMOVED
Definition Player.h:95
@ SPELL_ATTR0_PASSIVE
DiminishingGroup
@ SPELL_ATTR7_DISPEL_CHARGES
@ SPELL_ATTR2_CAN_TARGET_DEAD
@ SPELL_ATTR4_UNK21
#define PER_CASTER_AURA_STATE_MASK
@ SPELL_ATTR3_DEATH_PERSISTENT
SpellFamilyNames
DiminishingLevels
@ DIMINISHING_LEVEL_3
@ DIMINISHING_LEVEL_1
@ DIMINISHING_LEVEL_4
@ DIMINISHING_LEVEL_IMMUNE
@ DIMINISHING_LEVEL_TAUNT_IMMUNE
@ DIMINISHING_LEVEL_2
AuraStateType
@ AURA_STATE_ENRAGE
@ DRTYPE_PLAYER
@ DRTYPE_ALL
@ MECHANIC_ROOT
@ MECHANIC_SNARE
@ DISPEL_MAGIC
@ DISPEL_DISEASE
@ SPELL_STATE_CASTING
Definition Spell.h:266
#define MAX_AURAS
@ SPELL_AURA_PERIODIC_DAMAGE
@ SPELL_AURA_ABILITY_IGNORE_AURASTATE
@ SPELL_AURA_LINKED
@ SPELL_AURA_CAST_WHILE_WALKING
@ SPELL_AURA_CONTROL_VEHICLE
@ SPELL_AURA_PERIODIC_DAMAGE_PERCENT
@ SPELL_AURA_DUMMY
@ SPELL_AURA_NONE
@ SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
@ AURA_EFFECT_HANDLE_STAT
@ UNIT_AURA_TYPE
@ SPELL_ATTR0_CU_ENCHANT_PROC
Definition SpellInfo.h:65
DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group)
Definition SpellMgr.cpp:205
#define sSpellMgr
Definition SpellMgr.h:744
uint32 getMSTime()
Definition Timer.h:12
@ TOTEM_PASSIVE
Definition Totem.h:13
@ AURA_INTERRUPT_FLAG_MOVE
Definition Unit.h:44
@ AURA_INTERRUPT_FLAG_NOT_SEATED
Definition Unit.h:59
UnitMods
Definition Unit.h:439
@ UNIT_MOD_END
Definition Unit.h:475
@ JUST_DIED
Definition Unit.h:504
@ UNIT_STAND_STATE_SIT
Definition Unit.h:163
AuraRemoveMode
Definition Unit.h:405
@ AURA_REMOVE_BY_DEFAULT
Definition Unit.h:407
@ AURA_REMOVE_BY_DEATH
Definition Unit.h:411
@ AURA_REMOVE_BY_EXPIRE
Definition Unit.h:410
@ AURA_REMOVE_BY_ENEMY_SPELL
Definition Unit.h:409
@ BASE_VALUE
Definition Unit.h:384
@ TOTAL_VALUE
Definition Unit.h:386
@ TOTAL_PCT
Definition Unit.h:387
@ BASE_PCT
Definition Unit.h:385
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:1110
std::list< std::pair< Aura *, uint8 > > DispelChargesList
Definition Unit.h:371
@ UNIT_FIELD_AURA_STATE
T AddPct(T &base, U pct)
Definition Util.h:109
Unit * GetTarget() const
Definition SpellAuras.h:54
void SetRemoveMode(AuraRemoveMode mode)
Definition SpellAuras.h:65
bool IsPositive() const
Definition SpellAuras.h:61
void _HandleEffect(uint8 effIndex, bool apply)
Aura * GetBase() const
Definition SpellAuras.h:55
bool HasEffect(uint32 effect) const
Definition SpellAuras.h:60
uint32 GetEffectMask() const
Definition SpellAuras.h:59
AuraRemoveMode GetRemoveMode() const
Definition SpellAuras.h:66
AuraType GetAuraType() const
bool CanBeRecalculated() const
int32 GetMiscValue() const
int32 GetBaseAmount() const
int32 GetAmount() const
virtual void _UnapplyForTarget(Unit *target, Unit *caster, AuraApplication *auraApp)
uint64 GetCasterGUID() const
Definition SpellAuras.h:91
const AuraApplication * GetApplicationOfTarget(uint64 guid) const
Definition SpellAuras.h:176
int32 GetMaxDuration() const
Definition SpellAuras.h:115
uint64 GetCastItemGUID() const
Definition SpellAuras.h:90
bool ModStackAmount(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
void CallScriptDispel(DispelInfo *dispelInfo)
ApplicationMap const & GetApplicationMap()
Definition SpellAuras.h:174
void SetStackAmount(uint8 num)
Unit * GetUnitOwner() const
Definition SpellAuras.h:94
bool HasEffect(uint8 effIndex) const
Definition SpellAuras.h:166
bool IsRemoved() const
Definition SpellAuras.h:154
WorldObject * GetOwner() const
Definition SpellAuras.h:93
bool IsSingleTargetWith(Aura const *aura) const
bool ModCharges(int32 num, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
bool CanStackWith(Aura const *existingAura) const
uint32 GetId() const
Definition SpellAuras.h:88
std::map< uint64, AuraApplication * > ApplicationMap
Definition SpellAuras.h:77
int32 GetDuration() const
Definition SpellAuras.h:119
void UnregisterSingleTarget()
bool IsDeathPersistent() const
bool HasEffectType(AuraType type) const
AuraEffect * GetEffect(uint8 effIndex) const
Definition SpellAuras.h:168
Unit * GetCaster() const
static Aura * TryRefreshStackOrCreate(SpellInfo const *spellproto, uint32 tryEffMask, WorldObject *owner, Unit *caster, int32 *baseAmount=NULL, Item *castItem=NULL, uint64 casterGUID=0, bool *refresh=NULL)
void SetNeedClientUpdateForTargets() const
void SetDuration(int32 duration, bool withMods=false)
AuraObjectType GetType() const
uint8 GetStackAmount() const
Definition SpellAuras.h:133
uint8 GetCharges() const
Definition SpellAuras.h:126
SpellInfo const * GetSpellInfo() const
Definition SpellAuras.h:87
uint32 GetEffectMask() const
Definition SpellAuras.h:169
void HandleAuraSpecificMods(AuraApplication const *aurApp, Unit *caster, bool apply, bool onReapply)
void SetIsSingleTarget(bool val)
Definition SpellAuras.h:159
virtual void _ApplyForTarget(Unit *target, Unit *caster, AuraApplication *auraApp)
bool IsAppliedOnTarget(uint64 guid) const
Definition SpellAuras.h:178
bool IsPassive() const
virtual void Remove(AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)=0
void CallScriptAfterDispel(DispelInfo *dispelInfo)
void _Remove(AuraRemoveMode removeMode)
bool IsSingleTarget() const
Definition SpellAuras.h:157
void setDeathState(DeathState s) OVERRIDE
uint8 GetRemovedCharges() const
Definition Unit.h:848
Definition Item.h:202
uint64 GetGUID() const
Definition Object.h:119
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:325
Player * ToPlayer()
Definition Object.h:204
bool IsInWorld() const
Definition Object.h:114
uint32 GetGUIDLow() const
Definition Object.h:120
TypeID GetTypeId() const
Definition Object.h:131
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:1261
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition Object.cpp:1280
Creature * ToCreature()
Definition Object.h:207
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:1309
Definition Pet.h:28
bool isControlled() const
Definition Pet.cpp:2135
void SetAuraUpdateMaskForRaid(uint8 slot)
Definition Pet.h:139
void SetGroupUpdateFlag(uint32 flag)
Definition Player.h:2993
PlayerSpellMap const & GetSpellMap() const
Definition Player.h:2141
Group * GetGroup()
Definition Player.h:2972
Mechanics Mechanic
Definition SpellInfo.h:101
Definition Spell.h:289
SpellEffectInfo Effects[MAX_SPELL_EFFECTS]
Definition SpellInfo.h:255
bool IsRequiringDeadTarget() const
uint32 AttributesCu
Definition SpellInfo.h:178
bool IsDeathPersistent() const
bool IsPassive() const
uint32 Mechanic
Definition SpellInfo.h:163
uint32 Id
Definition SpellInfo.h:160
bool IsStackableOnOneSlotWithDifferentCasters() const
uint32 GetDispelMask() const
uint32 Dispel
Definition SpellInfo.h:162
bool IsMultiSlotAura() const
uint32 CasterAuraState
Definition SpellInfo.h:185
flag128 SpellFamilyFlags
Definition SpellInfo.h:227
uint32 AttributesEx3
Definition SpellInfo.h:167
AuraStateType GetAuraState() const
uint32 Attributes
Definition SpellInfo.h:164
bool IsPassiveStackableWithRanks() const
uint32 AttributesEx7
Definition SpellInfo.h:171
uint32 GetAllEffectsMechanicMask() const
uint32 SpellIconID
Definition SpellInfo.h:220
uint32 AttributesEx2
Definition SpellInfo.h:166
uint32 AttributesEx4
Definition SpellInfo.h:168
bool HasAura(AuraType aura) const
uint32 SpellFamilyName
Definition SpellInfo.h:226
uint32 AuraInterruptFlags
Definition SpellInfo.h:199
bool IsSingleTarget() const
bool HasAuraTypeWithAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
AuraApplication * GetAuraApplicationOfRankedSpell(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0, AuraApplication *except=NULL) const
std::pair< AuraApplicationMap::iterator, AuraApplicationMap::iterator > AuraApplicationMapBoundsNonConst
Definition Unit.h:1378
void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
Aura * _TryStackingOrRefreshingExistingAura(SpellInfo const *newAura, uint32 effMask, Unit *caster, int32 *baseAmount=NULL, Item *castItem=NULL, uint64 casterGUID=0)
AuraEffectList const & GetAuraEffectsByType(AuraType type) const
Definition Unit.h:2243
Spell * m_currentSpells[CURRENT_MAX_SPELL]
Definition Unit.h:2895
bool HasAuraState(AuraStateType flag, SpellInfo const *spellProto=NULL, Unit const *Caster=NULL) const
void _RemoveNoStackAurasDueToAura(Aura *aura)
int32 GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask, const AuraEffect *except=NULL) const
AuraList m_removedAuras
Definition Unit.h:2901
bool HasAuraTypeWithValue(AuraType auratype, int32 value) const
bool HasAuraTypeWithCaster(AuraType auratype, uint64 caster) const
float GetTotalAuraModValue(UnitMods unitMod) const
Unit * GetOwner() const
Definition Unit.cpp:2339
Pet * ToPet()
Definition Unit.h:2803
void RemoveAurasWithMechanic(uint32 mechanic_mask, AuraRemoveMode removemode=AURA_REMOVE_BY_DEFAULT, uint32 except=0)
void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode=AURA_REMOVE_BY_DEFAULT)
void AddInterruptMask(uint32 mask)
Definition Unit.h:2483
Diminishing m_Diminishing
Definition Unit.h:2973
void _UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode)
bool HasAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster=0) const
bool HasNegativeAuraWithAttribute(uint32 flag, uint64 guid=0) const
float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END]
Definition Unit.h:2911
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
std::list< Aura * > AuraList
Definition Unit.h:1384
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except=0)
void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer)
void RemoveAurasDueToSpell(uint32 spellId, uint64 casterGUID=0, uint32 reqEffMask=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
int32 GetTotalAuraModifierByAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
Totem * ToTotem()
Definition Unit.h:2812
std::multimap< uint32, AuraApplication * > AuraApplicationMap
Definition Unit.h:1376
virtual bool isBeingLoaded() const
Definition Unit.h:2794
void RemoveNotOwnSingleTargetAuras(uint32 newPhase=0, bool phaseid=false)
Aura * GetAura(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0) const
void RemoveAllAurasExceptType(AuraType type)
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid=0, bool withInstant=true)
Definition Unit.cpp:1433
void SetAuraStack(uint32 spellId, Unit *target, uint32 stack)
bool IsPet() const
Definition Unit.h:1511
float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration, Unit *caster, DiminishingLevels Level, int32 limitduration)
float GetTotalAuraMultiplierByMiscValue(AuraType auratype, int32 misc_value) const
void UpdateInterruptMask()
Definition Unit.cpp:512
Aura * AddAura(uint32 spellId, Unit *target)
void RemoveAurasDueToItemSpell(uint32 spellId, uint64 castItemGuid)
void RemoveAuraFromStack(uint32 spellId, uint64 casterGUID=0, AuraRemoveMode removeMode=AURA_REMOVE_BY_DEFAULT)
std::pair< AuraMap::const_iterator, AuraMap::const_iterator > AuraMapBounds
Definition Unit.h:1373
bool HasAuraWithMechanic(uint32 mechanicMask) const
int32 GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const
void RemoveAllAurasRequiringDeadTarget()
bool IsAlive() const
Definition Unit.h:2032
AuraEffect * GetAuraEffectOfRankedSpell(uint32 spellId, uint8 effIndex, uint64 casterGUID=0) const
AuraEffect * IsScriptOverriden(SpellInfo const *spell, int32 script) const
float GetTotalAuraMultiplierByAffectMask(AuraType auratype, SpellInfo const *affectedSpell) const
std::pair< AuraApplicationMap::const_iterator, AuraApplicationMap::const_iterator > AuraApplicationMapBounds
Definition Unit.h:1377
uint32 m_removedAurasCount
Definition Unit.h:2903
void RemoveAllAurasOnDeath()
AuraMap::iterator m_auraUpdateIterator
Definition Unit.h:2902
void RemoveAurasWithAttribute(uint32 flags)
void _DeleteRemovedAuras()
void _ApplyAura(AuraApplication *aurApp, uint32 effMask)
bool HasAura(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0) const
std::pair< AuraStateAurasMap::const_iterator, AuraStateAurasMap::const_iterator > AuraStateAurasMapBounds
Definition Unit.h:1381
uint32 BuildAuraStateUpdateForTarget(Unit *target) const
bool IsDuringRemoveFromWorld() const
Definition Unit.h:2798
Unit * GetCharmerOrOwner() const
Definition Unit.cpp:2419
int32 GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
void _ApplyAllAuraStatMods()
virtual bool IsImmunedToSpell(SpellInfo const *spellInfo) const
Definition Unit.cpp:3456
void RemoveAurasWithFamily(SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID)
AuraApplicationList m_interruptableAuras
Definition Unit.h:2907
void ModifyAuraState(AuraStateType flag, bool apply)
uint32 GetAuraCount(uint32 spellId) const
void UpdateAuraForGroup(uint8 slot)
int32 GetMaxPositiveAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
void _AddAura(UnitAura *aura, Unit *caster)
bool IsSummon() const
Definition Unit.h:1503
float GetTotalAuraMultiplier(AuraType auratype) const
std::multimap< uint32, Aura * > AuraMap
Definition Unit.h:1372
bool HasAuraType(AuraType auraType) const
int32 GetMaxPositiveAuraModifier(AuraType auratype) const
void RemoveArenaAuras()
void _RemoveAllAuraStatMods()
uint32 GetDiseasesByCaster(uint64 casterGUID, bool remove=false)
void RemoveAreaAurasDueToLeaveWorld()
void RemoveAurasByType(AuraType auraType, uint64 casterGUID=0, Aura *except=NULL, bool negative=true, bool positive=true)
AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, uint64 casterGUID=0) const
void DelayOwnedAuras(uint32 spellId, uint64 caster, int32 delaytime)
virtual bool IsImmunedToSpellEffect(SpellInfo const *spellInfo, uint32 index) const
Definition Unit.cpp:3520
AuraApplication * GetAuraApplication(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0, AuraApplication *except=NULL) const
AuraApplication * _CreateAuraApplication(Aura *aura, uint32 effMask)
AuraMap m_ownedAuras
Definition Unit.h:2899
Unit(bool isWorldObject)
Definition Unit.cpp:142
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:2283
std::pair< AuraMap::iterator, AuraMap::iterator > AuraMapBoundsNonConst
Definition Unit.h:1374
int32 GetMaxNegativeAuraModifier(AuraType auratype) const
AuraApplicationMap m_appliedAuras
Definition Unit.h:2900
int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, uint64 casterGUID, Unit *dispeller, uint8 chargesRemoved=1)
void _RegisterAuraEffect(AuraEffect *aurEff, bool apply)
void RemoveAllAuras()
float GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask) const
AuraEffect * GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
uint32 m_interruptMask
Definition Unit.h:2909
int32 GetTotalAuraModifier(AuraType auratype) const
AuraApplicationMap & GetAppliedAuras()
Definition Unit.h:2204
std::list< AuraEffect * > AuraEffectList
Definition Unit.h:1383
int32 GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const
void GetDispellableAuraList(Unit *caster, uint32 dispelMask, DispelChargesList &dispelList)
bool IsTotem() const
Definition Unit.h:1519
void ApplyDiminishingAura(DiminishingGroup group, bool apply)
AuraStateAurasMap m_auraStateAuras
Definition Unit.h:2908
AuraList & GetSingleCastAuras()
Definition Unit.h:2247
AuraEffectList m_modAuras[TOTAL_AURAS]
Definition Unit.h:2905
void SetStandState(uint8 state)
Definition Unit.cpp:5902
void _ApplyAuraEffect(Aura *aura, uint8 effIndex)
AuraMap & GetOwnedAuras()
Definition Unit.h:2188
Aura * GetAuraOfRankedSpell(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0) const
bool m_cleanupDone
Definition Unit.h:2983
bool HasAuraTypeWithMiscvalue(AuraType auratype, int32 miscvalue) const
void RemoveMovementImpairingAuras()
bool IsSitState() const
Definition Unit.cpp:5889
Aura * GetOwnedAura(uint32 spellId, uint64 casterGUID=0, uint64 itemCasterGUID=0, uint32 reqEffMask=0, Aura *except=NULL) const
bool HasNegativeAuraWithInterruptFlag(uint32 flag, uint64 guid=0) const
uint32 GetDoTsByCaster(uint64 casterGUID) const
bool IsPhased(WorldObject const *obj) const
Definition Object.cpp:3393
bool InSamePhase(WorldObject const *obj) const
Definition Object.cpp:3412
bool HasFlag(uint32 p1=0, uint32 p2=0, uint32 p3=0, uint32 p4=0) const
Definition Util.h:426
bool ShouldBindStackingAuraToCaster(bool canStackWithDifferentCasters, bool casterIsCreature, bool casterIsSummon, bool ownerIsSummon)