2010-10-07 15:35:36 +02:00
/*
2012-01-01 00:32:13 +01:00
* Copyright (C) 2008-2012 TrinityCore <http://www.trinitycore.org/>
2010-10-07 15:35:36 +02:00
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
2008-10-11 14:16:25 -05:00
*/
2009-10-17 15:51:44 -07:00
2008-10-11 14:16:25 -05:00
#include "Common.h"
#include "WorldPacket.h"
#include "Opcodes.h"
#include "Log.h"
#include "ObjectMgr.h"
#include "SpellMgr.h"
#include "Player.h"
#include "Unit.h"
#include "Spell.h"
2010-01-10 01:23:15 +01:00
#include "SpellAuraEffects.h"
2008-10-11 14:16:25 -05:00
#include "DynamicObject.h"
#include "ObjectAccessor.h"
#include "Util.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
2010-08-24 00:10:49 +02:00
#include "ScriptMgr.h"
#include "SpellScript.h"
2011-08-03 12:28:42 +02:00
#include "Vehicle.h"
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
AuraApplication :: AuraApplication ( Unit * target , Unit * caster , Aura * aura , uint8 effMask ) :
2010-08-21 20:08:47 +02:00
m_target ( target ), m_base ( aura ), m_slot ( MAX_AURAS ), m_flags ( AFLAG_NONE ),
m_effectsToApply ( effMask ), m_removeMode ( AURA_REMOVE_NONE ), m_needClientUpdate ( false )
2008-10-11 14:16:25 -05:00
{
2010-07-30 20:04:28 +02:00
ASSERT ( GetTarget () && GetBase ());
2009-10-17 15:51:44 -07:00
2011-06-08 10:41:32 +02:00
if ( GetBase () -> CanBeSentToClient ())
2009-02-17 14:52:46 -06:00
{
2010-01-10 01:23:15 +01:00
// Try find slot for aura
uint8 slot = MAX_AURAS ;
// Lookup for auras already applied from spell
2010-12-20 11:04:48 +01:00
if ( AuraApplication * foundAura = GetTarget () -> GetAuraApplication ( GetBase () -> GetId (), GetBase () -> GetCasterGUID (), GetBase () -> GetCastItemGUID ()))
2010-01-10 01:23:15 +01:00
{
// allow use single slot only by auras from same caster
slot = foundAura -> GetSlot ();
}
else
{
2011-06-11 22:35:29 +02:00
Unit :: VisibleAuraMap const * visibleAuras = GetTarget () -> GetVisibleAuras ();
2010-01-10 01:23:15 +01:00
// lookup for free slots in units visibleAuras
Unit :: VisibleAuraMap :: const_iterator itr = visibleAuras -> find ( 0 );
2011-09-29 12:43:05 +02:00
for ( uint32 freeSlot = 0 ; freeSlot < MAX_AURAS ; ++ itr , ++ freeSlot )
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( itr == visibleAuras -> end () || itr -> first != freeSlot )
2010-01-10 01:23:15 +01:00
{
slot = freeSlot ;
break ;
}
}
}
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
// Register Visible Aura
2010-04-07 19:14:10 +02:00
if ( slot < MAX_AURAS )
2010-01-10 01:23:15 +01:00
{
m_slot = slot ;
2010-12-20 11:04:48 +01:00
GetTarget () -> SetVisibleAura ( slot , this );
2010-01-10 01:23:15 +01:00
SetNeedClientUpdate ();
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "Aura: %u Effect: %d put to unit visible auras slot: %u" , GetBase () -> GetId (), GetEffectMask (), slot );
2010-01-10 01:23:15 +01:00
}
else
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "Aura: %u Effect: %d could not find empty unit visible slot" , GetBase () -> GetId (), GetEffectMask ());
2010-01-10 01:23:15 +01:00
}
2009-10-17 15:51:44 -07:00
2010-12-31 12:50:17 +01:00
_InitFlags ( caster , effMask );
2010-01-10 01:23:15 +01:00
}
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
void AuraApplication :: _Remove ()
{
uint8 slot = GetSlot ();
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
if ( slot >= MAX_AURAS )
return ;
2009-10-17 15:51:44 -07:00
2010-12-20 11:04:48 +01:00
if ( AuraApplication * foundAura = m_target -> GetAuraApplication ( GetBase () -> GetId (), GetBase () -> GetCasterGUID (), GetBase () -> GetCastItemGUID ()))
2009-04-06 13:31:14 +02:00
{
2010-01-10 01:23:15 +01:00
// Reuse visible aura slot by aura which is still applied - prevent storing dead pointers
if ( slot == foundAura -> GetSlot ())
2009-04-06 13:31:14 +02:00
{
2010-01-10 01:23:15 +01:00
if ( GetTarget () -> GetVisibleAura ( slot ) == this )
{
GetTarget () -> SetVisibleAura ( slot , foundAura );
foundAura -> SetNeedClientUpdate ();
}
// set not valid slot for aura - prevent removing other visible aura
slot = MAX_AURAS ;
2009-04-06 13:31:14 +02:00
}
}
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
// update for out of range group members
if ( slot < MAX_AURAS )
{
GetTarget () -> RemoveVisibleAura ( slot );
ClientUpdate ( true );
}
}
2011-06-11 22:35:29 +02:00
void AuraApplication :: _InitFlags ( Unit * caster , uint8 effMask )
2010-01-10 01:23:15 +01:00
{
2010-12-31 12:50:17 +01:00
// mark as selfcasted if needed
m_flags |= ( GetBase () -> GetCasterGUID () == GetTarget () -> GetGUID ()) ? AFLAG_CASTER : AFLAG_NONE ;
2010-12-31 16:12:29 +01:00
// aura is casted by self or an enemy
// one negative effect and we know aura is negative
if ( IsSelfcasted () || ! caster || ! caster -> IsFriendlyTo ( GetTarget ()))
2009-04-14 19:09:08 +02:00
{
2010-12-31 16:12:29 +01:00
bool negativeFound = false ;
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2009-04-06 13:31:14 +02:00
{
2011-07-26 23:09:28 +02:00
if ((( 1 << i ) & effMask ) && ! GetBase () -> GetSpellInfo () -> IsPositiveEffect ( i ))
2010-12-31 16:12:29 +01:00
{
negativeFound = true ;
break ;
}
}
m_flags |= negativeFound ? AFLAG_NEGATIVE : AFLAG_POSITIVE ;
}
// aura is casted by friend
// one positive effect and we know aura is positive
else
{
bool positiveFound = false ;
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
{
2011-07-26 23:09:28 +02:00
if ((( 1 << i ) & effMask ) && GetBase () -> GetSpellInfo () -> IsPositiveEffect ( i ))
2010-12-31 16:12:29 +01:00
{
positiveFound = true ;
break ;
}
2009-04-06 13:31:14 +02:00
}
2010-12-31 16:12:29 +01:00
m_flags |= positiveFound ? AFLAG_POSITIVE : AFLAG_NEGATIVE ;
2009-04-06 13:31:14 +02:00
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
void AuraApplication :: _HandleEffect ( uint8 effIndex , bool apply )
2008-10-11 14:16:25 -05:00
{
2011-09-15 14:08:17 +02:00
AuraEffect * aurEff = GetBase () -> GetEffect ( effIndex );
2010-07-30 20:04:28 +02:00
ASSERT ( aurEff );
ASSERT ( HasEffect ( effIndex ) == ( ! apply ));
ASSERT (( 1 << effIndex ) & m_effectsToApply );
2011-02-20 20:16:34 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "AuraApplication::_HandleEffect: %u, apply: %u: amount: %u" , aurEff -> GetAuraType (), apply , aurEff -> GetAmount ());
2010-01-10 01:23:15 +01:00
if ( apply )
{
2010-12-19 19:43:53 +01:00
ASSERT ( ! ( m_flags & ( 1 << effIndex )));
2010-01-10 01:23:15 +01:00
m_flags |= 1 << effIndex ;
aurEff -> HandleEffect ( this , AURA_EFFECT_HANDLE_REAL , true );
}
else
{
2010-12-19 19:43:53 +01:00
ASSERT ( m_flags & ( 1 << effIndex ));
2010-01-10 01:23:15 +01:00
m_flags &= ~ ( 1 << effIndex );
aurEff -> HandleEffect ( this , AURA_EFFECT_HANDLE_REAL , false );
// Remove all triggered by aura spells vs unlimited duration
aurEff -> CleanupTriggeredSpells ( GetTarget ());
}
SetNeedClientUpdate ();
2009-04-06 13:31:14 +02:00
}
2009-10-17 15:51:44 -07:00
2011-06-08 10:41:32 +02:00
void AuraApplication :: BuildUpdatePacket ( ByteBuffer & data , bool remove ) const
2009-04-06 13:31:14 +02:00
{
2010-01-10 01:23:15 +01:00
data << uint8 ( m_slot );
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( remove )
2010-01-10 01:23:15 +01:00
{
2010-07-30 20:04:28 +02:00
ASSERT ( ! m_target -> GetVisibleAura ( m_slot ));
2010-01-10 01:23:15 +01:00
data << uint32 ( 0 );
return ;
}
2010-07-30 20:04:28 +02:00
ASSERT ( m_target -> GetVisibleAura ( m_slot ));
2009-10-17 15:51:44 -07:00
2011-06-11 22:35:29 +02:00
Aura const * aura = GetBase ();
2010-01-10 01:23:15 +01:00
data << uint32 ( aura -> GetId ());
uint32 flags = m_flags ;
2011-07-26 23:09:28 +02:00
if ( aura -> GetMaxDuration () > 0 && ! ( aura -> GetSpellInfo () -> AttributesEx5 & SPELL_ATTR5_HIDE_DURATION ))
2010-01-10 01:23:15 +01:00
flags |= AFLAG_DURATION ;
data << uint8 ( flags );
data << uint8 ( aura -> GetCasterLevel ());
2011-07-13 20:57:11 +02:00
// send stack amount for aura which could be stacked (never 0 - causes incorrect display) or charges
2011-07-10 13:13:02 +02:00
// stack amount has priority over charges (checked on retail with spell 50262)
2011-07-26 23:09:28 +02:00
data << uint8 ( aura -> GetSpellInfo () -> StackAmount ? aura -> GetStackAmount () : aura -> GetCharges ());
2009-10-17 15:51:44 -07:00
2010-04-07 19:14:10 +02:00
if ( ! ( flags & AFLAG_CASTER ))
2010-01-10 01:23:15 +01:00
data . appendPackGUID ( aura -> GetCasterGUID ());
2010-04-07 19:14:10 +02:00
if ( flags & AFLAG_DURATION )
2009-04-06 13:31:14 +02:00
{
2010-01-10 01:23:15 +01:00
data << uint32 ( aura -> GetMaxDuration ());
data << uint32 ( aura -> GetDuration ());
}
2011-06-08 10:41:32 +02:00
}
void AuraApplication :: ClientUpdate ( bool remove )
{
m_needClientUpdate = false ;
WorldPacket data ( SMSG_AURA_UPDATE );
data . append ( GetTarget () -> GetPackGUID ());
BuildUpdatePacket ( data , remove );
2010-01-10 01:23:15 +01:00
m_target -> SendMessageToSet ( & data , true );
}
2011-07-26 23:09:28 +02:00
uint8 Aura :: BuildEffectMaskForOwner ( SpellInfo const * spellProto , uint8 avalibleEffectMask , WorldObject * owner )
2010-01-10 01:23:15 +01:00
{
2011-06-07 12:47:32 +02:00
ASSERT ( spellProto );
2010-07-30 20:04:28 +02:00
ASSERT ( owner );
2010-01-10 01:23:15 +01:00
uint8 effMask = 0 ;
2011-09-29 12:43:05 +02:00
switch ( owner -> GetTypeId ())
2010-01-10 01:23:15 +01:00
{
case TYPEID_UNIT :
case TYPEID_PLAYER :
2010-04-07 19:12:44 +02:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2009-04-06 13:31:14 +02:00
{
2011-07-26 23:09:28 +02:00
if ( spellProto -> Effects [ i ]. IsUnitOwnedAuraEffect ())
2010-01-10 01:23:15 +01:00
effMask |= 1 << i ;
}
break ;
case TYPEID_DYNAMICOBJECT :
2010-04-07 19:12:44 +02:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2010-01-10 01:23:15 +01:00
{
2011-07-26 23:09:28 +02:00
if ( spellProto -> Effects [ i ]. Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA )
2010-01-10 01:23:15 +01:00
effMask |= 1 << i ;
}
break ;
2010-08-21 20:08:47 +02:00
default :
break ;
2010-01-10 01:23:15 +01:00
}
2011-06-07 12:47:32 +02:00
return effMask & avalibleEffectMask ;
2010-01-10 01:23:15 +01:00
}
2009-10-17 15:51:44 -07:00
2011-07-26 23:09:28 +02:00
Aura * Aura :: TryRefreshStackOrCreate ( SpellInfo const * spellproto , uint8 tryEffMask , WorldObject * owner , Unit * caster , int32 * baseAmount /*= NULL*/ , Item * castItem /*= NULL*/ , uint64 casterGUID /*= 0*/ , bool * refresh /*= NULL*/ )
2010-01-10 01:23:15 +01:00
{
2010-07-30 20:04:28 +02:00
ASSERT ( spellproto );
ASSERT ( owner );
ASSERT ( caster || casterGUID );
2011-06-07 12:47:32 +02:00
ASSERT ( tryEffMask <= MAX_EFFECT_MASK );
if ( refresh )
* refresh = false ;
uint8 effMask = Aura :: BuildEffectMaskForOwner ( spellproto , tryEffMask , owner );
if ( ! effMask )
return NULL ;
if ( Aura * foundAura = owner -> ToUnit () -> _TryStackingOrRefreshingExistingAura ( spellproto , effMask , caster , baseAmount , castItem , casterGUID ))
2010-01-10 01:23:15 +01:00
{
2011-06-07 12:47:32 +02:00
// we've here aura, which script triggered removal after modding stack amount
// check the state here, so we won't create new Aura object
if ( foundAura -> IsRemoved ())
return NULL ;
if ( refresh )
* refresh = true ;
return foundAura ;
2009-04-06 13:31:14 +02:00
}
2011-06-07 12:47:32 +02:00
else
2011-04-29 20:47:02 +02:00
return Create ( spellproto , effMask , owner , caster , baseAmount , castItem , casterGUID );
2010-01-10 01:23:15 +01:00
}
2009-10-17 15:51:44 -07:00
2011-07-26 23:09:28 +02:00
Aura * Aura :: TryCreate ( SpellInfo const * spellproto , uint8 tryEffMask , WorldObject * owner , Unit * caster , int32 * baseAmount /*= NULL*/ , Item * castItem /*= NULL*/ , uint64 casterGUID /*= 0*/ )
2011-06-07 12:47:32 +02:00
{
ASSERT ( spellproto );
ASSERT ( owner );
ASSERT ( caster || casterGUID );
ASSERT ( tryEffMask <= MAX_EFFECT_MASK );
uint8 effMask = Aura :: BuildEffectMaskForOwner ( spellproto , tryEffMask , owner );
if ( ! effMask )
return NULL ;
return Create ( spellproto , effMask , owner , caster , baseAmount , castItem , casterGUID );
}
2011-07-26 23:09:28 +02:00
Aura * Aura :: Create ( SpellInfo const * spellproto , uint8 effMask , WorldObject * owner , Unit * caster , int32 * baseAmount , Item * castItem , uint64 casterGUID )
2010-01-10 01:23:15 +01:00
{
2010-07-30 20:04:28 +02:00
ASSERT ( effMask );
ASSERT ( spellproto );
ASSERT ( owner );
ASSERT ( caster || casterGUID );
ASSERT ( effMask <= MAX_EFFECT_MASK );
2010-01-16 15:12:21 +01:00
// try to get caster of aura
if ( casterGUID )
{
if ( owner -> GetGUID () == casterGUID )
2011-06-03 21:30:50 +02:00
caster = owner -> ToUnit ();
2010-01-16 15:12:21 +01:00
else
caster = ObjectAccessor :: GetUnit ( * owner , casterGUID );
}
2010-08-03 06:11:03 +02:00
else
casterGUID = caster -> GetGUID ();
2011-06-03 21:30:50 +02:00
2010-08-03 06:11:03 +02:00
// check if aura can be owned by owner
if ( owner -> isType ( TYPEMASK_UNIT ))
if ( ! owner -> IsInWorld () || (( Unit * ) owner ) -> IsDuringRemoveFromWorld ())
2011-06-03 21:30:50 +02:00
// owner not in world so don't allow to own not self casted single target auras
2011-07-26 23:09:28 +02:00
if ( casterGUID != owner -> GetGUID () && spellproto -> IsSingleTarget ())
2010-08-03 06:11:03 +02:00
return NULL ;
2011-06-03 21:30:50 +02:00
Aura * aura = NULL ;
switch ( owner -> GetTypeId ())
2010-01-10 01:23:15 +01:00
{
case TYPEID_UNIT :
case TYPEID_PLAYER :
2011-06-07 12:47:32 +02:00
aura = new UnitAura ( spellproto , effMask , owner , caster , baseAmount , castItem , casterGUID );
2010-01-16 15:12:21 +01:00
break ;
2010-01-10 01:23:15 +01:00
case TYPEID_DYNAMICOBJECT :
2011-03-08 16:42:00 +01:00
aura = new DynObjAura ( spellproto , effMask , owner , caster , baseAmount , castItem , casterGUID );
2010-01-16 15:12:21 +01:00
break ;
2010-01-10 01:23:15 +01:00
default :
2010-07-30 20:04:28 +02:00
ASSERT ( false );
2010-01-10 01:23:15 +01:00
return NULL ;
}
2010-01-16 15:12:21 +01:00
// aura can be removed in Unit::_AddAura call
if ( aura -> IsRemoved ())
return NULL ;
return aura ;
2010-01-10 01:23:15 +01:00
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
Aura :: Aura ( SpellInfo const * spellproto , WorldObject * owner , Unit * caster , Item * castItem , uint64 casterGUID ) :
2011-07-26 23:09:28 +02:00
m_spellInfo ( spellproto ), m_casterGuid ( casterGUID ? casterGUID : caster -> GetGUID ()),
2010-08-21 20:08:47 +02:00
m_castItemGuid ( castItem ? castItem -> GetGUID () : 0 ), m_applyTime ( time ( NULL )),
m_owner ( owner ), m_timeCla ( 0 ), m_updateTargetMapInterval ( 0 ),
2011-07-26 23:09:28 +02:00
m_casterLevel ( caster ? caster -> getLevel () : m_spellInfo -> SpellLevel ), m_procCharges ( 0 ), m_stackAmount ( 1 ),
2011-07-10 13:13:02 +02:00
m_isRemoved ( false ), m_isSingleTarget ( false ), m_isUsingCharges ( false )
2010-01-10 01:23:15 +01:00
{
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> ManaPerSecond || m_spellInfo -> ManaPerSecondPerLevel )
2010-07-12 00:30:17 +02:00
m_timeCla = 1 * IN_MILLISECONDS ;
2009-10-17 15:51:44 -07:00
2011-06-07 14:19:47 +02:00
m_maxDuration = CalcMaxDuration ( caster );
m_duration = m_maxDuration ;
2011-06-07 17:25:34 +02:00
m_procCharges = CalcMaxCharges ( caster );
2011-07-10 13:13:02 +02:00
m_isUsingCharges = m_procCharges != 0 ;
// m_casterLevel = cast item level/caster level, caster level should be saved to db, confirmed with sniffs
2011-02-06 13:17:29 +01:00
}
2009-10-17 15:51:44 -07:00
2011-06-11 22:35:29 +02:00
void Aura :: _InitEffects ( uint8 effMask , Unit * caster , int32 * baseAmount )
2011-02-06 13:17:29 +01:00
{
// shouldn't be in constructor - functions in AuraEffect::AuraEffect use polymorphism
2010-01-10 01:23:15 +01:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2008-10-11 14:16:25 -05:00
{
2010-01-10 01:23:15 +01:00
if ( effMask & ( uint8 ( 1 ) << i ))
m_effects [ i ] = new AuraEffect ( this , i , baseAmount ? baseAmount + i : NULL , caster );
else
m_effects [ i ] = NULL ;
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
Aura ::~ Aura ()
2008-10-11 14:16:25 -05:00
{
2010-10-04 17:44:49 +02:00
// unload scripts
2011-09-29 12:43:05 +02:00
while ( ! m_loadedScripts . empty ())
2010-10-04 17:44:49 +02:00
{
2011-09-15 14:08:17 +02:00
std :: list < AuraScript *>:: iterator itr = m_loadedScripts . begin ();
2010-10-04 17:44:49 +02:00
( * itr ) -> _Unload ();
delete ( * itr );
m_loadedScripts . erase ( itr );
}
2010-01-10 01:23:15 +01:00
// free effects memory
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2010-06-21 23:20:58 +02:00
delete m_effects [ i ];
2010-01-10 01:23:15 +01:00
2010-07-30 20:04:28 +02:00
ASSERT ( m_applications . empty ());
2010-01-10 01:23:15 +01:00
_DeleteRemovedApplications ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
Unit * Aura :: GetCaster () const
2009-08-25 00:43:31 -05:00
{
2010-01-10 01:23:15 +01:00
if ( GetOwner () -> GetGUID () == GetCasterGUID ())
return GetUnitOwner ();
2011-06-11 22:35:29 +02:00
if ( AuraApplication const * aurApp = GetApplicationOfTarget ( GetCasterGUID ()))
2010-01-10 01:23:15 +01:00
return aurApp -> GetTarget ();
return ObjectAccessor :: GetUnit ( * GetOwner (), GetCasterGUID ());
}
AuraObjectType Aura :: GetType () const
{
return ( m_owner -> GetTypeId () == TYPEID_DYNAMICOBJECT ) ? DYNOBJ_AURA_TYPE : UNIT_AURA_TYPE ;
2009-08-25 00:43:31 -05:00
}
2009-10-17 15:51:44 -07:00
2011-06-11 22:35:29 +02:00
void Aura :: _ApplyForTarget ( Unit * target , Unit * caster , AuraApplication * auraApp )
2008-10-11 14:16:25 -05:00
{
2010-07-30 20:04:28 +02:00
ASSERT ( target );
ASSERT ( auraApp );
2010-12-26 00:14:13 +01:00
// aura mustn't be already applied on target
ASSERT ( ! IsAppliedOnTarget ( target -> GetGUID ()) && "Aura::_ApplyForTarget: aura musn't be already applied on target" );
2010-01-10 01:23:15 +01:00
m_applications [ target -> GetGUID ()] = auraApp ;
// set infinity cooldown state for spells
2010-04-07 19:14:10 +02:00
if ( caster && caster -> GetTypeId () == TYPEID_PLAYER )
2009-05-23 22:21:26 -05:00
{
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> Attributes & SPELL_ATTR0_DISABLED_WHILE_ACTIVE )
2009-08-31 00:37:05 -05:00
{
2010-03-07 15:20:19 +01:00
Item * castItem = m_castItemGuid ? caster -> ToPlayer () -> GetItemByGuid ( m_castItemGuid ) : NULL ;
2011-07-26 23:09:28 +02:00
caster -> ToPlayer () -> AddSpellAndCategoryCooldowns ( m_spellInfo , castItem ? castItem -> GetEntry () : 0 , NULL , true );
2009-08-31 00:37:05 -05:00
}
2009-05-23 22:21:26 -05:00
}
2010-01-10 01:23:15 +01:00
}
2011-06-11 22:35:29 +02:00
void Aura :: _UnapplyForTarget ( Unit * target , Unit * caster , AuraApplication * auraApp )
2010-01-10 01:23:15 +01:00
{
2010-07-30 20:04:28 +02:00
ASSERT ( target );
ASSERT ( auraApp -> GetRemoveMode ());
ASSERT ( auraApp );
2010-01-10 01:23:15 +01:00
ApplicationMap :: iterator itr = m_applications . find ( target -> GetGUID ());
2011-01-26 01:03:35 +01:00
2010-12-19 19:43:53 +01:00
// TODO: Figure out why this happens
2010-06-07 09:06:17 +02:00
if ( itr == m_applications . end ())
{
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Aura::_UnapplyForTarget, target:%u, caster:%u, spell:%u was not found in owners application map!" ,
2011-07-26 23:09:28 +02:00
target -> GetGUIDLow (), caster -> GetGUIDLow (), auraApp -> GetBase () -> GetSpellInfo () -> Id );
2010-12-19 19:43:53 +01:00
ASSERT ( false );
2010-06-07 09:06:17 +02:00
}
2010-06-07 20:12:14 +02:00
2010-01-10 01:23:15 +01:00
// aura has to be already applied
2010-12-19 19:43:53 +01:00
ASSERT ( itr -> second == auraApp );
m_applications . erase ( itr );
2010-01-10 01:23:15 +01:00
m_removedApplications . push_back ( auraApp );
// reset cooldown state for spells
2010-04-07 19:14:10 +02:00
if ( caster && caster -> GetTypeId () == TYPEID_PLAYER )
2009-08-24 22:31:54 -05:00
{
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> Attributes & SPELL_ATTR0_DISABLED_WHILE_ACTIVE )
2010-01-10 01:23:15 +01:00
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
2011-07-26 23:09:28 +02:00
caster -> ToPlayer () -> SendCooldownEvent ( GetSpellInfo ());
2009-08-24 22:31:54 -05:00
}
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
// removes aura from all targets
// and marks aura as removed
void Aura :: _Remove ( AuraRemoveMode removeMode )
2008-10-11 14:16:25 -05:00
{
2010-07-30 20:04:28 +02:00
ASSERT ( ! m_isRemoved );
2010-01-10 01:23:15 +01:00
m_isRemoved = true ;
2010-01-24 18:26:29 +01:00
ApplicationMap :: iterator appItr = m_applications . begin ();
2010-06-07 09:06:17 +02:00
for ( appItr = m_applications . begin (); appItr != m_applications . end ();)
2010-01-10 01:23:15 +01:00
{
AuraApplication * aurApp = appItr -> second ;
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
target -> _UnapplyAura ( aurApp , removeMode );
2010-01-24 18:26:29 +01:00
appItr = m_applications . begin ();
2010-01-10 01:23:15 +01:00
}
}
2009-10-17 15:51:44 -07:00
2011-06-11 22:35:29 +02:00
void Aura :: UpdateTargetMap ( Unit * caster , bool apply )
2010-01-10 01:23:15 +01:00
{
2010-01-24 18:58:06 +01:00
if ( IsRemoved ())
return ;
2010-01-22 18:06:01 +01:00
m_updateTargetMapInterval = UPDATE_TARGET_MAP_INTERVAL ;
2010-01-24 13:08:25 +01:00
// fill up to date target list
// target, effMask
2011-09-29 12:43:05 +02:00
std :: map < Unit * , uint8 > targets ;
2010-01-24 13:08:25 +01:00
FillTargetMap ( targets , caster );
UnitList targetsToRemove ;
// mark all auras as ready to remove
for ( ApplicationMap :: iterator appIter = m_applications . begin (); appIter != m_applications . end (); ++ appIter )
{
2011-09-29 12:43:05 +02:00
std :: map < Unit * , uint8 >:: iterator existing = targets . find ( appIter -> second -> GetTarget ());
2010-01-24 13:08:25 +01:00
// not found in current area - remove the aura
if ( existing == targets . end ())
targetsToRemove . push_back ( appIter -> second -> GetTarget ());
else
{
2010-04-07 18:09:10 +02:00
// needs readding - remove now, will be applied in next update cycle
2010-01-24 13:08:25 +01:00
// (dbcs do not have auras which apply on same type of targets but have different radius, so this is not really needed)
2010-08-03 06:11:03 +02:00
if ( appIter -> second -> GetEffectMask () != existing -> second || ! CanBeAppliedOn ( existing -> first ))
2010-01-24 13:08:25 +01:00
targetsToRemove . push_back ( appIter -> second -> GetTarget ());
// nothing todo - aura already applied
// remove from auras to register list
targets . erase ( existing );
}
}
// register auras for units
2011-09-29 12:43:05 +02:00
for ( std :: map < Unit * , uint8 >:: iterator itr = targets . begin (); itr != targets . end ();)
2010-01-24 13:08:25 +01:00
{
2010-12-26 00:14:13 +01:00
// aura mustn't be already applied on target
2011-02-12 11:00:56 +01:00
if ( AuraApplication * aurApp = GetApplicationOfTarget ( itr -> first -> GetGUID ()))
2011-02-06 14:02:38 +01:00
{
2011-02-12 11:00:56 +01:00
// the core created 2 different units with same guid
// this is a major failue, which i can't fix right now
// let's remove one unit from aura list
// this may cause area aura "bouncing" between 2 units after each update
// but because we know the reason of a crash we can remove the assertion for now
if ( aurApp -> GetTarget () != itr -> first )
{
// remove from auras to register list
targets . erase ( itr ++ );
continue ;
}
else
{
// ok, we have one unit twice in target map (impossible, but...)
ASSERT ( false );
}
2011-02-06 14:02:38 +01:00
}
2010-12-26 00:14:13 +01:00
2010-01-24 13:08:25 +01:00
bool addUnit = true ;
2010-08-08 19:45:53 +02:00
// check target immunities
2011-07-26 23:09:28 +02:00
if ( itr -> first -> IsImmunedToSpell ( GetSpellInfo ())
2010-08-03 06:11:03 +02:00
|| ! CanBeAppliedOn ( itr -> first ))
2010-01-24 13:08:25 +01:00
addUnit = false ;
if ( addUnit )
{
// persistent area aura does not hit flying targets
if ( GetType () == DYNOBJ_AURA_TYPE )
{
if ( itr -> first -> isInFlight ())
addUnit = false ;
}
// unit auras can not stack with each other
else // (GetType() == UNIT_AURA_TYPE)
{
// Allow to remove by stack when aura is going to be applied on owner
if ( itr -> first != GetOwner ())
{
// check if not stacking aura already on target
// this one prevents unwanted usefull buff loss because of stacking and prevents overriding auras periodicaly by 2 near area aura owners
for ( Unit :: AuraApplicationMap :: iterator iter = itr -> first -> GetAppliedAuras (). begin (); iter != itr -> first -> GetAppliedAuras (). end (); ++ iter )
{
2011-06-11 22:35:29 +02:00
Aura const * aura = iter -> second -> GetBase ();
2011-07-26 23:09:28 +02:00
if ( ! CanStackWith ( aura ))
2010-01-24 13:08:25 +01:00
{
addUnit = false ;
break ;
}
}
}
}
}
if ( ! addUnit )
targets . erase ( itr ++ );
else
{
// owner has to be in world, or effect has to be applied to self
2011-11-11 11:29:59 -05:00
if ( ! GetOwner () -> IsSelfOrInSameMap ( itr -> first ))
{
//TODO: There is a crash caused by shadowfiend load addon
sLog -> outCrash ( "Aura %u: Owner %s (map %u) is not in the same map as target %s (map %u)." , GetSpellInfo () -> Id ,
GetOwner () -> GetName (), GetOwner () -> IsInWorld () ? GetOwner () -> GetMap () -> GetId () : uint32 ( - 1 ),
itr -> first -> GetName (), itr -> first -> IsInWorld () ? itr -> first -> GetMap () -> GetId () : uint32 ( - 1 ));
ASSERT ( false );
}
2010-01-24 13:08:25 +01:00
itr -> first -> _CreateAuraApplication ( this , itr -> second );
++ itr ;
}
}
// remove auras from units no longer needing them
for ( UnitList :: iterator itr = targetsToRemove . begin (); itr != targetsToRemove . end (); ++ itr )
if ( AuraApplication * aurApp = GetApplicationOfTarget (( * itr ) -> GetGUID ()))
( * itr ) -> _UnapplyAura ( aurApp , AURA_REMOVE_BY_DEFAULT );
if ( ! apply )
return ;
// apply aura effects for units
2011-09-29 12:43:05 +02:00
for ( std :: map < Unit * , uint8 >:: iterator itr = targets . begin (); itr != targets . end (); ++ itr )
2010-01-24 13:08:25 +01:00
{
if ( AuraApplication * aurApp = GetApplicationOfTarget ( itr -> first -> GetGUID ()))
{
// owner has to be in world, or effect has to be applied to self
2010-07-30 20:04:28 +02:00
ASSERT (( ! GetOwner () -> IsInWorld () && GetOwner () == itr -> first ) || GetOwner () -> IsInMap ( itr -> first ));
2010-01-24 13:08:25 +01:00
itr -> first -> _ApplyAura ( aurApp , itr -> second );
}
}
2009-08-25 00:43:31 -05:00
}
2009-10-17 15:51:44 -07:00
2010-01-24 13:08:25 +01:00
// targets have to be registered and not have effect applied yet to use this function
void Aura :: _ApplyEffectForTargets ( uint8 effIndex )
{
// prepare list of aura targets
UnitList targetList ;
for ( ApplicationMap :: iterator appIter = m_applications . begin (); appIter != m_applications . end (); ++ appIter )
{
2010-07-13 21:41:21 +02:00
if (( appIter -> second -> GetEffectsToApply () & ( 1 << effIndex )) && ! appIter -> second -> HasEffect ( effIndex ))
2010-01-24 13:08:25 +01:00
targetList . push_back ( appIter -> second -> GetTarget ());
}
// apply effect to targets
for ( UnitList :: iterator itr = targetList . begin (); itr != targetList . end (); ++ itr )
{
if ( GetApplicationOfTarget (( * itr ) -> GetGUID ()))
{
// owner has to be in world, or effect has to be applied to self
2010-07-30 20:04:28 +02:00
ASSERT (( ! GetOwner () -> IsInWorld () && GetOwner () == * itr ) || GetOwner () -> IsInMap ( * itr ));
2010-01-24 13:08:25 +01:00
( * itr ) -> _ApplyAuraEffect ( this , effIndex );
}
}
}
2011-09-15 14:08:17 +02:00
void Aura :: UpdateOwner ( uint32 diff , WorldObject * owner )
2009-08-25 00:43:31 -05:00
{
2010-07-30 20:04:28 +02:00
ASSERT ( owner == m_owner );
2010-01-10 01:23:15 +01:00
2011-06-11 22:35:29 +02:00
Unit * caster = GetCaster ();
2010-01-10 01:23:15 +01:00
// Apply spellmods for channeled auras
// used for example when triggered spell of spell:10 is modded
2011-06-11 22:35:29 +02:00
Spell * modSpell = NULL ;
Player * modOwner = NULL ;
2010-04-07 19:14:10 +02:00
if ( caster )
2010-04-19 17:03:10 +02:00
{
2010-04-29 23:12:16 +02:00
modOwner = caster -> GetSpellModOwner ();
if ( modOwner )
{
modSpell = modOwner -> FindCurrentSpellBySpellId ( GetId ());
if ( modSpell )
modOwner -> SetSpellModTakingSpell ( modSpell , true );
}
2010-04-19 17:03:10 +02:00
}
2010-01-10 01:23:15 +01:00
Update ( diff , caster );
2010-08-26 15:54:56 +06:00
if ( m_updateTargetMapInterval <= int32 ( diff ))
2010-01-24 18:58:06 +01:00
UpdateTargetMap ( caster );
else
m_updateTargetMapInterval -= diff ;
2010-01-10 01:23:15 +01:00
// update aura effects
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
if ( m_effects [ i ])
m_effects [ i ] -> Update ( diff , caster );
// remove spellmods after effects update
if ( modSpell )
modOwner -> SetSpellModTakingSpell ( modSpell , false );
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
_DeleteRemovedApplications ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-06-11 22:35:29 +02:00
void Aura :: Update ( uint32 diff , Unit * caster )
2008-10-11 14:16:25 -05:00
{
if ( m_duration > 0 )
{
m_duration -= diff ;
if ( m_duration < 0 )
m_duration = 0 ;
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
// handle manaPerSecond/manaPerSecondPerLevel
2010-04-07 19:14:10 +02:00
if ( m_timeCla )
2008-10-11 14:16:25 -05:00
{
2010-08-26 15:54:56 +06:00
if ( m_timeCla > int32 ( diff ))
2009-06-04 22:25:37 -05:00
m_timeCla -= diff ;
2010-04-07 19:14:10 +02:00
else if ( caster )
2008-10-11 14:16:25 -05:00
{
2011-07-26 23:09:28 +02:00
if ( int32 manaPerSecond = m_spellInfo -> ManaPerSecond + m_spellInfo -> ManaPerSecondPerLevel * caster -> getLevel ())
2008-10-11 14:16:25 -05:00
{
2009-06-04 22:25:37 -05:00
m_timeCla += 1000 - diff ;
2009-10-17 15:51:44 -07:00
2011-07-26 23:09:28 +02:00
Powers powertype = Powers ( m_spellInfo -> PowerType );
2010-04-07 19:14:10 +02:00
if ( powertype == POWER_HEALTH )
2009-03-22 11:34:34 +01:00
{
2010-08-26 15:54:56 +06:00
if ( int32 ( caster -> GetHealth ()) > manaPerSecond )
2009-03-22 11:34:34 +01:00
caster -> ModifyHealth ( - manaPerSecond );
else
2009-04-12 17:25:12 -05:00
{
2010-01-10 01:23:15 +01:00
Remove ();
2009-04-12 17:25:12 -05:00
return ;
}
2009-03-22 11:34:34 +01:00
}
else
2009-04-12 17:25:12 -05:00
{
2010-08-26 15:54:56 +06:00
if ( int32 ( caster -> GetPower ( powertype )) >= manaPerSecond )
2009-04-12 17:25:12 -05:00
caster -> ModifyPower ( powertype , - manaPerSecond );
else
{
2010-01-10 01:23:15 +01:00
Remove ();
2010-04-07 18:09:10 +02:00
return ;
2009-04-12 17:25:12 -05:00
}
}
2008-10-11 14:16:25 -05:00
}
}
}
}
2010-01-10 01:23:15 +01:00
}
2009-10-17 15:51:44 -07:00
2011-06-07 14:19:47 +02:00
int32 Aura :: CalcMaxDuration ( Unit * caster ) const
{
Player * modOwner = NULL ;
int32 maxDuration ;
if ( caster )
{
modOwner = caster -> GetSpellModOwner ();
2011-07-26 23:09:28 +02:00
maxDuration = caster -> CalcSpellDuration ( m_spellInfo );
2011-06-07 14:19:47 +02:00
}
else
2011-07-26 23:09:28 +02:00
maxDuration = m_spellInfo -> GetDuration ();
2011-06-07 14:19:47 +02:00
2011-07-26 23:09:28 +02:00
if ( IsPassive () && ! m_spellInfo -> DurationEntry )
2011-06-07 14:19:47 +02:00
maxDuration = - 1 ;
if ( ! IsPermanent () && modOwner )
modOwner -> ApplySpellMod ( GetId (), SPELLMOD_DURATION , maxDuration );
return maxDuration ;
}
2010-01-10 01:23:15 +01:00
void Aura :: SetDuration ( int32 duration , bool withMods )
{
if ( withMods )
{
2011-06-11 22:35:29 +02:00
if ( Unit * caster = GetCaster ())
if ( Player * modOwner = caster -> GetSpellModOwner ())
2010-01-10 01:23:15 +01:00
modOwner -> ApplySpellMod ( GetId (), SPELLMOD_DURATION , duration );
}
m_duration = duration ;
SetNeedClientUpdateForTargets ();
}
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
void Aura :: RefreshDuration ()
{
SetDuration ( GetMaxDuration ());
2009-10-17 15:51:44 -07:00
2011-07-26 23:09:28 +02:00
if ( m_spellInfo -> ManaPerSecond || m_spellInfo -> ManaPerSecondPerLevel )
2010-07-12 00:30:17 +02:00
m_timeCla = 1 * IN_MILLISECONDS ;
2009-04-06 13:31:14 +02:00
}
2009-10-17 15:51:44 -07:00
2011-06-09 17:04:52 +02:00
void Aura :: RefreshTimers ()
{
m_maxDuration = CalcMaxDuration ();
RefreshDuration ();
2011-06-11 22:35:29 +02:00
Unit * caster = GetCaster ();
2011-06-09 17:04:52 +02:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
if ( HasEffect ( i ))
GetEffect ( i ) -> CalculatePeriodic ( caster , false , false );
}
2010-01-10 01:23:15 +01:00
void Aura :: SetCharges ( uint8 charges )
2009-04-06 13:31:14 +02:00
{
2010-01-10 01:23:15 +01:00
if ( m_procCharges == charges )
return ;
m_procCharges = charges ;
2011-07-10 13:13:02 +02:00
m_isUsingCharges = m_procCharges != 0 ;
2010-01-10 01:23:15 +01:00
SetNeedClientUpdateForTargets ();
}
2011-06-11 22:35:29 +02:00
uint8 Aura :: CalcMaxCharges ( Unit * caster ) const
2011-06-07 17:25:34 +02:00
{
2011-07-26 23:09:28 +02:00
uint8 maxProcCharges = m_spellInfo -> ProcCharges ;
2011-07-10 13:13:02 +02:00
if ( SpellProcEntry const * procEntry = sSpellMgr -> GetSpellProcEntry ( GetId ()))
maxProcCharges = procEntry -> charges ;
2011-06-18 19:51:28 +02:00
2011-06-07 17:25:34 +02:00
if ( caster )
if ( Player * modOwner = caster -> GetSpellModOwner ())
modOwner -> ApplySpellMod ( GetId (), SPELLMOD_CHARGES , maxProcCharges );
return maxProcCharges ;
}
bool Aura :: ModCharges ( int32 num , AuraRemoveMode removeMode )
2010-01-10 01:23:15 +01:00
{
2011-07-10 13:13:02 +02:00
if ( IsUsingCharges ())
2008-10-11 14:16:25 -05:00
{
2011-06-07 17:25:34 +02:00
int32 charges = m_procCharges + num ;
int32 maxCharges = CalcMaxCharges ();
// limit charges (only on charges increase, charges may be changed manually)
if (( num > 0 ) && ( charges > int32 ( maxCharges )))
charges = maxCharges ;
// we're out of charges, remove
else if ( charges <= 0 )
2008-10-11 14:16:25 -05:00
{
2011-06-07 17:25:34 +02:00
Remove ( removeMode );
2010-01-10 01:23:15 +01:00
return true ;
2008-10-11 14:16:25 -05:00
}
2011-06-07 17:25:34 +02:00
SetCharges ( charges );
2008-10-11 14:16:25 -05:00
}
2010-01-10 01:23:15 +01:00
return false ;
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-05-29 13:18:47 +02:00
void Aura :: SetStackAmount ( uint8 stackAmount )
2008-10-11 14:16:25 -05:00
{
2011-05-29 13:18:47 +02:00
m_stackAmount = stackAmount ;
2011-06-11 22:35:29 +02:00
Unit * caster = GetCaster ();
2011-06-18 19:51:28 +02:00
2011-06-11 10:54:22 +02:00
std :: list < AuraApplication *> applications ;
GetApplicationList ( applications );
for ( std :: list < AuraApplication *>:: const_iterator apptItr = applications . begin (); apptItr != applications . end (); ++ apptItr )
if ( ! ( * apptItr ) -> GetRemoveMode ())
HandleAuraSpecificMods ( * apptItr , caster , false , true );
2011-05-29 13:18:47 +02:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
if ( HasEffect ( i ))
m_effects [ i ] -> ChangeAmount ( m_effects [ i ] -> CalculateAmount ( caster ), false , true );
2011-06-11 10:54:22 +02:00
for ( std :: list < AuraApplication *>:: const_iterator apptItr = applications . begin (); apptItr != applications . end (); ++ apptItr )
if ( ! ( * apptItr ) -> GetRemoveMode ())
HandleAuraSpecificMods ( * apptItr , caster , true , true );
2010-01-10 01:23:15 +01:00
SetNeedClientUpdateForTargets ();
}
2009-10-17 15:51:44 -07:00
2011-06-07 17:25:34 +02:00
bool Aura :: ModStackAmount ( int32 num , AuraRemoveMode removeMode )
2010-01-10 01:23:15 +01:00
{
int32 stackAmount = m_stackAmount + num ;
2011-05-29 13:18:47 +02:00
2011-06-07 17:25:34 +02:00
// limit the stack amount (only on stack increase, stack amount may be changed manually)
2011-07-26 23:09:28 +02:00
if (( num > 0 ) && ( stackAmount > int32 ( m_spellInfo -> StackAmount )))
2010-01-10 01:23:15 +01:00
{
2011-05-29 13:18:47 +02:00
// not stackable aura - set stack amount to 1
2011-07-26 23:09:28 +02:00
if ( ! m_spellInfo -> StackAmount )
2011-05-29 13:18:47 +02:00
stackAmount = 1 ;
else
2011-07-26 23:09:28 +02:00
stackAmount = m_spellInfo -> StackAmount ;
2011-05-29 13:18:47 +02:00
}
// we're out of stacks, remove
else if ( stackAmount <= 0 )
{
Remove ( removeMode );
2011-06-07 17:25:34 +02:00
return true ;
2010-01-10 01:23:15 +01:00
}
2011-05-29 13:18:47 +02:00
2010-01-10 01:23:15 +01:00
bool refresh = stackAmount >= GetStackAmount ();
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
// Update stack amount
SetStackAmount ( stackAmount );
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
if ( refresh )
2011-06-09 17:04:52 +02:00
{
2011-06-21 19:58:11 +02:00
RefreshSpellMods ();
2011-06-09 17:04:52 +02:00
RefreshTimers ();
// reset charges
SetCharges ( CalcMaxCharges ());
2011-07-09 14:59:35 +07:00
// FIXME: not a best way to synchronize charges, but works
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
if ( AuraEffect * aurEff = GetEffect ( i ))
if ( aurEff -> GetAuraType () == SPELL_AURA_ADD_FLAT_MODIFIER || aurEff -> GetAuraType () == SPELL_AURA_ADD_PCT_MODIFIER )
if ( SpellModifier * mod = aurEff -> GetSpellModifier ())
mod -> charges = GetCharges ();
2011-06-09 17:04:52 +02:00
}
2010-01-10 01:23:15 +01:00
SetNeedClientUpdateForTargets ();
2011-06-07 17:25:34 +02:00
return false ;
2010-01-10 01:23:15 +01:00
}
2009-10-17 15:51:44 -07:00
2011-06-21 19:58:11 +02:00
void Aura :: RefreshSpellMods ()
{
for ( Aura :: ApplicationMap :: const_iterator appIter = m_applications . begin (); appIter != m_applications . end (); ++ appIter )
2011-09-15 14:08:17 +02:00
if ( Player * player = appIter -> second -> GetTarget () -> ToPlayer ())
2011-06-21 19:58:11 +02:00
player -> RestoreAllSpellMods ( 0 , this );
}
2011-07-30 02:01:07 +02:00
bool Aura :: IsArea () const
{
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
{
if ( HasEffect ( i ) && GetSpellInfo () -> Effects [ i ]. IsAreaAuraEffect ())
return true ;
}
return false ;
}
2010-01-10 01:23:15 +01:00
bool Aura :: IsPassive () const
{
2011-07-26 23:09:28 +02:00
return GetSpellInfo () -> IsPassive ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-04-07 18:09:10 +02:00
bool Aura :: IsDeathPersistent () const
2008-10-11 14:16:25 -05:00
{
2011-07-26 23:09:28 +02:00
return GetSpellInfo () -> IsDeathPersistent ();
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
bool Aura :: CanBeSaved () const
2008-10-11 14:16:25 -05:00
{
2010-01-10 01:23:15 +01:00
if ( IsPassive ())
return false ;
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
if ( GetCasterGUID () != GetOwner () -> GetGUID ())
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> IsSingleTarget ())
2010-01-10 01:23:15 +01:00
return false ;
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
// Can't be saved - aura handler relies on calculated amount and changes it
if ( HasEffectType ( SPELL_AURA_CONVERT_RUNE ))
return false ;
2009-10-17 15:51:44 -07:00
2010-07-31 03:23:14 +02:00
// No point in saving this, since the stable dialog can't be open on aura load anyway.
if ( HasEffectType ( SPELL_AURA_OPEN_STABLE ))
return false ;
2011-03-22 21:51:39 +01:00
// Incanter's Absorbtion - considering the minimal duration and problems with aura stacking
// we skip saving this aura
if ( GetId () == 44413 )
return false ;
2011-07-10 13:13:02 +02:00
// don't save auras removed by proc system
if ( IsUsingCharges () && ! GetCharges ())
return false ;
2010-01-10 01:23:15 +01:00
return true ;
2009-05-16 17:59:36 +02:00
}
2009-10-17 15:51:44 -07:00
2011-06-08 10:41:32 +02:00
bool Aura :: CanBeSentToClient () const
2010-01-10 01:23:15 +01:00
{
2011-07-26 23:09:28 +02:00
return ! IsPassive () || GetSpellInfo () -> HasAreaAuraEffect () || HasEffectType ( SPELL_AURA_ABILITY_IGNORE_AURASTATE );
2009-04-06 13:31:14 +02:00
}
2009-10-17 15:51:44 -07:00
2010-01-16 15:12:21 +01:00
void Aura :: UnregisterSingleTarget ()
{
2010-07-30 20:04:28 +02:00
ASSERT ( m_isSingleTarget );
2011-06-11 22:35:29 +02:00
Unit * caster = GetCaster ();
2010-08-04 20:03:33 +02:00
// TODO: find a better way to do this.
if ( ! caster )
caster = ObjectAccessor :: GetObjectInOrOutOfWorld ( GetCasterGUID (), ( Unit * ) NULL );
2010-08-03 06:11:03 +02:00
ASSERT ( caster );
2010-01-16 15:12:21 +01:00
caster -> GetSingleCastAuras (). remove ( this );
SetIsSingleTarget ( false );
}
2011-07-26 23:09:28 +02:00
int32 Aura :: CalcDispelChance ( Unit * auraTarget , bool offensive ) const
{
// we assume that aura dispel chance is 100% on start
// need formula for level difference based chance
int32 resistChance = 0 ;
// Apply dispel mod from aura caster
if ( Unit * caster = GetCaster ())
if ( Player * modOwner = caster -> GetSpellModOwner ())
modOwner -> ApplySpellMod ( GetId (), SPELLMOD_RESIST_DISPEL_CHANCE , resistChance );
// Dispel resistance from target SPELL_AURA_MOD_DISPEL_RESIST
// Only affects offensive dispels
if ( offensive && auraTarget )
resistChance += auraTarget -> GetTotalAuraModifier ( SPELL_AURA_MOD_DISPEL_RESIST );
resistChance = resistChance < 0 ? 0 : resistChance ;
resistChance = resistChance > 100 ? 100 : resistChance ;
return 100 - resistChance ;
}
2010-01-10 01:23:15 +01:00
void Aura :: SetLoadedState ( int32 maxduration , int32 duration , int32 charges , uint8 stackamount , uint8 recalculateMask , int32 * amount )
2009-04-06 13:31:14 +02:00
{
2010-01-10 01:23:15 +01:00
m_maxDuration = maxduration ;
m_duration = duration ;
m_procCharges = charges ;
2011-07-10 13:13:02 +02:00
m_isUsingCharges = m_procCharges != 0 ;
2010-01-10 01:23:15 +01:00
m_stackAmount = stackamount ;
2011-06-11 22:35:29 +02:00
Unit * caster = GetCaster ();
2010-01-10 01:23:15 +01:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2010-04-07 19:14:10 +02:00
if ( m_effects [ i ])
2010-01-10 01:23:15 +01:00
{
m_effects [ i ] -> SetAmount ( amount [ i ]);
m_effects [ i ] -> SetCanBeRecalculated ( recalculateMask & ( 1 << i ));
2011-06-09 17:04:52 +02:00
m_effects [ i ] -> CalculatePeriodic ( caster , false , true );
2010-01-10 01:23:15 +01:00
m_effects [ i ] -> CalculateSpellMod ();
m_effects [ i ] -> RecalculateAmount ( caster );
}
2009-04-06 13:31:14 +02:00
}
2009-10-17 15:51:44 -07:00
2010-07-13 21:41:21 +02:00
bool Aura :: HasEffectType ( AuraType type ) const
{
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
{
2011-05-29 13:18:47 +02:00
if ( HasEffect ( i ) && m_effects [ i ] -> GetAuraType () == type )
2010-07-13 21:41:21 +02:00
return true ;
}
return false ;
}
void Aura :: RecalculateAmountOfEffects ()
{
2010-07-30 20:04:28 +02:00
ASSERT ( ! IsRemoved ());
2011-06-11 22:35:29 +02:00
Unit * caster = GetCaster ();
2010-07-13 21:41:21 +02:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
2011-05-29 13:18:47 +02:00
if ( HasEffect ( i ))
2010-07-13 21:41:21 +02:00
m_effects [ i ] -> RecalculateAmount ( caster );
}
2011-05-31 16:03:27 +02:00
void Aura :: HandleAllEffects ( AuraApplication * aurApp , uint8 mode , bool apply )
2010-07-13 21:41:21 +02:00
{
2010-07-30 20:04:28 +02:00
ASSERT ( ! IsRemoved ());
2010-07-13 21:41:21 +02:00
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
if ( m_effects [ i ] && ! IsRemoved ())
m_effects [ i ] -> HandleEffect ( aurApp , mode , apply );
}
2011-06-11 10:54:22 +02:00
void Aura :: GetApplicationList ( std :: list < AuraApplication *> & applicationList ) const
{
for ( Aura :: ApplicationMap :: const_iterator appIter = m_applications . begin (); appIter != m_applications . end (); ++ appIter )
{
if ( appIter -> second -> GetEffectMask ())
applicationList . push_back ( appIter -> second );
}
}
2010-07-13 21:41:21 +02:00
void Aura :: SetNeedClientUpdateForTargets () const
{
for ( ApplicationMap :: const_iterator appIter = m_applications . begin (); appIter != m_applications . end (); ++ appIter )
appIter -> second -> SetNeedClientUpdate ();
}
2010-01-10 01:23:15 +01:00
// trigger effects on real aura apply/remove
2011-06-11 22:35:29 +02:00
void Aura :: HandleAuraSpecificMods ( AuraApplication const * aurApp , Unit * caster , bool apply , bool onReapply )
2009-07-19 14:02:52 +02:00
{
2011-06-11 22:35:29 +02:00
Unit * target = aurApp -> GetTarget ();
2010-01-10 01:23:15 +01:00
AuraRemoveMode removeMode = aurApp -> GetRemoveMode ();
2011-06-26 19:31:11 +02:00
// handle spell_area table
2010-12-22 21:25:23 +01:00
SpellAreaForAreaMapBounds saBounds = sSpellMgr -> GetSpellAreaForAuraMapBounds ( GetId ());
2010-04-07 19:14:10 +02:00
if ( saBounds . first != saBounds . second )
2010-01-10 01:23:15 +01:00
{
uint32 zone , area ;
2011-04-29 20:47:02 +02:00
target -> GetZoneAndAreaId ( zone , area );
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
for ( SpellAreaForAreaMap :: const_iterator itr = saBounds . first ; itr != saBounds . second ; ++ itr )
{
// some auras remove at aura remove
2011-04-29 20:47:02 +02:00
if ( ! itr -> second -> IsFitToRequirements (( Player * ) target , zone , area ))
2010-01-10 01:23:15 +01:00
target -> RemoveAurasDueToSpell ( itr -> second -> spellId );
// some auras applied at aura apply
2010-04-07 19:14:10 +02:00
else if ( itr -> second -> autocast )
2010-01-10 01:23:15 +01:00
{
2010-04-07 22:59:46 +02:00
if ( ! target -> HasAura ( itr -> second -> spellId ))
2011-04-29 20:47:02 +02:00
target -> CastSpell ( target , itr -> second -> spellId , true );
2010-01-10 01:23:15 +01:00
}
}
}
2011-06-26 19:31:11 +02:00
// handle spell_linked_spell table
if ( ! onReapply )
2009-08-03 01:17:03 +02:00
{
2011-06-26 19:31:11 +02:00
// apply linked auras
if ( apply )
2009-08-08 17:47:15 +02:00
{
2011-07-26 23:09:28 +02:00
if ( std :: vector < int32 > const * spellTriggered = sSpellMgr -> GetSpellLinked ( GetId () + SPELL_LINK_AURA ))
2011-06-26 19:31:11 +02:00
{
for ( std :: vector < int32 >:: const_iterator itr = spellTriggered -> begin (); itr != spellTriggered -> end (); ++ itr )
2009-08-08 17:47:15 +02:00
{
2010-04-07 19:14:10 +02:00
if ( * itr < 0 )
2010-01-10 01:23:15 +01:00
target -> ApplySpellImmune ( GetId (), IMMUNITY_ID , - ( * itr ), true );
2010-04-07 19:14:10 +02:00
else if ( caster )
2010-01-10 01:23:15 +01:00
caster -> AddAura ( * itr , target );
2009-08-08 17:47:15 +02:00
}
2011-06-26 19:31:11 +02:00
}
}
else
{
// remove linked auras
2011-07-26 23:09:28 +02:00
if ( std :: vector < int32 > const * spellTriggered = sSpellMgr -> GetSpellLinked ( - ( int32 ) GetId ()))
2011-06-26 19:31:11 +02:00
{
for ( std :: vector < int32 >:: const_iterator itr = spellTriggered -> begin (); itr != spellTriggered -> end (); ++ itr )
{
if ( * itr < 0 )
target -> RemoveAurasDueToSpell ( - ( * itr ));
else if ( removeMode != AURA_REMOVE_BY_DEATH )
target -> CastSpell ( target , * itr , true , NULL , NULL , GetCasterGUID ());
}
}
2011-07-26 23:09:28 +02:00
if ( std :: vector < int32 > const * spellTriggered = sSpellMgr -> GetSpellLinked ( GetId () + SPELL_LINK_AURA ))
2011-06-26 19:31:11 +02:00
{
for ( std :: vector < int32 >:: const_iterator itr = spellTriggered -> begin (); itr != spellTriggered -> end (); ++ itr )
{
if ( * itr < 0 )
target -> ApplySpellImmune ( GetId (), IMMUNITY_ID , - ( * itr ), false );
else
target -> RemoveAura ( * itr , GetCasterGUID (), 0 , removeMode );
}
}
}
}
else if ( apply )
{
// modify stack amount of linked auras
2011-07-26 23:09:28 +02:00
if ( std :: vector < int32 > const * spellTriggered = sSpellMgr -> GetSpellLinked ( GetId () + SPELL_LINK_AURA ))
2011-06-26 19:31:11 +02:00
{
for ( std :: vector < int32 >:: const_iterator itr = spellTriggered -> begin (); itr != spellTriggered -> end (); ++ itr )
if ( * itr > 0 )
if ( Aura * triggeredAura = target -> GetAura ( * itr , GetCasterGUID ()))
triggeredAura -> ModStackAmount ( GetStackAmount () - triggeredAura -> GetStackAmount ());
2009-08-08 17:47:15 +02:00
}
2011-06-26 19:31:11 +02:00
}
// mods at aura apply
if ( apply )
{
2011-07-26 23:09:28 +02:00
switch ( GetSpellInfo () -> SpellFamilyName )
2009-08-03 03:22:08 +02:00
{
2010-01-10 01:23:15 +01:00
case SPELLFAMILY_GENERIC :
2011-09-29 12:43:05 +02:00
switch ( GetId ())
2009-10-16 13:33:46 -07:00
{
2010-01-10 01:23:15 +01:00
case 32474 : // Buffeting Winds of Susurrus
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> ActivateTaxiPathTo ( 506 , GetId ());
2010-01-10 01:23:15 +01:00
break ;
case 33572 : // Gronn Lord's Grasp, becomes stoned
2010-04-07 19:14:10 +02:00
if ( GetStackAmount () >= 5 && ! target -> HasAura ( 33652 ))
2010-01-10 01:23:15 +01:00
target -> CastSpell ( target , 33652 , true );
break ;
2010-06-19 23:51:33 +02:00
case 50836 : //Petrifying Grip, becomes stoned
if ( GetStackAmount () >= 5 && ! target -> HasAura ( 50812 ))
target -> CastSpell ( target , 50812 , true );
break ;
2010-01-10 01:23:15 +01:00
case 60970 : // Heroic Fury (remove Intercept cooldown)
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> RemoveSpellCooldown ( 20252 , true );
2010-01-10 01:23:15 +01:00
break ;
2009-10-16 13:33:46 -07:00
}
2010-01-10 01:23:15 +01:00
break ;
2011-05-11 12:28:04 +03:00
case SPELLFAMILY_DRUID :
if ( ! caster )
break ;
// Rejuvenation
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x10 && GetEffect ( EFFECT_0 ))
2011-05-11 12:28:04 +03:00
{
// Druid T8 Restoration 4P Bonus
2011-05-13 17:25:41 +02:00
if ( caster -> HasAura ( 64760 ))
2011-05-11 12:28:04 +03:00
{
int32 heal = GetEffect ( EFFECT_0 ) -> GetAmount ();
caster -> CastCustomSpell ( target , 64801 , & heal , NULL , NULL , true , NULL , GetEffect ( EFFECT_0 ));
}
2011-05-13 20:15:36 +07:00
}
2011-05-11 12:28:04 +03:00
break ;
2010-01-10 01:23:15 +01:00
case SPELLFAMILY_MAGE :
if ( ! caster )
break ;
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x00000001 && GetSpellInfo () -> SpellFamilyFlags [ 2 ] & 0x00000008 )
2010-01-10 01:23:15 +01:00
{
// Glyph of Fireball
2009-08-03 14:52:30 +02:00
if ( caster -> HasAura ( 56368 ))
2010-01-10 01:23:15 +01:00
SetDuration ( 0 );
}
2011-07-26 23:09:28 +02:00
else if ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x00000020 && GetSpellInfo () -> SpellVisual [ 0 ] == 13 )
2010-01-10 01:23:15 +01:00
{
// Glyph of Frostbolt
2009-08-03 14:52:30 +02:00
if ( caster -> HasAura ( 56370 ))
2010-01-10 01:23:15 +01:00
SetDuration ( 0 );
}
// Todo: This should be moved to similar function in spell::hit
2011-07-26 23:09:28 +02:00
else if ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x01000000 )
2009-08-03 14:52:30 +02:00
{
2010-01-10 01:23:15 +01:00
// Polymorph Sound - Sheep && Penguin
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellIconID == 82 && GetSpellInfo () -> SpellVisual [ 0 ] == 12978 )
2010-01-10 01:23:15 +01:00
{
// Glyph of the Penguin
if ( caster -> HasAura ( 52648 ))
2011-04-29 20:47:02 +02:00
caster -> CastSpell ( target , 61635 , true );
2010-01-10 01:23:15 +01:00
else
2011-04-29 20:47:02 +02:00
caster -> CastSpell ( target , 61634 , true );
2010-01-10 01:23:15 +01:00
}
2009-08-03 14:52:30 +02:00
}
2011-09-29 12:43:05 +02:00
switch ( GetId ())
2010-01-10 01:23:15 +01:00
{
case 12536 : // Clearcasting
case 12043 : // Presence of Mind
// Arcane Potency
2011-06-11 22:35:29 +02:00
if ( AuraEffect const * aurEff = caster -> GetAuraEffect ( SPELL_AURA_DUMMY , SPELLFAMILY_MAGE , 2120 , 0 ))
2010-01-10 01:23:15 +01:00
{
2010-07-16 18:05:25 +02:00
uint32 spellId = 0 ;
switch ( aurEff -> GetId ())
2010-01-10 01:23:15 +01:00
{
2010-07-16 18:05:25 +02:00
case 31571 : spellId = 57529 ; break ;
case 31572 : spellId = 57531 ; break ;
default :
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Aura::HandleAuraSpecificMods: Unknown rank of Arcane Potency (%d) found" , aurEff -> GetId ());
2010-01-10 01:23:15 +01:00
}
2010-07-16 18:05:25 +02:00
if ( spellId )
caster -> CastSpell ( caster , spellId , true );
2010-01-10 01:23:15 +01:00
}
break ;
2010-09-27 20:30:47 +02:00
case 44544 : // Fingers of Frost
{
// See if we already have the indicator aura. If not, create one.
2011-06-20 04:04:20 +07:00
if ( Aura * aur = target -> GetAura ( 74396 ))
2010-09-27 20:30:47 +02:00
{
// Aura already there. Refresh duration and set original charges
aur -> SetCharges ( 2 );
aur -> RefreshDuration ();
}
else
target -> AddAura ( 74396 , target );
}
default :
break ;
2010-01-10 01:23:15 +01:00
}
break ;
case SPELLFAMILY_WARLOCK :
2011-09-29 12:43:05 +02:00
switch ( GetId ())
2009-08-28 15:36:17 +02:00
{
2010-01-10 01:23:15 +01:00
case 48020 : // Demonic Circle
2010-04-07 19:14:10 +02:00
if ( target -> GetTypeId () == TYPEID_PLAYER )
if ( GameObject * obj = target -> GetGameObject ( 48018 ))
2010-12-11 20:37:38 +06:00
{
2011-04-29 23:04:18 +03:00
target -> NearTeleportTo ( obj -> GetPositionX (), obj -> GetPositionY (), obj -> GetPositionZ (), obj -> GetOrientation ());
target -> RemoveMovementImpairingAuras ();
2010-12-11 20:37:38 +06:00
}
2010-01-10 01:23:15 +01:00
break ;
2009-08-28 15:36:17 +02:00
}
2010-01-10 01:23:15 +01:00
break ;
case SPELLFAMILY_PRIEST :
2009-09-14 12:47:26 -07:00
if ( ! caster )
2010-01-10 01:23:15 +01:00
break ;
// Devouring Plague
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x02000000 && GetEffect ( 0 ))
2009-09-14 12:47:26 -07:00
{
2010-01-10 01:23:15 +01:00
// Improved Devouring Plague
2011-06-11 22:35:29 +02:00
if ( AuraEffect const * aurEff = caster -> GetDummyAuraEffect ( SPELLFAMILY_PRIEST , 3790 , 1 ))
2010-01-10 01:23:15 +01:00
{
2011-07-26 23:09:28 +02:00
int32 basepoints0 = aurEff -> GetAmount () * GetEffect ( 0 ) -> GetTotalTicks () * caster -> SpellDamageBonus ( target , GetSpellInfo (), GetEffect ( 0 ) -> GetAmount (), DOT ) / 100 ;
2011-05-15 00:55:41 +07:00
int32 heal = int32 ( CalculatePctN ( basepoints0 , 15 ));
2010-01-10 01:23:15 +01:00
caster -> CastCustomSpell ( target , 63675 , & basepoints0 , NULL , NULL , true , NULL , GetEffect ( 0 ));
2011-05-15 00:55:41 +07:00
caster -> CastCustomSpell ( caster , 75999 , & heal , NULL , NULL , true , NULL , GetEffect ( 0 ));
2010-01-10 01:23:15 +01:00
}
2009-09-14 12:47:26 -07:00
}
2010-01-10 01:23:15 +01:00
// Renew
2011-07-26 23:09:28 +02:00
else if ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x00000040 && GetEffect ( 0 ))
2009-08-27 22:39:06 +02:00
{
2010-01-10 01:23:15 +01:00
// Empowered Renew
2011-06-11 22:35:29 +02:00
if ( AuraEffect const * aurEff = caster -> GetDummyAuraEffect ( SPELLFAMILY_PRIEST , 3021 , 1 ))
2009-08-27 22:39:06 +02:00
{
2011-07-26 23:09:28 +02:00
int32 basepoints0 = aurEff -> GetAmount () * GetEffect ( 0 ) -> GetTotalTicks () * caster -> SpellHealingBonus ( target , GetSpellInfo (), GetEffect ( 0 ) -> GetAmount (), HEAL ) / 100 ;
2010-01-10 01:23:15 +01:00
caster -> CastCustomSpell ( target , 63544 , & basepoints0 , NULL , NULL , true , NULL , GetEffect ( 0 ));
2009-08-27 22:39:06 +02:00
}
}
2010-01-10 01:23:15 +01:00
// Power Word: Shield
2011-07-26 23:09:28 +02:00
else if ( m_spellInfo -> SpellFamilyFlags [ 0 ] & 0x1 && m_spellInfo -> SpellFamilyFlags [ 2 ] & 0x400 && GetEffect ( 0 ))
2009-08-27 22:39:06 +02:00
{
2010-01-10 01:23:15 +01:00
// Glyph of Power Word: Shield
2011-04-29 20:47:02 +02:00
if ( AuraEffect * glyph = caster -> GetAuraEffect ( 55672 , 0 ))
2009-08-27 22:39:06 +02:00
{
2010-01-10 01:23:15 +01:00
// instantly heal m_amount% of the absorb-value
int32 heal = glyph -> GetAmount () * GetEffect ( 0 ) -> GetAmount () / 100 ;
caster -> CastCustomSpell ( GetUnitOwner (), 56160 , & heal , NULL , NULL , true , 0 , GetEffect ( 0 ));
2009-08-27 22:39:06 +02:00
}
}
2010-01-10 01:23:15 +01:00
break ;
case SPELLFAMILY_ROGUE :
// Sprint (skip non player casted spells by category)
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x40 && GetSpellInfo () -> Category == 44 )
2010-01-10 01:23:15 +01:00
// in official maybe there is only one icon?
2010-04-07 19:14:10 +02:00
if ( target -> HasAura ( 58039 )) // Glyph of Blurred Speed
2010-01-10 01:23:15 +01:00
target -> CastSpell ( target , 61922 , true ); // Sprint (waterwalk)
break ;
case SPELLFAMILY_DEATHKNIGHT :
if ( ! caster )
2009-08-17 16:21:50 -05:00
break ;
2010-01-10 01:23:15 +01:00
// Frost Fever and Blood Plague
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 2 ] & 0x2 )
2010-01-10 01:23:15 +01:00
{
// Can't proc on self
if ( GetCasterGUID () == target -> GetGUID ())
break ;
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
AuraEffect * aurEff = NULL ;
2010-01-10 01:23:15 +01:00
// Ebon Plaguebringer / Crypt Fever
Unit :: AuraEffectList const & TalentAuras = caster -> GetAuraEffectsByType ( SPELL_AURA_OVERRIDE_CLASS_SCRIPTS );
for ( Unit :: AuraEffectList :: const_iterator itr = TalentAuras . begin (); itr != TalentAuras . end (); ++ itr )
{
if (( * itr ) -> GetMiscValue () == 7282 )
{
aurEff = * itr ;
// Ebon Plaguebringer - end search if found
2011-07-26 23:09:28 +02:00
if (( * itr ) -> GetSpellInfo () -> SpellIconID == 1766 )
2010-01-10 01:23:15 +01:00
break ;
}
}
if ( aurEff )
{
uint32 spellId = 0 ;
switch ( aurEff -> GetId ())
{
// Ebon Plague
case 51161 : spellId = 51735 ; break ;
case 51160 : spellId = 51734 ; break ;
case 51099 : spellId = 51726 ; break ;
// Crypt Fever
case 49632 : spellId = 50510 ; break ;
case 49631 : spellId = 50509 ; break ;
case 49032 : spellId = 50508 ; break ;
default :
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Aura::HandleAuraSpecificMods: Unknown rank of Crypt Fever/Ebon Plague (%d) found" , aurEff -> GetId ());
2010-01-10 01:23:15 +01:00
}
caster -> CastSpell ( target , spellId , true , 0 , GetEffect ( 0 ));
}
}
break ;
2009-08-11 19:57:27 +02:00
}
}
2010-01-10 01:23:15 +01:00
// mods at aura remove
else
2009-07-19 14:02:52 +02:00
{
2011-09-29 12:43:05 +02:00
switch ( GetSpellInfo () -> SpellFamilyName )
2009-07-19 14:02:52 +02:00
{
2010-03-26 22:21:33 +01:00
case SPELLFAMILY_GENERIC :
2011-09-29 12:43:05 +02:00
switch ( GetId ())
2010-05-20 20:09:18 +02:00
{
case 61987 : // Avenging Wrath
// Remove the immunity shield marker on Avenging Wrath removal if Forbearance is not present
if ( target -> HasAura ( 61988 ) && ! target -> HasAura ( 25771 ))
target -> RemoveAura ( 61988 );
break ;
case 72368 : // Shared Suffering
case 72369 :
if ( caster )
{
if ( AuraEffect * aurEff = GetEffect ( 0 ))
{
int32 remainingDamage = aurEff -> GetAmount () * ( aurEff -> GetTotalTicks () - aurEff -> GetTickNumber ());
if ( remainingDamage > 0 )
caster -> CastCustomSpell ( caster , 72373 , NULL , & remainingDamage , NULL , true );
}
}
break ;
}
2010-03-26 22:21:33 +01:00
break ;
2010-01-10 01:23:15 +01:00
case SPELLFAMILY_MAGE :
2011-09-29 12:43:05 +02:00
switch ( GetId ())
2009-07-19 14:02:52 +02:00
{
2010-01-10 01:23:15 +01:00
case 66 : // Invisibility
if ( removeMode != AURA_REMOVE_BY_EXPIRE )
break ;
target -> CastSpell ( target , 32612 , true , NULL , GetEffect ( 1 ));
2011-12-21 02:16:06 +01:00
target -> CombatStop ();
2010-01-10 01:23:15 +01:00
break ;
2010-09-27 20:30:47 +02:00
case 74396 : // Fingers of Frost
// Remove the IGNORE_AURASTATE aura
target -> RemoveAurasDueToSpell ( 44544 );
break ;
2010-08-23 13:26:25 -03:00
case 44401 : //Missile Barrage
case 48108 : //Hot Streak
case 57761 : //Fireball!
if ( removeMode != AURA_REMOVE_BY_EXPIRE || aurApp -> GetBase () -> IsExpired ())
break ;
if ( target -> HasAura ( 70752 )) //Item - Mage T10 2P Bonus
target -> CastSpell ( target , 70753 , true );
break ;
2010-09-27 20:30:47 +02:00
default :
break ;
2009-07-19 14:02:52 +02:00
}
2010-01-10 01:23:15 +01:00
if ( ! caster )
break ;
// Ice barrier - dispel/absorb remove
2011-07-26 23:09:28 +02:00
if ( removeMode == AURA_REMOVE_BY_ENEMY_SPELL && GetSpellInfo () -> SpellFamilyFlags [ 1 ] & 0x1 )
2009-07-19 14:02:52 +02:00
{
2010-01-10 01:23:15 +01:00
// Shattered Barrier
2011-09-05 16:40:54 +02:00
if ( AuraEffect * dummy = caster -> GetDummyAuraEffect ( SPELLFAMILY_MAGE , 2945 , 0 ))
if ( roll_chance_i ( dummy -> GetSpellInfo () -> ProcChance ))
caster -> CastSpell ( target , 55080 , true , NULL , GetEffect ( 0 ));
2009-07-19 14:02:52 +02:00
}
2010-01-10 01:23:15 +01:00
break ;
case SPELLFAMILY_WARRIOR :
if ( ! caster )
break ;
// Spell Reflection
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 1 ] & 0x2 )
2009-08-13 00:52:05 +02:00
{
2010-01-10 01:23:15 +01:00
if ( removeMode != AURA_REMOVE_BY_DEFAULT )
2009-08-13 00:52:05 +02:00
{
2010-01-10 01:23:15 +01:00
// Improved Spell Reflection
2011-04-29 20:47:02 +02:00
if ( caster -> GetDummyAuraEffect ( SPELLFAMILY_WARRIOR , 1935 , 1 ))
2009-10-16 13:33:46 -07:00
{
2010-01-10 01:23:15 +01:00
// aura remove - remove auras from all party members
std :: list < Unit *> PartyMembers ;
target -> GetPartyMembers ( PartyMembers );
2010-04-08 08:20:08 +02:00
for ( std :: list < Unit *>:: iterator itr = PartyMembers . begin (); itr != PartyMembers . end (); ++ itr )
2010-01-10 01:23:15 +01:00
{
if (( * itr ) != target )
( * itr ) -> RemoveAurasWithFamily ( SPELLFAMILY_WARRIOR , 0 , 0x2 , 0 , GetCasterGUID ());
}
2009-10-16 13:33:46 -07:00
}
}
}
2010-01-10 01:23:15 +01:00
break ;
case SPELLFAMILY_WARLOCK :
if ( ! caster )
2009-08-13 00:52:05 +02:00
break ;
2010-01-10 01:23:15 +01:00
// Curse of Doom
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 1 ] & 0x02 )
2010-01-10 01:23:15 +01:00
{
if ( removeMode == AURA_REMOVE_BY_DEATH )
2009-12-21 15:45:28 +02:00
{
2010-03-07 15:20:19 +01:00
if ( caster -> GetTypeId () == TYPEID_PLAYER && caster -> ToPlayer () -> isHonorOrXPTarget ( target ))
2010-01-10 01:23:15 +01:00
caster -> CastSpell ( target , 18662 , true , NULL , GetEffect ( 0 ));
2009-12-21 15:45:28 +02:00
}
2010-01-10 01:23:15 +01:00
}
// Improved Fear
2011-07-26 23:09:28 +02:00
else if ( GetSpellInfo () -> SpellFamilyFlags [ 1 ] & 0x00000400 )
2009-08-13 00:52:05 +02:00
{
2010-03-18 14:57:39 +01:00
if ( AuraEffect * aurEff = caster -> GetAuraEffect ( SPELL_AURA_DUMMY , SPELLFAMILY_WARLOCK , 98 , 0 ))
2009-08-13 00:52:05 +02:00
{
2010-03-18 14:57:39 +01:00
uint32 spellId = 0 ;
switch ( aurEff -> GetId ())
2009-08-13 00:52:05 +02:00
{
2010-03-18 14:57:39 +01:00
case 53759 : spellId = 60947 ; break ;
case 53754 : spellId = 60946 ; break ;
default :
2010-12-23 23:25:44 +01:00
sLog -> outError ( "Aura::HandleAuraSpecificMods: Unknown rank of Improved Fear (%d) found" , aurEff -> GetId ());
2009-08-13 00:52:05 +02:00
}
2010-03-18 14:57:39 +01:00
if ( spellId )
caster -> CastSpell ( target , spellId , true );
2009-08-13 00:52:05 +02:00
}
}
2011-09-29 12:43:05 +02:00
switch ( GetId ())
2009-10-15 14:27:29 -07:00
{
2010-01-10 01:23:15 +01:00
case 48018 : // Demonic Circle
2011-06-11 10:54:22 +02:00
// Do not remove GO when aura is removed by stack
// to prevent remove GO added by new spell
// old one is already removed
if ( ! onReapply )
target -> RemoveGameObject ( GetId (), true );
2010-01-10 01:23:15 +01:00
target -> RemoveAura ( 62388 );
2009-08-13 00:52:05 +02:00
break ;
2009-10-15 14:27:29 -07:00
}
2010-01-10 01:23:15 +01:00
break ;
case SPELLFAMILY_PRIEST :
if ( ! caster )
2009-08-13 00:52:05 +02:00
break ;
2010-01-10 01:23:15 +01:00
// Shadow word: Pain // Vampiric Touch
2011-07-26 23:09:28 +02:00
if ( removeMode == AURA_REMOVE_BY_ENEMY_SPELL && ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x00008000 || GetSpellInfo () -> SpellFamilyFlags [ 1 ] & 0x00000400 ))
2009-08-13 00:52:05 +02:00
{
2010-01-10 01:23:15 +01:00
// Shadow Affinity
2011-06-11 22:35:29 +02:00
if ( AuraEffect const * aurEff = caster -> GetDummyAuraEffect ( SPELLFAMILY_PRIEST , 178 , 1 ))
2009-08-13 00:52:05 +02:00
{
2010-03-04 17:49:10 -06:00
int32 basepoints0 = aurEff -> GetAmount () * caster -> GetCreateMana () / 100 ;
2010-01-10 01:23:15 +01:00
caster -> CastCustomSpell ( caster , 64103 , & basepoints0 , NULL , NULL , true , NULL , GetEffect ( 0 ));
2009-08-13 00:52:05 +02:00
}
}
2010-01-10 01:23:15 +01:00
// Power word: shield
2011-07-26 23:09:28 +02:00
else if ( removeMode == AURA_REMOVE_BY_ENEMY_SPELL && GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x00000001 )
2009-08-13 00:52:05 +02:00
{
2010-01-10 01:23:15 +01:00
// Rapture
2011-06-11 22:35:29 +02:00
if ( Aura const * aura = caster -> GetAuraOfRankedSpell ( 47535 ))
2009-08-13 00:52:05 +02:00
{
2010-01-10 01:23:15 +01:00
// check cooldown
2009-08-13 00:52:05 +02:00
if ( caster -> GetTypeId () == TYPEID_PLAYER )
{
2010-03-07 15:20:19 +01:00
if ( caster -> ToPlayer () -> HasSpellCooldown ( aura -> GetId ()))
2010-01-10 01:23:15 +01:00
break ;
// and add if needed
2010-03-07 15:20:19 +01:00
caster -> ToPlayer () -> AddSpellCooldown ( aura -> GetId (), 0 , uint32 ( time ( NULL ) + 12 ));
2009-08-13 00:52:05 +02:00
}
2010-01-10 01:23:15 +01:00
// effect on caster
2011-06-11 22:35:29 +02:00
if ( AuraEffect const * aurEff = aura -> GetEffect ( 0 ))
2009-12-21 15:45:28 +02:00
{
2010-08-22 12:39:39 -07:00
float multiplier = ( float ) aurEff -> GetAmount ();
2010-01-10 01:23:15 +01:00
if ( aurEff -> GetId () == 47535 )
multiplier -= 0.5f ;
else if ( aurEff -> GetId () == 47537 )
multiplier += 0.5f ;
2010-12-11 20:37:38 +06:00
int32 basepoints0 = int32 ( CalculatePctF ( caster -> GetMaxPower ( POWER_MANA ), multiplier ));
2009-12-21 15:45:28 +02:00
caster -> CastCustomSpell ( caster , 47755 , & basepoints0 , NULL , NULL , true );
}
2010-01-10 01:23:15 +01:00
// effect on aura target
2011-06-11 22:35:29 +02:00
if ( AuraEffect const * aurEff = aura -> GetEffect ( 1 ))
2009-12-21 15:45:28 +02:00
{
2010-01-10 01:23:15 +01:00
if ( ! roll_chance_i ( aurEff -> GetAmount ()))
2009-12-21 15:45:28 +02:00
break ;
2010-01-10 01:23:15 +01:00
int32 triggeredSpellId = 0 ;
2011-09-29 12:43:05 +02:00
switch ( target -> getPowerType ())
2009-12-21 15:45:28 +02:00
{
2010-01-10 01:23:15 +01:00
case POWER_MANA :
2009-12-21 15:45:28 +02:00
{
2010-12-11 20:37:38 +06:00
int32 basepoints0 = int32 ( CalculatePctN ( target -> GetMaxPower ( POWER_MANA ), 2 ));
2010-01-10 01:23:15 +01:00
caster -> CastCustomSpell ( target , 63654 , & basepoints0 , NULL , NULL , true );
2009-12-21 15:45:28 +02:00
break ;
}
2010-01-10 01:23:15 +01:00
case POWER_RAGE : triggeredSpellId = 63653 ; break ;
case POWER_ENERGY : triggeredSpellId = 63655 ; break ;
case POWER_RUNIC_POWER : triggeredSpellId = 63652 ; break ;
2010-08-21 20:08:47 +02:00
default :
break ;
2009-12-21 15:45:28 +02:00
}
2010-01-10 01:23:15 +01:00
if ( triggeredSpellId )
caster -> CastSpell ( target , triggeredSpellId , true );
2009-12-21 15:45:28 +02:00
}
}
}
2011-09-29 12:43:05 +02:00
switch ( GetId ())
2009-03-13 20:24:40 +01:00
{
2010-01-10 01:23:15 +01:00
case 47788 : // Guardian Spirit
if ( removeMode != AURA_REMOVE_BY_EXPIRE )
break ;
2010-04-07 19:14:10 +02:00
if ( caster -> GetTypeId () != TYPEID_PLAYER )
2010-01-10 01:23:15 +01:00
break ;
2009-10-17 15:51:44 -07:00
2011-06-12 01:47:45 +02:00
Player * player = caster -> ToPlayer ();
2010-01-10 01:23:15 +01:00
// Glyph of Guardian Spirit
2011-09-15 14:08:17 +02:00
if ( AuraEffect * aurEff = player -> GetAuraEffect ( 63231 , 0 ))
2010-01-10 01:23:15 +01:00
{
if ( ! player -> HasSpellCooldown ( 47788 ))
break ;
2009-10-17 15:51:44 -07:00
2011-07-26 23:09:28 +02:00
player -> RemoveSpellCooldown ( GetSpellInfo () -> Id , true );
player -> AddSpellCooldown ( GetSpellInfo () -> Id , 0 , uint32 ( time ( NULL ) + aurEff -> GetAmount ()));
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
WorldPacket data ( SMSG_SPELL_COOLDOWN , 8 + 1 + 4 + 4 );
data << uint64 ( player -> GetGUID ());
data << uint8 ( 0x0 ); // flags (0x1, 0x2)
2011-07-26 23:09:28 +02:00
data << uint32 ( GetSpellInfo () -> Id );
2010-07-12 00:30:17 +02:00
data << uint32 ( aurEff -> GetAmount () * IN_MILLISECONDS );
2010-01-10 01:23:15 +01:00
player -> SendDirectMessage ( & data );
2009-06-12 11:59:58 +02:00
}
2010-01-10 01:23:15 +01:00
break ;
2009-12-20 18:02:57 +01:00
}
2010-01-10 01:23:15 +01:00
break ;
2010-11-13 07:14:56 +01:00
case SPELLFAMILY_ROGUE :
// Remove Vanish on stealth remove
if ( GetId () == 1784 )
target -> RemoveAurasWithFamily ( SPELLFAMILY_ROGUE , 0x0000800 , 0 , 0 , target -> GetGUID ());
break ;
2010-03-26 22:21:33 +01:00
case SPELLFAMILY_PALADIN :
// Remove the immunity shield marker on Forbearance removal if AW marker is not present
if ( GetId () == 25771 && target -> HasAura ( 61988 ) && ! target -> HasAura ( 61987 ))
target -> RemoveAura ( 61988 );
break ;
2010-01-10 01:23:15 +01:00
case SPELLFAMILY_DEATHKNIGHT :
2010-01-23 10:33:16 +01:00
// Blood of the North
// Reaping
// Death Rune Mastery
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellIconID == 3041 || GetSpellInfo () -> SpellIconID == 22 || GetSpellInfo () -> SpellIconID == 2622 )
2010-01-23 10:33:16 +01:00
{
if ( ! GetEffect ( 0 ) || GetEffect ( 0 ) -> GetAuraType () != SPELL_AURA_PERIODIC_DUMMY )
break ;
if ( target -> GetTypeId () != TYPEID_PLAYER )
break ;
2010-04-07 19:14:10 +02:00
if ( target -> ToPlayer () -> getClass () != CLASS_DEATH_KNIGHT )
2010-01-23 10:33:16 +01:00
break ;
// aura removed - remove death runes
2010-03-07 15:20:19 +01:00
target -> ToPlayer () -> RemoveRunesByAuraEffect ( GetEffect ( 0 ));
2010-01-23 10:33:16 +01:00
}
2010-04-07 18:09:10 +02:00
break ;
2011-05-02 18:36:08 +03:00
case SPELLFAMILY_HUNTER :
// Glyph of Freezing Trap
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x00000008 )
2011-05-02 18:36:08 +03:00
if ( caster && caster -> HasAura ( 56845 ))
target -> CastSpell ( target , 61394 , true );
break ;
2008-12-24 09:58:26 -06:00
}
2010-01-10 01:23:15 +01:00
}
// mods at aura apply or remove
2011-07-26 23:09:28 +02:00
switch ( GetSpellInfo () -> SpellFamilyName )
2010-01-10 01:23:15 +01:00
{
2010-05-27 21:11:38 +02:00
case SPELLFAMILY_GENERIC :
2010-12-18 23:16:55 +01:00
switch ( GetId ())
2010-05-27 21:11:38 +02:00
{
case 50720 : // Vigilance
if ( apply )
target -> CastSpell ( caster , 59665 , true , 0 , 0 , caster -> GetGUID ());
else
2011-04-29 20:47:02 +02:00
target -> SetReducedThreatPercent ( 0 , 0 );
2010-05-27 21:11:38 +02:00
break ;
}
break ;
2011-12-19 23:29:04 -05:00
case SPELLFAMILY_DRUID :
// Enrage
if (( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x80000 ) && GetSpellInfo () -> SpellIconID == 961 )
{
if ( target -> HasAura ( 70726 )) // Item - Druid T10 Feral 4P Bonus
if ( apply )
target -> CastSpell ( target , 70725 , true );
break ;
}
break ;
2008-12-24 09:58:26 -06:00
case SPELLFAMILY_ROGUE :
2010-01-10 01:23:15 +01:00
// Stealth
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x00400000 )
2009-03-08 19:18:02 +01:00
{
2010-01-10 01:23:15 +01:00
// Master of subtlety
2011-06-11 22:35:29 +02:00
if ( AuraEffect const * aurEff = target -> GetAuraEffectOfRankedSpell ( 31221 , 0 ))
2009-06-04 16:18:52 -05:00
{
2010-01-10 01:23:15 +01:00
if ( ! apply )
2011-04-29 20:47:02 +02:00
target -> CastSpell ( target , 31666 , true );
2010-01-10 01:23:15 +01:00
else
2009-06-04 16:18:52 -05:00
{
2010-01-10 01:23:15 +01:00
int32 basepoints0 = aurEff -> GetAmount ();
2011-09-29 12:43:05 +02:00
target -> CastCustomSpell ( target , 31665 , & basepoints0 , NULL , NULL , true );
2009-06-04 16:18:52 -05:00
}
}
// Overkill
2010-01-10 01:23:15 +01:00
if ( target -> HasAura ( 58426 ))
{
if ( ! apply )
2011-04-29 20:47:02 +02:00
target -> CastSpell ( target , 58428 , true );
2010-01-10 01:23:15 +01:00
else
2011-04-29 20:47:02 +02:00
target -> CastSpell ( target , 58427 , true );
2010-01-10 01:23:15 +01:00
}
break ;
2009-03-08 19:18:02 +01:00
}
2008-12-24 09:58:26 -06:00
break ;
case SPELLFAMILY_HUNTER :
2011-09-29 12:43:05 +02:00
switch ( GetId ())
2008-12-24 09:58:26 -06:00
{
2010-01-10 01:23:15 +01:00
case 19574 : // Bestial Wrath
// The Beast Within cast on owner if talent present
2010-04-07 22:59:46 +02:00
if ( Unit * owner = target -> GetOwner ())
2010-01-10 01:23:15 +01:00
{
// Search talent
if ( owner -> HasAura ( 34692 ))
{
if ( apply )
owner -> CastSpell ( owner , 34471 , true , 0 , GetEffect ( 0 ));
else
owner -> RemoveAurasDueToSpell ( 34471 );
}
}
2008-12-24 09:58:26 -06:00
break ;
}
break ;
2010-01-10 01:23:15 +01:00
case SPELLFAMILY_PALADIN :
2011-09-29 12:43:05 +02:00
switch ( GetId ())
2009-01-10 11:30:45 -06:00
{
2010-01-10 01:23:15 +01:00
case 19746 :
case 31821 :
// Aura Mastery Triggered Spell Handler
// If apply Concentration Aura -> trigger -> apply Aura Mastery Immunity
// If remove Concentration Aura -> trigger -> remove Aura Mastery Immunity
// If remove Aura Mastery -> trigger -> remove Aura Mastery Immunity
// Do effects only on aura owner
if ( GetCasterGUID () != target -> GetGUID ())
break ;
if ( apply )
{
2011-07-26 23:09:28 +02:00
if (( GetSpellInfo () -> Id == 31821 && target -> HasAura ( 19746 , GetCasterGUID ())) || ( GetSpellInfo () -> Id == 19746 && target -> HasAura ( 31821 )))
2011-04-29 20:47:02 +02:00
target -> CastSpell ( target , 64364 , true );
2010-01-10 01:23:15 +01:00
}
else
target -> RemoveAurasDueToSpell ( 64364 , GetCasterGUID ());
break ;
2011-06-20 03:39:07 +07:00
case 31842 : // Divine Illumination
// Item - Paladin T10 Holy 2P Bonus
if ( target -> HasAura ( 70755 ))
2011-05-11 12:15:26 +03:00
{
if ( apply )
2011-06-20 03:39:07 +07:00
target -> CastSpell ( target , 71166 , true );
2011-05-11 12:15:26 +03:00
else
2011-06-20 03:39:07 +07:00
target -> RemoveAurasDueToSpell ( 71166 );
2011-05-11 12:15:26 +03:00
}
break ;
2009-01-10 11:30:45 -06:00
}
2008-12-24 09:58:26 -06:00
break ;
case SPELLFAMILY_DEATHKNIGHT :
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> GetSpellSpecific () == SPELL_SPECIFIC_PRESENCE )
2009-11-18 16:45:07 -08:00
{
2011-09-15 14:08:17 +02:00
AuraEffect * bloodPresenceAura = 0 ; // healing by damage done
AuraEffect * frostPresenceAura = 0 ; // increased health
AuraEffect * unholyPresenceAura = 0 ; // increased movement speed, faster rune recovery
2009-11-18 16:45:07 -08:00
2010-01-10 01:23:15 +01:00
// Improved Presences
Unit :: AuraEffectList const & vDummyAuras = target -> GetAuraEffectsByType ( SPELL_AURA_DUMMY );
for ( Unit :: AuraEffectList :: const_iterator itr = vDummyAuras . begin (); itr != vDummyAuras . end (); ++ itr )
2008-12-24 09:58:26 -06:00
{
2011-09-29 12:43:05 +02:00
switch (( * itr ) -> GetId ())
2010-01-10 01:23:15 +01:00
{
// Improved Blood Presence
case 50365 :
case 50371 :
{
bloodPresenceAura = ( * itr );
break ;
}
// Improved Frost Presence
case 50384 :
case 50385 :
{
frostPresenceAura = ( * itr );
break ;
}
// Improved Unholy Presence
case 50391 :
case 50392 :
{
unholyPresenceAura = ( * itr );
break ;
}
}
2008-12-24 09:58:26 -06:00
}
2009-10-17 15:51:44 -07:00
2011-07-15 04:58:14 +07:00
uint32 presence = GetId ();
2010-01-10 01:23:15 +01:00
if ( apply )
2009-08-05 02:36:26 +02:00
{
2010-01-10 01:23:15 +01:00
// Blood Presence bonus
2010-02-15 18:23:39 +01:00
if ( presence == 48266 )
target -> CastSpell ( target , 63611 , true );
2010-01-10 01:23:15 +01:00
else if ( bloodPresenceAura )
2009-08-05 02:36:26 +02:00
{
2011-07-15 04:58:14 +07:00
int32 basePoints1 = bloodPresenceAura -> GetAmount ();
2011-04-29 20:47:02 +02:00
target -> CastCustomSpell ( target , 63611 , NULL , & basePoints1 , NULL , true , 0 , bloodPresenceAura );
2009-08-05 02:36:26 +02:00
}
2010-01-10 01:23:15 +01:00
// Frost Presence bonus
2010-02-15 18:23:39 +01:00
if ( presence == 48263 )
target -> CastSpell ( target , 61261 , true );
2010-01-10 01:23:15 +01:00
else if ( frostPresenceAura )
2009-08-05 02:36:26 +02:00
{
2011-07-16 01:02:50 +07:00
int32 basePoints0 = frostPresenceAura -> GetAmount ();
2011-04-29 20:47:02 +02:00
target -> CastCustomSpell ( target , 61261 , & basePoints0 , NULL , NULL , true , 0 , frostPresenceAura );
2010-01-10 01:23:15 +01:00
}
// Unholy Presence bonus
2010-02-15 18:23:39 +01:00
if ( presence == 48265 )
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( unholyPresenceAura )
2010-01-10 01:23:15 +01:00
{
// Not listed as any effect, only base points set
2011-07-26 23:09:28 +02:00
int32 basePoints0 = unholyPresenceAura -> GetSpellInfo () -> Effects [ EFFECT_1 ]. CalcValue ();
2011-09-29 12:43:05 +02:00
target -> CastCustomSpell ( target , 63622 , & basePoints0 , & basePoints0 , & basePoints0 , true , 0 , unholyPresenceAura );
2010-01-10 01:23:15 +01:00
}
2011-04-29 20:47:02 +02:00
target -> CastSpell ( target , 49772 , true );
2010-01-10 01:23:15 +01:00
}
else if ( unholyPresenceAura )
{
2011-07-15 04:58:14 +07:00
int32 basePoints0 = unholyPresenceAura -> GetAmount ();
2011-04-29 20:47:02 +02:00
target -> CastCustomSpell ( target , 49772 , & basePoints0 , NULL , NULL , true , 0 , unholyPresenceAura );
2010-01-10 01:23:15 +01:00
}
}
else
{
// Remove passive auras
2010-02-15 18:23:39 +01:00
if ( presence == 48266 || bloodPresenceAura )
2010-01-10 01:23:15 +01:00
target -> RemoveAurasDueToSpell ( 63611 );
2010-02-15 18:23:39 +01:00
if ( presence == 48263 || frostPresenceAura )
2010-01-10 01:23:15 +01:00
target -> RemoveAurasDueToSpell ( 61261 );
2010-02-15 18:23:39 +01:00
if ( presence == 48265 || unholyPresenceAura )
2010-01-10 01:23:15 +01:00
{
2010-04-07 19:14:10 +02:00
if ( presence == 48265 && unholyPresenceAura )
2010-02-18 01:06:47 +01:00
target -> RemoveAurasDueToSpell ( 63622 );
2010-01-10 01:23:15 +01:00
target -> RemoveAurasDueToSpell ( 49772 );
2009-08-05 02:36:26 +02:00
}
}
}
2008-12-24 09:58:26 -06:00
break ;
2010-03-17 16:38:31 +01:00
case SPELLFAMILY_WARLOCK :
// Drain Soul - If the target is at or below 25% health, Drain Soul causes four times the normal damage
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> SpellFamilyFlags [ 0 ] & 0x00004000 )
2010-03-17 16:38:31 +01:00
{
2010-03-19 16:30:07 +01:00
if ( ! caster )
break ;
2010-03-17 16:38:31 +01:00
if ( apply )
{
2010-08-26 01:20:57 +06:00
if ( target != caster && ! target -> HealthAbovePct ( 25 ))
2011-05-13 12:17:21 +03:00
caster -> CastSpell ( caster , 100001 , true );
2010-03-17 16:38:31 +01:00
}
else
{
if ( target != caster )
caster -> RemoveAurasDueToSpell ( GetId ());
else
2011-05-13 12:17:21 +03:00
caster -> RemoveAurasDueToSpell ( 100001 );
2010-03-17 16:38:31 +01:00
}
}
break ;
2008-10-11 14:16:25 -05:00
}
}
2009-10-17 15:51:44 -07:00
2011-06-12 01:47:45 +02:00
bool Aura :: CanBeAppliedOn ( Unit * target )
2010-08-03 06:11:03 +02:00
{
// unit not in world or during remove from world
if ( ! target -> IsInWorld () || target -> IsDuringRemoveFromWorld ())
{
// area auras mustn't be applied
if ( GetOwner () != target )
return false ;
// not selfcasted single target auras mustn't be applied
2011-07-26 23:09:28 +02:00
if ( GetCasterGUID () != GetOwner () -> GetGUID () && GetSpellInfo () -> IsSingleTarget ())
2010-08-03 06:11:03 +02:00
return false ;
2011-05-31 20:02:55 +02:00
return true ;
2010-08-03 06:11:03 +02:00
}
2011-05-31 20:02:55 +02:00
else
2010-08-03 06:11:03 +02:00
return CheckAreaTarget ( target );
}
2011-05-31 20:02:55 +02:00
bool Aura :: CheckAreaTarget ( Unit * target )
2008-10-11 14:16:25 -05:00
{
2011-05-31 20:02:55 +02:00
return CallScriptCheckAreaTargetHandlers ( target );
2008-10-11 14:16:25 -05:00
}
2009-10-17 15:51:44 -07:00
2011-07-26 23:09:28 +02:00
bool Aura :: CanStackWith ( Aura const * existingAura ) const
{
// Can stack with self
if ( this == existingAura )
return true ;
// Dynobj auras always stack
if ( existingAura -> GetType () == DYNOBJ_AURA_TYPE )
return true ;
SpellInfo const * existingSpellInfo = existingAura -> GetSpellInfo ();
bool sameCaster = GetCasterGUID () == existingAura -> GetCasterGUID ();
2011-07-28 03:08:42 +02:00
// passive auras don't stack with another rank of the spell cast by same caster
if ( IsPassive () && sameCaster && m_spellInfo -> IsDifferentRankOf ( existingSpellInfo ))
2011-07-26 23:09:28 +02:00
return false ;
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
{
// prevent remove triggering aura by triggered aura
if ( existingSpellInfo -> Effects [ i ]. TriggerSpell == GetId ()
// prevent remove triggered aura by triggering aura refresh
|| m_spellInfo -> Effects [ i ]. TriggerSpell == existingAura -> GetId ())
return true ;
}
// check spell specific stack rules
if ( m_spellInfo -> IsAuraExclusiveBySpecificWith ( existingSpellInfo )
|| ( sameCaster && m_spellInfo -> IsAuraExclusiveBySpecificPerCasterWith ( existingSpellInfo )))
return false ;
// check spell group stack rules
SpellGroupStackRule stackRule = sSpellMgr -> CheckSpellGroupStackRules ( m_spellInfo , existingSpellInfo );
if ( stackRule )
{
if ( stackRule == SPELL_GROUP_STACK_RULE_EXCLUSIVE )
return false ;
if ( sameCaster && stackRule == SPELL_GROUP_STACK_RULE_EXCLUSIVE_FROM_SAME_CASTER )
return false ;
}
if ( m_spellInfo -> SpellFamilyName != existingSpellInfo -> SpellFamilyName )
return true ;
if ( ! sameCaster )
{
if ( m_spellInfo -> AttributesEx3 & SPELL_ATTR3_STACK_FOR_DIFF_CASTERS )
return true ;
// check same periodic auras
for ( uint32 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
{
switch ( m_spellInfo -> Effects [ i ]. ApplyAuraName )
{
// DOT or HOT from different casters will stack
case SPELL_AURA_PERIODIC_DAMAGE :
case SPELL_AURA_PERIODIC_DUMMY :
case SPELL_AURA_PERIODIC_HEAL :
case SPELL_AURA_PERIODIC_TRIGGER_SPELL :
case SPELL_AURA_PERIODIC_ENERGIZE :
case SPELL_AURA_PERIODIC_MANA_LEECH :
case SPELL_AURA_PERIODIC_LEECH :
2011-08-31 12:11:38 +03:00
case SPELL_AURA_POWER_BURN :
2011-07-26 23:09:28 +02:00
case SPELL_AURA_OBS_MOD_POWER :
case SPELL_AURA_OBS_MOD_HEALTH :
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE :
// periodic auras which target areas are not allowed to stack this way (replenishment for example)
if ( m_spellInfo -> Effects [ i ]. IsArea () || existingSpellInfo -> Effects [ i ]. IsArea ())
break ;
return true ;
default :
break ;
}
}
}
bool isVehicleAura1 = false ;
bool isVehicleAura2 = false ;
uint8 i = 0 ;
while ( i < MAX_SPELL_EFFECTS && ! ( isVehicleAura1 && isVehicleAura2 ))
{
if ( m_spellInfo -> Effects [ i ]. ApplyAuraName == SPELL_AURA_CONTROL_VEHICLE )
isVehicleAura1 = true ;
if ( existingSpellInfo -> Effects [ i ]. ApplyAuraName == SPELL_AURA_CONTROL_VEHICLE )
isVehicleAura2 = true ;
++ i ;
}
if ( isVehicleAura1 && isVehicleAura2 )
{
Vehicle * veh = NULL ;
if ( GetOwner () -> ToUnit ())
veh = GetOwner () -> ToUnit () -> GetVehicleKit ();
if ( ! veh ) // We should probably just let it stack. Vehicle system will prevent undefined behaviour later
return true ;
if ( ! veh -> GetAvailableSeatCount ())
return false ; // No empty seat available
return true ; // Empty seat available (skip rest)
}
// spell of same spell rank chain
if ( m_spellInfo -> IsRankOf ( existingSpellInfo ))
{
2011-07-30 02:01:07 +02:00
// don't allow passive area auras to stack
if ( m_spellInfo -> IsMultiSlotAura () && ! IsArea ())
2011-07-26 23:09:28 +02:00
return true ;
if ( GetCastItemGUID () && existingAura -> GetCastItemGUID ())
if ( GetCastItemGUID () != existingAura -> GetCastItemGUID () && ( m_spellInfo -> AttributesCu & SPELL_ATTR0_CU_ENCHANT_PROC ))
return true ;
// same spell with same caster should not stack
return false ;
}
return true ;
}
2011-07-10 13:13:02 +02:00
bool Aura :: IsProcOnCooldown () const
{
/*if (m_procCooldown)
{
if (m_procCooldown > time(NULL))
return true;
}*/
return false ;
}
2011-07-18 14:49:08 +02:00
void Aura :: AddProcCooldown ( uint32 /*msec*/ )
2011-07-10 13:13:02 +02:00
{
//m_procCooldown = time(NULL) + msec;
}
void Aura :: PrepareProcToTrigger ()
{
// TODO: allow scripts to prevent charge drop/cooldown
// take one charge, aura expiration will be handled in Aura::TriggerProcOnEvent (if needed)
if ( IsUsingCharges ())
{
-- m_procCharges ;
SetNeedClientUpdateForTargets ();
}
SpellProcEntry const * procEntry = sSpellMgr -> GetSpellProcEntry ( GetId ());
ASSERT ( procEntry );
// cooldowns should be added to the whole aura (see 51698 area aura)
AddProcCooldown ( procEntry -> cooldown );
}
bool Aura :: IsProcTriggeredOnEvent ( AuraApplication * aurApp , ProcEventInfo & eventInfo ) const
{
SpellProcEntry const * procEntry = sSpellMgr -> GetSpellProcEntry ( GetId ());
// only auras with spell proc entry can trigger proc
if ( ! procEntry )
return false ;
// check if we have charges to proc with
if ( IsUsingCharges () && ! GetCharges ())
return false ;
// check proc cooldown
if ( IsProcOnCooldown ())
return false ;
// TODO:
// something about triggered spells triggering, and add extra attack effect
// do checks against db data
if ( ! sSpellMgr -> CanSpellTriggerProcOnEvent ( * procEntry , eventInfo ))
return false ;
// Check if current equipment meets aura requirements
// do that only for passive spells
// TODO: this needs to be unified for all kinds of auras
Unit * target = aurApp -> GetTarget ();
if ( IsPassive () && target -> GetTypeId () == TYPEID_PLAYER )
{
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> EquippedItemClass == ITEM_CLASS_WEAPON )
2011-07-10 13:13:02 +02:00
{
if ( target -> ToPlayer () -> IsInFeralForm ())
return false ;
if ( eventInfo . GetDamageInfo ())
{
WeaponAttackType attType = eventInfo . GetDamageInfo () -> GetAttackType ();
2011-09-15 14:08:17 +02:00
Item * item = NULL ;
2011-07-10 13:13:02 +02:00
if ( attType == BASE_ATTACK )
item = target -> ToPlayer () -> GetUseableItemByPos ( INVENTORY_SLOT_BAG_0 , EQUIPMENT_SLOT_MAINHAND );
else if ( attType == OFF_ATTACK )
item = target -> ToPlayer () -> GetUseableItemByPos ( INVENTORY_SLOT_BAG_0 , EQUIPMENT_SLOT_OFFHAND );
else
item = target -> ToPlayer () -> GetUseableItemByPos ( INVENTORY_SLOT_BAG_0 , EQUIPMENT_SLOT_RANGED );
2011-07-26 23:09:28 +02:00
if ( ! item || item -> IsBroken () || item -> GetTemplate () -> Class != ITEM_CLASS_WEAPON || ! (( 1 << item -> GetTemplate () -> SubClass ) & GetSpellInfo () -> EquippedItemSubClassMask ))
2011-07-10 13:13:02 +02:00
return false ;
}
}
2011-07-26 23:09:28 +02:00
else if ( GetSpellInfo () -> EquippedItemClass == ITEM_CLASS_ARMOR )
2011-07-10 13:13:02 +02:00
{
// Check if player is wearing shield
2011-09-15 14:08:17 +02:00
Item * item = target -> ToPlayer () -> GetUseableItemByPos ( INVENTORY_SLOT_BAG_0 , EQUIPMENT_SLOT_OFFHAND );
2011-07-26 23:09:28 +02:00
if ( ! item || item -> IsBroken () || item -> GetTemplate () -> Class != ITEM_CLASS_ARMOR || ! (( 1 << item -> GetTemplate () -> SubClass ) & GetSpellInfo () -> EquippedItemSubClassMask ))
2011-07-10 13:13:02 +02:00
return false ;
}
}
return roll_chance_f ( CalcProcChance ( * procEntry , eventInfo ));
}
float Aura :: CalcProcChance ( SpellProcEntry const & procEntry , ProcEventInfo & eventInfo ) const
{
float chance = procEntry . chance ;
// calculate chances depending on unit with caster's data
// so talents modifying chances and judgements will have properly calculated proc chance
2011-09-15 14:08:17 +02:00
if ( Unit * caster = GetCaster ())
2011-07-10 13:13:02 +02:00
{
// calculate ppm chance if present and we're using weapon
if ( eventInfo . GetDamageInfo () && procEntry . ratePerMinute != 0 )
{
uint32 WeaponSpeed = caster -> GetAttackTime ( eventInfo . GetDamageInfo () -> GetAttackType ());
2011-07-26 23:09:28 +02:00
chance = caster -> GetPPMProcChance ( WeaponSpeed , procEntry . ratePerMinute , GetSpellInfo ());
2011-07-10 13:13:02 +02:00
}
// apply chance modifer aura, applies also to ppm chance (see improved judgement of light spell)
if ( Player * modOwner = caster -> GetSpellModOwner ())
modOwner -> ApplySpellMod ( GetId (), SPELLMOD_CHANCE_OF_SUCCESS , chance );
}
return chance ;
}
void Aura :: TriggerProcOnEvent ( AuraApplication * aurApp , ProcEventInfo & eventInfo )
{
// TODO: script hooks here (allowing prevention of selected effects)
for ( uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++ i )
if ( aurApp -> HasEffect ( i ))
GetEffect ( i ) -> HandleProc ( aurApp , eventInfo );
// TODO: script hooks here
// Remove aura if we've used last charge to proc
if ( IsUsingCharges () && ! GetCharges ())
Remove ();
}
2010-01-10 01:23:15 +01:00
void Aura :: _DeleteRemovedApplications ()
2008-12-03 19:42:06 -06:00
{
2010-04-07 19:13:19 +02:00
while ( ! m_removedApplications . empty ())
2009-05-05 16:56:15 -05:00
{
2010-01-10 01:23:15 +01:00
delete m_removedApplications . front ();
m_removedApplications . pop_front ();
2009-05-23 20:40:14 -05:00
}
2008-12-24 09:58:26 -06:00
}
2009-10-17 15:51:44 -07:00
2010-08-24 00:10:49 +02:00
void Aura :: LoadScripts ()
{
2011-07-26 23:09:28 +02:00
sScriptMgr -> CreateAuraScripts ( m_spellInfo -> Id , m_loadedScripts );
2011-09-15 14:08:17 +02:00
for ( std :: list < AuraScript *>:: iterator itr = m_loadedScripts . begin (); itr != m_loadedScripts . end () ;)
2010-08-24 00:10:49 +02:00
{
if ( ! ( * itr ) -> _Load ( this ))
{
2011-09-15 14:08:17 +02:00
std :: list < AuraScript *>:: iterator bitr = itr ;
2010-08-24 00:10:49 +02:00
++ itr ;
m_loadedScripts . erase ( bitr );
continue ;
}
2011-12-31 13:10:13 +01:00
sLog -> outDebug ( LOG_FILTER_SPELLS_AURAS , "Aura::LoadScripts: Script `%s` for aura `%u` is loaded now" , ( * itr ) -> _GetScriptName () -> c_str (), m_spellInfo -> Id );
2010-08-24 00:10:49 +02:00
( * itr ) -> Register ();
++ itr ;
}
}
2011-05-31 20:02:55 +02:00
bool Aura :: CallScriptCheckAreaTargetHandlers ( Unit * target )
{
2011-06-12 02:30:32 +02:00
for ( std :: list < AuraScript *>:: iterator scritr = m_loadedScripts . begin (); scritr != m_loadedScripts . end () ; ++ scritr )
2011-05-31 20:02:55 +02:00
{
( * scritr ) -> _PrepareScriptCall ( AURA_SCRIPT_HOOK_CHECK_AREA_TARGET );
std :: list < AuraScript :: CheckAreaTargetHandler >:: iterator hookItrEnd = ( * scritr ) -> DoCheckAreaTarget . end (), hookItr = ( * scritr ) -> DoCheckAreaTarget . begin ();
for (; hookItr != hookItrEnd ; ++ hookItr )
2011-06-12 02:30:32 +02:00
if ( ! ( * hookItr ). Call ( * scritr , target ))
2011-05-31 20:02:55 +02:00
return false ;
( * scritr ) -> _FinishScriptCall ();
}
return true ;
}
2011-06-11 22:35:29 +02:00
bool Aura :: CallScriptEffectApplyHandlers ( AuraEffect const * aurEff , AuraApplication const * aurApp , AuraEffectHandleModes mode )
2010-08-24 00:10:49 +02:00
{
bool preventDefault = false ;
2011-09-15 14:08:17 +02:00
for ( std :: list < AuraScript *>:: iterator scritr = m_loadedScripts . begin (); scritr != m_loadedScripts . end () ; ++ scritr )
2010-08-24 00:10:49 +02:00
{
2010-12-27 20:14:54 +01:00
( * scritr ) -> _PrepareScriptCall ( AURA_SCRIPT_HOOK_EFFECT_APPLY , aurApp );
2010-08-24 00:10:49 +02:00
std :: list < AuraScript :: EffectApplyHandler >:: iterator effEndItr = ( * scritr ) -> OnEffectApply . end (), effItr = ( * scritr ) -> OnEffectApply . begin ();
2011-06-12 02:30:32 +02:00
for (; effItr != effEndItr ; ++ effItr )
2010-08-24 00:10:49 +02:00
{
2011-07-26 23:09:28 +02:00
if (( * effItr ). IsEffectAffected ( m_spellInfo , aurEff -> GetEffIndex ()))
2010-12-27 20:14:54 +01:00
( * effItr ). Call ( * scritr , aurEff , mode );
2010-08-24 00:10:49 +02:00
}
if ( ! preventDefault )
2010-10-04 17:44:49 +02:00
preventDefault = ( * scritr ) -> _IsDefaultActionPrevented ();
( * scritr ) -> _FinishScriptCall ();
2010-08-24 00:10:49 +02:00
}
return preventDefault ;
}
2011-06-11 22:35:29 +02:00
bool Aura :: CallScriptEffectRemoveHandlers ( AuraEffect const * aurEff , AuraApplication const * aurApp , AuraEffectHandleModes mode )
2010-08-24 00:10:49 +02:00
{
bool preventDefault = false ;
2011-09-15 14:08:17 +02:00
for ( std :: list < AuraScript *>:: iterator scritr = m_loadedScripts . begin (); scritr != m_loadedScripts . end () ; ++ scritr )
2010-08-24 00:10:49 +02:00
{
2010-12-27 20:14:54 +01:00
( * scritr ) -> _PrepareScriptCall ( AURA_SCRIPT_HOOK_EFFECT_REMOVE , aurApp );
2010-08-24 00:10:49 +02:00
std :: list < AuraScript :: EffectApplyHandler >:: iterator effEndItr = ( * scritr ) -> OnEffectRemove . end (), effItr = ( * scritr ) -> OnEffectRemove . begin ();
2011-06-12 02:30:32 +02:00
for (; effItr != effEndItr ; ++ effItr )
2010-08-24 00:10:49 +02:00
{
2011-07-26 23:09:28 +02:00
if (( * effItr ). IsEffectAffected ( m_spellInfo , aurEff -> GetEffIndex ()))
2010-12-27 20:14:54 +01:00
( * effItr ). Call ( * scritr , aurEff , mode );
2010-08-24 00:10:49 +02:00
}
if ( ! preventDefault )
2010-10-04 17:44:49 +02:00
preventDefault = ( * scritr ) -> _IsDefaultActionPrevented ();
( * scritr ) -> _FinishScriptCall ();
2010-08-24 00:10:49 +02:00
}
return preventDefault ;
}
2011-06-11 22:35:29 +02:00
void Aura :: CallScriptAfterEffectApplyHandlers ( AuraEffect const * aurEff , AuraApplication const * aurApp , AuraEffectHandleModes mode )
2011-05-25 17:13:32 +02:00
{
2011-09-15 14:08:17 +02:00
for ( std :: list < AuraScript *>:: iterator scritr = m_loadedScripts . begin (); scritr != m_loadedScripts . end () ; ++ scritr )
2011-05-25 17:13:32 +02:00
{
2011-05-26 16:12:33 +02:00
( * scritr ) -> _PrepareScriptCall ( AURA_SCRIPT_HOOK_EFFECT_AFTER_APPLY , aurApp );
2011-05-25 17:13:32 +02:00
std :: list < AuraScript :: EffectApplyHandler >:: iterator effEndItr = ( * scritr ) -> AfterEffectApply . end (), effItr = ( * scritr ) -> AfterEffectApply . begin ();
2011-06-12 02:30:32 +02:00
for (; effItr != effEndItr ; ++ effItr )
2011-05-25 17:13:32 +02:00
{
2011-07-26 23:09:28 +02:00
if (( * effItr ). IsEffectAffected ( m_spellInfo , aurEff -> GetEffIndex ()))
2011-05-25 17:13:32 +02:00
( * effItr ). Call ( * scritr , aurEff , mode );
}
( * scritr ) -> _FinishScriptCall ();
}
}
2011-06-11 22:35:29 +02:00
void Aura :: CallScriptAfterEffectRemoveHandlers ( AuraEffect const * aurEff , AuraApplication const * aurApp , AuraEffectHandleModes mode )
2011-05-25 17:13:32 +02:00
{
2011-09-15 14:08:17 +02:00
for ( std :: list < AuraScript *>:: iterator scritr = m_loadedScripts . begin (); scritr != m_loadedScripts . end () ; ++ scritr )
2011-05-25 17:13:32 +02:00
{
2011-05-26 16:12:33 +02:00
( * scritr ) -> _PrepareScriptCall ( AURA_SCRIPT_HOOK_EFFECT_AFTER_REMOVE , aurApp );
2011-05-25 17:13:32 +02:00
std :: list < AuraScript :: EffectApplyHandler >:: iterator effEndItr = ( * scritr ) -> AfterEffectRemove . end (), effItr = ( * scritr ) -> AfterEffectRemove . begin ();
2011-06-12 02:30:32 +02:00
for (; effItr != effEndItr ; ++ effItr )
2011-05-25 17:13:32 +02:00
{
2011-07-26 23:09:28 +02:00
if (( * effItr ). IsEffectAffected ( m_spellInfo , aurEff -> GetEffIndex ()))
2011-05-25 17:13:32 +02:00
( * effItr ). Call ( * scritr , aurEff , mode );
}
( * scritr ) -> _FinishScriptCall ();
}
}
2011-06-11 22:35:29 +02:00
bool Aura :: CallScriptEffectPeriodicHandlers ( AuraEffect const * aurEff , AuraApplication const * aurApp )
2010-08-24 00:10:49 +02:00
{
bool preventDefault = false ;
2011-09-15 14:08:17 +02:00
for ( std :: list < AuraScript *>:: iterator scritr = m_loadedScripts . begin (); scritr != m_loadedScripts . end () ; ++ scritr )
2010-08-24 00:10:49 +02:00
{
2010-12-27 20:14:54 +01:00
( * scritr ) -> _PrepareScriptCall ( AURA_SCRIPT_HOOK_EFFECT_PERIODIC , aurApp );
2010-08-24 00:10:49 +02:00
std :: list < AuraScript :: EffectPeriodicHandler >:: iterator effEndItr = ( * scritr ) -> OnEffectPeriodic . end (), effItr = ( * scritr ) -> OnEffectPeriodic . begin ();
2011-06-12 02:30:32 +02:00
for (; effItr != effEndItr ; ++ effItr )
2010-08-24 00:10:49 +02:00
{
2011-07-26 23:09:28 +02:00
if (( * effItr ). IsEffectAffected ( m_spellInfo , aurEff -> GetEffIndex ()))
2010-12-27 20:14:54 +01:00
( * effItr ). Call ( * scritr , aurEff );
2010-08-24 00:10:49 +02:00
}
if ( ! preventDefault )
2010-10-04 17:44:49 +02:00
preventDefault = ( * scritr ) -> _IsDefaultActionPrevented ();
( * scritr ) -> _FinishScriptCall ();
2010-08-24 00:10:49 +02:00
}
return preventDefault ;
}
2011-09-15 14:08:17 +02:00
void Aura :: CallScriptEffectUpdatePeriodicHandlers ( AuraEffect * aurEff )
2010-08-24 00:10:49 +02:00
{
2011-09-15 14:08:17 +02:00
for ( std :: list < AuraScript *>:: iterator scritr = m_loadedScripts . begin (); scritr != m_loadedScripts . end () ; ++ scritr )
2010-08-24 00:10:49 +02:00
{
2010-10-04 17:44:49 +02:00
( * scritr ) -> _PrepareScriptCall ( AURA_SCRIPT_HOOK_EFFECT_UPDATE_PERIODIC );
2010-08-24 00:10:49 +02:00
std :: list < AuraScript :: EffectUpdatePeriodicHandler >:: iterator effEndItr = ( * scritr ) -> OnEffectUpdatePeriodic . end (), effItr = ( * scritr ) -> OnEffectUpdatePeriodic . begin ();
2011-06-12 02:30:32 +02:00
for (; effItr != effEndItr ; ++ effItr )
2010-08-24 00:10:49 +02:00
{
2011-07-26 23:09:28 +02:00
if (( * effItr ). IsEffectAffected ( m_spellInfo , aurEff -> GetEffIndex ()))
2010-08-24 00:10:49 +02:00
( * effItr ). Call ( * scritr , aurEff );
}
2010-10-04 17:44:49 +02:00
( * scritr ) -> _FinishScriptCall ();
2010-08-24 00:10:49 +02:00
}
}
2011-06-11 22:35:29 +02:00
void Aura :: CallScriptEffectCalcAmountHandlers ( AuraEffect const * aurEff , int32 & amount , bool & canBeRecalculated )
2010-08-24 00:10:49 +02:00
{
2011-09-15 14:08:17 +02:00
for ( std :: list < AuraScript *>:: iterator scritr = m_loadedScripts . begin (); scritr != m_loadedScripts . end () ; ++ scritr )
2010-08-24 00:10:49 +02:00
{
2010-10-04 17:44:49 +02:00
( * scritr ) -> _PrepareScriptCall ( AURA_SCRIPT_HOOK_EFFECT_CALC_AMOUNT );
2010-12-27 20:14:54 +01:00
std :: list < AuraScript :: EffectCalcAmountHandler >:: iterator effEndItr = ( * scritr ) -> DoEffectCalcAmount . end (), effItr = ( * scritr ) -> DoEffectCalcAmount . begin ();
2011-06-12 02:30:32 +02:00
for (; effItr != effEndItr ; ++ effItr )
2010-08-24 00:10:49 +02:00
{
2011-07-26 23:09:28 +02:00
if (( * effItr ). IsEffectAffected ( m_spellInfo , aurEff -> GetEffIndex ()))
2010-08-24 00:10:49 +02:00
( * effItr ). Call ( * scritr , aurEff , amount , canBeRecalculated );
}
2010-10-04 17:44:49 +02:00
( * scritr ) -> _FinishScriptCall ();
2010-08-24 00:10:49 +02:00
}
}
2011-06-11 22:35:29 +02:00
void Aura :: CallScriptEffectCalcPeriodicHandlers ( AuraEffect const * aurEff , bool & isPeriodic , int32 & amplitude )
2010-08-24 00:10:49 +02:00
{
2011-09-15 14:08:17 +02:00
for ( std :: list < AuraScript *>:: iterator scritr = m_loadedScripts . begin (); scritr != m_loadedScripts . end () ; ++ scritr )
2010-08-24 00:10:49 +02:00
{
2010-10-04 17:44:49 +02:00
( * scritr ) -> _PrepareScriptCall ( AURA_SCRIPT_HOOK_EFFECT_CALC_PERIODIC );
2010-12-27 20:14:54 +01:00
std :: list < AuraScript :: EffectCalcPeriodicHandler >:: iterator effEndItr = ( * scritr ) -> DoEffectCalcPeriodic . end (), effItr = ( * scritr ) -> DoEffectCalcPeriodic . begin ();
2011-06-12 02:30:32 +02:00
for (; effItr != effEndItr ; ++ effItr )
2010-08-24 00:10:49 +02:00
{
2011-07-26 23:09:28 +02:00
if (( * effItr ). IsEffectAffected ( m_spellInfo , aurEff -> GetEffIndex ()))
2010-08-24 00:10:49 +02:00
( * effItr ). Call ( * scritr , aurEff , isPeriodic , amplitude );
}
2010-10-04 17:44:49 +02:00
( * scritr ) -> _FinishScriptCall ();
2010-08-24 00:10:49 +02:00
}
}
2011-09-15 14:08:17 +02:00
void Aura :: CallScriptEffectCalcSpellModHandlers ( AuraEffect const * aurEff , SpellModifier * & spellMod )
2010-08-24 00:10:49 +02:00
{
2011-09-15 14:08:17 +02:00
for ( std :: list < AuraScript *>:: iterator scritr = m_loadedScripts . begin (); scritr != m_loadedScripts . end () ; ++ scritr )
2010-08-24 00:10:49 +02:00
{
2010-10-04 17:44:49 +02:00
( * scritr ) -> _PrepareScriptCall ( AURA_SCRIPT_HOOK_EFFECT_CALC_SPELLMOD );
2010-12-27 20:14:54 +01:00
std :: list < AuraScript :: EffectCalcSpellModHandler >:: iterator effEndItr = ( * scritr ) -> DoEffectCalcSpellMod . end (), effItr = ( * scritr ) -> DoEffectCalcSpellMod . begin ();
2011-06-12 02:30:32 +02:00
for (; effItr != effEndItr ; ++ effItr )
2010-08-24 00:10:49 +02:00
{
2011-07-26 23:09:28 +02:00
if (( * effItr ). IsEffectAffected ( m_spellInfo , aurEff -> GetEffIndex ()))
2010-08-24 00:10:49 +02:00
( * effItr ). Call ( * scritr , aurEff , spellMod );
}
2010-10-04 17:44:49 +02:00
( * scritr ) -> _FinishScriptCall ();
2010-08-24 00:10:49 +02:00
}
}
2011-09-15 14:08:17 +02:00
void Aura :: CallScriptEffectAbsorbHandlers ( AuraEffect * aurEff , AuraApplication const * aurApp , DamageInfo & dmgInfo , uint32 & absorbAmount , bool & /*defaultPrevented*/ )
2010-12-27 20:14:54 +01:00
{
2011-09-15 14:08:17 +02:00
for ( std :: list < AuraScript *>:: iterator scritr = m_loadedScripts . begin (); scritr != m_loadedScripts . end () ; ++ scritr )
2010-12-27 20:14:54 +01:00
{
( * scritr ) -> _PrepareScriptCall ( AURA_SCRIPT_HOOK_EFFECT_ABSORB , aurApp );
std :: list < AuraScript :: EffectAbsorbHandler >:: iterator effEndItr = ( * scritr ) -> OnEffectAbsorb . end (), effItr = ( * scritr ) -> OnEffectAbsorb . begin ();
2011-06-12 02:30:32 +02:00
for (; effItr != effEndItr ; ++ effItr )
2010-12-27 20:14:54 +01:00
{
2011-07-26 23:09:28 +02:00
if (( * effItr ). IsEffectAffected ( m_spellInfo , aurEff -> GetEffIndex ()))
2010-12-27 20:14:54 +01:00
( * effItr ). Call ( * scritr , aurEff , dmgInfo , absorbAmount );
}
( * scritr ) -> _FinishScriptCall ();
}
}
2011-09-15 14:08:17 +02:00
void Aura :: CallScriptEffectAfterAbsorbHandlers ( AuraEffect * aurEff , AuraApplication const * aurApp , DamageInfo & dmgInfo , uint32 & absorbAmount )
2010-12-30 02:03:46 +01:00
{
2011-09-15 14:08:17 +02:00
for ( std :: list < AuraScript *>:: iterator scritr = m_loadedScripts . begin (); scritr != m_loadedScripts . end () ; ++ scritr )
2010-12-30 02:03:46 +01:00
{
( * scritr ) -> _PrepareScriptCall ( AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB , aurApp );
std :: list < AuraScript :: EffectAbsorbHandler >:: iterator effEndItr = ( * scritr ) -> AfterEffectAbsorb . end (), effItr = ( * scritr ) -> AfterEffectAbsorb . begin ();
2011-06-12 02:30:32 +02:00
for (; effItr != effEndItr ; ++ effItr )
2010-12-30 02:03:46 +01:00
{
2011-07-26 23:09:28 +02:00
if (( * effItr ). IsEffectAffected ( m_spellInfo , aurEff -> GetEffIndex ()))
2010-12-30 02:03:46 +01:00
( * effItr ). Call ( * scritr , aurEff , dmgInfo , absorbAmount );
}
( * scritr ) -> _FinishScriptCall ();
}
}
2011-09-15 14:08:17 +02:00
void Aura :: CallScriptEffectManaShieldHandlers ( AuraEffect * aurEff , AuraApplication const * aurApp , DamageInfo & dmgInfo , uint32 & absorbAmount , bool & /*defaultPrevented*/ )
2010-12-30 19:05:19 +01:00
{
2011-09-15 14:08:17 +02:00
for ( std :: list < AuraScript *>:: iterator scritr = m_loadedScripts . begin (); scritr != m_loadedScripts . end () ; ++ scritr )
2010-12-30 19:05:19 +01:00
{
( * scritr ) -> _PrepareScriptCall ( AURA_SCRIPT_HOOK_EFFECT_MANASHIELD , aurApp );
std :: list < AuraScript :: EffectManaShieldHandler >:: iterator effEndItr = ( * scritr ) -> OnEffectManaShield . end (), effItr = ( * scritr ) -> OnEffectManaShield . begin ();
2011-06-12 02:30:32 +02:00
for (; effItr != effEndItr ; ++ effItr )
2010-12-30 19:05:19 +01:00
{
2011-07-26 23:09:28 +02:00
if (( * effItr ). IsEffectAffected ( m_spellInfo , aurEff -> GetEffIndex ()))
2010-12-30 19:05:19 +01:00
( * effItr ). Call ( * scritr , aurEff , dmgInfo , absorbAmount );
}
( * scritr ) -> _FinishScriptCall ();
}
}
2011-09-15 14:08:17 +02:00
void Aura :: CallScriptEffectAfterManaShieldHandlers ( AuraEffect * aurEff , AuraApplication const * aurApp , DamageInfo & dmgInfo , uint32 & absorbAmount )
2010-12-30 19:05:19 +01:00
{
2011-09-15 14:08:17 +02:00
for ( std :: list < AuraScript *>:: iterator scritr = m_loadedScripts . begin (); scritr != m_loadedScripts . end () ; ++ scritr )
2010-12-30 19:05:19 +01:00
{
( * scritr ) -> _PrepareScriptCall ( AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD , aurApp );
std :: list < AuraScript :: EffectManaShieldHandler >:: iterator effEndItr = ( * scritr ) -> AfterEffectManaShield . end (), effItr = ( * scritr ) -> AfterEffectManaShield . begin ();
2011-06-12 02:30:32 +02:00
for (; effItr != effEndItr ; ++ effItr )
2010-12-30 19:05:19 +01:00
{
2011-07-26 23:09:28 +02:00
if (( * effItr ). IsEffectAffected ( m_spellInfo , aurEff -> GetEffIndex ()))
2010-12-30 19:05:19 +01:00
( * effItr ). Call ( * scritr , aurEff , dmgInfo , absorbAmount );
}
( * scritr ) -> _FinishScriptCall ();
}
}
2011-09-15 14:08:17 +02:00
UnitAura :: UnitAura ( SpellInfo const * spellproto , uint8 effMask , WorldObject * owner , Unit * caster , int32 * baseAmount , Item * castItem , uint64 casterGUID )
2011-03-08 16:42:00 +01:00
: Aura ( spellproto , owner , caster , castItem , casterGUID )
2008-12-24 09:58:26 -06:00
{
2010-01-10 01:23:15 +01:00
m_AuraDRGroup = DIMINISHING_NONE ;
2011-02-06 13:17:29 +01:00
LoadScripts ();
_InitEffects ( effMask , caster , baseAmount );
2010-01-16 15:12:21 +01:00
GetUnitOwner () -> _AddAura ( this , caster );
2010-01-10 01:23:15 +01:00
};
2009-10-17 15:51:44 -07:00
2011-06-11 22:35:29 +02:00
void UnitAura :: _ApplyForTarget ( Unit * target , Unit * caster , AuraApplication * aurApp )
2010-01-10 01:23:15 +01:00
{
Aura :: _ApplyForTarget ( target , caster , aurApp );
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
// register aura diminishing on apply
if ( DiminishingGroup group = GetDiminishGroup ())
2011-04-29 20:47:02 +02:00
target -> ApplyDiminishingAura ( group , true );
2008-12-24 09:58:26 -06:00
}
2009-10-17 15:51:44 -07:00
2011-06-11 22:35:29 +02:00
void UnitAura :: _UnapplyForTarget ( Unit * target , Unit * caster , AuraApplication * aurApp )
2009-02-21 17:34:03 -06:00
{
2010-01-10 01:23:15 +01:00
Aura :: _UnapplyForTarget ( target , caster , aurApp );
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
// unregister aura diminishing (and store last time)
if ( DiminishingGroup group = GetDiminishGroup ())
2011-04-29 20:47:02 +02:00
target -> ApplyDiminishingAura ( group , false );
2009-02-21 17:34:03 -06:00
}
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
void UnitAura :: Remove ( AuraRemoveMode removeMode )
2009-02-21 17:34:03 -06:00
{
2010-01-10 01:23:15 +01:00
if ( IsRemoved ())
2009-02-21 17:34:03 -06:00
return ;
2010-01-10 01:23:15 +01:00
GetUnitOwner () -> RemoveOwnedAura ( this , removeMode );
2009-02-21 17:34:03 -06:00
}
2009-10-17 15:51:44 -07:00
2011-09-29 12:43:05 +02:00
void UnitAura :: FillTargetMap ( std :: map < Unit * , uint8 > & targets , Unit * caster )
2009-01-09 16:43:23 -06:00
{
2010-01-24 13:08:25 +01:00
for ( uint8 effIndex = 0 ; effIndex < MAX_SPELL_EFFECTS ; ++ effIndex )
2009-01-09 16:43:23 -06:00
{
2010-01-24 13:08:25 +01:00
if ( ! HasEffect ( effIndex ))
continue ;
UnitList targetList ;
// non-area aura
2011-07-26 23:09:28 +02:00
if ( GetSpellInfo () -> Effects [ effIndex ]. Effect == SPELL_EFFECT_APPLY_AURA )
2009-01-09 16:43:23 -06:00
{
2010-01-24 13:08:25 +01:00
targetList . push_back ( GetUnitOwner ());
2009-01-09 16:43:23 -06:00
}
2010-01-24 13:08:25 +01:00
else
2010-01-10 01:23:15 +01:00
{
2011-07-26 23:09:28 +02:00
float radius = GetSpellInfo () -> Effects [ effIndex ]. CalcRadius ( caster );
2010-01-24 13:08:25 +01:00
2010-12-17 13:43:24 +01:00
if ( ! GetUnitOwner () -> HasUnitState ( UNIT_STAT_ISOLATED ))
2010-01-10 01:23:15 +01:00
{
2011-08-30 13:46:36 +02:00
switch ( GetSpellInfo () -> Effects [ effIndex ]. Effect )
2010-01-10 01:23:15 +01:00
{
2010-01-24 13:08:25 +01:00
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY :
targetList . push_back ( GetUnitOwner ());
GetUnitOwner () -> GetPartyMemberInDist ( targetList , radius );
break ;
case SPELL_EFFECT_APPLY_AREA_AURA_RAID :
targetList . push_back ( GetUnitOwner ());
GetUnitOwner () -> GetRaidMember ( targetList , radius );
break ;
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND :
{
targetList . push_back ( GetUnitOwner ());
Trinity :: AnyFriendlyUnitInObjectRangeCheck u_check ( GetUnitOwner (), GetUnitOwner (), radius );
Trinity :: UnitListSearcher < Trinity :: AnyFriendlyUnitInObjectRangeCheck > searcher ( GetUnitOwner (), targetList , u_check );
GetUnitOwner () -> VisitNearbyObject ( radius , searcher );
break ;
}
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY :
{
Trinity :: AnyAoETargetUnitInObjectRangeCheck u_check ( GetUnitOwner (), GetUnitOwner (), radius ); // No GetCharmer in searcher
Trinity :: UnitListSearcher < Trinity :: AnyAoETargetUnitInObjectRangeCheck > searcher ( GetUnitOwner (), targetList , u_check );
GetUnitOwner () -> VisitNearbyObject ( radius , searcher );
break ;
}
case SPELL_EFFECT_APPLY_AREA_AURA_PET :
targetList . push_back ( GetUnitOwner ());
case SPELL_EFFECT_APPLY_AREA_AURA_OWNER :
2010-01-10 01:23:15 +01:00
{
2011-06-20 04:04:20 +07:00
if ( Unit * owner = GetUnitOwner () -> GetCharmerOrOwner ())
2010-01-24 13:08:25 +01:00
if ( GetUnitOwner () -> IsWithinDistInMap ( owner , radius ))
targetList . push_back ( owner );
2010-01-10 01:23:15 +01:00
break ;
}
}
}
}
2009-10-17 15:51:44 -07:00
2010-01-24 13:08:25 +01:00
for ( UnitList :: iterator itr = targetList . begin (); itr != targetList . end (); ++ itr )
2010-01-10 01:23:15 +01:00
{
2011-09-29 12:43:05 +02:00
std :: map < Unit * , uint8 >:: iterator existing = targets . find ( * itr );
2010-01-24 13:08:25 +01:00
if ( existing != targets . end ())
existing -> second |= 1 << effIndex ;
else
targets [ * itr ] = 1 << effIndex ;
2010-01-10 01:23:15 +01:00
}
2009-01-29 18:18:33 -06:00
}
}
2009-10-17 15:51:44 -07:00
2011-09-15 14:08:17 +02:00
DynObjAura :: DynObjAura ( SpellInfo const * spellproto , uint8 effMask , WorldObject * owner , Unit * caster , int32 * baseAmount , Item * castItem , uint64 casterGUID )
2011-03-08 16:42:00 +01:00
: Aura ( spellproto , owner , caster , castItem , casterGUID )
2009-07-22 17:10:30 +02:00
{
2011-02-06 13:17:29 +01:00
LoadScripts ();
2010-07-30 15:51:07 +02:00
ASSERT ( GetDynobjOwner ());
ASSERT ( GetDynobjOwner () -> IsInWorld ());
ASSERT ( GetDynobjOwner () -> GetMap () == caster -> GetMap ());
2011-02-06 13:17:29 +01:00
_InitEffects ( effMask , caster , baseAmount );
2010-01-10 01:23:15 +01:00
GetDynobjOwner () -> SetAura ( this );
2009-07-22 17:10:30 +02:00
}
2009-10-17 15:51:44 -07:00
2010-01-10 01:23:15 +01:00
void DynObjAura :: Remove ( AuraRemoveMode removeMode )
2009-07-22 17:10:30 +02:00
{
2010-01-10 01:23:15 +01:00
if ( IsRemoved ())
2009-07-22 17:10:30 +02:00
return ;
2010-01-10 01:23:15 +01:00
_Remove ( removeMode );
2009-07-22 17:10:30 +02:00
}
2009-10-17 15:51:44 -07:00
2011-09-29 12:43:05 +02:00
void DynObjAura :: FillTargetMap ( std :: map < Unit * , uint8 > & targets , Unit * /*caster*/ )
2009-08-17 16:30:14 +02:00
{
2011-06-11 22:35:29 +02:00
Unit * dynObjOwnerCaster = GetDynobjOwner () -> GetCaster ();
2010-01-24 13:08:25 +01:00
float radius = GetDynobjOwner () -> GetRadius ();
2009-10-17 15:51:44 -07:00
2010-01-24 13:08:25 +01:00
for ( uint8 effIndex = 0 ; effIndex < MAX_SPELL_EFFECTS ; ++ effIndex )
2010-01-10 01:23:15 +01:00
{
2010-01-24 13:08:25 +01:00
if ( ! HasEffect ( effIndex ))
continue ;
UnitList targetList ;
2011-07-27 12:35:59 +02:00
if ( GetSpellInfo () -> Effects [ effIndex ]. TargetB . GetTarget () == TARGET_DEST_DYNOBJ_ALLY
2011-08-16 19:44:18 +02:00
|| GetSpellInfo () -> Effects [ effIndex ]. TargetB . GetTarget () == TARGET_UNIT_DEST_AREA_ALLY )
2010-01-10 01:23:15 +01:00
{
2010-01-24 13:08:25 +01:00
Trinity :: AnyFriendlyUnitInObjectRangeCheck u_check ( GetDynobjOwner (), dynObjOwnerCaster , radius );
Trinity :: UnitListSearcher < Trinity :: AnyFriendlyUnitInObjectRangeCheck > searcher ( GetDynobjOwner (), targetList , u_check );
GetDynobjOwner () -> VisitNearbyObject ( radius , searcher );
2010-01-10 01:23:15 +01:00
}
2010-01-24 13:08:25 +01:00
else
2009-07-11 15:58:19 +02:00
{
2010-01-24 13:08:25 +01:00
Trinity :: AnyAoETargetUnitInObjectRangeCheck u_check ( GetDynobjOwner (), dynObjOwnerCaster , radius );
Trinity :: UnitListSearcher < Trinity :: AnyAoETargetUnitInObjectRangeCheck > searcher ( GetDynobjOwner (), targetList , u_check );
GetDynobjOwner () -> VisitNearbyObject ( radius , searcher );
2009-07-11 15:58:19 +02:00
}
2010-01-10 01:23:15 +01:00
2010-01-24 13:08:25 +01:00
for ( UnitList :: iterator itr = targetList . begin (); itr != targetList . end (); ++ itr )
{
2011-09-29 12:43:05 +02:00
std :: map < Unit * , uint8 >:: iterator existing = targets . find ( * itr );
2010-01-24 13:08:25 +01:00
if ( existing != targets . end ())
existing -> second |= 1 << effIndex ;
else
targets [ * itr ] = 1 << effIndex ;
}
2009-08-28 19:46:09 +02:00
}
2009-12-21 15:52:02 +02:00
}
2010-01-24 13:08:25 +01:00