aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bindings/scripts/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp20
-rw-r--r--src/bindings/scripts/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp79
-rw-r--r--src/bindings/scripts/scripts/northrend/draktharon_keep/boss_trollgore.cpp3
-rw-r--r--src/bindings/scripts/scripts/northrend/vault_of_archavon/boss_emalon.cpp2
-rw-r--r--src/bindings/scripts/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp6
-rw-r--r--src/bindings/scripts/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp16
-rw-r--r--src/bindings/scripts/scripts/outland/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp10
-rw-r--r--src/bindings/scripts/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp10
-rw-r--r--src/bindings/scripts/scripts/world/npcs_special.cpp4
-rw-r--r--src/game/BattleGround.cpp18
-rw-r--r--src/game/CMakeLists.txt2
-rw-r--r--src/game/CharacterHandler.cpp4
-rw-r--r--src/game/ChatHandler.cpp5
-rw-r--r--src/game/Creature.cpp30
-rw-r--r--src/game/Creature.h3
-rw-r--r--src/game/CreatureAI.h3
-rw-r--r--src/game/CreatureEventAI.cpp4
-rw-r--r--src/game/DBCStructure.h1
-rw-r--r--src/game/DynamicObject.cpp93
-rw-r--r--src/game/DynamicObject.h30
-rw-r--r--src/game/GridNotifiers.h23
-rw-r--r--src/game/GridNotifiersImpl.h86
-rw-r--r--src/game/GroupHandler.cpp16
-rw-r--r--src/game/Level3.cpp61
-rw-r--r--src/game/Object.cpp5
-rw-r--r--src/game/ObjectMgr.cpp63
-rw-r--r--src/game/OutdoorPvPWG.cpp2
-rw-r--r--src/game/Pet.cpp83
-rw-r--r--src/game/Pet.h1
-rw-r--r--src/game/Player.cpp376
-rw-r--r--src/game/Player.h13
-rw-r--r--src/game/SharedDefines.h2
-rw-r--r--src/game/Spell.cpp270
-rw-r--r--src/game/Spell.h14
-rw-r--r--src/game/SpellAuraDefines.h13
-rw-r--r--src/game/SpellAuraEffects.cpp6064
-rw-r--r--src/game/SpellAuraEffects.h263
-rw-r--r--src/game/SpellAuras.cpp7828
-rw-r--r--src/game/SpellAuras.h508
-rw-r--r--src/game/SpellEffects.cpp346
-rw-r--r--src/game/SpellHandler.cpp4
-rw-r--r--src/game/SpellMgr.cpp187
-rw-r--r--src/game/SpellMgr.h82
-rw-r--r--src/game/StatSystem.cpp27
-rw-r--r--src/game/ThreatManager.cpp2
-rw-r--r--src/game/Unit.cpp2110
-rw-r--r--src/game/Unit.h202
-rw-r--r--src/game/UnitAI.cpp5
-rw-r--r--src/shared/ByteBuffer.h16
49 files changed, 9606 insertions, 9409 deletions
diff --git a/src/bindings/scripts/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp b/src/bindings/scripts/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp
index 1ff205162a4..cbfc86ea183 100644
--- a/src/bindings/scripts/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp
+++ b/src/bindings/scripts/scripts/kalimdor/temple_of_ahnqiraj/boss_twinemperors.cpp
@@ -413,15 +413,7 @@ struct TRINITY_DLL_DECL boss_veknilashAI : public boss_twinemperorsAI
{
pTarget->setFaction(14);
pTarget->AI()->AttackStart(m_creature->getThreatManager().getHostilTarget());
- SpellEntry *spell = GET_SPELL(SPELL_MUTATE_BUG);
- uint8 eff_mask=0;
- for (int i=0; i<3; ++i)
- {
- if (!spell->Effect[i])
- continue;
- eff_mask|=1<<i;
- }
- pTarget->AddAura(new Aura(spell, eff_mask, pTarget, pTarget, pTarget));
+ pTarget->AddAura(SPELL_MUTATE_BUG, pTarget);
pTarget->SetHealth(pTarget->GetMaxHealth());
}
@@ -498,15 +490,7 @@ struct TRINITY_DLL_DECL boss_veklorAI : public boss_twinemperorsAI
void CastSpellOnBug(Creature *pTarget)
{
pTarget->setFaction(14);
- SpellEntry *spell = GET_SPELL(SPELL_EXPLODEBUG);
- uint8 eff_mask=0;
- for (int i=0; i<3; ++i)
- {
- if (!spell->Effect[i])
- continue;
- eff_mask|=1<<i;
- }
- pTarget->AddAura(new Aura(spell, eff_mask, pTarget, pTarget, pTarget));
+ pTarget->AddAura(SPELL_EXPLODEBUG, pTarget);
pTarget->SetHealth(pTarget->GetMaxHealth());
}
diff --git a/src/bindings/scripts/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp b/src/bindings/scripts/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp
index d548ff7155e..0d715785140 100644
--- a/src/bindings/scripts/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp
+++ b/src/bindings/scripts/scripts/kalimdor/temple_of_ahnqiraj/mob_anubisath_sentinel.cpp
@@ -53,19 +53,6 @@ EndScriptData */
#define SPELL_STORM_BUFF 2148
#define SPELL_STORM 26546
-struct TRINITY_DLL_DECL aqsentinelAI;
-class TRINITY_DLL_DECL SentinelAbilityAura : public Aura
-{
- public:
- ~SentinelAbilityAura();
- Unit* GetTriggerTarget() const;
- SentinelAbilityAura(aqsentinelAI *abilityOwner, SpellEntry *spell, uint32 ability, uint32 eff);
- protected:
- aqsentinelAI *aOwner;
- int32 currentBasePoints;
- uint32 abilityId;
-};
-
struct TRINITY_DLL_DECL aqsentinelAI : public ScriptedAI
{
uint32 ability;
@@ -222,16 +209,7 @@ struct TRINITY_DLL_DECL aqsentinelAI : public ScriptedAI
void GainSentinelAbility(uint32 id)
{
- const SpellEntry *spell = GetSpellStore()->LookupEntry(id);
- uint8 eff_mask=0;
- for (int i=0; i<3; ++i)
- {
- if (!spell->Effect[i])
- continue;
- eff_mask=1<<i;
- }
- SentinelAbilityAura *a = new SentinelAbilityAura(this, (SpellEntry*)spell, id, eff_mask);
- m_creature->AddAura(a);
+ m_creature->AddAura(id, m_creature);
}
void EnterCombat(Unit *who)
@@ -260,7 +238,7 @@ struct TRINITY_DLL_DECL aqsentinelAI : public ScriptedAI
}
}
- Unit *GetHatedManaUser()
+ Unit *GetHatedManaUser() const
{
std::list<HostilReference*>::iterator i;
for (i = m_creature->getThreatManager().getThreatList().begin(); i != m_creature->getThreatManager().getThreatList().end(); ++i)
@@ -271,6 +249,28 @@ struct TRINITY_DLL_DECL aqsentinelAI : public ScriptedAI
}
return NULL;
}
+
+ Unit* GetAuraEffectTriggerTarget(uint32 spellId, uint8 effIndex) const
+ {
+ switch (spellId)
+ {
+ case SPELL_KNOCK_BUFF:
+ case SPELL_THUNDER_BUFF:
+ case SPELL_MSTRIKE_BUFF:
+ case SPELL_STORM_BUFF:
+ return m_creature->getVictim();
+
+ case SPELL_MANAB_BUFF:
+ return GetHatedManaUser();
+
+ case SPELL_MENDING_BUFF:
+ case SPELL_REFLECTAF_BUFF:
+ case SPELL_REFLECTSFr_BUFF:
+ case SPELL_THORNS_BUFF:
+ default:
+ return m_creature;
+ }
+ }
};
CreatureAI* GetAI_mob_anubisath_sentinelAI(Creature* pCreature)
{
@@ -285,34 +285,3 @@ void AddSC_mob_anubisath_sentinel()
newscript->GetAI = &GetAI_mob_anubisath_sentinelAI;
newscript->RegisterSelf();
}
-
-SentinelAbilityAura::~SentinelAbilityAura() {}
-Unit* SentinelAbilityAura::GetTriggerTarget() const
-{
- switch (abilityId)
- {
- case SPELL_KNOCK_BUFF:
- case SPELL_THUNDER_BUFF:
- case SPELL_MSTRIKE_BUFF:
- case SPELL_STORM_BUFF:
- return aOwner->m_creature->getVictim();
-
- case SPELL_MANAB_BUFF:
- return aOwner->GetHatedManaUser();
-
- case SPELL_MENDING_BUFF:
- case SPELL_REFLECTAF_BUFF:
- case SPELL_REFLECTSFr_BUFF:
- case SPELL_THORNS_BUFF:
- default:
- return aOwner->m_creature;
- }
-}
-
-SentinelAbilityAura::SentinelAbilityAura(aqsentinelAI *abilityOwner, SpellEntry *spell, uint32 ability, uint32 eff)
-: Aura(spell, eff, abilityOwner->m_creature, abilityOwner->m_creature, abilityOwner->m_creature, NULL)
-{
- aOwner = abilityOwner;
- abilityId = ability;
-}
-
diff --git a/src/bindings/scripts/scripts/northrend/draktharon_keep/boss_trollgore.cpp b/src/bindings/scripts/scripts/northrend/draktharon_keep/boss_trollgore.cpp
index a2c7d44a7c3..ed54bd05eb8 100644
--- a/src/bindings/scripts/scripts/northrend/draktharon_keep/boss_trollgore.cpp
+++ b/src/bindings/scripts/scripts/northrend/draktharon_keep/boss_trollgore.cpp
@@ -133,9 +133,8 @@ struct TRINITY_DLL_DECL boss_trollgoreAI : public ScriptedAI
{
if (uiAuraCountTimer <= diff)
{
- if (m_creature->HasAura(HEROIC(SPELL_CONSUME,H_SPELL_CONSUME)))
+ if (Aura *pConsumeAura = m_creature->GetAura(HEROIC(SPELL_CONSUME,H_SPELL_CONSUME)))
{
- Aura *pConsumeAura = m_creature->GetAura(HEROIC(SPELL_CONSUME,H_SPELL_CONSUME));
if (pConsumeAura && pConsumeAura->GetStackAmount() > 9)
bAchiev = false;
}
diff --git a/src/bindings/scripts/scripts/northrend/vault_of_archavon/boss_emalon.cpp b/src/bindings/scripts/scripts/northrend/vault_of_archavon/boss_emalon.cpp
index 1260cd98557..412920961a6 100644
--- a/src/bindings/scripts/scripts/northrend/vault_of_archavon/boss_emalon.cpp
+++ b/src/bindings/scripts/scripts/northrend/vault_of_archavon/boss_emalon.cpp
@@ -225,7 +225,7 @@ struct TRINITY_DLL_DECL mob_tempest_minionAI : public ScriptedAI
if(me->hasUnitState(UNIT_STAT_CASTING))
return;
- if(Aura *OverchargedAura = m_creature->GetAura(SPELL_OVERCHARGED))
+ if(Aura * OverchargedAura = m_creature->GetAura(SPELL_OVERCHARGED))
{
if(OverchargedAura->GetStackAmount() < 10)
{
diff --git a/src/bindings/scripts/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp b/src/bindings/scripts/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp
index e94c8953117..0a4fe3e8cd1 100644
--- a/src/bindings/scripts/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp
+++ b/src/bindings/scripts/scripts/outland/auchindoun/shadow_labyrinth/boss_grandmaster_vorpil.cpp
@@ -92,10 +92,8 @@ struct TRINITY_DLL_DECL mob_voidtravelerAI : public ScriptedAI
{
if (sacrificed)
{
- SpellEntry *spell = GET_SPELL(HeroicMode?H_SPELL_EMPOWERING_SHADOWS:SPELL_EMPOWERING_SHADOWS);
- if (spell)
- Vorpil->AddAura(new Aura(spell, 1, Vorpil, me, me));
- Vorpil->SetHealth(Vorpil->GetHealth()+Vorpil->GetMaxHealth()/25);
+ m_creature->AddAura(HEROIC(H_SPELL_EMPOWERING_SHADOWS, SPELL_EMPOWERING_SHADOWS), Vorpil);
+ Vorpil->SetHealth(Vorpil->GetHealth() + Vorpil->GetMaxHealth()/25);
DoCast(m_creature, SPELL_SHADOW_NOVA, true);
m_creature->Kill(m_creature);
return;
diff --git a/src/bindings/scripts/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp b/src/bindings/scripts/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp
index d0c7753f0ac..db440ef0cc1 100644
--- a/src/bindings/scripts/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp
+++ b/src/bindings/scripts/scripts/outland/coilfang_resevoir/serpent_shrine/boss_lady_vashj.cpp
@@ -636,21 +636,7 @@ struct TRINITY_DLL_DECL mob_enchanted_elementalAI : public ScriptedAI
{
m_creature->GetMotionMaster()->MovePoint(0, MIDDLE_X, MIDDLE_Y, MIDDLE_Z);
if (m_creature->IsWithinDist3d(MIDDLE_X, MIDDLE_Y, MIDDLE_Z, 3))
- {
- SpellEntry *spell = GET_SPELL(SPELL_SURGE);
- if (spell)
- {
- uint8 eff_mask=0;
- for (uint8 i = 0; i < 3; ++i)
- {
- if (!spell->Effect[i])
- continue;
- eff_mask|=1<<i;
- }
- Vashj->AddAura(new Aura(spell, eff_mask, Vashj, Vashj, Vashj));
- }
- m_creature->Kill(m_creature);
- }
+ DoCast(m_creature, SPELL_SURGE);
}
if (!Vashj->isInCombat() || CAST_AI(boss_lady_vashjAI, Vashj->AI())->Phase != 2 || Vashj->isDead())
{
diff --git a/src/bindings/scripts/scripts/outland/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp b/src/bindings/scripts/scripts/outland/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp
index eaa5ce84174..24f47dff4a6 100644
--- a/src/bindings/scripts/scripts/outland/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp
+++ b/src/bindings/scripts/scripts/outland/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp
@@ -497,14 +497,8 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI
demon->AI()->AttackStart((*itr));
CAST_AI(mob_inner_demonAI, demon->AI())->victimGUID = (*itr)->GetGUID();
- uint8 eff_mask=0;
- for (int i=0; i<3; ++i)
- {
- if (!spell->Effect[i])
- continue;
- eff_mask|=1<<i;
- }
- (*itr)->AddAura(new Aura(spell, eff_mask, *itr, *itr, *itr));
+ (*itr)->AddAura(SPELL_INSIDIOUS_WHISPER, *itr);
+
if (InnerDemon_Count > 4)
InnerDemon_Count = 0;
diff --git a/src/bindings/scripts/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp b/src/bindings/scripts/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp
index 615d242018a..49b167422af 100644
--- a/src/bindings/scripts/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp
+++ b/src/bindings/scripts/scripts/outland/hellfire_citadel/blood_furnace/boss_kelidan_the_breaker.cpp
@@ -232,14 +232,8 @@ struct TRINITY_DLL_DECL boss_kelidan_the_breakerAI : public ScriptedAI
if (SpellEntry *nova = GET_SPELL(SPELL_BURNING_NOVA))
{
- uint8 eff_mask=0;
- for (int i=0; i<3; ++i)
- {
- if (!nova->Effect[i])
- continue;
- eff_mask|=1<<i;
- }
- m_creature->AddAura(new Aura(nova, eff_mask, me, me, me));
+ if (Aura * aura = Aura::TryCreate(nova, me, me))
+ aura->ApplyForTargets();
}
if (HeroicMode)
diff --git a/src/bindings/scripts/scripts/world/npcs_special.cpp b/src/bindings/scripts/scripts/world/npcs_special.cpp
index d5c7d48b607..f3ccb1076cc 100644
--- a/src/bindings/scripts/scripts/world/npcs_special.cpp
+++ b/src/bindings/scripts/scripts/world/npcs_special.cpp
@@ -190,7 +190,7 @@ struct TRINITY_DLL_DECL npc_air_force_botsAI : public ScriptedAI
if (!pWho->IsWithinDistInMap(m_creature, RANGE_GUARDS_MARK))
return;
- Aura* pMarkAura = pWho->GetAura(SPELL_GUARDS_MARK, 0);
+ Aura* pMarkAura = pWho->GetAura(SPELL_GUARDS_MARK);
if (pMarkAura)
{
// the target wasn't able to move out of our range within 25 seconds
@@ -202,7 +202,7 @@ struct TRINITY_DLL_DECL npc_air_force_botsAI : public ScriptedAI
return;
}
- if (pMarkAura->GetAuraDuration() < AURA_DURATION_TIME_LEFT)
+ if (pMarkAura->GetDuration() < AURA_DURATION_TIME_LEFT)
{
if (!pLastSpawnedGuard->getVictim())
pLastSpawnedGuard->AI()->AttackStart(pWho);
diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp
index 554f8555627..19643a6003e 100644
--- a/src/game/BattleGround.cpp
+++ b/src/game/BattleGround.cpp
@@ -34,6 +34,7 @@
#include "MapManager.h"
#include "Object.h"
#include "SpellAuras.h"
+#include "SpellAuraEffects.h"
#include "Util.h"
namespace Trinity
@@ -427,15 +428,16 @@ void BattleGround::Update(uint32 diff)
{
plr->RemoveAurasDueToSpell(SPELL_ARENA_PREPARATION);
// remove auras with duration lower than 30s
- Unit::AuraMap & aurMap = plr->GetAuras();
- for (Unit::AuraMap::iterator iter = aurMap.begin(); iter != aurMap.end();)
+ Unit::AuraMap & auraMap = plr->GetOwnedAuras();
+ for (Unit::AuraMap::iterator iter = auraMap.begin(); iter != auraMap.end();)
{
- if (!iter->second->IsPermanent()
- && iter->second->GetAuraDuration()<=30*IN_MILISECONDS
- && iter->second->IsPositive()
- && (!(iter->second->GetSpellProto()->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY))
- && (!iter->second->IsAuraType(SPELL_AURA_MOD_INVISIBILITY)))
- plr->RemoveAura(iter);
+ Aura * aura = iter->second;
+ if (!aura->IsPermanent()
+ && aura->GetDuration() <= 30*IN_MILISECONDS
+ && aura->IsPositive(plr)
+ && (!(aura->GetSpellProto()->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY))
+ && (!aura->HasEffectType(SPELL_AURA_MOD_INVISIBILITY)))
+ plr->RemoveOwnedAura(iter);
else
++iter;
}
diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt
index 435271c6a20..96abf30a72c 100644
--- a/src/game/CMakeLists.txt
+++ b/src/game/CMakeLists.txt
@@ -232,6 +232,8 @@ SET(game_STAT_SRCS
SpellAuraDefines.h
SpellAuras.cpp
SpellAuras.h
+ SpellAuraEffects.cpp
+ SpellAuraEffects.h
Spell.cpp
SpellEffects.cpp
SpellId.h
diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp
index f5b7e0ac7f2..1deda64ead9 100644
--- a/src/game/CharacterHandler.cpp
+++ b/src/game/CharacterHandler.cpp
@@ -68,7 +68,7 @@ bool LoginQueryHolder::Initialize()
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADFROM, "SELECT guid, account, data, name, race, class, gender, level, xp, money, playerBytes, playerBytes2, playerFlags, position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeon_difficulty, arena_pending_points, instance_id, speccount, activespec FROM characters WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGROUP, "SELECT leaderGuid FROM group_member WHERE memberGuid ='%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADBOUNDINSTANCES, "SELECT id, permanent, map, difficulty, resettime FROM character_instance LEFT JOIN instance ON instance = id WHERE guid = '%u'", GUID_LOPART(m_guid));
- res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_mask,stackcount,amount0, amount1, amount2 ,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid));
+ res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADAURAS, "SELECT caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSPELLS, "SELECT spell,active,disabled FROM character_spell WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADQUESTSTATUS, "SELECT quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4 FROM character_queststatus WHERE guid = '%u'", GUID_LOPART(m_guid));
res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest,time FROM character_queststatus_daily WHERE guid = '%u'", GUID_LOPART(m_guid));
@@ -454,6 +454,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
if(!pNewChar->Create( objmgr.GenerateLowGuid(HIGHGUID_PLAYER), name, race_, class_, gender, skin, face, hairStyle, hairColor, facialHair, outfitId ))
{
// Player not create (race/class problem?)
+ pNewChar->CleanupsBeforeDelete();
delete pNewChar;
data << (uint8)CHAR_CREATE_ERROR;
@@ -472,6 +473,7 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )
loginDatabase.PExecute("DELETE FROM realmcharacters WHERE acctid= '%d' AND realmid = '%d'", GetAccountId(), realmID);
loginDatabase.PExecute("INSERT INTO realmcharacters (numchars, acctid, realmid) VALUES (%u, %u, %u)", charcount, GetAccountId(), realmID);
+ pNewChar->CleanupsBeforeDelete();
delete pNewChar; // created only to call SaveToDB()
data << (uint8)CHAR_CREATE_SUCCESS;
diff --git a/src/game/ChatHandler.cpp b/src/game/ChatHandler.cpp
index 47e89bf4fff..d36a7cfd50b 100644
--- a/src/game/ChatHandler.cpp
+++ b/src/game/ChatHandler.cpp
@@ -38,6 +38,7 @@
#include "Player.h"
#include "ScriptCalls.h"
#include "SpellAuras.h"
+#include "SpellAuraEffects.h"
#include "Util.h"
bool WorldSession::processChatmessageFurtherAfterSecurityChecks(std::string& msg, uint32 lang)
@@ -88,7 +89,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
if(langDesc->skill_id != 0 && !_player->HasSkill(langDesc->skill_id))
{
// also check SPELL_AURA_COMPREHEND_LANGUAGE (client offers option to speak in that language)
- Unit::AuraEffectList const& langAuras = _player->GetAurasByType(SPELL_AURA_COMPREHEND_LANGUAGE);
+ Unit::AuraEffectList const& langAuras = _player->GetAuraEffectsByType(SPELL_AURA_COMPREHEND_LANGUAGE);
bool foundAura = false;
for (Unit::AuraEffectList::const_iterator i = langAuras.begin(); i != langAuras.end(); ++i)
{
@@ -159,7 +160,7 @@ void WorldSession::HandleMessagechatOpcode( WorldPacket & recv_data )
}
// but overwrite it by SPELL_AURA_MOD_LANGUAGE auras (only single case used)
- Unit::AuraEffectList const& ModLangAuras = _player->GetAurasByType(SPELL_AURA_MOD_LANGUAGE);
+ Unit::AuraEffectList const& ModLangAuras = _player->GetAuraEffectsByType(SPELL_AURA_MOD_LANGUAGE);
if(!ModLangAuras.empty())
lang = ModLangAuras.front()->GetMiscValue();
}
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 4bcf866632c..9795671ef22 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -47,6 +47,7 @@
#include "GameEventMgr.h"
#include "CreatureGroups.h"
#include "Vehicle.h"
+#include "SpellAuraEffects.h"
// apply implementation of the singletons
#include "Policies/SingletonImp.h"
@@ -142,7 +143,7 @@ m_creatureInfo(NULL), m_reactState(REACT_AGGRESSIVE), m_formation(NULL)
, m_AlreadySearchedAssistance(false)
, m_creatureData(NULL), m_PlayerDamageReq(0)
{
- m_regenTimer = 2000;
+ m_regenTimer = CREATURE_REGEN_INTERVAL;
m_valuesCount = UNIT_END;
for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
@@ -571,12 +572,12 @@ void Creature::Update(uint32 diff)
RegenerateMana();
/*if(!bIsPolymorphed) // only increase the timer if not polymorphed
- m_regenTimer += 2000 - diff;
+ m_regenTimer += CREATURE_REGEN_INTERVAL - diff;
}
else
if(!bIsPolymorphed) // if polymorphed, skip the timer
m_regenTimer -= diff;*/
- m_regenTimer = 2000;
+ m_regenTimer = CREATURE_REGEN_INTERVAL;
break;
}
case DEAD_FALLING:
@@ -611,6 +612,14 @@ void Creature::RegenerateMana()
else
addvalue = maxValue/3;
+ // Apply modifiers (if any).
+ AuraEffectList const& ModPowerRegenPCTAuras = GetAuraEffectsByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
+ for (AuraEffectList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
+ if ((*i)->GetMiscValue() == POWER_MANA)
+ addvalue *= ((*i)->GetAmount() + 100) / 100.0f;
+
+ addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) * CREATURE_REGEN_INTERVAL / (5 * IN_MILISECONDS);
+
ModifyPower(POWER_MANA, addvalue);
}
@@ -641,6 +650,13 @@ void Creature::RegenerateHealth()
else
addvalue = maxValue/3;
+ // Apply modifiers (if any).
+ AuraEffectList const& ModPowerRegenPCTAuras = GetAuraEffectsByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
+ for (AuraEffectList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
+ addvalue *= ((*i)->GetAmount() + 100) / 100.0f;
+
+ addvalue += GetTotalAuraModifier(SPELL_AURA_MOD_REGEN) * CREATURE_REGEN_INTERVAL / (5 * IN_MILISECONDS);
+
ModifyHealth(addvalue);
}
@@ -1988,16 +2004,16 @@ bool Creature::LoadCreaturesAddon(bool reload)
}
// skip already applied aura
- if(HasAuraEffect(cAura->spell_id,cAura->effect_idx))
+ if(HasAura(cAura->spell_id))
{
if(!reload)
- sLog.outErrorDb("Creature (GUID: %u Entry: %u) has duplicate aura (spell %u effect %u) in `auras` field.",GetGUIDLow(),GetEntry(),cAura->spell_id,cAura->effect_idx);
+ sLog.outErrorDb("Creature (GUID: %u Entry: %u) has duplicate aura (spell %u) in `auras` field.",GetGUIDLow(),GetEntry(),cAura->spell_id);
continue;
}
- AddAuraEffect(AdditionalSpellInfo, cAura->effect_idx, this, this);
- sLog.outDebug("Spell: %u with Aura %u added to creature (GUID: %u Entry: %u)", cAura->spell_id, AdditionalSpellInfo->EffectApplyAuraName[cAura->effect_idx],GetGUIDLow(),GetEntry());
+ AddAura(AdditionalSpellInfo, cAura->effectMask, this);
+ sLog.outDebug("Spell: %u with AuraEffectMask %u added to creature (GUID: %u Entry: %u)", cAura->spell_id, cAura->effectMask,GetGUIDLow(),GetEntry());
}
}
return true;
diff --git a/src/game/Creature.h b/src/game/Creature.h
index efe77737dcd..2ec18efbcff 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -64,6 +64,7 @@ enum CreatureFlagsExtra
#endif
#define MAX_KILL_CREDIT 2
+#define CREATURE_REGEN_INTERVAL 2 * IN_MILISECONDS
// from `creature_template` table
struct CreatureInfo
@@ -241,7 +242,7 @@ struct CreatureData
struct CreatureDataAddonAura
{
uint32 spell_id;
- uint8 effect_idx;
+ uint8 effectMask;
};
// from `creature_addon` table
diff --git a/src/game/CreatureAI.h b/src/game/CreatureAI.h
index ce2c7098623..c0b713c0d5a 100644
--- a/src/game/CreatureAI.h
+++ b/src/game/CreatureAI.h
@@ -121,6 +121,9 @@ class TRINITY_DLL_SPEC CreatureAI : public UnitAI
// Called when spell hits a target
virtual void SpellHitTarget(Unit* target, const SpellEntry*) {}
+ // Called to get trigger target for aura effect
+ virtual Unit * GetAuraEffectTriggerTarget(uint32 spellId, uint8 effIndex) {return NULL;}
+
// Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc)
//virtual void AttackedBy(Unit* attacker);
virtual bool IsEscorted() { return false; }
diff --git a/src/game/CreatureEventAI.cpp b/src/game/CreatureEventAI.cpp
index 3bef84e87b4..2f64a75ca7b 100644
--- a/src/game/CreatureEventAI.cpp
+++ b/src/game/CreatureEventAI.cpp
@@ -295,7 +295,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
{
//Note: checked only aura for effect 0, if need check aura for effect 1/2 then
// possible way: pack in event.buffed.amount 2 uint16 (ammount+effectIdx)
- Aura* aura = m_creature->GetAura(event.buffed.spellId,0);
+ Aura const * aura = m_creature->GetAura(event.buffed.spellId);
if(!aura || aura->GetStackAmount() < event.buffed.amount)
return false;
@@ -311,7 +311,7 @@ bool CreatureEventAI::ProcessEvent(CreatureEventAIHolder& pHolder, Unit* pAction
//Note: checked only aura for effect 0, if need check aura for effect 1/2 then
// possible way: pack in event.buffed.amount 2 uint16 (ammount+effectIdx)
- Aura* aura = pActionInvoker->GetAura(event.buffed.spellId,0);
+ Aura const * aura = m_creature->GetAura(event.buffed.spellId);
if(!aura || aura->GetStackAmount() < event.buffed.amount)
return false;
diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
index 9f84cda3155..b8663bbcd0a 100644
--- a/src/game/DBCStructure.h
+++ b/src/game/DBCStructure.h
@@ -1342,6 +1342,7 @@ struct SoundEntriesEntry
};
#define MAX_SPELL_EFFECTS 3
+#define MAX_EFFECT_MASK 7
struct SpellEntry
{
diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp
index 1cd85fa0946..6105ece654e 100644
--- a/src/game/DynamicObject.cpp
+++ b/src/game/DynamicObject.cpp
@@ -36,6 +36,9 @@ DynamicObject::DynamicObject() : WorldObject()
m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION);
m_valuesCount = DYNAMICOBJECT_END;
+
+ m_aura = 0;
+ m_duration = 0;
}
void DynamicObject::AddToWorld()
@@ -70,13 +73,13 @@ void DynamicObject::RemoveFromWorld()
}
}
-bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32 effMask, const Position &pos, int32 duration, float radius, bool active)
+bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, const Position &pos, float radius, bool active)
{
SetMap(caster->GetMap());
Relocate(pos);
if(!IsPositionValid())
{
- sLog.outError("DynamicObject (spell %u eff %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",spellId,effMask,GetPositionX(),GetPositionY());
+ sLog.outError("DynamicObject (spell %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",spellId,GetPositionX(),GetPositionY());
return false;
}
@@ -85,17 +88,11 @@ bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32
SetEntry(spellId);
SetFloatValue( OBJECT_FIELD_SCALE_X, 1 );
SetUInt64Value( DYNAMICOBJECT_CASTER, caster->GetGUID() );
- SetUInt32Value( DYNAMICOBJECT_BYTES, 0x00000001 );
+ SetUInt32Value( DYNAMICOBJECT_BYTES, 0x00000001 ); // effectMask?
SetUInt32Value( DYNAMICOBJECT_SPELLID, spellId );
- SetFloatValue( DYNAMICOBJECT_RADIUS, radius);
+ SetFloatValue( DYNAMICOBJECT_RADIUS, radius );
SetUInt32Value( DYNAMICOBJECT_CASTTIME, getMSTime() ); // new 2.4.0
- m_aliveDuration = duration;
- m_radius = radius;
- m_effMask = effMask;
- m_spellId = spellId;
- m_updateTimer = 0;
-
m_isWorldObject = active;
return true;
}
@@ -116,45 +113,25 @@ void DynamicObject::Update(uint32 p_time)
return;
}
- bool deleteThis = false;
+ bool expired = false;
- if(m_aliveDuration > int32(p_time))
- m_aliveDuration -= p_time;
- else
- deleteThis = true;
-
- /*
- // have radius and work as persistent effect
- if(m_radius)
+ if (m_aura)
{
- // TODO: make a timer and update this in larger intervals
- CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY()));
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
- cell.SetNoCreate();
-
- Trinity::DynamicObjectUpdater notifier(*this, caster);
+ if (!m_aura->IsRemoved())
+ m_aura->UpdateOwner(p_time, this);
- TypeContainerVisitor<Trinity::DynamicObjectUpdater, WorldTypeMapContainer > world_object_notifier(notifier);
- TypeContainerVisitor<Trinity::DynamicObjectUpdater, GridTypeMapContainer > grid_object_notifier(notifier);
-
- CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, world_object_notifier, *GetMap(), *this, m_radius);
- cell_lock->Visit(cell_lock, grid_object_notifier, *GetMap(), *this, m_radius);
+ if (m_aura->IsRemoved() || m_aura->IsExpired())
+ expired = true;
}
- */
-
- if (m_effMask)
+ else
{
- if (m_updateTimer < p_time)
- {
- Trinity::DynamicObjectUpdater notifier(*this,caster);
- VisitNearbyObject(GetRadius(), notifier);
- m_updateTimer = 500; // is this official-like?
- } else m_updateTimer -= p_time;
+ if(GetDuration() > int32(p_time))
+ m_duration -= p_time;
+ else
+ expired = true;
}
- if (deleteThis)
+ if (expired)
{
caster->RemoveDynObjectWithGUID(GetGUID());
Delete();
@@ -163,21 +140,43 @@ void DynamicObject::Update(uint32 p_time)
void DynamicObject::Delete()
{
+ if (m_aura)
+ {
+ // dynObj may be removed in Aura::Remove - we cannot delete there
+ // so recheck aura here
+ if (!m_aura->IsRemoved())
+ m_aura->_Remove(AURA_REMOVE_BY_DEFAULT);
+ delete m_aura;
+ m_aura = NULL;
+ }
SendObjectDeSpawnAnim(GetGUID());
RemoveFromWorld();
AddObjectToRemoveList();
}
+int32 DynamicObject::GetDuration() const
+{
+ if (!m_aura)
+ return m_duration;
+ else
+ return m_aura->GetDuration();
+}
+
+void DynamicObject::SetDuration(int32 newDuration)
+{
+ if (!m_aura)
+ m_duration = newDuration;
+ else
+ m_aura->SetDuration(newDuration);
+}
+
void DynamicObject::Delay(int32 delaytime)
{
- m_aliveDuration -= delaytime;
- for (AffectedSet::iterator iunit = m_affected.begin(); iunit != m_affected.end(); ++iunit)
- if (*iunit)
- (*iunit)->DelayAura(m_spellId, GetCaster()->GetGUID(), delaytime);
+ SetDuration(GetDuration() - delaytime);
}
bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const
{
return IsInWorld() && u->IsInWorld()
&& (IsWithinDistInMap(u->m_seer,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false));
-}
+} \ No newline at end of file
diff --git a/src/game/DynamicObject.h b/src/game/DynamicObject.h
index 11cf030a6c6..de94b5877bd 100644
--- a/src/game/DynamicObject.h
+++ b/src/game/DynamicObject.h
@@ -24,32 +24,28 @@
#include "Object.h"
class Unit;
+class Aura;
struct SpellEntry;
class DynamicObject : public WorldObject, public GridObject<DynamicObject>
{
public:
- typedef std::set<Unit*> AffectedSet;
explicit DynamicObject();
void AddToWorld();
void RemoveFromWorld();
- bool Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32 effMask, const Position &pos, int32 duration, float radius, bool active);
+ bool Create(uint32 guidlow, Unit *caster, uint32 spellId, const Position &pos, float radius, bool active);
void Update(uint32 p_time);
void Delete();
- uint32 GetSpellId() const { return m_spellId; }
- uint32 GetEffectMask() const { return m_effMask; }
- void AddEffect(uint32 effIndex) { m_effMask |= (1<<effIndex); }
- bool HasEffect(uint32 effIndex) const { return m_effMask & (1<<effIndex); }
- uint32 GetDuration() const { return m_aliveDuration; }
+ void SetDuration(int32 newDuration);
+ int32 GetDuration() const;
+ void SetAura(Aura * aura) {assert (!m_aura && aura); m_aura = aura;}
+ void Delay(int32 delaytime);
+ uint32 GetSpellId() const { return GetUInt32Value(DYNAMICOBJECT_SPELLID); }
uint64 GetCasterGUID() const { return GetUInt64Value(DYNAMICOBJECT_CASTER); }
+ float GetRadius() const { return GetFloatValue(DYNAMICOBJECT_RADIUS); }
Unit* GetCaster() const;
- float GetRadius() const { return m_radius; }
- bool IsAffecting(Unit *unit) const { return m_affected.find(unit) != m_affected.end(); }
- void AddAffected(Unit *unit) { m_affected.insert(unit); }
- void RemoveAffected(Unit *unit) { m_affected.erase(unit); }
- void Delay(int32 delaytime);
bool isVisibleForInState(Player const* u, bool inVisibleList) const;
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
@@ -59,11 +55,7 @@ class DynamicObject : public WorldObject, public GridObject<DynamicObject>
void YellToZone(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYellToZone(textId,language,TargetGuid); }
protected:
- uint32 m_spellId;
- uint32 m_effMask;
- int32 m_aliveDuration;
- uint32 m_updateTimer;
- float m_radius;
- AffectedSet m_affected;
+ int32 m_duration; // for non-aura dynobjects
+ Aura * m_aura;
};
-#endif
+#endif \ No newline at end of file
diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h
index f5d7b988fca..ca7844db21b 100644
--- a/src/game/GridNotifiers.h
+++ b/src/game/GridNotifiers.h
@@ -221,27 +221,6 @@ namespace Trinity
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) {}
};
- struct TRINITY_DLL_DECL DynamicObjectUpdater
- {
- DynamicObject &i_dynobject;
- Unit* i_check;
- DynamicObjectUpdater(DynamicObject &dynobject, Unit* caster) : i_dynobject(dynobject)
- {
- i_check = caster;
- Unit* owner = i_check->GetOwner();
- if(owner)
- i_check = owner;
- }
-
- template<class T> inline void Visit(GridRefManager<T> &) {}
- #ifdef WIN32
- template<> inline void Visit<Player>(PlayerMapType &);
- template<> inline void Visit<Creature>(CreatureMapType &);
- #endif
-
- void VisitHelper(Unit* target);
- };
-
// SEARCHERS & LIST SEARCHERS & WORKERS
// WorldObject searchers & workers
@@ -1292,8 +1271,6 @@ namespace Trinity
template<> inline void PlayerRelocationNotifier::Visit<Creature>(CreatureMapType &);
template<> inline void CreatureRelocationNotifier::Visit<Player>(PlayerMapType &);
template<> inline void CreatureRelocationNotifier::Visit<Creature>(CreatureMapType &);
- template<> inline void DynamicObjectUpdater::Visit<Creature>(CreatureMapType &);
- template<> inline void DynamicObjectUpdater::Visit<Player>(PlayerMapType &);
#endif
}
#endif
diff --git a/src/game/GridNotifiersImpl.h b/src/game/GridNotifiersImpl.h
index c19dc66139c..6f8b191d551 100644
--- a/src/game/GridNotifiersImpl.h
+++ b/src/game/GridNotifiersImpl.h
@@ -170,92 +170,6 @@ Trinity::CreatureRelocationNotifier::Visit(CreatureMapType &m)
}
}
-inline void Trinity::DynamicObjectUpdater::VisitHelper(Unit* target)
-{
- if(!target->isAlive() || target->isInFlight() )
- return;
-
- if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem())
- return;
-
- if (!i_dynobject.IsWithinDistInMap(target, i_dynobject.GetRadius()))
- return;
-
- //Check targets for not_selectable unit flag and remove
- if (target->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE))
- return;
-
- // Evade target
- if( target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->IsInEvadeMode() )
- return;
-
- //Check player targets and remove if in GM mode or GM invisibility (for not self casting case)
- if( target->GetTypeId() == TYPEID_PLAYER && target != i_check && (((Player*)target)->isGameMaster() || ((Player*)target)->GetVisibility()==VISIBILITY_OFF) )
- return;
-
- if (i_dynobject.IsAffecting(target))
- return;
-
- if(target->HasAura(i_dynobject.GetSpellId(), i_check->GetGUID()))
- return;
-
- uint32 eff_index = 0;
- for (; eff_index < MAX_SPELL_EFFECTS; ++eff_index)
- if(i_dynobject.HasEffect(eff_index))
- break;
-
- if(eff_index == MAX_SPELL_EFFECTS)
- return;
-
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(i_dynobject.GetSpellId());
- if(spellInfo->EffectImplicitTargetB[eff_index] == TARGET_DEST_DYNOBJ_ALLY
- || spellInfo->EffectImplicitTargetB[eff_index] == TARGET_UNIT_AREA_ALLY_DST)
- {
- if(!i_check->IsFriendlyTo(target))
- return;
- }
- else if( i_check->GetTypeId() == TYPEID_PLAYER )
- {
- if (i_check->IsFriendlyTo( target ))
- return;
-
- i_check->CombatStart(target);
- }
- else
- {
- if (!i_check->IsHostileTo( target ))
- return;
-
- i_check->CombatStart(target);
- }
-
- // Check target immune to spell or aura
- if (target->IsImmunedToSpell(spellInfo) || target->IsImmunedToSpellEffect(spellInfo, eff_index))
- return;
-
- // Apply PersistentAreaAura on target
- Aura *aur = new Aura(spellInfo, i_dynobject.GetEffectMask(), target, &i_dynobject, i_check);
- aur->SetAuraDuration(i_dynobject.GetDuration());
- if(target->AddAura(aur, true))
- i_dynobject.AddAffected(target);
-}
-
-template<>
-inline void
-Trinity::DynamicObjectUpdater::Visit(CreatureMapType &m)
-{
- for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- VisitHelper(itr->getSource());
-}
-
-template<>
-inline void
-Trinity::DynamicObjectUpdater::Visit(PlayerMapType &m)
-{
- for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
- VisitHelper(itr->getSource());
-}
-
// SEARCHERS & LIST SEARCHERS & WORKERS
// WorldObject searchers & workers
diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp
index ef7cee5cfa4..c074d275614 100644
--- a/src/game/GroupHandler.cpp
+++ b/src/game/GroupHandler.cpp
@@ -703,8 +703,8 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
{
if(auramask & (uint64(1) << i))
{
- Aura * pAura = player->GetVisibleAura(i);
- *data << uint32(pAura ? pAura->GetId() : 0);
+ AuraApplication const * aurApp = player->GetVisibleAura(i);
+ *data << uint32(aurApp ? aurApp->GetBase()->GetId() : 0);
*data << uint8(1);
}
}
@@ -785,8 +785,8 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke
{
if(auramask & (uint64(1) << i))
{
- Aura * pAura = pet->GetVisibleAura(i);
- *data << uint32(pAura ? pAura->GetId() : 0);
+ AuraApplication const * aurApp = player->GetVisibleAura(i);
+ *data << uint32(aurApp ? aurApp->GetBase()->GetId() : 0);
*data << uint8(1);
}
}
@@ -843,10 +843,10 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
data << (uint64) auramask; // placeholder
for (uint8 i = 0; i < MAX_AURAS; ++i)
{
- if(Aura * pAura = player->GetVisibleAura(i))
+ if(AuraApplication * aurApp = player->GetVisibleAura(i))
{
auramask |= (uint64(1) << i);
- data << (uint32) pAura->GetId();
+ data << (uint32) aurApp->GetBase()->GetId();
data << (uint8) 1;
}
}
@@ -869,10 +869,10 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )
data << (uint64) petauramask; // placeholder
for (uint8 i = 0; i < MAX_AURAS; ++i)
{
- if(Aura * pAura = pet->GetVisibleAura(i))
+ if(AuraApplication * auraApp = pet->GetVisibleAura(i))
{
petauramask |= (uint64(1) << i);
- data << (uint32) pAura->GetId();
+ data << (uint32) auraApp->GetBase()->GetId();
data << (uint8) 1;
}
}
diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp
index d616a93e2d6..7aee776c710 100644
--- a/src/game/Level3.cpp
+++ b/src/game/Level3.cpp
@@ -54,6 +54,7 @@
#include "InstanceData.h"
#include "AuctionHouseBot.h"
#include "CreatureEventAIMgr.h"
+#include "SpellAuraEffects.h"
#include "DBCEnums.h"
bool ChatHandler::HandleAHBotOptionsCommand(const char *args)
@@ -4387,25 +4388,8 @@ bool ChatHandler::HandleAuraCommand(const char *args)
// number or [name] Shift-click form |color|Hspell:spell_id|h[name]|h|r or Htalent form
uint32 spellID = extractSpellIdFromLink((char*)args);
- SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID );
- uint8 eff_mask=0;
- if(spellInfo)
- {
- for (uint32 i = 0; i<3; ++i)
- {
- uint8 eff = spellInfo->Effect[i];
- if (eff>=TOTAL_SPELL_EFFECTS)
- continue;
- if( IsAreaAuraEffect(eff) ||
- eff == SPELL_EFFECT_APPLY_AURA ||
- eff == SPELL_EFFECT_PERSISTENT_AREA_AURA )
- {
- eff_mask|=1<<i;
- }
- }
- Aura *Aur = new Aura(spellInfo, eff_mask, target, target, target);
- target->AddAura(Aur);
- }
+ if (SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellID ))
+ Aura::TryCreate(spellInfo, target, target);
return true;
}
@@ -5117,39 +5101,41 @@ bool ChatHandler::HandleListAurasCommand (const char * /*args*/)
char const* talentStr = GetTrinityString(LANG_TALENT);
char const* passiveStr = GetTrinityString(LANG_PASSIVE);
- Unit::AuraMap const& uAuras = unit->GetAuras();
+ Unit::AuraApplicationMap const& uAuras = unit->GetAppliedAuras();
PSendSysMessage(LANG_COMMAND_TARGET_LISTAURAS, uAuras.size());
- for (Unit::AuraMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
+ for (Unit::AuraApplicationMap::const_iterator itr = uAuras.begin(); itr != uAuras.end(); ++itr)
{
- bool talent = GetTalentSpellCost(itr->second->GetId()) > 0;
+ bool talent = GetTalentSpellCost(itr->second->GetBase()->GetId()) > 0;
- char const* name = itr->second->GetSpellProto()->SpellName[GetSessionDbcLocale()];
+ AuraApplication const * aurApp = itr->second;
+ Aura const * aura = aurApp->GetBase();
+ char const* name = aura->GetSpellProto()->SpellName[GetSessionDbcLocale()];
if (m_session)
{
std::ostringstream ss_name;
- ss_name << "|cffffffff|Hspell:" << itr->second->GetId() << "|h[" << name << "]|h|r";
+ ss_name << "|cffffffff|Hspell:" << aura->GetId() << "|h[" << name << "]|h|r";
- PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffectMask(),
- itr->second->GetAuraCharges(), itr->second->GetStackAmount(),itr->second->GetAuraSlot(),
- itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
+ PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, aura->GetId(), aurApp->GetEffectMask(),
+ aura->GetCharges(), aura->GetStackAmount(), aurApp->GetSlot(),
+ aura->GetDuration(), aura->GetMaxDuration(),
ss_name.str().c_str(),
- (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
- IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
+ (aura->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
+ IS_PLAYER_GUID(aura->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(aura->GetCasterGUID()));
}
else
{
- PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, itr->second->GetId(), itr->second->GetEffectMask(),
- itr->second->GetAuraCharges(), itr->second->GetStackAmount(),itr->second->GetAuraSlot(),
- itr->second->GetAuraDuration(), itr->second->GetAuraMaxDuration(),
+ PSendSysMessage(LANG_COMMAND_TARGET_AURADETAIL, aura->GetId(), aurApp->GetEffectMask(),
+ aura->GetCharges(), aura->GetStackAmount(), aurApp->GetSlot(),
+ aura->GetDuration(), aura->GetMaxDuration(),
name,
- (itr->second->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
- IS_PLAYER_GUID(itr->second->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(itr->second->GetCasterGUID()));
+ (aura->IsPassive() ? passiveStr : ""),(talent ? talentStr : ""),
+ IS_PLAYER_GUID(aura->GetCasterGUID()) ? "player" : "creature",GUID_LOPART(aura->GetCasterGUID()));
}
}
for (uint16 i = 0; i < TOTAL_AURAS; ++i)
{
- Unit::AuraEffectList const& uAuraList = unit->GetAurasByType(AuraType(i));
+ Unit::AuraEffectList const& uAuraList = unit->GetAuraEffectsByType(AuraType(i));
if (uAuraList.empty()) continue;
PSendSysMessage(LANG_COMMAND_TARGET_LISTAURATYPE, uAuraList.size(), i);
for (Unit::AuraEffectList::const_iterator itr = uAuraList.begin(); itr != uAuraList.end(); ++itr)
@@ -7376,9 +7362,8 @@ bool ChatHandler::HandleFreezeCommand(const char *args)
}
//m_session->GetPlayer()->CastSpell(player,spellID,false);
- SpellEntry const *spellInfo = sSpellStore.LookupEntry( 9454 );
- Aura *Aur = new Aura(spellInfo, 1, player, player, player);
- player->AddAura(Aur);
+ if (SpellEntry const *spellInfo = sSpellStore.LookupEntry(9454))
+ Aura::TryCreate(spellInfo, player, player);
//save player
player->SaveToDB();
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index ca622edb9c6..2d08dfe6110 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -42,6 +42,7 @@
#include "CellImpl.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
+#include "SpellAuraEffects.h"
#include "TemporarySummon.h"
#include "Totem.h"
@@ -1805,7 +1806,7 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
if(petType == SUMMON_PET && pet->LoadPetFromDB(this, entry))
{
// Remove Demonic Sacrifice auras (known pet)
- Unit::AuraEffectList const& auraClassScripts = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ Unit::AuraEffectList const& auraClassScripts = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (Unit::AuraEffectList::const_iterator itr = auraClassScripts.begin(); itr!=auraClassScripts.end();)
{
if((*itr)->GetMiscValue()==2228)
@@ -1886,7 +1887,7 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy
if(petType == SUMMON_PET)
{
// Remove Demonic Sacrifice auras (known pet)
- Unit::AuraEffectList const& auraClassScripts = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ Unit::AuraEffectList const& auraClassScripts = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (Unit::AuraEffectList::const_iterator itr = auraClassScripts.begin(); itr!=auraClassScripts.end();)
{
if((*itr)->GetMiscValue()==2228)
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index 4197f52c689..7faca78d73a 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -781,27 +781,40 @@ void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const*
{
// Now add the auras, format "spellid effectindex spellid effectindex..."
char *p,*s;
- std::vector<int> val;
+ std::map<uint32, uint32> val;
s=p=(char*)reinterpret_cast<char const*>(addon->auras);
if(p)
{
+ uint32 currSpellId = 0;
+ bool spell = true;
while (p[0]!=0)
{
++p;
- if (p[0]==' ')
+ if (p[0] == ' ' || p[0] == 0)
{
- val.push_back(atoi(s));
+ if (spell)
+ currSpellId = atoi(s);
+ else
+ {
+ uint8 eff = atoi(s);
+ if (eff >=3)
+ {
+ sLog.outErrorDb("Creature (%s: %u) has wrong `auras` data in `%s`(too high aura effect: %d for spell: %d)",guidEntryStr,addon->guidOrEntry,table,eff,currSpellId);
+ }
+ val[currSpellId] |= 1<<eff;
+ }
+ spell = !spell;
+ if (p[0] == 0)
+ break;
s=++p;
}
}
- if (p!=s)
- val.push_back(atoi(s));
// free char* loaded memory
delete[] (char*)reinterpret_cast<char const*>(addon->auras);
// wrong list
- if (val.size()%2)
+ if (!spell)
{
addon->auras = NULL;
sLog.outErrorDb("Creature (%s: %u) has wrong `auras` data in `%s`.",guidEntryStr,addon->guidOrEntry,table);
@@ -817,17 +830,17 @@ void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const*
}
// replace by new structures array
- const_cast<CreatureDataAddonAura*&>(addon->auras) = new CreatureDataAddonAura[val.size()/2+1];
+ const_cast<CreatureDataAddonAura*&>(addon->auras) = new CreatureDataAddonAura[val.size()+1];
uint32 i=0;
- for (uint32 j = 0; j < val.size()/2; ++j)
+ for (std::map<uint32, uint32>::iterator itr = val.begin(); itr!=val.end();++itr)
{
CreatureDataAddonAura& cAura = const_cast<CreatureDataAddonAura&>(addon->auras[i]);
- cAura.spell_id = (uint32)val[2*j+0];
- cAura.effect_idx = (uint32)val[2*j+1];
- if ( cAura.effect_idx > 2 )
+ cAura.spell_id = itr->first;
+ cAura.effectMask = itr->second;
+ if ( cAura.effectMask > 7 || !cAura.effectMask)
{
- sLog.outErrorDb("Creature (%s: %u) has wrong effect %u for spell %u in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.effect_idx,cAura.spell_id,table);
+ sLog.outErrorDb("Creature (%s: %u) has wrong effect for spell %u in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.spell_id,table);
continue;
}
SpellEntry const *AdditionalSpellInfo = sSpellStore.LookupEntry(cAura.spell_id);
@@ -836,11 +849,21 @@ void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const*
sLog.outErrorDb("Creature (%s: %u) has wrong spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.spell_id,table);
continue;
}
-
- if (!AdditionalSpellInfo->Effect[cAura.effect_idx] || !AdditionalSpellInfo->EffectApplyAuraName[cAura.effect_idx])
+ for (uint8 eff = 0; eff < MAX_SPELL_EFFECTS; ++eff)
{
- sLog.outErrorDb("Creature (%s: %u) has not aura effect %u of spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,cAura.effect_idx,cAura.spell_id,table);
- continue;
+ if ((1<<eff) & cAura.effectMask)
+ {
+ if (!AdditionalSpellInfo->Effect[eff] || !AdditionalSpellInfo->EffectApplyAuraName[eff])
+ {
+ sLog.outErrorDb("Creature (%s: %u) has not aura effect %u of spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,eff,cAura.spell_id,table);
+ continue;
+ }
+ else if (AdditionalSpellInfo->Effect[eff] == SPELL_EFFECT_PERSISTENT_AREA_AURA)
+ {
+ sLog.outErrorDb("Creature (%s: %u) has persistent area aura effect %u of spell %u defined in `auras` field in `%s`.",guidEntryStr,addon->guidOrEntry,eff,cAura.spell_id,table);
+ continue;
+ }
+ }
}
++i;
@@ -849,7 +872,7 @@ void ObjectMgr::ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const*
// fill terminator element (after last added)
CreatureDataAddonAura& endAura = const_cast<CreatureDataAddonAura&>(addon->auras[i]);
endAura.spell_id = 0;
- endAura.effect_idx = 0;
+ endAura.effectMask = 0;
}
void ObjectMgr::LoadCreatureAddons(SQLStorage& creatureaddons, char const* entryName, char const* comment)
@@ -7641,9 +7664,9 @@ bool PlayerCondition::Meets(Player const * player) const
}
case CONDITION_AD_COMMISSION_AURA:
{
- Unit::AuraMap const& auras = player->GetAuras();
- for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- if((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual[0]==3580)
+ Unit::AuraApplicationMap const& auras = player->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ if((itr->second->GetBase()->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetBase()->GetSpellProto()->SpellVisual[0]==3580)
return true;
return false;
}
diff --git a/src/game/OutdoorPvPWG.cpp b/src/game/OutdoorPvPWG.cpp
index 27a9a026f79..2fbf5359a40 100644
--- a/src/game/OutdoorPvPWG.cpp
+++ b/src/game/OutdoorPvPWG.cpp
@@ -1078,7 +1078,7 @@ void OutdoorPvPWG::HandlePlayerLeaveZone(Player * plr, uint32 zone)
void OutdoorPvPWG::PromotePlayer(Player *killer) const
{
- Aura *aur;
+ Aura * aur;
if (aur = killer->GetAura(SPELL_RECRUIT))
{
if (aur->GetStackAmount() >= 5)
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
index 8cee92c485e..71827be8bc9 100644
--- a/src/game/Pet.cpp
+++ b/src/game/Pet.cpp
@@ -27,6 +27,7 @@
#include "Pet.h"
#include "Formulas.h"
#include "SpellAuras.h"
+#include "SpellAuraEffects.h"
#include "CreatureAI.h"
#include "Unit.h"
#include "Util.h"
@@ -57,7 +58,7 @@ m_declinedname(NULL), m_owner(owner)
}
m_name = "Pet";
- m_regenTimer = 4000;
+ m_regenTimer = PET_FOCUS_REGEN_INTERVAL;
m_isWorldObject = true;
}
@@ -553,13 +554,13 @@ void Pet::Update(uint32 diff)
{
case POWER_FOCUS:
Regenerate(POWER_FOCUS);
- m_regenTimer += 4000 - diff;
+ m_regenTimer += PET_FOCUS_REGEN_INTERVAL - diff;
if(!m_regenTimer) ++m_regenTimer;
break;
// in creature::update
//case POWER_ENERGY:
// Regenerate(POWER_ENERGY);
- // m_regenTimer += 2000 - diff;
+ // m_regenTimer += CREATURE_REGEN_INTERVAL - diff;
// if(!m_regenTimer) ++m_regenTimer;
// break;
default:
@@ -617,11 +618,13 @@ void Creature::Regenerate(Powers power)
}
// Apply modifiers (if any).
- AuraEffectList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
+ AuraEffectList const& ModPowerRegenPCTAuras = GetAuraEffectsByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
for (AuraEffectList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
if ((*i)->GetMiscValue() == power)
addvalue *= ((*i)->GetAmount() + 100) / 100.0f;
+ addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, power) * (isHunterPet()? PET_FOCUS_REGEN_INTERVAL : CREATURE_REGEN_INTERVAL) / (5 * IN_MILISECONDS);
+
ModifyPower(power, (int32)addvalue);
}
@@ -1154,24 +1157,29 @@ void Pet::_LoadAuras(uint32 timediff)
{
sLog.outDebug("Loading auras for pet %u",GetGUIDLow());
- QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_mask,stackcount,amount0,amount1,amount2,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber());
+ QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber());
if (result)
{
do
{
int32 damage[3];
+ int32 baseDamage[3];
Field *fields = result->Fetch();
uint64 caster_guid = fields[0].GetUInt64();
uint32 spellid = fields[1].GetUInt32();
uint8 effmask = fields[2].GetUInt8();
- uint8 stackcount = fields[3].GetUInt8();
- damage[0] = fields[4].GetInt32();
- damage[1] = fields[5].GetInt32();
- damage[2] = fields[6].GetInt32();
- int32 maxduration = fields[7].GetInt32();
- int32 remaintime = fields[8].GetInt32();
- uint8 remaincharges = fields[9].GetUInt8();
+ uint8 recalculatemask = fields[3].GetUInt8();
+ uint8 stackcount = fields[4].GetUInt8();
+ damage[0] = fields[5].GetInt32();
+ damage[1] = fields[6].GetInt32();
+ damage[2] = fields[7].GetInt32();
+ baseDamage[0] = fields[8].GetInt32();
+ baseDamage[1] = fields[9].GetInt32();
+ baseDamage[2] = fields[10].GetInt32();
+ int32 maxduration = fields[11].GetInt32();
+ int32 remaintime = fields[12].GetInt32();
+ uint8 remaincharges = fields[13].GetUInt8();
SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid);
if(!spellproto)
@@ -1198,15 +1206,17 @@ void Pet::_LoadAuras(uint32 timediff)
else
remaincharges = 0;
- Aura* aura = new Aura(spellproto, effmask, this, this, this);
- aura->SetLoadedState(caster_guid,maxduration,remaintime,remaincharges, stackcount, &damage[0]);
- if(!aura->CanBeSaved())
+ if (Aura * aura = Aura::TryCreate( spellproto, effmask, this, NULL, &baseDamage[0], NULL, caster_guid))
{
- delete aura;
- continue;
+ if (!aura->CanBeSaved())
+ {
+ aura->Remove();
+ continue;
+ }
+ aura->SetLoadedState(maxduration,remaintime,remaincharges,stackcount,recalculatemask,&damage[0]);
+ aura->ApplyForTargets();
+ sLog.outDetail("Added aura spellid %u, effectmask %u", spellproto->Id, effmask);
}
- AddAura(aura);
- sLog.outDetail("Added aura spellid %u, effectmask %u", spellproto->Id, effmask);
}
while (result->NextRow());
@@ -1218,26 +1228,39 @@ void Pet::_SaveAuras()
{
CharacterDatabase.PExecute("DELETE FROM pet_aura WHERE guid = '%u'", m_charmInfo->GetPetNumber());
- AuraMap const& auras = GetAuras();
- for (AuraMap::const_iterator itr = auras.begin(); itr !=auras.end() ; ++itr)
+ for (AuraMap::const_iterator itr = m_ownedAuras.begin(); itr != m_ownedAuras.end() ; ++itr)
{
if (!itr->second->CanBeSaved())
continue;
- int32 amounts[MAX_SPELL_EFFECTS];
+ Aura * aura = itr->second;
+
+ int32 damage[MAX_SPELL_EFFECTS];
+ int32 baseDamage[MAX_SPELL_EFFECTS];
+ uint8 effMask = 0;
+ uint8 recalculateMask = 0;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (AuraEffect *partAura = itr->second->GetPartAura(i))
- amounts[i] = partAura->GetAmount();
+ if (aura->GetEffect(i))
+ {
+ baseDamage[i] = aura->GetEffect(i)->GetBaseAmount();
+ damage[i] = aura->GetEffect(i)->GetAmount();
+ effMask |= (1<<i);
+ if (aura->GetEffect(i)->CanBeRecalculated())
+ recalculateMask |= (1<<i);
+ }
else
- amounts[i] = 0;
+ {
+ baseDamage[i] = NULL;
+ damage[i] = NULL;
+ }
}
- CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_mask,stackcount,amount0,amount1,amount2,maxduration,remaintime,remaincharges) "
- "VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%u')",
- m_charmInfo->GetPetNumber(), itr->second->GetCasterGUID(), itr->second->GetId(), itr->second->GetEffectMask(),
- itr->second->GetStackAmount(), amounts[0], amounts[1], amounts[2],
- itr->second->GetAuraMaxDuration(), itr->second->GetAuraDuration(),itr->second->GetAuraCharges());
+ CharacterDatabase.PExecute("INSERT INTO pet_aura (guid,caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges) "
+ "VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')",
+ m_charmInfo->GetPetNumber(), itr->second->GetCasterGUID(), itr->second->GetId(), effMask, recalculateMask,
+ itr->second->GetStackAmount(), damage[0], damage[1], damage[2], baseDamage[0], baseDamage[1], baseDamage[2],
+ itr->second->GetMaxDuration(), itr->second->GetDuration(),itr->second->GetCharges());
}
}
diff --git a/src/game/Pet.h b/src/game/Pet.h
index 17df70b0a65..7c1334c4b56 100644
--- a/src/game/Pet.h
+++ b/src/game/Pet.h
@@ -118,6 +118,7 @@ typedef std::vector<uint32> AutoSpellList;
#define PET_FOLLOW_DIST 1
#define PET_FOLLOW_ANGLE (M_PI/2)
+#define PET_FOCUS_REGEN_INTERVAL 4 * IN_MILISECONDS
class Player;
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 03078a35b3e..1f94d5a78fd 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -65,6 +65,7 @@
#include "GameEventMgr.h"
#include "AchievementMgr.h"
#include "SpellAuras.h"
+#include "SpellAuraEffects.h"
#include <cmath>
@@ -945,7 +946,7 @@ int32 Player::getMaxTimer(MirrorTimerType timer)
if (!isAlive() || HasAuraType(SPELL_AURA_WATER_BREATHING) || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING))
return DISABLED_MIRROR_TIMER;
int32 UnderWaterTime = 3*MINUTE*IN_MILISECONDS;
- AuraEffectList const& mModWaterBreathing = GetAurasByType(SPELL_AURA_MOD_WATER_BREATHING);
+ AuraEffectList const& mModWaterBreathing = GetAuraEffectsByType(SPELL_AURA_MOD_WATER_BREATHING);
for (AuraEffectList::const_iterator i = mModWaterBreathing.begin(); i != mModWaterBreathing.end(); ++i)
UnderWaterTime = uint32(UnderWaterTime * (100.0f + (*i)->GetAmount()) / 100.0f);
return UnderWaterTime;
@@ -2022,14 +2023,12 @@ void Player::RegenerateAll()
HasAuraType(SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT) || IsPolymorphed() )
{
RegenerateHealth();
- if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN))
- {
- Regenerate(POWER_RAGE);
- if (getClass() == CLASS_DEATH_KNIGHT)
- Regenerate(POWER_RUNIC_POWER);
- }
}
+ Regenerate(POWER_RAGE);
+ if (getClass() == CLASS_DEATH_KNIGHT)
+ Regenerate(POWER_RUNIC_POWER);
+
if(getClass() == CLASS_DEATH_KNIGHT)
Regenerate(POWER_RUNE);
@@ -2051,18 +2050,6 @@ void Player::Regenerate(Powers power)
return;
uint32 curValue = GetPower(power);
- switch (power)
- {
- case POWER_RAGE:
- case POWER_RUNIC_POWER:
- if (curValue == 0)
- return;
- break;
- default:
- if (curValue == maxValue)
- return;
- break;
- }
// TODO: possible use of miscvalueb instead of amount
if (HasAuraTypeWithValue(SPELL_AURA_PREVENT_REGENERATE_POWER, power))
@@ -2077,22 +2064,28 @@ void Player::Regenerate(Powers power)
bool recentCast = IsUnderLastManaUseEffect();
float ManaIncreaseRate = sWorld.getRate(RATE_POWER_MANA);
if (recentCast) // Trinity Updates Mana in intervals of 2s, which is correct
- addvalue = GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) * ManaIncreaseRate * 0.001f * m_regenTimer;
+ addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) * ManaIncreaseRate * 0.001f * m_regenTimer;
else
- addvalue = GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER) * ManaIncreaseRate * 0.001f * m_regenTimer;
+ addvalue += GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER) * ManaIncreaseRate * 0.001f * m_regenTimer;
} break;
case POWER_RAGE: // Regenerate rage
{
- float RageDecreaseRate = sWorld.getRate(RATE_POWER_RAGE_LOSS);
- addvalue = 20 * RageDecreaseRate; // 2 rage by tick (= 2 seconds => 1 rage/sec)
+ if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN))
+ {
+ float RageDecreaseRate = sWorld.getRate(RATE_POWER_RAGE_LOSS);
+ addvalue += -20 * RageDecreaseRate; // 2 rage by tick (= 2 seconds => 1 rage/sec)
+ }
} break;
case POWER_ENERGY: // Regenerate energy (rogue)
- addvalue = 0.01f * m_regenTimer;
+ addvalue += 0.01f * m_regenTimer;
break;
case POWER_RUNIC_POWER:
{
- float RunicPowerDecreaseRate = sWorld.getRate(RATE_POWER_RUNICPOWER_LOSS);
- addvalue = 30 * RunicPowerDecreaseRate; // 3 RunicPower by tick
+ if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN))
+ {
+ float RunicPowerDecreaseRate = sWorld.getRate(RATE_POWER_RUNICPOWER_LOSS);
+ addvalue += -30 * RunicPowerDecreaseRate; // 3 RunicPower by tick
+ }
} break;
case POWER_RUNE:
case POWER_FOCUS:
@@ -2102,44 +2095,58 @@ void Player::Regenerate(Powers power)
}
// Mana regen calculated in Player::UpdateManaRegen()
- // Exist only for POWER_MANA, POWER_ENERGY, POWER_FOCUS auras
if (power != POWER_MANA)
{
- AuraEffectList const& ModPowerRegenPCTAuras = GetAurasByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
+ AuraEffectList const& ModPowerRegenPCTAuras = GetAuraEffectsByType(SPELL_AURA_MOD_POWER_REGEN_PERCENT);
for (AuraEffectList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i)
if ((*i)->GetMiscValue() == power)
addvalue *= ((*i)->GetAmount() + 100) / 100.0f;
+
+ // Butchery requires combat for this effect
+ if (power != POWER_RUNIC_POWER || isInCombat())
+ addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, power) * ((power != POWER_ENERGY) ? m_regenTimerCount : m_regenTimer) / (5 * IN_MILISECONDS);
}
+ if (addvalue < 0.0f)
+ {
+ if (curValue == 0)
+ return;
+ }
+ else if (addvalue > 0.0f)
+ {
+ if (curValue == maxValue)
+ return;
+ }
+ else
+ return;
+
addvalue += m_powerFraction[power];
- uint32 integerValue = uint32(addvalue);
+ uint32 integerValue = uint32(abs(addvalue));
- switch (power)
+ if (addvalue < 0.0f)
{
- case POWER_RAGE:
- case POWER_RUNIC_POWER:
- if(curValue > integerValue)
- {
- curValue -= integerValue;
- m_powerFraction[power] = addvalue - integerValue;
- }
- else
- {
- curValue = 0;
- m_powerFraction[power] = 0;
- }
- break;
- default:
- curValue += integerValue;
+ if(curValue > integerValue)
+ {
+ curValue -= integerValue;
+ m_powerFraction[power] = addvalue + integerValue;
+ }
+ else
+ {
+ curValue = 0;
+ m_powerFraction[power] = 0;
+ }
+ }
+ else
+ {
+ curValue += integerValue;
- if (curValue > maxValue)
- {
- curValue = maxValue;
- m_powerFraction[power] = 0;
- }
- else
- m_powerFraction[power] = addvalue - integerValue;
- break;
+ if (curValue > maxValue)
+ {
+ curValue = maxValue;
+ m_powerFraction[power] = 0;
+ }
+ else
+ m_powerFraction[power] = addvalue - integerValue;
}
if(m_regenTimerCount >= 2000)
SetPower(power, curValue);
@@ -2168,9 +2175,11 @@ void Player::RegenerateHealth()
addvalue = OCTRegenHPPerSpirit()* HealthIncreaseRate;
if (!isInCombat())
{
- AuraEffectList const& mModHealthRegenPct = GetAurasByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
+ AuraEffectList const& mModHealthRegenPct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALTH_REGEN_PERCENT);
for (AuraEffectList::const_iterator i = mModHealthRegenPct.begin(); i != mModHealthRegenPct.end(); ++i)
addvalue *= (100.0f + (*i)->GetAmount()) / 100.0f;
+
+ addvalue += GetTotalAuraModifier(SPELL_AURA_MOD_REGEN) * 2 * IN_MILISECONDS / (5 * IN_MILISECONDS);
}
else if (HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT))
addvalue *= GetTotalAuraModifier(SPELL_AURA_MOD_REGEN_DURING_COMBAT) / 100.0f;
@@ -2330,7 +2339,7 @@ void Player::SetGameMaster(bool on)
else
{
// restore phase
- AuraEffectList const& phases = GetAurasByType(SPELL_AURA_PHASE);
+ AuraEffectList const& phases = GetAuraEffectsByType(SPELL_AURA_PHASE);
SetPhaseMask(!phases.empty() ? phases.front()->GetMiscValue() : PHASEMASK_NORMAL,false);
m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON;
@@ -4454,9 +4463,9 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)
{
int32 delta = (int32(getLevel()) - startLevel + 1)*MINUTE;
- if(Aura* Aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS, GetGUID()))
+ if(Aura * aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS, GetGUID()))
{
- Aur->SetAuraDuration(delta*IN_MILISECONDS);
+ aur->SetDuration(delta*IN_MILISECONDS);
}
}
}
@@ -5194,10 +5203,10 @@ void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)
int32 amount = uint32(m_baseRatingValue[cr]);
// Apply bonus from SPELL_AURA_MOD_RATING_FROM_STAT
// stat used stored in miscValueB for this aura
- AuraEffectList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT);
+ AuraEffectList const& modRatingFromStat = GetAuraEffectsByType(SPELL_AURA_MOD_RATING_FROM_STAT);
for (AuraEffectList::const_iterator i = modRatingFromStat.begin(); i != modRatingFromStat.end(); ++i)
if ((*i)->GetMiscValue() & (1<<cr))
- amount += int32(GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetAmount() / 100.0f);
+ amount += int32(GetStat(Stats((*i)->GetMiscValueB())) * (*i)->GetAmount() / 100.0f);
if (amount < 0)
amount = 0;
SetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, uint32(amount));
@@ -5723,16 +5732,16 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)
SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0);
// temporary bonuses
- AuraEffectList const& mModSkill = GetAurasByType(SPELL_AURA_MOD_SKILL);
+ AuraEffectList const& mModSkill = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL);
for (AuraEffectList::const_iterator j = mModSkill.begin(); j != mModSkill.end(); ++j)
if ((*j)->GetMiscValue() == int32(id))
- (*j)->ApplyModifier(true);
+ (*j)->HandleEffect(this, 0, true);
// permanent bonuses
- AuraEffectList const& mModSkillTalent = GetAurasByType(SPELL_AURA_MOD_SKILL_TALENT);
+ AuraEffectList const& mModSkillTalent = GetAuraEffectsByType(SPELL_AURA_MOD_SKILL_TALENT);
for (AuraEffectList::const_iterator j = mModSkillTalent.begin(); j != mModSkillTalent.end(); ++j)
if ((*j)->GetMiscValue() == int32(id))
- (*j)->ApplyModifier(true);
+ (*j)->HandleEffect(this, 0, true);
// Learn all spells for skill
learnSkillRewardedSpells(id, currVal);
@@ -6826,19 +6835,21 @@ void Player::DuelComplete(DuelCompleteType type)
duel->initiator->RemoveGameObject(obj,true);
/* remove auras */
- AuraMap &itsAuras = duel->opponent->GetAuras();
- for (AuraMap::iterator i = itsAuras.begin(); i != itsAuras.end();)
+ AuraApplicationMap &itsAuras = duel->opponent->GetAppliedAuras();
+ for (AuraApplicationMap::iterator i = itsAuras.begin(); i != itsAuras.end();)
{
- if (!i->second->IsPositive() && i->second->GetCasterGUID() == GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime)
+ Aura const * aura = i->second->GetBase();
+ if (!i->second->IsPositive() && aura->GetCasterGUID() == GetGUID() && aura->GetApplyTime() >= duel->startTime)
duel->opponent->RemoveAura(i);
else
++i;
}
- AuraMap &myAuras = GetAuras();
- for (AuraMap::iterator i = myAuras.begin(); i != myAuras.end();)
+ AuraApplicationMap &myAuras = GetAppliedAuras();
+ for (AuraApplicationMap::iterator i = myAuras.begin(); i != myAuras.end();)
{
- if (!i->second->IsPositive() && i->second->GetCasterGUID() == duel->opponent->GetGUID() && i->second->GetAuraApplyTime() >= duel->startTime)
+ Aura const * aura = i->second->GetBase();
+ if (!i->second->IsPositive() && aura->GetCasterGUID() == duel->opponent->GetGUID() && aura->GetApplyTime() >= duel->startTime)
RemoveAura(i);
else
++i;
@@ -7215,20 +7226,20 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool appl
void Player::_ApplyWeaponDependentAuraMods(Item *item,WeaponAttackType attackType,bool apply)
{
- AuraEffectList const& auraCritList = GetAurasByType(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
+ AuraEffectList const& auraCritList = GetAuraEffectsByType(SPELL_AURA_MOD_WEAPON_CRIT_PERCENT);
for (AuraEffectList::const_iterator itr = auraCritList.begin(); itr!=auraCritList.end(); ++itr)
_ApplyWeaponDependentAuraCritMod(item,attackType,*itr,apply);
- AuraEffectList const& auraDamageFlatList = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE);
+ AuraEffectList const& auraDamageFlatList = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE);
for (AuraEffectList::const_iterator itr = auraDamageFlatList.begin(); itr!=auraDamageFlatList.end(); ++itr)
_ApplyWeaponDependentAuraDamageMod(item,attackType,*itr,apply);
- AuraEffectList const& auraDamagePCTList = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ AuraEffectList const& auraDamagePCTList = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
for (AuraEffectList::const_iterator itr = auraDamagePCTList.begin(); itr!=auraDamagePCTList.end(); ++itr)
_ApplyWeaponDependentAuraDamageMod(item,attackType,*itr,apply);
}
-void Player::_ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attackType, AuraEffect* aura, bool apply)
+void Player::_ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attackType, AuraEffect const* aura, bool apply)
{
// generic not weapon specific case processes in aura code
if (aura->GetSpellProto()->EquippedItemClass == -1)
@@ -7247,7 +7258,7 @@ void Player::_ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attac
HandleBaseModValue(mod, FLAT_MOD, float (aura->GetAmount()), apply);
}
-void Player::_ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType attackType, AuraEffect* aura, bool apply)
+void Player::_ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType attackType, AuraEffect const* aura, bool apply)
{
//don't apply mod if item is broken
if (item->IsBroken())
@@ -7271,7 +7282,7 @@ void Player::_ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType att
}
UnitModifierType unitModType = TOTAL_VALUE;
- switch (aura->GetAuraName())
+ switch (aura->GetAuraType())
{
case SPELL_AURA_MOD_DAMAGE_DONE: unitModType = TOTAL_VALUE; break;
case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE: unitModType = TOTAL_PCT; break;
@@ -7322,9 +7333,9 @@ void Player::ApplyEquipSpell(SpellEntry const* spellInfo, Item* item, bool apply
if (form_change) // check aura active state from other form
{
- AuraMap const& auras = GetAuras();
- for (AuraMap::const_iterator itr = auras.lower_bound(spellInfo->Id); itr != auras.upper_bound(spellInfo->Id); ++itr)
- if (!item || itr->second->GetCastItemGUID()==item->GetGUID())
+ AuraApplicationMap const& auras = GetAppliedAuras();
+ for (AuraApplicationMap::const_iterator itr = auras.lower_bound(spellInfo->Id); itr != auras.upper_bound(spellInfo->Id); ++itr)
+ if (!item || itr->second->GetBase()->GetCastItemGUID() == item->GetGUID())
return;
}
@@ -13851,7 +13862,7 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver
uint32 XP = q_status.m_rewarded ? 0 : uint32(pQuest->XPValue( this )*sWorld.getRate(RATE_XP_QUEST));
// handle SPELL_AURA_MOD_XP_QUEST_PCT auras
- Unit::AuraEffectList const& ModXPPctAuras = GetAurasByType(SPELL_AURA_MOD_XP_QUEST_PCT);
+ Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_QUEST_PCT);
for (Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin(); i != ModXPPctAuras.end(); ++i)
XP = uint32(XP*(1.0f + (*i)->GetAmount() / 100.0f));
@@ -16007,24 +16018,29 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
{
sLog.outDebug("Loading auras for player %u",GetGUIDLow());
- //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_mask,stackcount,amount0,amount1,amount2,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow());
+ //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow());
if (result)
{
do
{
int32 damage[3];
+ int32 baseDamage[3];
Field *fields = result->Fetch();
uint64 caster_guid = fields[0].GetUInt64();
uint32 spellid = fields[1].GetUInt32();
uint8 effmask = fields[2].GetUInt8();
- uint8 stackcount = fields[3].GetUInt8();
- damage[0] = fields[4].GetInt32();
- damage[1] = fields[5].GetInt32();
- damage[2] = fields[6].GetInt32();
- int32 maxduration = fields[7].GetInt32();
- int32 remaintime = fields[8].GetInt32();
- uint8 remaincharges = fields[9].GetUInt8();
+ uint8 recalculatemask = fields[3].GetUInt8();
+ uint8 stackcount = fields[4].GetUInt8();
+ damage[0] = fields[5].GetInt32();
+ damage[1] = fields[6].GetInt32();
+ damage[2] = fields[7].GetInt32();
+ baseDamage[0] = fields[8].GetInt32();
+ baseDamage[1] = fields[9].GetInt32();
+ baseDamage[2] = fields[10].GetInt32();
+ int32 maxduration = fields[11].GetInt32();
+ int32 remaintime = fields[12].GetInt32();
+ uint8 remaincharges = fields[13].GetUInt8();
SpellEntry const* spellproto = sSpellStore.LookupEntry(spellid);
if (!spellproto)
@@ -16051,15 +16067,17 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)
else
remaincharges = 0;
- Aura* aura = new Aura(spellproto, effmask, this, this, this);
- aura->SetLoadedState(caster_guid,maxduration,remaintime,remaincharges, stackcount, &damage[0]);
- if (!aura->CanBeSaved())
+ if (Aura * aura = Aura::TryCreate(spellproto, effmask, this, NULL, &baseDamage[0], NULL, caster_guid))
{
- delete aura;
- continue;
+ if (!aura->CanBeSaved())
+ {
+ aura->Remove();
+ continue;
+ }
+ aura->SetLoadedState(maxduration,remaintime,remaincharges,stackcount,recalculatemask,&damage[0]);
+ aura->ApplyForTargets();
+ sLog.outDetail("Added aura spellid %u, effectmask %u", spellproto->Id, effmask);
}
- AddAura(aura);
- sLog.outDetail("Added aura spellid %u, effectmask %u", spellproto->Id, effmask);
}
while (result->NextRow());
@@ -17170,26 +17188,39 @@ void Player::_SaveAuras()
{
CharacterDatabase.PExecute("DELETE FROM character_aura WHERE guid = '%u'",GetGUIDLow());
- AuraMap const& auras = GetAuras();
- for (AuraMap::const_iterator itr = auras.begin(); itr !=auras.end() ; ++itr)
+ for (AuraMap::const_iterator itr = m_ownedAuras.begin(); itr != m_ownedAuras.end() ; ++itr)
{
if (!itr->second->CanBeSaved())
continue;
- int32 amounts[MAX_SPELL_EFFECTS];
+ Aura * aura = itr->second;
+
+ int32 damage[MAX_SPELL_EFFECTS];
+ int32 baseDamage[MAX_SPELL_EFFECTS];
+ uint8 effMask = 0;
+ uint8 recalculateMask = 0;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (AuraEffect * partAura = itr->second->GetPartAura(i))
- amounts[i] = partAura->GetAmount();
+ if (aura->GetEffect(i))
+ {
+ baseDamage[i] = aura->GetEffect(i)->GetBaseAmount();
+ damage[i] = aura->GetEffect(i)->GetAmount();
+ effMask |= (1<<i);
+ if (aura->GetEffect(i)->CanBeRecalculated())
+ recalculateMask |= (1<<i);
+ }
else
- amounts[i] = 0;
+ {
+ baseDamage[i] = NULL;
+ damage[i] = NULL;
+ }
}
- CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_mask,stackcount,amount0,amount1,amount2,maxduration,remaintime,remaincharges) "
- "VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%u')",
- GetGUIDLow(), itr->second->GetCasterGUID(), itr->second->GetId(), itr->second->GetEffectMask(),
- itr->second->GetStackAmount(), amounts[0], amounts[1], amounts[2],
- itr->second->GetAuraMaxDuration(),itr->second->GetAuraDuration(),itr->second->GetAuraCharges());
+ CharacterDatabase.PExecute("INSERT INTO character_aura (guid,caster_guid,spell,effect_mask,recalculate_mask,stackcount,amount0,amount1,amount2,base_amount0,base_amount1,base_amount2,maxduration,remaintime,remaincharges) "
+ "VALUES ('%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%u')",
+ GetGUIDLow(), itr->second->GetCasterGUID(), itr->second->GetId(), effMask, recalculateMask,
+ itr->second->GetStackAmount(), damage[0], damage[1], damage[2], baseDamage[0], baseDamage[1], baseDamage[2],
+ itr->second->GetMaxDuration(), itr->second->GetDuration(),itr->second->GetCharges());
}
}
@@ -18204,6 +18235,7 @@ bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mo
void Player::AddSpellMod(SpellModifier* mod, bool apply)
{
+ sLog.outDebug("Player::AddSpellMod %d", mod->spellId);
uint16 Opcode = (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER;
int i = 0;
@@ -18236,7 +18268,9 @@ void Player::AddSpellMod(SpellModifier* mod, bool apply)
else
{
m_spellMods[mod->op].remove(mod);
- delete mod;
+ // mods bound to aura will be removed in AuraEffect::~AuraEffect
+ if (!mod->ownerAura)
+ delete mod;
}
}
@@ -18253,7 +18287,7 @@ void Player::RestoreSpellMods(Spell * spell)
SpellModifier *mod = *itr;
// spellmods without aura set cannot be charged
- if (!mod->ownerAura || !mod->ownerAura->GetAuraCharges())
+ if (!mod->ownerAura || !mod->ownerAura->GetCharges())
continue;
// check if mod affected this spell
@@ -18271,12 +18305,12 @@ void Player::RestoreSpellMods(Spell * spell)
mod->charges++;
// Do not set more spellmods than avalible
- if (mod->ownerAura->GetAuraCharges() < mod->charges)
- mod->charges = mod->ownerAura->GetAuraCharges();
+ if (mod->ownerAura->GetCharges() < mod->charges)
+ mod->charges = mod->ownerAura->GetCharges();
// Skip this check for now - aura charges may change due to various reason
// TODO: trac these changes correctly
- //assert (mod->ownerAura->GetAuraCharges() <= mod->charges);
+ //assert (mod->ownerAura->GetCharges() <= mod->charges);
}
}
}
@@ -18287,27 +18321,28 @@ void Player::RemoveSpellMods(Spell * spell)
return;
std::set <Aura *> checkedSpells;
- AuraEffectList const & auraList = GetAurasByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
+ AuraEffectList const & auraList = GetAuraEffectsByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
for (AuraEffectList::const_iterator itr = auraList.begin(); itr != auraList.end();)
{
- AuraEffect * aur = *itr;
+ AuraEffect * aurEff = *itr;
+ Aura * aura = aurEff->GetBase();
++itr;
- if (!aur->GetParentAura()->GetAuraCharges())
+ if (!aura->GetCharges())
continue;
- SpellEntry const * spellInfo = aur->GetSpellProto();
+ SpellEntry const * spellInfo = aura->GetSpellProto();
if (spellInfo->SpellFamilyName != spell->m_spellInfo->SpellFamilyName ||
- checkedSpells.find(aur->GetParentAura()) != checkedSpells.end())
+ checkedSpells.find(aura) != checkedSpells.end())
continue;
- if (spell->m_spellInfo->SpellFamilyFlags & spellInfo->EffectSpellClassMask[aur->GetEffIndex()]
+ if (spell->m_spellInfo->SpellFamilyFlags & spellInfo->EffectSpellClassMask[aurEff->GetEffIndex()]
// this is for fingers of frost, look at spell::finish part, a charge will be taken by the triggering spell
- && aur->GetParentAura()->GetAuraDuration() != aur->GetParentAura()->GetAuraMaxDuration())
+ && aura->GetDuration() != aura->GetMaxDuration())
{
- checkedSpells.insert(aur->GetParentAura());
- spell->m_appliedMods.erase(aur->GetParentAura());
- if (aur->GetParentAura()->DropAuraCharge())
+ checkedSpells.insert(aura);
+ spell->m_appliedMods.erase(aura);
+ if (aura->DropCharge())
itr = auraList.begin();
}
}
@@ -18323,7 +18358,7 @@ void Player::RemoveSpellMods(Spell * spell)
++itr;
// spellmods without aura set cannot be charged
- if (!mod->ownerAura || !mod->ownerAura->GetAuraCharges())
+ if (!mod->ownerAura || !mod->ownerAura->GetCharges())
continue;
// check if mod affected this spell
@@ -18334,7 +18369,7 @@ void Player::RemoveSpellMods(Spell * spell)
// remove from list
spell->m_appliedMods.erase(iterMod);
- if (mod->ownerAura->DropAuraCharge())
+ if (mod->ownerAura->DropCharge())
itr = m_spellMods[i].begin();
}
}
@@ -19565,7 +19600,7 @@ void Player::SetBattleGroundEntryPoint()
// Mount spell id storing
if (IsMounted())
{
- AuraEffectList const& auras = GetAurasByType(SPELL_AURA_MOUNTED);
+ AuraEffectList const& auras = GetAuraEffectsByType(SPELL_AURA_MOUNTED);
if (!auras.empty())
m_bgData.mountSpell = (*auras.begin())->GetId();
}
@@ -20181,15 +20216,15 @@ void Player::SendInitialPacketsAfterAddToMap()
};
for (AuraType const* itr = &auratypes[0]; itr && itr[0] != SPELL_AURA_NONE; ++itr)
{
- Unit::AuraEffectList const& auraList = GetAurasByType(*itr);
+ Unit::AuraEffectList const& auraList = GetAuraEffectsByType(*itr);
if(!auraList.empty())
- auraList.front()->ApplyModifier(true,true);
+ auraList.front()->HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true);
}
if(HasAuraType(SPELL_AURA_MOD_STUN))
SetMovement(MOVE_ROOT);
- // manual send package (have code in ApplyModifier(true,true); that don't must be re-applied.
+ // manual send package (have code in HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true); that don't must be re-applied.
if(HasAuraType(SPELL_AURA_MOD_ROOT))
{
WorldPacket data2(SMSG_FORCE_MOVE_ROOT, 10);
@@ -20489,29 +20524,28 @@ void Player::SendAurasForTarget(Unit *target)
Unit::VisibleAuraMap const *visibleAuras = target->GetVisibleAuras();
for (Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)
{
- Aura * aura=itr->second;
- data << uint8(aura->GetAuraSlot());
+ AuraApplication * auraApp = itr->second;
+ Aura * aura = auraApp->GetBase();
+ data << uint8(auraApp->GetSlot());
data << uint32(aura->GetId());
// flags
- data << aura->m_auraFlags;
+ uint32 flags = auraApp->GetFlags();
+ if (aura->GetMaxDuration() > 0)
+ flags |= AFLAG_DURATION;
+ data << uint8(flags);
// level
- data << aura->m_auraLevel;
+ data << uint8(aura->GetCasterLevel());
// charges
- data << uint8(aura->GetStackAmount()>1 ? aura->GetStackAmount() : aura->GetAuraCharges());
+ data << uint8(aura->GetStackAmount() > 1 ? aura->GetStackAmount() : (aura->GetCharges()) ? aura->GetCharges() : 1);
- if(!(aura->m_auraFlags & AFLAG_CASTER))
- {
- if (Unit * caster = aura->GetCaster())
- data.append(caster->GetPackGUID());
- else
- data << uint8(0);
- }
+ if(!(flags & AFLAG_CASTER))
+ data.appendPackGUID(aura->GetCasterGUID());
- if(aura->m_auraFlags & AFLAG_DURATION) // include aura duration
+ if(flags & AFLAG_DURATION) // include aura duration
{
- data << uint32(aura->GetAuraMaxDuration());
- data << uint32(aura->GetAuraDuration());
+ data << uint32(aura->GetMaxDuration());
+ data << uint32(aura->GetDuration());
}
}
@@ -20847,14 +20881,13 @@ bool Player::CanNoReagentCast(SpellEntry const* spellInfo) const
void Player::RemoveItemDependentAurasAndCasts( Item * pItem )
{
- AuraMap& auras = GetAuras();
- for (AuraMap::iterator itr = auras.begin(); itr != auras.end();)
+ for (AuraMap::iterator itr = m_ownedAuras.begin(); itr != m_ownedAuras.end();)
{
- Aura* aura = itr->second;
+ Aura * aura = itr->second;
// skip passive (passive item dependent spells work in another way) and not self applied auras
SpellEntry const* spellInfo = aura->GetSpellProto();
- if(aura->IsPassive() || aura->GetCasterGUID()!=GetGUID())
+ if(aura->IsPassive() || aura->GetCasterGUID() != GetGUID())
{
++itr;
continue;
@@ -20868,7 +20901,7 @@ void Player::RemoveItemDependentAurasAndCasts( Item * pItem )
}
// no alt item, remove aura, restart check
- RemoveAura(itr);
+ RemoveOwnedAura(itr);
}
// currently casted spells can be dependent from item
@@ -20883,7 +20916,7 @@ uint32 Player::GetResurrectionSpellId()
// search priceless resurrection possibilities
uint32 prio = 0;
uint32 spell_id = 0;
- AuraEffectList const& dummyAuras = GetAurasByType(SPELL_AURA_DUMMY);
+ AuraEffectList const& dummyAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY);
for (AuraEffectList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
{
// Soulstone Resurrection // prio: 3 (max, non death persistent)
@@ -20997,7 +21030,7 @@ bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim)
uint32 itr_xp = (member_with_max_level == not_gray_member_with_max_level) ? uint32(xp*rate) : uint32((xp*rate/2)+1);
// handle SPELL_AURA_MOD_XP_PCT auras
- Unit::AuraEffectList const& ModXPPctAuras = GetAurasByType(SPELL_AURA_MOD_XP_PCT);
+ Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT);
for (Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin(); i != ModXPPctAuras.end(); ++i)
itr_xp = uint32(itr_xp*(1.0f + (*i)->GetAmount() / 100.0f));
@@ -21031,7 +21064,7 @@ bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim)
RewardReputation(pVictim,1);
// handle SPELL_AURA_MOD_XP_PCT auras
- Unit::AuraEffectList const& ModXPPctAuras = GetAurasByType(SPELL_AURA_MOD_XP_PCT);
+ Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT);
for (Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin(); i != ModXPPctAuras.end(); ++i)
xp = uint32(xp*(1.0f + (*i)->GetAmount() / 100.0f));
@@ -21158,11 +21191,11 @@ void Player::UpdateZoneDependentAuras( uint32 newZone )
void Player::UpdateAreaDependentAuras( uint32 newArea )
{
// remove auras from spells with area limitations
- for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
+ for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
{
// use m_zoneUpdateId for speed: UpdateArea called from UpdateZone or instead UpdateZone in both cases m_zoneUpdateId up-to-date
if(spellmgr.GetSpellAllowedInLocationError(iter->second->GetSpellProto(),GetMapId(),m_zoneUpdateId,newArea,this) != SPELL_CAST_OK)
- RemoveAura(iter);
+ RemoveOwnedAura(iter);
else
++iter;
}
@@ -21575,7 +21608,7 @@ void Player::InitGlyphsForLevel()
bool Player::isTotalImmune()
{
- AuraEffectList const& immune = GetAurasByType(SPELL_AURA_SCHOOL_IMMUNITY);
+ AuraEffectList const& immune = GetAuraEffectsByType(SPELL_AURA_SCHOOL_IMMUNITY);
uint32 immuneMask = 0;
for (AuraEffectList::const_iterator itr = immune.begin(); itr != immune.end(); ++itr)
@@ -21626,7 +21659,7 @@ void Player::SetTitle(CharTitlesEntry const* title, bool lost)
/*-----------------------TRINITY--------------------------*/
bool Player::isTotalImmunity()
{
- AuraEffectList const& immune = GetAurasByType(SPELL_AURA_SCHOOL_IMMUNITY);
+ AuraEffectList const& immune = GetAuraEffectsByType(SPELL_AURA_SCHOOL_IMMUNITY);
for (AuraEffectList::const_iterator itr = immune.begin(); itr != immune.end(); ++itr)
{
@@ -21656,9 +21689,9 @@ void Player::UpdateCharmedAI()
//kill self if charm aura has infinite duration
if(charmer->IsInEvadeMode())
{
- AuraEffectList const& auras = GetAurasByType(SPELL_AURA_MOD_CHARM);
+ AuraEffectList const& auras = GetAuraEffectsByType(SPELL_AURA_MOD_CHARM);
for (AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
- if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetParentAura()->IsPermanent())
+ if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetBase()->IsPermanent())
{
charmer->DealDamage(this, GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
return;
@@ -21680,6 +21713,34 @@ void Player::UpdateCharmedAI()
}
}
+void Player::RemoveRunesByAuraEffect(AuraEffect const * aura)
+{
+ for(uint8 i = 0; i < MAX_RUNES; ++i)
+ {
+ if (m_runes->runes[i].ConvertAura == aura)
+ {
+ ConvertRune(i, GetBaseRune(i));
+ SetRuneConvertAura(i, NULL);
+ }
+ }
+}
+
+void Player::RestoreBaseRune(uint8 index)
+{
+ AuraEffect const * aura = m_runes->runes[index].ConvertAura;
+ ConvertRune(index, GetBaseRune(index));
+ SetRuneConvertAura(index, NULL);
+ // Don't drop passive talents providing rune convertion
+ if (!aura || aura->GetAuraType() != SPELL_AURA_CONVERT_RUNE)
+ return;
+ for(uint8 i = 0; i < MAX_RUNES; ++i)
+ {
+ if (aura == m_runes->runes[i].ConvertAura)
+ return;
+ }
+ aura->GetBase()->Remove();
+}
+
void Player::ConvertRune(uint8 index, RuneType newType)
{
SetCurrentRune(index, newType);
@@ -21732,6 +21793,7 @@ void Player::InitRunes()
SetBaseRune(i, runeSlotTypes[i]); // init base types
SetCurrentRune(i, runeSlotTypes[i]); // init current types
SetRuneCooldown(i, 0); // reset cooldowns
+ SetRuneConvertAura(i, NULL);
m_runes->SetRuneState(i);
}
@@ -21915,7 +21977,7 @@ uint32 Player::GetPhaseMaskForSpawn() const
phase = GetPhaseMask();
else
{
- AuraEffectList const& phases = GetAurasByType(SPELL_AURA_PHASE);
+ AuraEffectList const& phases = GetAuraEffectsByType(SPELL_AURA_PHASE);
if (!phases.empty())
phase = phases.front()->GetMiscValue();
}
@@ -22034,7 +22096,7 @@ void Player::HandleFall(MovementInfo const& movementInfo)
DEBUG_LOG("FALLDAMAGE z=%f sz=%f pZ=%f FallTime=%d mZ=%f damage=%d SF=%d" , movementInfo.z, height, GetPositionZ(), movementInfo.fallTime, height, damage, safe_fall);
}
}
- RemoveAura(44795); // No fly zone - Parachute
+ RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_LANDING); // No fly zone - Parachute
}
void Player::UpdateAchievementCriteria( AchievementCriteriaTypes type, uint32 miscvalue1/*=0*/, uint32 miscvalue2/*=0*/, Unit *unit/*=NULL*/, uint32 time/*=0*/ )
diff --git a/src/game/Player.h b/src/game/Player.h
index 53358c03817..cac6e889345 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -111,7 +111,7 @@ struct SpellModifier
int32 value;
flag96 mask;
uint32 spellId;
- Aura *const ownerAura;
+ Aura * const ownerAura;
};
typedef UNORDERED_MAP<uint32, PlayerTalent*> PlayerTalentMap;
@@ -297,6 +297,7 @@ struct RuneInfo
uint8 BaseRune;
uint8 CurrentRune;
uint8 Cooldown;
+ AuraEffect const * ConvertAura;
};
struct Runes
@@ -1924,8 +1925,8 @@ class TRINITY_DLL_SPEC Player : public Unit, public GridObject<Player>
void _RemoveAllStatBonuses();
void _ApplyWeaponDependentAuraMods(Item *item, WeaponAttackType attackType, bool apply);
- void _ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attackType, AuraEffect* aura, bool apply);
- void _ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType attackType, AuraEffect* aura, bool apply);
+ void _ApplyWeaponDependentAuraCritMod(Item *item, WeaponAttackType attackType, AuraEffect const * aura, bool apply);
+ void _ApplyWeaponDependentAuraDamageMod(Item *item, WeaponAttackType attackType, AuraEffect const * aura, bool apply);
void _ApplyItemMods(Item *item,uint8 slot,bool apply);
void _RemoveAllItemMods();
@@ -2259,6 +2260,10 @@ class TRINITY_DLL_SPEC Player : public Unit, public GridObject<Player>
void SetBaseRune(uint8 index, RuneType baseRune) { m_runes->runes[index].BaseRune = baseRune; }
void SetCurrentRune(uint8 index, RuneType currentRune) { m_runes->runes[index].CurrentRune = currentRune; }
void SetRuneCooldown(uint8 index, uint8 cooldown) { m_runes->runes[index].Cooldown = cooldown; m_runes->SetRuneState(index, (cooldown == 0) ? true : false); }
+ void SetRuneConvertAura(uint8 index, AuraEffect const * aura) { m_runes->runes[index].ConvertAura = aura; }
+ void AddRuneByAuraEffect(uint8 index, RuneType newType, AuraEffect const * aura) { SetRuneConvertAura(index, aura); ConvertRune(index, newType); }
+ void RemoveRunesByAuraEffect(AuraEffect const * aura);
+ void RestoreBaseRune(uint8 index);
void ConvertRune(uint8 index, RuneType newType);
void ResyncRunes(uint8 count);
void AddRunePower(uint8 index);
@@ -2594,6 +2599,7 @@ template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T &bas
if(!IsAffectedBySpellmod(spellInfo,mod,spell))
continue;
+
if (mod->type == SPELLMOD_FLAT)
totalflat += mod->value;
else if (mod->type == SPELLMOD_PCT)
@@ -2611,7 +2617,6 @@ template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T &bas
DropModCharge(mod, spell);
}
-
float diff = (float)basevalue*(float)totalpct/100.0f + (float)totalflat;
basevalue = T((float)basevalue + diff);
return T(diff);
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index 1b5c094e28c..d08ad736819 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -2495,7 +2495,7 @@ enum DiminishingReturnsType
enum DiminishingGroup
{
// Common Groups
- DIMINISHING_NONE,
+ DIMINISHING_NONE = 0,
DIMINISHING_CONTROL_STUN, // Player Controlled stuns
DIMINISHING_TRIGGER_STUN, // By aura proced stuns, usualy chance on hit talents
DIMINISHING_CONTROL_ROOT, // Immobilizing effects from casted spells
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 3d053ebb8b9..569602ad680 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -50,6 +50,7 @@
#include "TemporarySummon.h"
#include "Vehicle.h"
#include "ScriptCalls.h"
+#include "SpellAuraEffects.h"
#define SPELL_CHANNEL_UPDATE_INTERVAL (1 * IN_MILISECONDS)
@@ -382,8 +383,6 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
m_delayStart = 0;
m_delayAtDamageCount = 0;
- m_canTrigger=true;
-
m_applyMultiplierMask = 0;
m_effectMask = 0;
m_auraScaleMask = 0;
@@ -455,7 +454,6 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi
m_preCastSpell = 0;
m_triggeredByAuraSpell = NULL;
m_spellAura = NULL;
- m_spellDynObj = NULL;
//Auto Shot & Shoot (wand)
m_autoRepeat = IsAutoRepeatRangedSpell(m_spellInfo);
@@ -773,7 +771,7 @@ void Spell::SelectSpellTargets()
}
}
-void Spell::prepareDataForTriggerSystem(AuraEffect * triggeredByAura)
+void Spell::prepareDataForTriggerSystem(AuraEffect const * triggeredByAura)
{
//==========================================================================================
// Now fill data for trigger system, need know:
@@ -828,10 +826,6 @@ void Spell::prepareDataForTriggerSystem(AuraEffect * triggeredByAura)
Effects which are result of aura proc from triggered spell cannot proc
to prevent chain proc of these spells
*/
- if ((triggeredByAura && !triggeredByAura->GetParentAura()->GetTarget()->CanProc()))
- {
- m_canTrigger=false;
- }
// Ranged autorepeat attack is set as triggered spell - ignore it
if (!(m_procAttacker & PROC_FLAG_SUCCESSFUL_RANGED_HIT))
@@ -1072,7 +1066,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
//Spells with this flag cannot trigger if effect is casted on self
// Slice and Dice, relentless strikes, eviscerate
- bool canEffectTrigger = m_canTrigger && (m_spellInfo->AttributesEx4 & (SPELL_ATTR_EX4_CANT_PROC_FROM_SELFCAST) ? m_caster!=unitTarget : true);
+ bool canEffectTrigger = unitTarget->CanProc() && (m_spellInfo->AttributesEx4 & (SPELL_ATTR_EX4_CANT_PROC_FROM_SELFCAST) ? m_caster!=unitTarget : true);
Unit * spellHitTarget = NULL;
if (missInfo==SPELL_MISS_NONE) // In case spell hit target, do all effect on that target
@@ -1166,9 +1160,6 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
if (canEffectTrigger && missInfo != SPELL_MISS_REFLECT)
caster->ProcDamageAndSpell(unitTarget, procAttacker, procVictim, procEx, addhealth, m_attackType, m_spellInfo, m_triggeredByAuraSpell);
- if (m_spellAura)
- m_spellAura->SetProcDamage(addhealth);
-
int32 gain = caster->DealHeal(unitTarget, addhealth, m_spellInfo, crit);
unitTarget->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, m_spellInfo);
}
@@ -1197,10 +1188,14 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
((Player *)caster)->CastItemCombatSpell(unitTarget, m_attackType, procVictim, procEx);
}
- if (m_spellAura)
- m_spellAura->SetProcDamage(damageInfo.damage);
caster->DealSpellDamage(&damageInfo, true);
+ // Haunt
+ if(m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->SpellFamilyFlags[1] & 0x40000 && m_spellAura && m_spellAura->GetEffect(1))
+ {
+ AuraEffect * aurEff = m_spellAura->GetEffect(1);
+ aurEff->SetAmount(aurEff->GetAmount() * damageInfo.damage / 100);
+ }
}
// Passive spell hits/misses or active spells only misses (only triggers)
else
@@ -1339,7 +1334,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask, bool
uint8 aura_effmask = 0;
for (uint8 i = 0; i < 3; ++i)
- if (effectMask & (1<<i) && (m_spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA || IsAreaAuraEffect(m_spellInfo->Effect[i])))
+ if (effectMask & (1<<i) && IsUnitOwnedAuraEffect(m_spellInfo->Effect[i]))
aura_effmask |= 1<<i;
if (aura_effmask)
@@ -1355,52 +1350,50 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask, bool
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
basePoints[i] = aurSpellInfo->EffectBasePoints[i];
- }
- }
- else
- {
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- {
- basePoints[i] = m_currentBasePoints[i];
+ if (m_spellInfo->Effect[i] != aurSpellInfo->Effect[i])
+ {
+ aurSpellInfo = m_spellInfo;
+ break;
+ }
}
}
if(m_originalCaster)
{
- Aura *Aur = new Aura(aurSpellInfo, aura_effmask, unit, m_caster, m_originalCaster, basePoints, m_CastItem);
+ if (m_spellAura = Aura::TryCreate(aurSpellInfo, effectMask, unit,
+ m_originalCaster,(aurSpellInfo == m_spellInfo)? &m_currentBasePoints[0] : &basePoints[0], m_CastItem))
+ {
+ // Now Reduce spell duration using data received at spell hit
+ int32 duration = m_spellAura->GetMaxDuration();
+ int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup,aurSpellInfo);
+ unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel,limitduration);
+ ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup);
- if (!Aur->IsAreaAura())
- {
- // Now Reduce spell duration using data received at spell hit
- int32 duration = Aur->GetAuraMaxDuration();
- int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup,aurSpellInfo);
- unitTarget->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel,limitduration);
- Aur->setDiminishGroup(m_diminishGroup);
+ bool positive = IsPositiveSpell(m_spellAura->GetId());
+ AuraApplication * aurApp = m_spellAura->GetApplicationOfTarget(m_originalCaster->GetGUID());
+ if (aurApp)
+ positive = aurApp->IsPositive();
- duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, Aur->IsPositive());
+ duration = m_originalCaster->ModSpellDuration(aurSpellInfo, unit, duration, positive);
- //mod duration of channeled aura by spell haste
- if (IsChanneledSpell(m_spellInfo))
- m_originalCaster->ModSpellCastTime(aurSpellInfo, duration, this);
+ //mod duration of channeled aura by spell haste
+ if (IsChanneledSpell(m_spellInfo))
+ m_originalCaster->ModSpellCastTime(aurSpellInfo, duration, this);
- if(duration != Aur->GetAuraMaxDuration())
- {
- Aur->SetAuraMaxDuration(duration);
- Aur->SetAuraDuration(duration);
- }
+ if(duration != m_spellAura->GetMaxDuration())
+ {
+ m_spellAura->SetMaxDuration(duration);
+ m_spellAura->SetDuration(duration);
+ }
- // Prayer of Mending (jump animation), we need formal caster instead original for correct animation
- if( aurSpellInfo->SpellFamilyName == SPELLFAMILY_PRIEST)
- {
- if(aurSpellInfo->SpellFamilyFlags[1] & 0x000020)
- m_caster->CastSpell(unit, 41637, true, NULL, NULL, m_originalCasterGUID);
+ // Prayer of Mending (jump animation), we need formal caster instead original for correct animation
+ if(aurSpellInfo->SpellFamilyName == SPELLFAMILY_PRIEST)
+ {
+ if(aurSpellInfo->SpellFamilyFlags[1] & 0x000020)
+ m_caster->CastSpell(unit, 41637, true, NULL, NULL, m_originalCasterGUID);
+ }
}
}
- // Set aura only when successfully applied
- if (unit->AddAura(Aur, false))
- m_spellAura = Aur;
-
- }
}
for (uint32 effectNumber = 0; effectNumber < 3; ++effectNumber)
@@ -1451,10 +1444,9 @@ void Spell::DoTriggersOnSpellHit(Unit *unit)
if (!_duration)
{
Aura * aur = unit->GetAura(m_spellInfo->Id, m_caster->GetGUID());
- _duration = aur ? aur->GetAuraDuration() : -1;
+ _duration = aur ? aur->GetDuration() : -1;
}
- triggeredAur->SetAuraDuration(_duration);
- triggeredAur->SetPermanent(false);
+ triggeredAur->SetDuration(_duration);
}
}
}
@@ -1541,12 +1533,12 @@ bool Spell::UpdateChanneledTargetList()
{
if (needAuraMask & ihit->effectMask)
{
- if(Aura * aur = unit->GetAura(m_spellInfo->Id, m_originalCasterGUID))
+ if(AuraApplication * aurApp = unit->GetAuraApplication(m_spellInfo->Id, m_originalCasterGUID))
{
if (m_caster != unit && !m_caster->IsWithinDistInMap(unit,range))
{
- ihit->effectMask &= ~aur->GetEffectMask();
- unit->RemoveAura(aur);
+ ihit->effectMask &= ~aurApp->GetEffectMask();
+ unit->RemoveAura(aurApp);
continue;
}
}
@@ -1615,10 +1607,10 @@ void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, float max_range, uin
// Get spell max affected targets
/*uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets;
- Unit::AuraList const& mod = m_caster->GetAurasByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
+ Unit::AuraList const& mod = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
for (Unit::AuraList::const_iterator m = mod.begin(); m != mod.end(); ++m)
{
- if (!(*m)->isAffectedOnSpell(m_spellInfo))
+ if (!(*m)->IsAffectedOnSpell(m_spellInfo))
continue;
unMaxTargets+=(*m)->GetAmount();
}*/
@@ -2448,9 +2440,9 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
{
if(uint32 maxTargets = m_spellValue->MaxAffectedTargets)
{
- Unit::AuraEffectList const& Auras = m_caster->GetAurasByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
+ Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS);
for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
- if((*j)->isAffectedOnSpell(m_spellInfo))
+ if((*j)->IsAffectedOnSpell(m_spellInfo))
maxTargets += (*j)->GetAmount();
if(m_spellInfo->Id == 5246) //Intimidating Shout
@@ -2572,7 +2564,7 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur)
}
}
-void Spell::prepare(SpellCastTargets const* targets, AuraEffect* triggeredByAura)
+void Spell::prepare(SpellCastTargets const* targets, AuraEffect const * triggeredByAura)
{
if (m_CastItem)
m_castItemGUID = m_CastItem->GetGUID();
@@ -2677,7 +2669,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect* triggeredByAura
if(triggeredByAura)
{
SendChannelUpdate(0);
- triggeredByAura->GetParentAura()->SetAuraDuration(0);
+ triggeredByAura->GetBase()->SetDuration(0);
}
SendCastResult(result);
@@ -2761,11 +2753,10 @@ void Spell::cancel()
case SPELL_STATE_CASTING:
{
- for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
- if(ihit->missCondition == SPELL_MISS_NONE)
- if(Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
- if(unit->isAlive())
- unit->RemoveAurasDueToSpell(m_spellInfo->Id, m_originalCasterGUID, AURA_REMOVE_BY_CANCEL);
+ for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
+ if ((*ihit).missCondition == SPELL_MISS_NONE)
+ if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
+ unit->RemoveOwnedAura(m_spellInfo->Id, m_originalCasterGUID, 0, AURA_REMOVE_BY_CANCEL);
SendChannelUpdate(0);
SendInterrupted(0);
@@ -2912,18 +2903,18 @@ void Spell::cast(bool skipCheck)
// are there any spells need to be triggered after hit?
// handle SPELL_AURA_ADD_TARGET_TRIGGER auras
- Unit::AuraEffectList const& targetTriggers = m_caster->GetAurasByType(SPELL_AURA_ADD_TARGET_TRIGGER);
+ Unit::AuraEffectList const& targetTriggers = m_caster->GetAuraEffectsByType(SPELL_AURA_ADD_TARGET_TRIGGER);
for (Unit::AuraEffectList::const_iterator i = targetTriggers.begin(); i != targetTriggers.end(); ++i)
{
- if (!(*i)->isAffectedOnSpell(m_spellInfo))
+ if (!(*i)->IsAffectedOnSpell(m_spellInfo))
continue;
SpellEntry const *auraSpellInfo = (*i)->GetSpellProto();
uint32 auraSpellIdx = (*i)->GetEffIndex();
if(SpellEntry const *spellInfo = sSpellStore.LookupEntry(auraSpellInfo->EffectTriggerSpell[auraSpellIdx]))
{
// Calculate chance at that moment (can be depend for example from combo points)
- int32 chance = m_caster->CalculateSpellDamage(auraSpellInfo, auraSpellIdx, (*i)->GetBasePoints(), NULL);
- m_ChanceTriggerSpells.push_back(std::make_pair(spellInfo, chance * (*i)->GetParentAura()->GetStackAmount()));
+ int32 chance = m_caster->CalculateSpellDamage(auraSpellInfo, auraSpellIdx, (*i)->GetBaseAmount(), NULL);
+ m_ChanceTriggerSpells.push_back(std::make_pair(spellInfo, chance * (*i)->GetBase()->GetStackAmount()));
}
}
@@ -3091,6 +3082,7 @@ uint64 Spell::handle_delayed(uint64 t_offset)
void Spell::_handle_immediate_phase()
{
+ m_spellAura = NULL;
// handle some immediate features of the spell here
HandleThreatSpells(m_spellInfo->Id);
@@ -4204,52 +4196,8 @@ void Spell::TakeRunePower()
plr->SetRuneCooldown(i, RUNE_COOLDOWN); // 5*2=10 sec
plr->SetLastUsedRune(RuneType(rune));
runeCost[rune]--;
- bool auraFound = false;
- plr->ConvertRune(i, plr->GetBaseRune(i));
- // * * * * * * * * * * *
- // update convert rune auras
- // * * * * * * * * * * *
- // Remove rune from SPELL_AURA_CONVERT_RUNE when rune is used
- // To prevent overriding other rune convert effects
- Unit::AuraEffectList const& runeconvert = m_caster->GetAurasByType(SPELL_AURA_CONVERT_RUNE);
- for (Unit::AuraEffectList::const_iterator itr = runeconvert.begin(); itr != runeconvert.end(); ++itr)
- {
- // Remove rune of aura if avalible
- if ((*itr)->GetAmount() & (1<<i))
- {
- (*itr)->SetAmount((*itr)->GetAmount() & ~(1<<i));
- auraFound = true;
- }
- // All runes from aura used - remove aura
- if (!(*itr)->GetAmount())
- plr->RemoveAura((*itr)->GetParentAura(), AURA_REMOVE_BY_EXPIRE);
- break;
- }
- if (!auraFound)
- {
- // Decrease used rune count for dk talent auras
- // To prevent overriding other rune convert effects
- Unit::AuraEffectList const& runeconvert = m_caster->GetAurasByType(SPELL_AURA_CONVERT_RUNE);
- for (Unit::AuraEffectList::const_iterator itr = runeconvert.begin(); itr != runeconvert.end(); ++itr)
- {
- if (plr->GetBaseRune(i) != RUNE_DEATH)
- {
- // Death Rune Mastery
- if ((*itr)->GetSpellProto()->SpellIconID != 2622)
- continue;
- }
- // Blood of the North
- // Reaping
- else if ((*itr)->GetSpellProto()->SpellIconID != 3041 &&
- (*itr)->GetSpellProto()->SpellIconID != 22)
- continue;
- // Remove rune of aura if avalible
- if ((*itr)->GetAmount() & (1<<i))
- (*itr)->SetAmount((*itr)->GetAmount() & ~(1<<i));
- break;
- }
- }
+ plr->RestoreBaseRune(i);
if(runeCost[RUNE_DEATH] == 0)
break;
@@ -4401,10 +4349,10 @@ SpellCastResult Spell::CheckCast(bool strict)
{
bool checkForm = true;
// Ignore form req aura
- Unit::AuraEffectList const& ignore = m_caster->GetAurasByType(SPELL_AURA_MOD_IGNORE_SHAPESHIFT);
+ Unit::AuraEffectList const& ignore = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_SHAPESHIFT);
for (Unit::AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
{
- if (!(*i)->isAffectedOnSpell(m_spellInfo))
+ if (!(*i)->IsAffectedOnSpell(m_spellInfo))
continue;
checkForm = false;
break;
@@ -4422,10 +4370,10 @@ SpellCastResult Spell::CheckCast(bool strict)
}
bool reqCombat=true;
- Unit::AuraEffectList const& stateAuras = m_caster->GetAurasByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
+ Unit::AuraEffectList const& stateAuras = m_caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
for (Unit::AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
{
- if((*j)->isAffectedOnSpell(m_spellInfo))
+ if((*j)->IsAffectedOnSpell(m_spellInfo))
{
if ((*j)->GetMiscValue()==1)
{
@@ -5395,48 +5343,46 @@ SpellCastResult Spell::CheckCasterAuras() const
if(school_immune || mechanic_immune || dispel_immune)
{
//Checking auras is needed now, because you are prevented by some state but the spell grants immunity.
- Unit::AuraMap const& auras = m_caster->GetAuras();
- for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ Unit::AuraApplicationMap const& auras = m_caster->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
{
- if(itr->second)
- {
- if( GetAllSpellMechanicMask(itr->second->GetSpellProto()) & mechanic_immune )
- continue;
- if( GetSpellSchoolMask(itr->second->GetSpellProto()) & school_immune )
- continue;
- if( (1<<(itr->second->GetSpellProto()->Dispel)) & dispel_immune)
- continue;
+ Aura const * aura = itr->second->GetBase();
+ if( GetAllSpellMechanicMask(aura->GetSpellProto()) & mechanic_immune )
+ continue;
+ if( GetSpellSchoolMask(aura->GetSpellProto()) & school_immune )
+ continue;
+ if( (1<<(aura->GetSpellProto()->Dispel)) & dispel_immune)
+ continue;
- //Make a second check for spell failed so the right SPELL_FAILED message is returned.
- //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
- for (uint8 i=0; i<MAX_SPELL_EFFECTS; ++i)
+ //Make a second check for spell failed so the right SPELL_FAILED message is returned.
+ //That is needed when your casting is prevented by multiple states and you are only immune to some of them.
+ for (uint8 i=0; i<MAX_SPELL_EFFECTS; ++i)
+ {
+ if (AuraEffect * part = aura->GetEffect(i))
{
- if (AuraEffect * part = itr->second->GetPartAura(i))
+ switch(part->GetAuraType())
{
- switch(part->GetAuraName())
- {
- case SPELL_AURA_MOD_STUN:
- if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED))
- return SPELL_FAILED_STUNNED;
- break;
- case SPELL_AURA_MOD_CONFUSE:
- if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED))
- return SPELL_FAILED_CONFUSED;
- break;
- case SPELL_AURA_MOD_FEAR:
- if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED))
- return SPELL_FAILED_FLEEING;
- break;
- case SPELL_AURA_MOD_SILENCE:
- case SPELL_AURA_MOD_PACIFY:
- case SPELL_AURA_MOD_PACIFY_SILENCE:
- if( m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_PACIFY)
- return SPELL_FAILED_PACIFIED;
- else if ( m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_SILENCE)
- return SPELL_FAILED_SILENCED;
- break;
- default: break;
- }
+ case SPELL_AURA_MOD_STUN:
+ if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_STUNNED))
+ return SPELL_FAILED_STUNNED;
+ break;
+ case SPELL_AURA_MOD_CONFUSE:
+ if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_CONFUSED))
+ return SPELL_FAILED_CONFUSED;
+ break;
+ case SPELL_AURA_MOD_FEAR:
+ if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_USABLE_WHILE_FEARED))
+ return SPELL_FAILED_FLEEING;
+ break;
+ case SPELL_AURA_MOD_SILENCE:
+ case SPELL_AURA_MOD_PACIFY:
+ case SPELL_AURA_MOD_PACIFY_SILENCE:
+ if( m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_PACIFY)
+ return SPELL_FAILED_PACIFIED;
+ else if ( m_spellInfo->PreventionType==SPELL_PREVENTION_TYPE_SILENCE)
+ return SPELL_FAILED_SILENCED;
+ break;
+ default: break;
}
}
}
@@ -5465,7 +5411,7 @@ bool Spell::CanAutoCast(Unit* target)
else
{
if( AuraEffect * aureff = target->GetAuraEffect(m_spellInfo->Id, j))
- if (aureff->GetParentAura()->GetStackAmount() >= m_spellInfo->StackAmount)
+ if (aureff->GetBase()->GetStackAmount() >= m_spellInfo->StackAmount)
return false;
}
}
@@ -6134,8 +6080,8 @@ void Spell::DelayedChannel()
for (std::list<TargetInfo>::const_iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
if ((*ihit).missCondition == SPELL_MISS_NONE)
- if (Unit* unit = m_caster->GetGUID() == ihit->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
- unit->DelayAura(m_spellInfo->Id, m_caster->GetGUID(), delaytime);
+ if (Unit* unit = (m_caster->GetGUID() == ihit->targetGUID) ? m_caster : ObjectAccessor::GetUnit(*m_caster, ihit->targetGUID))
+ unit->DelayOwnedAuras(m_spellInfo->Id, m_originalCasterGUID, delaytime);
// partially interrupt persistent area auras
if(DynamicObject* dynObj = m_caster->GetDynObject(m_spellInfo->Id))
@@ -6509,10 +6455,10 @@ void Spell::CalculateDamageDoneForAllTargets()
}
bool usesAmmo = true;
- Unit::AuraEffectList const& Auras = m_caster->GetAurasByType(SPELL_AURA_ABILITY_CONSUME_NO_AMMO);
+ Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_CONSUME_NO_AMMO);
for (Unit::AuraEffectList::const_iterator j = Auras.begin(); j != Auras.end(); ++j)
{
- if((*j)->isAffectedOnSpell(m_spellInfo))
+ if((*j)->IsAffectedOnSpell(m_spellInfo))
usesAmmo=false;
}
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 96d220bd696..04f3984ed91 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -363,6 +363,7 @@ class Spell
void EffectPlayMusic(uint32 i);
void EffectSpecCount(uint32 i);
void EffectActivateSpec(uint32 i);
+ void EffectPlayerNotification(uint32 i);
void EffectCastButtons(uint32 i);
void EffectRechargeManaGem(uint32 i);
@@ -371,7 +372,7 @@ class Spell
Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, Spell** triggeringContainer = NULL, bool skipCheck = false );
~Spell();
- void prepare(SpellCastTargets const* targets, AuraEffect* triggeredByAura = NULL);
+ void prepare(SpellCastTargets const* targets, AuraEffect const * triggeredByAura = NULL);
void cancel();
void update(uint32 difftime);
void cast(bool skipCheck = false);
@@ -440,8 +441,7 @@ class Spell
void HandleEffects(Unit *pUnitTarget,Item *pItemTarget,GameObject *pGOTarget,uint32 i);
void HandleThreatSpells(uint32 spellId);
- //void HandleAddAura(Unit* Target);
-
+
const SpellEntry * const m_spellInfo;
int32 m_currentBasePoints[3]; // cache SpellEntry::EffectBasePoints and use for set custom base points
Item* m_CastItem;
@@ -492,7 +492,6 @@ class Spell
void CleanupTargetList();
void SetSpellValue(SpellValueMod mod, int32 value);
- //void SetSpellValue(SpellValueMod mod, float value);
protected:
void SendLoot(uint64 guid, LootType loottype);
@@ -545,8 +544,8 @@ class Spell
Item* itemTarget;
GameObject* gameObjTarget;
int32 damage;
- Aura * m_spellAura; // only used in DoAllEffectOnTarget
- DynamicObject *m_spellDynObj; // only used in DoAllEffectOnTarget
+ // used in effects handlers
+ Aura * m_spellAura;
// this is set in Spell Hit, but used in Apply Aura handler
DiminishingLevels m_diminishLevel;
@@ -566,8 +565,7 @@ class Spell
uint32 m_procAttacker; // Attacker trigger flags
uint32 m_procVictim; // Victim trigger flags
uint32 m_procEx;
- bool m_canTrigger;
- void prepareDataForTriggerSystem(AuraEffect * triggeredByAura);
+ void prepareDataForTriggerSystem(AuraEffect const * triggeredByAura);
//*****************************************
// Spell target subsystem
diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h
index e95c1bb9620..3a3942e9840 100644
--- a/src/game/SpellAuraDefines.h
+++ b/src/game/SpellAuraDefines.h
@@ -21,7 +21,6 @@
#define TRINITY_SPELLAURADEFINES_H
#define MAX_AURAS 64 // client support up to 255, but it will cause problems with group auras updating
-#define FRIENDLY_AA_REMOVE_TIME 2*IN_MILISECONDS
enum AURA_FLAGS
{
@@ -349,19 +348,15 @@ enum AuraType
SPELL_AURA_301 = 301,
SPELL_AURA_302 = 302,
SPELL_AURA_303 = 303,
- SPELL_AURA_MOD_INEBRIATION = 304,
+ SPELL_AURA_304 = 304,
SPELL_AURA_MOD_MINIMUM_SPEED = 305,
SPELL_AURA_306 = 306,
TOTAL_AURAS = 307
};
-enum AreaAuraType
+enum AuraObjectType
{
- AREA_AURA_PARTY,
- AREA_AURA_RAID,
- AREA_AURA_FRIEND,
- AREA_AURA_ENEMY,
- AREA_AURA_PET,
- AREA_AURA_OWNER
+ UNIT_AURA_TYPE,
+ DYNOBJ_AURA_TYPE,
};
#endif
diff --git a/src/game/SpellAuraEffects.cpp b/src/game/SpellAuraEffects.cpp
new file mode 100644
index 00000000000..e9aa7b194ac
--- /dev/null
+++ b/src/game/SpellAuraEffects.cpp
@@ -0,0 +1,6064 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2009 Trinity <http://www.trinitycore.org/>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#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 "ObjectAccessor.h"
+#include "Util.h"
+#include "Spell.h"
+#include "SpellAuraEffects.h"
+#include "SpellId.h"
+#include "BattleGround.h"
+#include "OutdoorPvPMgr.h"
+#include "Formulas.h"
+#include "ScriptCalls.h"
+#include "GridNotifiers.h"
+#include "GridNotifiersImpl.h"
+#include "CellImpl.h"
+
+class Aura;
+//
+// EFFECT HANDLER NOTES
+//
+// in aura handler there should be check for modes:
+// AURA_EFFECT_HANDLE_REAL set - aura mod is just applied/removed on the target
+// AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK set - aura is just applied/removed, or aura packet request is made
+// AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK set - aura is recalculated or is just applied/removed - need to redo all things related to m_amount
+// AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK - logical or of above conditions
+// AURA_EFFECT_HANDLE_STAT - set when stats are reapplied
+// such checks will speedup trinity change amount/send for client operations
+// because for change amount operation packets will not be send
+// aura effect handlers shouldn't contain any AuraEffect or Aura object modifications
+
+pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]=
+{
+ &AuraEffect::HandleNULL, // 0 SPELL_AURA_NONE
+ &AuraEffect::HandleBindSight, // 1 SPELL_AURA_BIND_SIGHT
+ &AuraEffect::HandleModPossess, // 2 SPELL_AURA_MOD_POSSESS
+ &AuraEffect::HandleNoImmediateEffect, // 3 SPELL_AURA_PERIODIC_DAMAGE implemented in AuraEffect::PeriodicTick
+ &AuraEffect::HandleAuraDummy, // 4 SPELL_AURA_DUMMY
+ &AuraEffect::HandleModConfuse, // 5 SPELL_AURA_MOD_CONFUSE
+ &AuraEffect::HandleModCharm, // 6 SPELL_AURA_MOD_CHARM
+ &AuraEffect::HandleModFear, // 7 SPELL_AURA_MOD_FEAR
+ &AuraEffect::HandleNoImmediateEffect, // 8 SPELL_AURA_PERIODIC_HEAL implemented in AuraEffect::PeriodicTick
+ &AuraEffect::HandleModAttackSpeed, // 9 SPELL_AURA_MOD_ATTACKSPEED
+ &AuraEffect::HandleModThreat, // 10 SPELL_AURA_MOD_THREAT
+ &AuraEffect::HandleModTaunt, // 11 SPELL_AURA_MOD_TAUNT
+ &AuraEffect::HandleAuraModStun, // 12 SPELL_AURA_MOD_STUN
+ &AuraEffect::HandleModDamageDone, // 13 SPELL_AURA_MOD_DAMAGE_DONE
+ &AuraEffect::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, // 15 SPELL_AURA_DAMAGE_SHIELD implemented in Unit::DoAttackDamage
+ &AuraEffect::HandleModStealth, // 16 SPELL_AURA_MOD_STEALTH
+ &AuraEffect::HandleNoImmediateEffect, // 17 SPELL_AURA_MOD_DETECT implement in GameObject::canDetectTrap and Unit::canDetectStealthOf
+ &AuraEffect::HandleInvisibility, // 18 SPELL_AURA_MOD_INVISIBILITY
+ &AuraEffect::HandleInvisibilityDetect, // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
+ &AuraEffect::HandleNoImmediateEffect, // 20 SPELL_AURA_OBS_MOD_HEALTH implemented in AuraEffect::PeriodicTick
+ &AuraEffect::HandleNoImmediateEffect, // 21 SPELL_AURA_OBS_MOD_POWER implemented in AuraEffect::PeriodicTick
+ &AuraEffect::HandleAuraModResistance, // 22 SPELL_AURA_MOD_RESISTANCE
+ &AuraEffect::HandleNoImmediateEffect, // 23 SPELL_AURA_PERIODIC_TRIGGER_SPELL implemented in AuraEffect::PeriodicTick
+ &AuraEffect::HandleNoImmediateEffect, // 24 SPELL_AURA_PERIODIC_ENERGIZE implemented in AuraEffect::PeriodicTick
+ &AuraEffect::HandleAuraModPacify, // 25 SPELL_AURA_MOD_PACIFY
+ &AuraEffect::HandleAuraModRoot, // 26 SPELL_AURA_MOD_ROOT
+ &AuraEffect::HandleAuraModSilence, // 27 SPELL_AURA_MOD_SILENCE
+ &AuraEffect::HandleNoImmediateEffect, // 28 SPELL_AURA_REFLECT_SPELLS implement in Unit::SpellHitResult
+ &AuraEffect::HandleAuraModStat, // 29 SPELL_AURA_MOD_STAT
+ &AuraEffect::HandleAuraModSkill, // 30 SPELL_AURA_MOD_SKILL
+ &AuraEffect::HandleAuraModIncreaseSpeed, // 31 SPELL_AURA_MOD_INCREASE_SPEED
+ &AuraEffect::HandleAuraModIncreaseMountedSpeed, // 32 SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED
+ &AuraEffect::HandleAuraModDecreaseSpeed, // 33 SPELL_AURA_MOD_DECREASE_SPEED
+ &AuraEffect::HandleAuraModIncreaseHealth, // 34 SPELL_AURA_MOD_INCREASE_HEALTH
+ &AuraEffect::HandleAuraModIncreaseEnergy, // 35 SPELL_AURA_MOD_INCREASE_ENERGY
+ &AuraEffect::HandleAuraModShapeshift, // 36 SPELL_AURA_MOD_SHAPESHIFT
+ &AuraEffect::HandleAuraModEffectImmunity, // 37 SPELL_AURA_EFFECT_IMMUNITY
+ &AuraEffect::HandleAuraModStateImmunity, // 38 SPELL_AURA_STATE_IMMUNITY
+ &AuraEffect::HandleAuraModSchoolImmunity, // 39 SPELL_AURA_SCHOOL_IMMUNITY
+ &AuraEffect::HandleAuraModDmgImmunity, // 40 SPELL_AURA_DAMAGE_IMMUNITY
+ &AuraEffect::HandleAuraModDispelImmunity, // 41 SPELL_AURA_DISPEL_IMMUNITY
+ &AuraEffect::HandleNoImmediateEffect, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Unit::ProcDamageAndSpellFor and Unit::HandleProcTriggerSpell
+ &AuraEffect::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor
+ &AuraEffect::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES
+ &AuraEffect::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES
+ &AuraEffect::HandleNULL, // 46 SPELL_AURA_46 (used in test spells 54054 and 54058, and spell 48050) (3.0.8a)
+ &AuraEffect::HandleAuraModParryPercent, // 47 SPELL_AURA_MOD_PARRY_PERCENT
+ &AuraEffect::HandleNULL, // 48 SPELL_AURA_48 spell Napalm (area damage spell with additional delayed damage effect)
+ &AuraEffect::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT
+ &AuraEffect::HandleNoImmediateEffect, // 50 SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT implemented in Unit::SpellCriticalHealingBonus
+ &AuraEffect::HandleAuraModBlockPercent, // 51 SPELL_AURA_MOD_BLOCK_PERCENT
+ &AuraEffect::HandleAuraModWeaponCritPercent, // 52 SPELL_AURA_MOD_WEAPON_CRIT_PERCENT
+ &AuraEffect::HandleNoImmediateEffect, // 53 SPELL_AURA_PERIODIC_LEECH implemented in AuraEffect::PeriodicTick
+ &AuraEffect::HandleModHitChance, // 54 SPELL_AURA_MOD_HIT_CHANCE
+ &AuraEffect::HandleModSpellHitChance, // 55 SPELL_AURA_MOD_SPELL_HIT_CHANCE
+ &AuraEffect::HandleAuraTransform, // 56 SPELL_AURA_TRANSFORM
+ &AuraEffect::HandleModSpellCritChance, // 57 SPELL_AURA_MOD_SPELL_CRIT_CHANCE
+ &AuraEffect::HandleAuraModIncreaseSwimSpeed, // 58 SPELL_AURA_MOD_INCREASE_SWIM_SPEED
+ &AuraEffect::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
+ &AuraEffect::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE
+ &AuraEffect::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE
+ &AuraEffect::HandleNoImmediateEffect, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL implemented in AuraEffect::PeriodicTick
+ &AuraEffect::HandleNULL, // 63 unused (3.2.0) old SPELL_AURA_PERIODIC_MANA_FUNNEL
+ &AuraEffect::HandleNoImmediateEffect, // 64 SPELL_AURA_PERIODIC_MANA_LEECH implemented in AuraEffect::PeriodicTick
+ &AuraEffect::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK
+ &AuraEffect::HandleFeignDeath, // 66 SPELL_AURA_FEIGN_DEATH
+ &AuraEffect::HandleAuraModDisarm, // 67 SPELL_AURA_MOD_DISARM
+ &AuraEffect::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED
+ &AuraEffect::HandleNoImmediateEffect, // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist
+ &AuraEffect::HandleUnused, // 70 SPELL_AURA_EXTRA_ATTACKS clientside
+ &AuraEffect::HandleModSpellCritChanceShool, // 71 SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
+ &AuraEffect::HandleModPowerCostPCT, // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
+ &AuraEffect::HandleModPowerCost, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
+ &AuraEffect::HandleNoImmediateEffect, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL implemented in Unit::SpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, // 75 SPELL_AURA_MOD_LANGUAGE
+ &AuraEffect::HandleNoImmediateEffect, // 76 SPELL_AURA_FAR_SIGHT
+ &AuraEffect::HandleModMechanicImmunity, // 77 SPELL_AURA_MECHANIC_IMMUNITY
+ &AuraEffect::HandleAuraMounted, // 78 SPELL_AURA_MOUNTED
+ &AuraEffect::HandleModDamagePercentDone, // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
+ &AuraEffect::HandleModPercentStat, // 80 SPELL_AURA_MOD_PERCENT_STAT
+ &AuraEffect::HandleNoImmediateEffect, // 81 SPELL_AURA_SPLIT_DAMAGE_PCT implemented in Unit::CalcAbsorbResist
+ &AuraEffect::HandleWaterBreathing, // 82 SPELL_AURA_WATER_BREATHING
+ &AuraEffect::HandleModBaseResistance, // 83 SPELL_AURA_MOD_BASE_RESISTANCE
+ &AuraEffect::HandleNoImmediateEffect, // 84 SPELL_AURA_MOD_REGEN implemented in Player::RegenerateHealth
+ &AuraEffect::HandleModPowerRegen, // 85 SPELL_AURA_MOD_POWER_REGEN implemented in Player::Regenerate
+ &AuraEffect::HandleChannelDeathItem, // 86 SPELL_AURA_CHANNEL_DEATH_ITEM
+ &AuraEffect::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT implemented in Player::RegenerateHealth
+ &AuraEffect::HandleNoImmediateEffect, // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT
+ &AuraEffect::HandleNULL, // 90 unused (3.0.8a) old SPELL_AURA_MOD_RESIST_CHANCE
+ &AuraEffect::HandleNoImmediateEffect, // 91 SPELL_AURA_MOD_DETECT_RANGE implemented in Creature::GetAttackDistance
+ &AuraEffect::HandlePreventFleeing, // 92 SPELL_AURA_PREVENTS_FLEEING
+ &AuraEffect::HandleModUnattackable, // 93 SPELL_AURA_MOD_UNATTACKABLE
+ &AuraEffect::HandleNoImmediateEffect, // 94 SPELL_AURA_INTERRUPT_REGEN implemented in Player::Regenerate
+ &AuraEffect::HandleAuraGhost, // 95 SPELL_AURA_GHOST
+ &AuraEffect::HandleNoImmediateEffect, // 96 SPELL_AURA_SPELL_MAGNET implemented in Unit::SelectMagnetTarget
+ &AuraEffect::HandleNoImmediateEffect, // 97 SPELL_AURA_MANA_SHIELD implemented in Unit::CalcAbsorbResist
+ &AuraEffect::HandleAuraModSkill, // 98 SPELL_AURA_MOD_SKILL_TALENT
+ &AuraEffect::HandleAuraModAttackPower, // 99 SPELL_AURA_MOD_ATTACK_POWER
+ &AuraEffect::HandleUnused, //100 SPELL_AURA_AURAS_VISIBLE obsolete? all player can see all auras now, but still have spells including GM-spell
+ &AuraEffect::HandleModResistancePercent, //101 SPELL_AURA_MOD_RESISTANCE_PCT
+ &AuraEffect::HandleNoImmediateEffect, //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleAuraModTotalThreat, //103 SPELL_AURA_MOD_TOTAL_THREAT
+ &AuraEffect::HandleAuraWaterWalk, //104 SPELL_AURA_WATER_WALK
+ &AuraEffect::HandleAuraFeatherFall, //105 SPELL_AURA_FEATHER_FALL
+ &AuraEffect::HandleAuraHover, //106 SPELL_AURA_HOVER
+ &AuraEffect::HandleNoImmediateEffect, //107 SPELL_AURA_ADD_FLAT_MODIFIER implemented in AuraEffect::CalculateSpellMod()
+ &AuraEffect::HandleNoImmediateEffect, //108 SPELL_AURA_ADD_PCT_MODIFIER implemented in AuraEffect::CalculateSpellMod()
+ &AuraEffect::HandleNoImmediateEffect, //109 SPELL_AURA_ADD_TARGET_TRIGGER
+ &AuraEffect::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT implemented in Player::Regenerate, Creature::Regenerate
+ &AuraEffect::HandleNoImmediateEffect, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER implemented in Unit::SelectMagnetTarget
+ &AuraEffect::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
+ &AuraEffect::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, //115 SPELL_AURA_MOD_HEALING implemented in Unit::SpellBaseHealingBonusForVictim
+ &AuraEffect::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT
+ &AuraEffect::HandleNoImmediateEffect, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, //118 SPELL_AURA_MOD_HEALING_PCT implemented in Unit::SpellHealingBonus
+ &AuraEffect::HandleNULL, //119 unused (3.2.0) old SPELL_AURA_SHARE_PET_TRACKING
+ &AuraEffect::HandleAuraUntrackable, //120 SPELL_AURA_UNTRACKABLE
+ &AuraEffect::HandleAuraEmpathy, //121 SPELL_AURA_EMPATHY
+ &AuraEffect::HandleModOffhandDamagePercent, //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT
+ &AuraEffect::HandleModTargetResistance, //123 SPELL_AURA_MOD_TARGET_RESISTANCE
+ &AuraEffect::HandleAuraModRangedAttackPower, //124 SPELL_AURA_MOD_RANGED_ATTACK_POWER
+ &AuraEffect::HandleNoImmediateEffect, //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleModPossessPet, //128 SPELL_AURA_MOD_POSSESS_PET
+ &AuraEffect::HandleAuraModIncreaseSpeed, //129 SPELL_AURA_MOD_SPEED_ALWAYS
+ &AuraEffect::HandleAuraModIncreaseMountedSpeed, //130 SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS
+ &AuraEffect::HandleNoImmediateEffect, //131 SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleAuraModIncreaseEnergyPercent, //132 SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT
+ &AuraEffect::HandleAuraModIncreaseHealthPercent, //133 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT
+ &AuraEffect::HandleAuraModRegenInterrupt, //134 SPELL_AURA_MOD_MANA_REGEN_INTERRUPT
+ &AuraEffect::HandleModHealingDone, //135 SPELL_AURA_MOD_HEALING_DONE
+ &AuraEffect::HandleNoImmediateEffect, //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT implemented in Unit::SpellHealingBonus
+ &AuraEffect::HandleModTotalPercentStat, //137 SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE
+ &AuraEffect::HandleHaste, //138 SPELL_AURA_MOD_HASTE
+ &AuraEffect::HandleForceReaction, //139 SPELL_AURA_FORCE_REACTION
+ &AuraEffect::HandleAuraModRangedHaste, //140 SPELL_AURA_MOD_RANGED_HASTE
+ &AuraEffect::HandleRangedAmmoHaste, //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE
+ &AuraEffect::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT
+ &AuraEffect::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE
+ &AuraEffect::HandleNoImmediateEffect, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
+ &AuraEffect::HandleAuraModPetTalentsPoints, //145 SPELL_AURA_MOD_PET_TALENT_POINTS
+ &AuraEffect::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE
+ &AuraEffect::HandleModStateImmunityMask, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK
+ &AuraEffect::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
+ &AuraEffect::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK
+ &AuraEffect::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
+ &AuraEffect::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
+ &AuraEffect::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
+ &AuraEffect::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
+ &AuraEffect::HandleNoImmediateEffect, //154 SPELL_AURA_MOD_STEALTH_LEVEL
+ &AuraEffect::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING
+ &AuraEffect::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN
+ &AuraEffect::HandleNULL, //157 SPELL_AURA_PET_DAMAGE_MULTI
+ &AuraEffect::HandleShieldBlockValue, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE
+ &AuraEffect::HandleNoImmediateEffect, //159 SPELL_AURA_NO_PVP_CREDIT only for Honorless Target spell
+ &AuraEffect::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
+ &AuraEffect::HandleNoImmediateEffect, //162 SPELL_AURA_POWER_BURN_MANA implemented in AuraEffect::PeriodicTick
+ &AuraEffect::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE
+ &AuraEffect::HandleUnused, //164 unused (3.2.0), only one test spell
+ &AuraEffect::HandleNoImmediateEffect, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
+ &AuraEffect::HandleAuraModAttackPowerPercent, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT
+ &AuraEffect::HandleAuraModRangedAttackPowerPercent, //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT
+ &AuraEffect::HandleNoImmediateEffect, //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus
+ &AuraEffect::HandleNoImmediateEffect, //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS implemented in Unit::DealDamageBySchool, Unit::DoAttackDamage, Unit::SpellCriticalBonus
+ &AuraEffect::HandleNULL, //170 SPELL_AURA_DETECT_AMORE various spells that change visual of units for aura target (clientside?)
+ &AuraEffect::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK
+ &AuraEffect::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
+ &AuraEffect::HandleNULL, //173 unused (3.2.0) no spells, old SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
+ &AuraEffect::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus
+ &AuraEffect::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus
+ &AuraEffect::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end
+ &AuraEffect::HandleCharmConvert, //177 SPELL_AURA_AOE_CHARM
+ &AuraEffect::HandleNoImmediateEffect, //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus
+ &AuraEffect::HandleNoImmediateEffect, //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS implemented in Unit::SpellDamageBonus
+ &AuraEffect::HandleNULL, //181 unused (3.2.0) old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS
+ &AuraEffect::HandleAuraModResistenceOfStatPercent, //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT
+ &AuraEffect::HandleNULL, //183 SPELL_AURA_MOD_CRITICAL_THREAT only used in 28746 - miscvalue - spell school
+ &AuraEffect::HandleNoImmediateEffect, //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
+ &AuraEffect::HandleNoImmediateEffect, //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
+ &AuraEffect::HandleNoImmediateEffect, //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
+ &AuraEffect::HandleNoImmediateEffect, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
+ &AuraEffect::HandleModRating, //189 SPELL_AURA_MOD_RATING
+ &AuraEffect::HandleNoImmediateEffect, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN implemented in Player::CalculateReputationGain
+ &AuraEffect::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
+ &AuraEffect::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE
+ &AuraEffect::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
+ &AuraEffect::HandleNoImmediateEffect, //194 SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
+ &AuraEffect::HandleNoImmediateEffect, //195 SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
+ &AuraEffect::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN - flat mod of spell cooldowns
+ &AuraEffect::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
+ &AuraEffect::HandleNULL, //198 unused (3.2.0) old SPELL_AURA_MOD_ALL_WEAPON_SKILLS
+ &AuraEffect::HandleNoImmediateEffect, //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT implemented in Unit::MagicSpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_XP_PCT implemented in Player::RewardPlayerAndGroupAtKill
+ &AuraEffect::HandleAuraAllowFlight, //201 SPELL_AURA_FLY this aura enable flight mode...
+ &AuraEffect::HandleNoImmediateEffect, //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst
+ &AuraEffect::HandleNoImmediateEffect, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
+ &AuraEffect::HandleNoImmediateEffect, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
+ &AuraEffect::HandleNULL, //205 SPELL_AURA_MOD_SCHOOL_CRIT_DMG_TAKEN
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //206 SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //207 SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //208 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //209 SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //210 SPELL_AURA_MOD_VEHICLE_SPEED_ALWAYS
+ &AuraEffect::HandleAuraModIncreaseFlightSpeed, //211 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK
+ &AuraEffect::HandleAuraModRangedAttackPowerOfStatPercent, //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT
+ &AuraEffect::HandleNoImmediateEffect, //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage
+ &AuraEffect::HandleNULL, //214 Tamed Pet Passive
+ &AuraEffect::HandleArenaPreparation, //215 SPELL_AURA_ARENA_PREPARATION
+ &AuraEffect::HandleModCastingSpeed, //216 SPELL_AURA_HASTE_SPELLS
+ &AuraEffect::HandleUnused, //217 unused (3.2.0)
+ &AuraEffect::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED
+ &AuraEffect::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT
+ &AuraEffect::HandleModRatingFromStat, //220 SPELL_AURA_MOD_RATING_FROM_STAT
+ &AuraEffect::HandleNULL, //221 SPELL_AURA_MOD_DETAUNT
+ &AuraEffect::HandleUnused, //222 unused (3.2.0) only for spell 44586 that not used in real spell cast
+ &AuraEffect::HandleNoImmediateEffect, //223 SPELL_AURA_RAID_PROC_FROM_CHARGE
+ &AuraEffect::HandleUnused, //224 unused (3.0.8a)
+ &AuraEffect::HandleNoImmediateEffect, //225 SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE
+ &AuraEffect::HandleNoImmediateEffect, //226 SPELL_AURA_PERIODIC_DUMMY implemented in AuraEffect::PeriodicTick
+ &AuraEffect::HandleNoImmediateEffect, //227 SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE implemented in AuraEffect::PeriodicTick
+ &AuraEffect::HandleNoImmediateEffect, //228 SPELL_AURA_DETECT_STEALTH stealth detection
+ &AuraEffect::HandleNoImmediateEffect, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE
+ &AuraEffect::HandleAuraModIncreaseHealth, //230 SPELL_AURA_MOD_INCREASE_HEALTH_2
+ &AuraEffect::HandleNoImmediateEffect, //231 SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
+ &AuraEffect::HandleNoImmediateEffect, //232 SPELL_AURA_MECHANIC_DURATION_MOD implement in Unit::CalculateSpellDuration
+ &AuraEffect::HandleUnused, //233 set model id to the one of the creature with id GetMiscValue() - clientside
+ &AuraEffect::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration
+ &AuraEffect::HandleNoImmediateEffect, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult
+ &AuraEffect::HandleAuraControlVehicle, //236 SPELL_AURA_CONTROL_VEHICLE
+ &AuraEffect::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus
+ &AuraEffect::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus
+ &AuraEffect::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61
+ &AuraEffect::HandleAuraModExpertise, //240 SPELL_AURA_MOD_EXPERTISE
+ &AuraEffect::HandleForceMoveForward, //241 SPELL_AURA_FORCE_MOVE_FORWARD Forces the player to move forward
+ &AuraEffect::HandleNULL, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING - 2 test spells: 44183 and 44182
+ &AuraEffect::HandleNULL, //243 faction reaction override spells
+ &AuraEffect::HandleComprehendLanguage, //244 SPELL_AURA_COMPREHEND_LANGUAGE
+ &AuraEffect::HandleNoImmediateEffect, //245 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL
+ &AuraEffect::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK implemented in Spell::EffectApplyAura
+ &AuraEffect::HandleAuraCloneCaster, //247 SPELL_AURA_CLONE_CASTER
+ &AuraEffect::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
+ &AuraEffect::HandleAuraConvertRune, //249 SPELL_AURA_CONVERT_RUNE
+ &AuraEffect::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2
+ &AuraEffect::HandleNoImmediateEffect, //251 SPELL_AURA_MOD_ENEMY_DODGE
+ &AuraEffect::HandleModCombatSpeedPct, //252 SPELL_AURA_252 Is there any difference between this and SPELL_AURA_MELEE_SLOW ? maybe not stacking mod?
+ &AuraEffect::HandleNoImmediateEffect, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE implemented in Unit::isBlockCritical
+ &AuraEffect::HandleAuraModDisarm, //254 SPELL_AURA_MOD_DISARM_OFFHAND
+ &AuraEffect::HandleNoImmediateEffect, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT implemented in Unit::SpellDamageBonus
+ &AuraEffect::HandleNoReagentUseAura, //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select
+ &AuraEffect::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select
+ &AuraEffect::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL
+ &AuraEffect::HandleNoImmediateEffect, //259 SPELL_AURA_MOD_HOT_PCT implemented in Unit::SpellHealingBonus
+ &AuraEffect::HandleNoImmediateEffect, //260 SPELL_AURA_SCREEN_EFFECT (miscvalue = id in ScreenEffect.dbc) not required any code
+ &AuraEffect::HandlePhase, //261 SPELL_AURA_PHASE undetactable invisibility? implemented in Unit::isVisibleForOrDetect
+ &AuraEffect::HandleNoImmediateEffect, //262 SPELL_AURA_ABILITY_IGNORE_AURASTATE implemented in spell::cancast
+ &AuraEffect::HandleAuraAllowOnlyAbility, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilities set in SpellClassMask
+ &AuraEffect::HandleUnused, //264 unused (3.2.0)
+ &AuraEffect::HandleUnused, //265 unused (3.2.0)
+ &AuraEffect::HandleUnused, //266 unused (3.2.0)
+ &AuraEffect::HandleNoImmediateEffect, //267 SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL implemented in Unit::IsImmunedToSpellEffect
+ &AuraEffect::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT
+ &AuraEffect::HandleNoImmediateEffect, //269 SPELL_AURA_MOD_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
+ &AuraEffect::HandleNoImmediateEffect, //270 SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
+ &AuraEffect::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus
+ &AuraEffect::HandleUnused, //272 unknown use for this aura
+ &AuraEffect::HandleUnused, //273 clientside
+ &AuraEffect::HandleNoImmediateEffect, //274 SPELL_AURA_CONSUME_NO_AMMO implemented in spell::CalculateDamageDoneForAllTargets
+ &AuraEffect::HandleNoImmediateEffect, //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select
+ &AuraEffect::HandleNULL, //276 mod damage % mechanic?
+ &AuraEffect::HandleNoImmediateEffect, //277 SPELL_AURA_MOD_ABILITY_AFFECTED_TARGETS implemented in spell::settargetmap
+ &AuraEffect::HandleAuraModDisarm, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon
+ &AuraEffect::HandleNoImmediateEffect, //279 SPELL_AURA_INITIALIZE_IMAGES
+ &AuraEffect::HandleNoImmediateEffect, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT
+ &AuraEffect::HandleNoImmediateEffect, //281 SPELL_AURA_MOD_HONOR_GAIN_PCT implemented in Player::RewardHonor
+ &AuraEffect::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT
+ &AuraEffect::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus
+ &AuraEffect::HandleAuraLinked, //284 SPELL_AURA_LINKED
+ &AuraEffect::HandleAuraModAttackPowerOfArmor, //285 SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR implemented in Player::UpdateAttackPowerAndDamage
+ &AuraEffect::HandleNoImmediateEffect, //286 SPELL_AURA_ABILITY_PERIODIC_CRIT implemented in AuraEffect::PeriodicTick
+ &AuraEffect::HandleNoImmediateEffect, //287 SPELL_AURA_DEFLECT_SPELLS implemented in Unit::MagicSpellHitResult and Unit::MeleeSpellHitResult
+ &AuraEffect::HandleNoImmediateEffect, //288 SPELL_AURA_IGNORE_HIT_DIRECTION implemented in Unit::MagicSpellHitResult and Unit::MeleeSpellHitResult Unit::RollMeleeOutcomeAgainst
+ &AuraEffect::HandleNULL, //289 unused (3.2.0)
+ &AuraEffect::HandleAuraModCritPct, //290 SPELL_AURA_MOD_CRIT_PCT
+ &AuraEffect::HandleNoImmediateEffect, //291 SPELL_AURA_MOD_XP_QUEST_PCT implemented in Player::RewardQuest
+ &AuraEffect::HandleNULL, //292 call stabled pet
+ &AuraEffect::HandleNULL, //293 2 test spells
+ &AuraEffect::HandleNoImmediateEffect, //294 SPELL_AURA_PREVENT_REGENERATE_POWER implemented in Player::Regenerate(Powers power)
+ &AuraEffect::HandleNULL, //296 2 spells
+ &AuraEffect::HandleNULL, //297 1 spell (counter spell school?)
+ &AuraEffect::HandleNULL, //298 unused
+ &AuraEffect::HandleNULL, //299 unused
+ &AuraEffect::HandleNULL, //300 3 spells (share damage?)
+ &AuraEffect::HandleNULL, //301 5 spells
+ &AuraEffect::HandleNULL, //302 unused
+ &AuraEffect::HandleNULL, //303 17 spells
+ &AuraEffect::HandleNULL, //304 2 spells (alcohol effect?)
+ &AuraEffect::HandleAuraModIncreaseSpeed, //305 SPELL_AURA_MOD_MINIMUM_SPEED
+ &AuraEffect::HandleNULL //306 1 spell
+};
+
+AuraEffect::AuraEffect(Aura * base, uint8 effIndex, int32 *baseAmount, Unit * caster) :
+ m_base(base), m_spellProto(base->GetSpellProto()), m_spellmod(NULL), m_periodicTimer(0),
+ m_tickNumber(0), m_effIndex(effIndex), m_isPeriodic(false), m_canBeRecalculated(true),
+ m_baseAmount (baseAmount ? *baseAmount : m_spellProto->EffectBasePoints[m_effIndex])
+{
+ CalculatePeriodic(caster, true);
+
+ m_amount = CalculateAmount(caster);
+
+ CalculateSpellMod();
+}
+
+AuraEffect::~AuraEffect()
+{
+ if (m_spellmod)
+ delete m_spellmod;
+}
+
+void AuraEffect::GetTargetList(std::list<Unit *> & targetList) const
+{
+ Aura::ApplicationMap const & targetMap = GetBase()->GetApplicationMap();
+ // remove all targets which were not added to new list - they no longer deserve area aura
+ for (Aura::ApplicationMap::const_iterator appIter = targetMap.begin(); appIter != targetMap.end(); appIter++)
+ {
+ if(appIter->second->HasEffect(GetEffIndex()))
+ targetList.push_back(appIter->second->GetTarget());
+ }
+}
+
+int32 AuraEffect::CalculateAmount(Unit * caster)
+{
+ int32 amount;
+ // default amount calculation
+ if(caster)
+ amount = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_baseAmount, NULL);
+ else
+ amount = m_baseAmount + m_spellProto->EffectBaseDice[m_effIndex];
+
+ // check item enchant aura cast
+ if(!amount && caster)
+ if(uint64 itemGUID = GetBase()->GetCastItemGUID())
+ if(Player *playerCaster = dynamic_cast<Player*>(caster))
+ if(Item *castItem = playerCaster->GetItemByGuid(itemGUID))
+ if (castItem->GetItemSuffixFactor())
+ {
+ ItemRandomSuffixEntry const *item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(castItem->GetItemRandomPropertyId()));
+ if(item_rand_suffix)
+ {
+ for (int k=0; k<MAX_SPELL_EFFECTS; k++)
+ {
+ SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(item_rand_suffix->enchant_id[k]);
+ if(pEnchant)
+ {
+ for (int t=0; t<MAX_SPELL_EFFECTS; t++)
+ if(pEnchant->spellid[t] == m_spellProto->Id)
+ {
+ amount = uint32((item_rand_suffix->prefix[k]*castItem->GetItemSuffixFactor()) / 10000 );
+ break;
+ }
+ }
+
+ if(amount)
+ break;
+ }
+ }
+ }
+
+ float DoneActualBenefit = 0.0f;
+
+ // custom amount calculations go here
+ switch(GetAuraType())
+ {
+ // crowd control auras
+ case SPELL_AURA_MOD_CONFUSE:
+ case SPELL_AURA_MOD_FEAR:
+ case SPELL_AURA_MOD_STUN:
+ case SPELL_AURA_MOD_ROOT:
+ case SPELL_AURA_TRANSFORM:
+ m_canBeRecalculated = false;
+ if (!m_spellProto->procFlags)
+ break;
+ amount = GetBase()->GetUnitOwner()->GetMaxHealth()*0.10f;
+ if (caster)
+ {
+ // Glyphs increasing damage cap
+ Unit::AuraEffectList const& overrideClassScripts = caster->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ for (Unit::AuraEffectList::const_iterator itr = overrideClassScripts.begin(); itr != overrideClassScripts.end(); ++itr)
+ {
+ if((*itr)->IsAffectedOnSpell(m_spellProto))
+ {
+ // Glyph of Fear, Glyph of Frost nova and similar auras
+ if ((*itr)->GetMiscValue() == 7801)
+ {
+ amount += (int32)(amount*(*itr)->GetAmount()/100.0f);
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case SPELL_AURA_SCHOOL_ABSORB:
+ m_canBeRecalculated = false;
+ if (!caster)
+ break;
+ switch(GetSpellProto()->SpellFamilyName)
+ {
+ case SPELLFAMILY_MAGE:
+ // Ice Barrier
+ if(GetSpellProto()->SpellFamilyFlags[1] & 0x1 && GetSpellProto()->SpellFamilyFlags[2] & 0x8)
+ {
+ // +80.67% from sp bonus
+ DoneActualBenefit += caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.8067f;
+ }
+ break;
+ case SPELLFAMILY_WARLOCK:
+ // Shadow Ward
+ if(m_spellProto->SpellFamilyFlags[2]& 0x40)
+ {
+ // +30% from sp bonus
+ DoneActualBenefit += caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.3f;
+ }
+ break;
+ case SPELLFAMILY_PRIEST:
+ // Power Word: Shield
+ if(GetSpellProto()->SpellFamilyFlags[0] & 0x1 && GetSpellProto()->SpellFamilyFlags[2] & 0x400)
+ {
+ //+80.68% from sp bonus
+ float bonus = 0.8068f;
+ // Borrowed Time
+ if (AuraEffect const * aurEff = caster->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_PRIEST, 2899, 1))
+ bonus += aurEff->GetAmount() / 100;
+
+ DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(GetSpellProto())) * bonus;
+ }
+ break;
+ case SPELLFAMILY_PALADIN:
+ // Sacred Shield
+ if (m_spellProto->SpellFamilyFlags[1] & 0x80000)
+ {
+ // 0.75 from sp bonus
+ DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * 0.75f;
+ }
+ break;
+ }
+ break;
+ case SPELL_AURA_MANA_SHIELD:
+ m_canBeRecalculated = false;
+ if (!caster)
+ break;
+ // Mana Shield
+ if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_MAGE && GetSpellProto()->SpellFamilyFlags[0] & 0x8000 && m_spellProto->SpellFamilyFlags[2] & 0x8)
+ {
+ // +80.53% from +spd bonus
+ DoneActualBenefit += caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.8053f;;
+ }
+ break;
+ case SPELL_AURA_DUMMY:
+ if (!caster)
+ break;
+ // Earth Shield
+ if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && m_spellProto->SpellFamilyFlags[1] & 0x400)
+ amount = caster->SpellHealingBonus(GetBase()->GetUnitOwner(), GetSpellProto(), amount, SPELL_DIRECT_DAMAGE);
+ break;
+ case SPELL_AURA_DAMAGE_SHIELD:
+ if (!caster)
+ break;
+ // Thorns
+ if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[0] & 0x100)
+ // 3.3% from sp bonus
+ DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.033f;
+ break;
+ case SPELL_AURA_PERIODIC_DAMAGE:
+ if (!caster)
+ break;
+ // Rupture
+ if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto->SpellFamilyFlags[0] & 0x100000)
+ {
+ m_canBeRecalculated = false;
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ break;
+ //1 point : ${($m1+$b1*1+0.015*$AP)*4} damage over 8 secs
+ //2 points: ${($m1+$b1*2+0.024*$AP)*5} damage over 10 secs
+ //3 points: ${($m1+$b1*3+0.03*$AP)*6} damage over 12 secs
+ //4 points: ${($m1+$b1*4+0.03428571*$AP)*7} damage over 14 secs
+ //5 points: ${($m1+$b1*5+0.0375*$AP)*8} damage over 16 secs
+ float AP_per_combo[6] = {0.0f, 0.015f, 0.024f, 0.03f, 0.03428571f, 0.0375f};
+ uint8 cp = ((Player*)caster)->GetComboPoints();
+ if (cp > 5) cp = 5;
+ amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * AP_per_combo[cp]);
+ }
+ // Rip
+ else if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[0] & 0x00800000 && GetAuraType() == SPELL_AURA_PERIODIC_DAMAGE)
+ {
+ m_canBeRecalculated = false;
+ // 0.01*$AP*cp
+ if (caster->GetTypeId() != TYPEID_PLAYER)
+ break;
+
+ uint8 cp = ((Player*)caster)->GetComboPoints();
+
+ // Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
+ if (AuraEffect const * aurEff = caster->GetAuraEffect(34241,0))
+ amount += cp * aurEff->GetAmount();
+
+ amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
+ }
+ // Rend
+ else if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARRIOR && GetSpellProto()->SpellFamilyFlags[0] & 0x20)
+ {
+ m_canBeRecalculated = false;
+ // $0.2*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
+ float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
+ int32 mws = caster->GetAttackTime(BASE_ATTACK);
+ float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE);
+ float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE);
+ amount+=int32(((mwb_min+mwb_max)/2+ap*mws/14000)*0.2f);
+ // "If used while your target is above 75% health, Rend does 35% more damage."
+ // as for 3.1.3 only ranks above 9 (wrong tooltip?)
+ if (spellmgr.GetSpellRank(m_spellProto->Id) >= 9)
+ {
+ if (GetBase()->GetUnitOwner()->HasAuraState(AURA_STATE_HEALTH_ABOVE_75_PERCENT, m_spellProto, caster))
+ amount += int32(amount * m_spellProto->CalculateSimpleValue(2) / 100.0f);
+ }
+ }
+ break;
+ case SPELL_AURA_PERIODIC_ENERGIZE:
+ if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_GENERIC)
+ {
+ // Replenishment (0.25% from max)
+ // Infinite Replenishment
+ if (m_spellProto->SpellIconID == 3184 && m_spellProto->SpellVisual[0] == 12495)
+ amount = GetBase()->GetUnitOwner()->GetMaxPower(POWER_MANA) * 25 / 10000;
+ }
+ // Innervate
+ else if (m_spellProto->Id == 29166)
+ amount = GetBase()->GetUnitOwner()->GetCreatePowers(POWER_MANA) * amount / (GetTotalTicks() * 100.0f);
+ // Owlkin Frenzy
+ else if (m_spellProto->Id == 48391)
+ amount = GetBase()->GetUnitOwner()->GetCreatePowers(POWER_MANA) * amount / 100;
+ break;
+ case SPELL_AURA_PERIODIC_HEAL:
+ if (!caster)
+ break;
+ // Lightwell Renew
+ if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellProto->SpellFamilyFlags[2] & 0x4000)
+ {
+ if (caster->GetTypeId() == TYPEID_PLAYER)
+ // Bonus from Glyph of Lightwell
+ if (AuraEffect* modHealing = caster->GetAuraEffect(55673, 0))
+ amount *= (100.0f + modHealing->GetAmount()) / 100.0f;
+ }
+ break;
+ case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN:
+ if (!caster)
+ break;
+ // Icebound Fortitude
+ if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellProto->SpellFamilyFlags[0] & 0x00100000)
+ {
+ if (caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ int32 value = int32((amount*-1)-10);
+ uint32 defva = uint32(((Player*)caster)->GetSkillValue(SKILL_DEFENSE) + ((Player*)caster)->GetRatingBonusValue(CR_DEFENSE_SKILL));
+
+ if(defva > 400)
+ value += int32((defva-400)*0.15);
+
+ // Glyph of Icebound Fortitude
+ if (AuraEffect const * aurEff = caster->GetAuraEffect(58625,0))
+ {
+ uint32 valMax = aurEff->GetAmount();
+ if(value < valMax)
+ value = valMax;
+ }
+ amount = -value;
+ }
+ }
+ break;
+ case SPELL_AURA_MOD_THREAT:
+ {
+ uint8 level_diff = 0;
+ float multiplier = 0.0;
+ switch (GetId())
+ {
+ // Arcane Shroud
+ case 26400:
+ level_diff = GetBase()->GetUnitOwner()->getLevel() - 60;
+ multiplier = 2;
+ break;
+ // The Eye of Diminution
+ case 28862:
+ level_diff = GetBase()->GetUnitOwner()->getLevel() - 60;
+ multiplier = 1;
+ break;
+ }
+ if (level_diff > 0)
+ amount += multiplier * level_diff;
+ break;
+ }
+ case SPELL_AURA_MOD_INCREASE_HEALTH:
+ // Vampiric Blood
+ if (GetId() == 55233)
+ amount = GetBase()->GetUnitOwner()->GetMaxHealth() * amount / 100;
+ break;
+ case SPELL_AURA_MOD_INCREASE_ENERGY:
+ // Hymn of Hope
+ if (GetId() == 64904)
+ amount = GetBase()->GetUnitOwner()->GetMaxPower(GetBase()->GetUnitOwner()->getPowerType()) * amount / 100;
+ break;
+ case SPELL_AURA_MOD_INCREASE_SPEED:
+ // Dash - do not set speed if not in cat form
+ if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && GetSpellProto()->SpellFamilyFlags[2] & 0x00000008)
+ amount = GetBase()->GetUnitOwner()->m_form == FORM_CAT ? amount : 0;
+ }
+ if (DoneActualBenefit != 0.0f)
+ {
+ DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto());
+ amount += (int32)DoneActualBenefit;
+ }
+ amount *= GetBase()->GetStackAmount();
+ return amount;
+}
+
+void AuraEffect::CalculatePeriodic(Unit * caster, bool create)
+{
+ m_amplitude = m_spellProto->EffectAmplitude[m_effIndex];
+
+ // prepare periodics
+ switch (GetAuraType())
+ {
+ case SPELL_AURA_OBS_MOD_POWER:
+ // 3 spells have no amplitude set
+ if (!m_amplitude)
+ m_amplitude = 1 * IN_MILISECONDS;
+ case SPELL_AURA_PERIODIC_DAMAGE:
+ case SPELL_AURA_PERIODIC_HEAL:
+ case SPELL_AURA_PERIODIC_ENERGIZE:
+ case SPELL_AURA_OBS_MOD_HEALTH:
+ case SPELL_AURA_PERIODIC_LEECH:
+ case SPELL_AURA_PERIODIC_HEALTH_FUNNEL:
+ case SPELL_AURA_PERIODIC_MANA_LEECH:
+ case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
+ case SPELL_AURA_POWER_BURN_MANA:
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
+ case SPELL_AURA_PERIODIC_DUMMY:
+ m_isPeriodic = true;
+ break;
+ case SPELL_AURA_DUMMY:
+ // Haunting Spirits - perdiodic trigger demon
+ if (GetId() == 7057)
+ {
+ m_isPeriodic = true;
+ m_amplitude = irand (0, 60) + 30;
+ m_amplitude *= IN_MILISECONDS;
+ }
+ break;
+ }
+
+ if (!m_isPeriodic)
+ return;
+
+ Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
+ //apply casting time mods for channeled spells
+ if(modOwner && m_amplitude && IsChanneledSpell(m_spellProto))
+ modOwner->ModSpellCastTime(m_spellProto, m_amplitude);
+
+ // Apply periodic time mod
+ if(modOwner && m_amplitude)
+ modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_amplitude);
+
+ if (create)
+ {
+ // Start periodic on next tick or at aura apply
+ if (m_amplitude && !(m_spellProto->AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY))
+ m_periodicTimer += m_amplitude;
+ }
+ else if (m_amplitude) // load aura from character_aura
+ {
+ m_tickNumber = GetBase()->GetDuration() / m_amplitude;
+ m_periodicTimer = GetBase()->GetDuration() % m_amplitude;
+ if (m_spellProto->AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY)
+ ++m_tickNumber;
+ }
+}
+
+void AuraEffect::CalculateSpellMod()
+{
+ switch (GetAuraType())
+ {
+ case SPELL_AURA_DUMMY:
+ switch(GetSpellProto()->SpellFamilyName)
+ {
+ case SPELLFAMILY_PRIEST:
+ // Pain and Suffering
+ if(m_spellProto->SpellIconID == 2874)
+ {
+ if (!m_spellmod)
+ {
+ m_spellmod = new SpellModifier(GetBase());
+ m_spellmod->op = SPELLMOD_DOT;
+ m_spellmod->type = SPELLMOD_PCT;
+ m_spellmod->spellId = GetId();
+ m_spellmod->mask[1] = 0x00002000;
+ }
+ m_spellmod->value = GetAmount();
+ }
+ break;
+ case SPELLFAMILY_DRUID:
+ switch (GetId())
+ {
+ case 34246: // Idol of the Emerald Queen
+ case 60779: // Idol of Lush Moss
+ {
+ if (!m_spellmod)
+ {
+ m_spellmod = new SpellModifier(GetBase());
+ m_spellmod->op = SPELLMOD_DOT;
+ m_spellmod->type = SPELLMOD_FLAT;
+ m_spellmod->spellId = GetId();
+ m_spellmod->mask[1] = 0x0010;
+ }
+ m_spellmod->value = GetAmount()/7;
+ }
+ break;
+ }
+ break;
+ }
+ case SPELL_AURA_PROC_TRIGGER_SPELL:
+ switch(GetId())
+ {
+ case 51466: // Elemental oath
+ case 51470: // Elemental oath
+ // "while Clearcasting from Elemental Focus is active, you deal 5%/10% more spell damage."
+ if (!m_spellmod)
+ {
+ m_spellmod = new SpellModifier(GetBase());
+ m_spellmod->op = SPELLMOD_EFFECT2;
+ m_spellmod->type = SPELLMOD_FLAT;
+ m_spellmod->spellId = GetId();
+ m_spellmod->mask[1] = 0x0004000;
+ }
+ m_spellmod->value = GetBase()->GetUnitOwner()->CalculateSpellDamage(GetSpellProto(), 1, GetSpellProto()->EffectBasePoints[1], GetBase()->GetUnitOwner());
+ break;
+ }
+ // Drain Soul - If the target is at or below 25% health, Drain Soul causes four times the normal damage
+ if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && GetSpellProto()->SpellFamilyFlags[0] & 0x00004000)
+ {
+ if (!m_spellmod)
+ {
+ m_spellmod = new SpellModifier(GetBase());
+ m_spellmod->op = SPELLMOD_DOT;
+ m_spellmod->type = SPELLMOD_PCT;
+ m_spellmod->spellId = GetId();
+ m_spellmod->mask[0] = 0x00004000;
+ // 300% more dmg
+ if (GetBase()->GetUnitOwner()->GetMaxHealth() / 4 > GetBase()->GetUnitOwner()->GetHealth())
+ m_spellmod->value = 300;
+ else
+ m_spellmod->value = 0;
+ }
+ }
+ break;
+ case SPELL_AURA_ADD_FLAT_MODIFIER:
+ case SPELL_AURA_ADD_PCT_MODIFIER:
+ if (!m_spellmod)
+ {
+ m_spellmod = new SpellModifier(GetBase());
+ m_spellmod->op = SpellModOp(GetMiscValue());
+ assert(m_spellmod->op < MAX_SPELLMOD);
+
+ m_spellmod->type = SpellModType(GetAuraType()); // SpellModType value == spell aura types
+ m_spellmod->spellId = GetId();
+ m_spellmod->mask = GetSpellProto()->EffectSpellClassMask[GetEffIndex()];
+ m_spellmod->charges = GetBase()->GetCharges();
+ }
+ m_spellmod->value = GetAmount();
+ break;
+ }
+}
+
+void AuraEffect::ChangeAmount(int32 newAmount, bool mark)
+{
+ Unit * caster = GetCaster();
+ // Reapply if amount change
+ if (newAmount!=GetAmount())
+ {
+ UnitList targetList;
+ GetTargetList(targetList);
+ for (UnitList::iterator aurEffTarget = targetList.begin(); aurEffTarget != targetList.end(); ++aurEffTarget)
+ {
+ HandleEffect(*aurEffTarget, AURA_EFFECT_HANDLE_CHANGE_AMOUNT, false);
+ }
+ if (!mark)
+ m_amount = newAmount;
+ else
+ SetAmount(newAmount);
+ CalculateSpellMod();
+ for (UnitList::iterator aurEffTarget = targetList.begin(); aurEffTarget != targetList.end(); ++aurEffTarget)
+ {
+ HandleEffect(*aurEffTarget, AURA_EFFECT_HANDLE_CHANGE_AMOUNT, true);
+ }
+ }
+}
+
+void AuraEffect::HandleEffect(AuraApplication const * aurApp, uint8 mode, bool apply)
+{
+ // check if call is correct
+ assert(!mode
+ || mode == AURA_EFFECT_HANDLE_REAL
+ || mode == AURA_EFFECT_HANDLE_SEND_FOR_CLIENT
+ || mode == AURA_EFFECT_HANDLE_CHANGE_AMOUNT
+ || mode == AURA_EFFECT_HANDLE_STAT);
+
+ // real aura apply/remove, handle modifier
+ if (mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK)
+ ApplySpellMod(aurApp->GetTarget(), apply);
+
+ (*this.*AuraEffectHandler [GetAuraType()])(aurApp, mode, apply);
+}
+
+void AuraEffect::HandleEffect(Unit * target, uint8 mode, bool apply)
+{
+ AuraApplication const * aurApp = GetBase()->GetApplicationOfTarget(target->GetGUID());
+ assert(aurApp);
+ HandleEffect(aurApp, mode, apply);
+}
+
+void AuraEffect::ApplySpellMod(Unit * target, bool apply)
+{
+ if(!m_spellmod || target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ ((Player*)target)->AddSpellMod(m_spellmod, apply);
+
+ // Auras with charges do not mod amount of passive auras
+ if (GetBase()->GetCharges())
+ return;
+ // reapply some passive spells after add/remove related spellmods
+ // Warning: it is a dead loop if 2 auras each other amount-shouldn't happen
+ switch (GetMiscValue())
+ {
+ case SPELLMOD_ALL_EFFECTS:
+ case SPELLMOD_EFFECT1:
+ case SPELLMOD_EFFECT2:
+ case SPELLMOD_EFFECT3:
+ {
+ uint64 guid = target->GetGUID();
+ Unit::AuraApplicationMap & auras = target->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::iterator iter = auras.begin(); iter != auras.end(); ++iter)
+ {
+ Aura * aura = iter->second->GetBase();
+ // only passive auras-active auras should have amount set on spellcast and not be affected
+ // if aura is casted by others, it will not be affected
+ if (aura->IsPassive() && aura->GetCasterGUID() == guid && spellmgr.IsAffectedByMod(aura->GetSpellProto(), m_spellmod))
+ {
+ if (GetMiscValue() == SPELLMOD_ALL_EFFECTS)
+ {
+ for (uint8 i = 0; i<MAX_SPELL_EFFECTS; ++i)
+ {
+ if (AuraEffect * aurEff = aura->GetEffect(i))
+ aurEff->RecalculateAmount();
+ }
+ }
+ else if (GetMiscValue() == SPELLMOD_EFFECT1)
+ {
+ if (AuraEffect * aurEff = aura->GetEffect(0))
+ aurEff->RecalculateAmount();
+ }
+ else if (GetMiscValue() == SPELLMOD_EFFECT2)
+ {
+ if (AuraEffect * aurEff = aura->GetEffect(1))
+ aurEff->RecalculateAmount();
+ }
+ else //if (modOp ==SPELLMOD_EFFECT3)
+ {
+ if (AuraEffect * aurEff = aura->GetEffect(2))
+ aurEff->RecalculateAmount();
+ }
+ }
+ }
+ }
+ default:
+ break;
+ }
+}
+
+void AuraEffect::Update(uint32 diff, Unit * caster)
+{
+ if (m_isPeriodic && (GetBase()->GetDuration() >=0 || GetBase()->IsPassive() || GetBase()->IsPermanent()))
+ {
+ if(m_periodicTimer > diff)
+ m_periodicTimer -= diff;
+ else // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
+ {
+ ++m_tickNumber;
+
+ // update before tick (aura can be removed in TriggerSpell or PeriodicTick calls)
+ m_periodicTimer += m_amplitude - diff;
+ UpdatePeriodic(caster);
+
+ UnitList effectTargets;
+ GetTargetList(effectTargets);
+ // tick on targets of effects
+ if (!caster || !caster->hasUnitState(UNIT_STAT_ISOLATED))
+ {
+ for (UnitList::iterator targetItr = effectTargets.begin(); targetItr != effectTargets.end(); ++targetItr)
+ PeriodicTick(*targetItr, caster);
+ }
+ }
+ }
+}
+
+void AuraEffect::UpdatePeriodic(Unit * caster)
+{
+ switch(GetAuraType())
+ {
+ case SPELL_AURA_PERIODIC_DAMAGE:
+ switch (GetId())
+ {
+ case 41337: // Aura of Anger
+ if (AuraEffect * aurEff = GetBase()->GetEffect(1))
+ aurEff->ChangeAmount(aurEff->GetAmount()+5);
+ SetAmount(100 * m_tickNumber);
+ break;
+ case 46394: // Brutallus Burn
+ if (m_tickNumber % 11 == 0)
+ SetAmount(GetAmount() * 2); ;
+ break;
+ }
+ break;
+ case SPELL_AURA_DUMMY:
+ // Haunting Spirits
+ if (GetId() == 7057)
+ {
+ m_amplitude = irand (0 , 60 ) + 30;
+ m_amplitude *= IN_MILISECONDS;
+ }
+ break;
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
+ switch (GetId())
+ {
+ // Sniper training
+ case 53302:
+ case 53303:
+ case 53304:
+ Unit * target = GetBase()->GetUnitOwner();
+ if (target->GetTypeId() != TYPEID_PLAYER)
+ break;
+
+ if (((Player*)target)->isMoving())
+ m_amount = target->CalculateSpellDamage(m_spellProto,m_effIndex,m_baseAmount,target);
+ else
+ --m_amount;
+ break;
+ }
+ break;
+ case SPELL_AURA_PERIODIC_DUMMY:
+ switch(GetSpellProto()->SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
+ switch(GetId())
+ {
+ // Drink
+ case 430:
+ case 431:
+ case 432:
+ case 1133:
+ case 1135:
+ case 1137:
+ case 10250:
+ case 22734:
+ case 27089:
+ case 34291:
+ case 43182:
+ case 43183:
+ case 46755:
+ case 49472: // Drink Coffee
+ case 57073:
+ case 61830:
+ if (!caster || caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+ // Get SPELL_AURA_MOD_POWER_REGEN aura from spell
+ if (AuraEffect * aurEff = GetBase()->GetEffect(0))
+ {
+ if (aurEff->GetAuraType() != SPELL_AURA_MOD_POWER_REGEN)
+ {
+ m_isPeriodic = false;
+ sLog.outError("Aura %d structure has been changed - first aura is no longer SPELL_AURA_MOD_POWER_REGEN", GetId());
+ }
+ else
+ {
+ // default case - not in arena
+ if (!((Player*)caster)->InArena())
+ {
+ aurEff->ChangeAmount(GetAmount());
+ m_isPeriodic = false;
+ }
+ else
+ {
+ //**********************************************
+ // This feature uses only in arenas
+ //**********************************************
+ // Here need increase mana regen per tick (6 second rule)
+ // on 0 tick - 0 (handled in 2 second)
+ // on 1 tick - 166% (handled in 4 second)
+ // on 2 tick - 133% (handled in 6 second)
+
+ // Apply bonus for 1 - 4 tick
+ switch (m_tickNumber)
+ {
+ case 1: // 0%
+ aurEff->ChangeAmount(0);
+ break;
+ case 2: // 166%
+ aurEff->ChangeAmount(GetAmount() * 5 / 3);
+ break;
+ case 3: // 133%
+ aurEff->ChangeAmount(GetAmount() * 4 / 3);
+ break;
+ default: // 100% - normal regen
+ aurEff->ChangeAmount(GetAmount());
+ // No need to update after 4th tick
+ m_isPeriodic = false;
+ break;
+ }
+ }
+ }
+ }
+ break;
+ case 58549: // Tenacity
+ case 59911: // Tenacity (vehicle)
+ GetBase()->RefreshDuration();
+ break;
+ }
+ break;
+ case SPELLFAMILY_MAGE:
+ if (GetId() == 55342)// Mirror Image
+ m_isPeriodic = false;
+ break;
+ case SPELLFAMILY_DEATHKNIGHT:
+ // Chains of Ice
+ if (GetSpellProto()->SpellFamilyFlags[1] & 0x00004000)
+ {
+ // Get 0 effect aura
+ if (AuraEffect *slow = GetBase()->GetEffect(0))
+ {
+ int32 newAmount = slow->GetAmount() + GetAmount();
+ if (newAmount > 0)
+ newAmount = 0;
+ slow->ChangeAmount(newAmount);
+ }
+ return;
+ }
+ }
+ }
+}
+
+bool AuraEffect::IsPeriodicTickCrit(Unit * target, Unit const * caster) const
+{
+ assert(caster);
+ Unit::AuraEffectList const& mPeriodicCritAuras= caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_PERIODIC_CRIT);
+ for (Unit::AuraEffectList::const_iterator itr = mPeriodicCritAuras.begin(); itr != mPeriodicCritAuras.end(); ++itr)
+ {
+ if ((*itr)->IsAffectedOnSpell(m_spellProto) && caster->isSpellCrit(target, m_spellProto, GetSpellSchoolMask(m_spellProto)))
+ return true;
+ }
+ return false;
+}
+
+void AuraEffect::PeriodicTick(Unit * target, Unit * caster) const
+{
+ if(!target->isAlive() || target->hasUnitState(UNIT_STAT_ISOLATED))
+ return;
+
+ switch(GetAuraType())
+ {
+ case SPELL_AURA_PERIODIC_DAMAGE:
+ case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
+ {
+ if(!caster)
+ break;
+
+ // Consecrate ticks can miss and will not show up in the combat log
+ if (GetSpellProto()->Effect[GetEffIndex()] == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
+ caster->SpellHitResult(target,GetSpellProto(),false) != SPELL_MISS_NONE)
+ break;
+
+ // Check for immune (not use charges)
+ if (target->IsImmunedToDamage(GetSpellProto()))
+ break;
+
+ // some auras remove at specific health level or more
+ if (GetAuraType() == SPELL_AURA_PERIODIC_DAMAGE)
+ {
+ switch (GetId())
+ {
+ case 43093: case 31956: case 38801: // Grievous Wound
+ case 35321: case 38363: case 39215: // Gushing Wound
+ if(target->GetHealth() == target->GetMaxHealth())
+ {
+ target->RemoveAurasDueToSpell(GetId());
+ return;
+ }
+ break;
+ case 38772: // Grievous Wound
+ {
+ uint32 percent =
+ GetEffIndex() < 2 && GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_DUMMY ?
+ caster->CalculateSpellDamage(GetSpellProto(),GetEffIndex()+1,GetSpellProto()->EffectBasePoints[GetEffIndex()+1],target) :
+ 100;
+ if(target->GetHealth()*100 >= target->GetMaxHealth()*percent)
+ {
+ target->RemoveAurasDueToSpell(GetId());
+ return;
+ }
+ break;
+ }
+ }
+ }
+
+ uint32 absorb=0;
+ uint32 resist=0;
+ CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL );
+
+ // ignore non positive values (can be result apply spellmods to aura damage
+ uint32 damage = GetAmount() > 0 ? GetAmount() : 0;
+
+ if(GetAuraType() == SPELL_AURA_PERIODIC_DAMAGE)
+ {
+ damage = caster->SpellDamageBonus(target, GetSpellProto(), damage, DOT, GetBase()->GetStackAmount());
+
+ // Calculate armor mitigation if it is a physical spell
+ // But not for bleed mechanic spells
+ if ( GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL &&
+ GetEffectMechanic(GetSpellProto(), m_effIndex) != MECHANIC_BLEED)
+ {
+ uint32 damageReductedArmor = caster->CalcArmorReducedDamage(target, damage, GetSpellProto());
+ cleanDamage.mitigated_damage += damage - damageReductedArmor;
+ damage = damageReductedArmor;
+ }
+
+ // Curse of Agony damage-per-tick calculation
+ if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags[0] & 0x400) && GetSpellProto()->SpellIconID==544)
+ {
+ uint32 totalTick = GetTotalTicks();
+ // 1..4 ticks, 1/2 from normal tick damage
+ if(m_tickNumber <= totalTick / 3)
+ damage = damage/2;
+ // 9..12 ticks, 3/2 from normal tick damage
+ else if(m_tickNumber > totalTick * 2 / 3)
+ damage += (damage+1)/2; // +1 prevent 0.5 damage possible lost at 1..4 ticks
+ // 5..8 ticks have normal tick damage
+ }
+ // There is a Chance to make a Soul Shard when Drain soul does damage
+ if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags[0] & 0x00004000))
+ {
+ if(caster && roll_chance_i(20))
+ caster->CastSpell(caster, 24827, true, 0, this);
+ }
+ }
+ else
+ damage = uint32(target->GetMaxHealth()*damage/100);
+
+ bool crit = IsPeriodicTickCrit(target, caster);
+ if (crit)
+ damage = caster->SpellCriticalDamageBonus(m_spellProto, damage, target);
+
+ // only from players
+ if (IS_PLAYER_GUID(GetCasterGUID()))
+ damage -= target->GetSpellDamageReduction(damage);
+
+ caster->CalcAbsorbResist(target, GetSpellSchoolMask(GetSpellProto()), DOT, damage, &absorb, &resist, m_spellProto);
+
+ sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
+ GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), target->GetGUIDLow(), target->GetTypeId(), damage, GetId(),absorb);
+
+ caster->DealDamageMods(target,damage,&absorb);
+
+ // Set trigger flag
+ uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;
+ uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;
+ uint32 procEx = PROC_EX_NORMAL_HIT | PROC_EX_INTERNAL_DOT;
+ damage = (damage <= absorb+resist) ? 0 : (damage-absorb-resist);
+ if (damage)
+ procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE;
+
+ int32 overkill = damage - target->GetHealth();
+ if (overkill < 0)
+ overkill = 0;
+
+ SpellPeriodicAuraLogInfo pInfo(this, damage, overkill, absorb, resist, 0.0f, crit);
+ target->SendPeriodicAuraLog(&pInfo);
+
+ caster->ProcDamageAndSpell(target, procAttacker, procVictim, procEx, damage, BASE_ATTACK, GetSpellProto());
+
+ caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true);
+ break;
+ }
+ case SPELL_AURA_PERIODIC_LEECH:
+ {
+ if(!caster)
+ return;
+
+ if(!caster->isAlive())
+ return;
+
+ if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA &&
+ caster->SpellHitResult(target,GetSpellProto(),false)!=SPELL_MISS_NONE)
+ return;
+
+ // Check for immune
+ if(target->IsImmunedToDamage(GetSpellProto()))
+ return;
+
+ uint32 absorb=0;
+ uint32 resist=0;
+ CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL );
+
+ //uint32 damage = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
+ uint32 damage = GetAmount() > 0 ? GetAmount() : 0;
+ damage = caster->SpellDamageBonus(target, GetSpellProto(), damage, DOT, GetBase()->GetStackAmount());
+
+ bool crit = IsPeriodicTickCrit(target, caster);
+ if (crit)
+ damage = caster->SpellCriticalDamageBonus(m_spellProto, damage, target);
+
+ //Calculate armor mitigation if it is a physical spell
+ if (GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL)
+ {
+ uint32 damageReductedArmor = caster->CalcArmorReducedDamage(target, damage, GetSpellProto());
+ cleanDamage.mitigated_damage += damage - damageReductedArmor;
+ damage = damageReductedArmor;
+ }
+
+ // Reduce dot damage from resilience for players.
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ damage-=target->GetSpellDamageReduction(damage);
+
+ caster->CalcAbsorbResist(target, GetSpellSchoolMask(GetSpellProto()), DOT, damage, &absorb, &resist, m_spellProto);
+
+ if(target->GetHealth() < damage)
+ damage = uint32(target->GetHealth());
+
+ sLog.outDetail("PeriodicTick: %u (TypeId: %u) health leech of %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
+ GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), target->GetGUIDLow(), target->GetTypeId(), damage, GetId(),absorb);
+
+ caster->SendSpellNonMeleeDamageLog(target, GetId(), damage, GetSpellSchoolMask(GetSpellProto()), absorb, resist, false, 0, crit);
+
+ // Set trigger flag
+ uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;
+ uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;
+ uint32 procEx = PROC_EX_NORMAL_HIT | PROC_EX_INTERNAL_DOT;
+ damage = (damage <= absorb+resist) ? 0 : (damage-absorb-resist);
+ if (damage)
+ procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE;
+ caster->ProcDamageAndSpell(target, procAttacker, procVictim, procEx, damage, BASE_ATTACK, GetSpellProto());
+ int32 new_damage = caster->DealDamage(target, damage, &cleanDamage, DOT, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), false);
+
+ if (!target->isAlive() && caster->IsNonMeleeSpellCasted(false))
+ for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i)
+ if (Spell* spell = caster->GetCurrentSpell(CurrentSpellTypes(i)))
+ if (spell->m_spellInfo->Id == GetId())
+ spell->cancel();
+
+ float multiplier = GetSpellProto()->EffectMultipleValue[GetEffIndex()];
+
+ if(Player *modOwner = caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(GetSpellProto()->Id, SPELLMOD_MULTIPLE_VALUE, multiplier);
+
+ uint32 heal = uint32(caster->SpellHealingBonus(caster, GetSpellProto(), uint32(new_damage * multiplier), DOT, GetBase()->GetStackAmount()));
+
+ int32 gain = caster->DealHeal(caster, heal, GetSpellProto());
+ caster->getHostilRefManager().threatAssist(caster, gain * 0.5f, GetSpellProto());
+ break;
+ }
+ case SPELL_AURA_PERIODIC_HEALTH_FUNNEL: // only three spells
+ {
+ if(!caster || !caster->GetHealth())
+ break;
+
+ uint32 damage = GetAmount();
+ // do not kill health donator
+ if(caster->GetHealth() < damage)
+ damage = caster->GetHealth() - 1;
+ if(!damage)
+ break;
+
+ //donator->SendSpellNonMeleeDamageLog(donator, GetId(), damage, GetSpellSchoolMask(spellProto), 0, 0, false, 0);
+ caster->ModifyHealth(-(int32)damage);
+ sLog.outDebug("PeriodicTick: donator %u target %u damage %u.", target->GetEntry(), target->GetEntry(), damage);
+
+ float multiplier = GetSpellProto()->EffectMultipleValue[GetEffIndex()];
+
+ if(Player *modOwner = caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(GetSpellProto()->Id, SPELLMOD_MULTIPLE_VALUE, multiplier);
+
+ damage *= multiplier;
+
+ caster->DealHeal(target, damage, GetSpellProto());
+ break;
+ }
+ case SPELL_AURA_PERIODIC_HEAL:
+ case SPELL_AURA_OBS_MOD_HEALTH:
+ {
+ if(!caster)
+ break;
+
+ // heal for caster damage (must be alive)
+ if(target != caster && GetSpellProto()->AttributesEx2 & SPELL_ATTR_EX2_HEALTH_FUNNEL && !caster->isAlive())
+ break;
+
+ if(GetBase()->GetDuration() == -1 && target->GetHealth() == target->GetMaxHealth())
+ break;
+
+ // ignore non positive values (can be result apply spellmods to aura damage
+ int32 damage = m_amount > 0 ? m_amount : 0;
+
+ if(GetAuraType() == SPELL_AURA_OBS_MOD_HEALTH)
+ damage = uint32(target->GetMaxHealth() * damage / 100);
+ else
+ {
+ // Wild Growth = amount + (6 - 2*doneTicks) * ticks* amount / 100
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellIconID == 2864)
+ {
+ damage += float(damage * GetTotalTicks()) * ((6-float(2*(GetTickNumber()-1)))/100);
+ }
+
+ damage = caster->SpellHealingBonus(target, GetSpellProto(), damage, DOT, GetBase()->GetStackAmount());
+ }
+
+ bool crit = IsPeriodicTickCrit(target, caster);
+ if (crit)
+ damage = caster->SpellCriticalHealingBonus(m_spellProto, damage, target);
+
+ sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u",
+ GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), target->GetGUIDLow(), target->GetTypeId(), damage, GetId());
+
+ int32 gain = target->ModifyHealth(damage);
+
+ SpellPeriodicAuraLogInfo pInfo(this, damage, damage - gain, 0, 0, 0.0f, crit);
+ target->SendPeriodicAuraLog(&pInfo);
+
+ // add HoTs to amount healed in bgs
+ if( caster->GetTypeId() == TYPEID_PLAYER )
+ if( BattleGround *bg = ((Player*)caster)->GetBattleGround() )
+ bg->UpdatePlayerScore(((Player*)caster), SCORE_HEALING_DONE, gain);
+
+ target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, GetSpellProto());
+
+ bool haveCastItem = GetBase()->GetCastItemGUID() != 0;
+
+ // Health Funnel
+ // damage caster for heal amount
+ if(target != caster && GetSpellProto()->AttributesEx2 & SPELL_ATTR_EX2_HEALTH_FUNNEL)
+ {
+ uint32 damage = gain;
+ uint32 absorb = 0;
+ caster->DealDamageMods(caster,damage,&absorb);
+ caster->SendSpellNonMeleeDamageLog(caster, GetId(), damage, GetSpellSchoolMask(GetSpellProto()), absorb, 0, false, 0, false);
+
+ CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL );
+ caster->DealDamage(caster, damage, &cleanDamage, NODAMAGE, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true);
+ }
+
+ uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;
+ uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;
+ uint32 procEx = PROC_EX_NORMAL_HIT | PROC_EX_INTERNAL_HOT;
+ // ignore item heals
+ if(!haveCastItem)
+ caster->ProcDamageAndSpell(target, procAttacker, procVictim, procEx, damage, BASE_ATTACK, GetSpellProto());
+ break;
+ }
+ case SPELL_AURA_PERIODIC_MANA_LEECH:
+ {
+ if(GetMiscValue() < 0 || GetMiscValue() >= MAX_POWERS)
+ break;
+
+ Powers power = Powers(GetMiscValue());
+
+ // power type might have changed between aura applying and tick (druid's shapeshift)
+ if(target->getPowerType() != power)
+ break;
+
+ if(!caster || !caster->isAlive())
+ break;
+
+ if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA &&
+ caster->SpellHitResult(target,GetSpellProto(),false) != SPELL_MISS_NONE)
+ break;
+
+ // Check for immune (not use charges)
+ if(target->IsImmunedToDamage(GetSpellProto()))
+ break;
+
+ // ignore non positive values (can be result apply spellmods to aura damage
+ uint32 damage = m_amount > 0 ? m_amount : 0;
+
+ // Special case: draining x% of mana (up to a maximum of 2*x% of the caster's maximum mana)
+ // It's mana percent cost spells, m_amount is percent drain from target
+ if (m_spellProto->ManaCostPercentage)
+ {
+ // max value
+ uint32 maxmana = caster->GetMaxPower(power) * damage * 2 / 100;
+ damage = target->GetMaxPower(power) * damage / 100;
+ if(damage > maxmana)
+ damage = maxmana;
+ }
+
+ sLog.outDetail("PeriodicTick: %u (TypeId: %u) power leech of %u (TypeId: %u) for %u dmg inflicted by %u",
+ GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), target->GetGUIDLow(), target->GetTypeId(), damage, GetId());
+
+ int32 drain_amount = target->GetPower(power) > damage ? damage : target->GetPower(power);
+
+ // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
+ if (power == POWER_MANA)
+ drain_amount -= target->GetSpellCritDamageReduction(drain_amount);
+
+ target->ModifyPower(power, -drain_amount);
+
+ float gain_multiplier = 0.0f;
+
+ if(caster->GetMaxPower(power) > 0)
+ {
+ gain_multiplier = GetSpellProto()->EffectMultipleValue[GetEffIndex()];
+
+ if(Player *modOwner = caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(GetId(), SPELLMOD_MULTIPLE_VALUE, gain_multiplier);
+ }
+
+ SpellPeriodicAuraLogInfo pInfo(this, drain_amount, 0, 0, 0, gain_multiplier, false);
+ target->SendPeriodicAuraLog(&pInfo);
+
+ int32 gain_amount = int32(drain_amount*gain_multiplier);
+
+ if(gain_amount)
+ {
+ int32 gain = caster->ModifyPower(power,gain_amount);
+ target->AddThreat(caster, float(gain) * 0.5f, GetSpellSchoolMask(GetSpellProto()), GetSpellProto());
+ }
+
+ switch(GetId())
+ {
+ case 31447: // Mark of Kaz'rogal
+ if(target->GetPower(power) == 0)
+ {
+ target->CastSpell(target, 31463, true, 0, this);
+ // Remove aura
+ GetBase()->SetDuration(0);
+ }
+ break;
+
+ case 32960: // Mark of Kazzak
+ int32 modifier = (target->GetPower(power) * 0.05f);
+ target->ModifyPower(power, -modifier);
+
+ if(target->GetPower(power) == 0)
+ {
+ target->CastSpell(target, 32961, true, 0, this);
+ // Remove aura
+ GetBase()->SetDuration(0);
+ }
+ }
+ // Drain Mana
+ if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK
+ && m_spellProto->SpellFamilyFlags[0] & 0x00000010)
+ {
+ int32 manaFeedVal = 0;
+ if (AuraEffect const * aurEff = GetBase()->GetEffect(1))
+ manaFeedVal = aurEff->GetAmount();
+ // Mana Feed - Drain Mana
+ if(manaFeedVal > 0)
+ {
+ manaFeedVal = manaFeedVal * gain_amount / 100;
+ caster->CastCustomSpell(caster, 32554, &manaFeedVal, NULL, NULL, true, NULL, this);
+ }
+ }
+ break;
+ }
+ case SPELL_AURA_OBS_MOD_POWER:
+ {
+ if(GetMiscValue() < 0)
+ return;
+
+ Powers power;
+ if (GetMiscValue() == POWER_ALL)
+ power = target->getPowerType();
+ else
+ power = Powers(GetMiscValue());
+
+ if(target->GetMaxPower(power) == 0)
+ return;
+
+ if(GetBase()->GetDuration() == -1 && target->GetPower(power) == target->GetMaxPower(power))
+ return;
+
+ uint32 amount = m_amount * target->GetMaxPower(power) /100;
+ sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u",
+ GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), target->GetGUIDLow(), target->GetTypeId(), amount, GetId());
+
+ SpellPeriodicAuraLogInfo pInfo(this, amount, 0, 0, 0, 0.0f, false);
+ target->SendPeriodicAuraLog(&pInfo);
+
+ int32 gain = target->ModifyPower(power,amount);
+
+ if(caster)
+ target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, GetSpellProto());
+ break;
+ }
+ case SPELL_AURA_PERIODIC_ENERGIZE:
+ {
+ // ignore non positive values (can be result apply spellmods to aura damage
+ if(m_amount < 0 || GetMiscValue() >= MAX_POWERS)
+ return;
+
+ Powers power = Powers(GetMiscValue());
+
+ if(target->GetMaxPower(power) == 0)
+ return;
+
+ if(GetBase()->GetDuration() ==-1 && target->GetPower(power)==target->GetMaxPower(power))
+ return;
+
+ uint32 amount = m_amount;
+
+ SpellPeriodicAuraLogInfo pInfo(this, amount, 0, 0, 0, 0.0f, false);
+ target->SendPeriodicAuraLog(&pInfo);
+
+ sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u",
+ GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), target->GetGUIDLow(), target->GetTypeId(), amount, GetId());
+
+ int32 gain = target->ModifyPower(power,amount);
+
+ if(caster)
+ target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, GetSpellProto());
+ break;
+ }
+ case SPELL_AURA_POWER_BURN_MANA:
+ {
+ if(!caster)
+ return;
+
+ // Check for immune (not use charges)
+ if(target->IsImmunedToDamage(GetSpellProto()))
+ return;
+
+ int32 damage = m_amount > 0 ? m_amount : 0;
+
+ Powers powerType = Powers(GetMiscValue());
+
+ if(!target->isAlive() || target->getPowerType() != powerType)
+ return;
+
+ // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
+ if (powerType == POWER_MANA)
+ damage -= target->GetSpellCritDamageReduction(damage);
+
+ uint32 gain = uint32(-target->ModifyPower(powerType, -damage));
+
+ gain = uint32(gain * GetSpellProto()->EffectMultipleValue[GetEffIndex()]);
+
+ SpellEntry const* spellProto = GetSpellProto();
+ //maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG
+ SpellNonMeleeDamage damageInfo(caster, target, spellProto->Id, spellProto->SchoolMask);
+ //no SpellDamageBonus for burn mana
+ caster->CalculateSpellDamageTaken(&damageInfo, gain, spellProto);
+
+ caster->DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb);
+
+ caster->SendSpellNonMeleeDamageLog(&damageInfo);
+
+ // Set trigger flag
+ uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;
+ uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;
+ uint32 procEx = createProcExtendMask(&damageInfo, SPELL_MISS_NONE) | PROC_EX_INTERNAL_DOT;
+ if (damageInfo.damage)
+ procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE;
+
+ caster->ProcDamageAndSpell(damageInfo.target, procAttacker, procVictim, procEx, damageInfo.damage, BASE_ATTACK, spellProto);
+
+ caster->DealSpellDamage(&damageInfo, true);
+ break;
+ }
+ case SPELL_AURA_DUMMY:
+ // Haunting Spirits
+ if (GetId() == 7057)
+ target->CastSpell((Unit*)NULL , GetAmount() , true);
+ break;
+ case SPELL_AURA_PERIODIC_DUMMY:
+ PeriodicDummyTick(target, caster);
+ break;
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
+ TriggerSpell(target, caster);
+ break;
+ case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
+ TriggerSpellWithValue(target, caster);
+ break;
+ }
+}
+
+void AuraEffect::PeriodicDummyTick(Unit * target, Unit * caster) const
+{
+ switch (GetSpellProto()->SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
+ switch (GetId())
+ {
+ // Forsaken Skills
+ case 7054:
+ {
+ // Possibly need cast one of them (but
+ // 7038 Forsaken Skill: Swords
+ // 7039 Forsaken Skill: Axes
+ // 7040 Forsaken Skill: Daggers
+ // 7041 Forsaken Skill: Maces
+ // 7042 Forsaken Skill: Staves
+ // 7043 Forsaken Skill: Bows
+ // 7044 Forsaken Skill: Guns
+ // 7045 Forsaken Skill: 2H Axes
+ // 7046 Forsaken Skill: 2H Maces
+ // 7047 Forsaken Skill: 2H Swords
+ // 7048 Forsaken Skill: Defense
+ // 7049 Forsaken Skill: Fire
+ // 7050 Forsaken Skill: Frost
+ // 7051 Forsaken Skill: Holy
+ // 7053 Forsaken Skill: Shadow
+ return;
+ }
+ case 45472: // Parachute
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ {
+ Player *plr = (Player*)target;
+ if (plr->IsFalling())
+ {
+ plr->RemoveAurasDueToSpell(45472);
+ plr->CastSpell(plr, 44795, true);
+ }
+ }
+ break;
+ case SPELL_RESTRICTED_FLIGHT_AREA_58730: // No Fly Zone - Wintergrasp
+ case SPELL_RESTRICTED_FLIGHT_AREA_58600: // No fly Zone - Dalaran
+ if (GetTickNumber() == 10)
+ {
+ target->RemoveAurasByType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED);
+ target->RemoveAurasByType(SPELL_AURA_FLY);
+ }
+ break;
+ case 62292: // Blaze (Pool of Tar)
+ // should we use custom damage?
+ target->CastSpell((Unit*)NULL, m_spellProto->EffectTriggerSpell[m_effIndex], true);
+ break;
+ case 62399: // Overload Circuit
+ if(target->GetMap()->IsDungeon() && target->GetAppliedAuras().count(62399) >= (target->GetMap()->IsHeroic() ? 4 : 2))
+ {
+ target->CastSpell(target, 62475, true); // System Shutdown
+ if(Unit *veh = target->GetVehicleBase())
+ veh->CastSpell(target, 62475, true);
+ }
+ break;
+ case 64821: // Fuse Armor (Razorscale)
+ if(GetBase()->GetStackAmount() == GetSpellProto()->StackAmount)
+ {
+ target->CastSpell(target, 64774, true, NULL, NULL, GetCasterGUID());
+ target->RemoveAura(64821);
+ }
+ break;
+ }
+ break;
+ case SPELLFAMILY_MAGE:
+ {
+ // Mirror Image
+ if (GetId() == 55342)
+ // Set name of summons to name of caster
+ target->CastSpell((Unit *)NULL, m_spellProto->EffectTriggerSpell[m_effIndex], true);
+ break;
+ }
+ case SPELLFAMILY_WARLOCK:
+ {
+ switch (GetSpellProto()->Id)
+ {
+ // Demonic Circle
+ case 48018:
+ if(GameObject* obj = target->GetGameObject(GetSpellProto()->Id))
+ {
+ if (target->IsWithinDist(obj, GetSpellMaxRange(48020, true)))
+ {
+ if (!target->HasAura(62388))
+ target->CastSpell(target, 62388, true);
+ }
+ else
+ target->RemoveAura(62388);
+ }
+ break;
+ }
+ break;
+ }
+ case SPELLFAMILY_DRUID:
+ {
+ switch (GetSpellProto()->Id)
+ {
+ // Frenzied Regeneration
+ case 22842:
+ {
+ // Converts up to 10 rage per second into health for $d. Each point of rage is converted into ${$m2/10}.1% of max health.
+ // Should be manauser
+ if (target->getPowerType()!=POWER_RAGE)
+ break;
+ uint32 rage = target->GetPower(POWER_RAGE);
+ // Nothing todo
+ if (rage == 0)
+ break;
+ int32 mod = (rage < 100) ? rage : 100;
+ int32 points = target->CalculateSpellDamage(GetSpellProto(), 1, GetSpellProto()->EffectBasePoints[1], target);
+ int32 regen = target->GetMaxHealth() * (mod * points / 10) / 1000;
+ target->CastCustomSpell(target, 22845, &regen, 0, 0, true, 0, this);
+ target->SetPower(POWER_RAGE, rage-mod);
+ break;
+ }
+ // Force of Nature
+ case 33831:
+ break;
+ }
+ break;
+ }
+ case SPELLFAMILY_ROGUE:
+ {
+ switch (GetSpellProto()->Id)
+ {
+ // Master of Subtlety
+ case 31666:
+ if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH))
+ target->RemoveAurasDueToSpell(31665);
+ break;
+ // Killing Spree
+ case 51690:
+ {
+ // TODO: this should use effect[1] of 51690
+ UnitList targets;
+ {
+ // eff_radius ==0
+ float radius = GetSpellMaxRange(GetSpellProto(), false);
+
+ CellPair p(Trinity::ComputeCellPair(caster->GetPositionX(),caster->GetPositionY()));
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+
+ Trinity::AnyUnfriendlyVisibleUnitInObjectRangeCheck u_check(caster, caster, radius);
+ Trinity::UnitListSearcher<Trinity::AnyUnfriendlyVisibleUnitInObjectRangeCheck> checker(caster,targets, u_check);
+
+ TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyUnfriendlyVisibleUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
+ TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyUnfriendlyVisibleUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
+
+ CellLock<GridReadGuard> cell_lock(cell, p);
+
+ cell_lock->Visit(cell_lock, grid_object_checker, *GetBase()->GetOwner()->GetMap(), *caster, radius);
+ cell_lock->Visit(cell_lock, world_object_checker, *GetBase()->GetOwner()->GetMap(), *caster, radius);
+ }
+
+ if(targets.empty())
+ return;
+
+ UnitList::const_iterator itr = targets.begin();
+ std::advance(itr, rand()%targets.size());
+ Unit* spellTarget = *itr;
+
+ target->CastSpell(spellTarget, 57840, true);
+ target->CastSpell(spellTarget, 57841, true);
+ break;
+ }
+ // Overkill
+ case 58428:
+ if (!target->HasAuraType(SPELL_AURA_MOD_STEALTH))
+ target->RemoveAurasDueToSpell(58427);
+ break;
+ }
+ break;
+ }
+ case SPELLFAMILY_HUNTER:
+ {
+ // Explosive Shot
+ if (GetSpellProto()->SpellFamilyFlags[1] & 0x80000000)
+ {
+ if(caster)
+ caster->CastCustomSpell(53352, SPELLVALUE_BASE_POINT0, m_amount, target, true, NULL, this);
+ break;
+ }
+ switch (GetSpellProto()->Id)
+ {
+ // Feeding Frenzy Rank 1
+ case 53511:
+ if ( target->getVictim() && target->getVictim()->GetHealth() * 100 < target->getVictim()->GetMaxHealth() * 35 )
+ target->CastSpell(target, 60096, true, 0, this);
+ return;
+ // Feeding Frenzy Rank 2
+ case 53512:
+ if ( target->getVictim() && target->getVictim()->GetHealth() * 100 < target->getVictim()->GetMaxHealth() * 35 )
+ target->CastSpell(target, 60097, true, 0, this);
+ return;
+ default:
+ break;
+ }
+ break;
+ }
+ case SPELLFAMILY_SHAMAN:
+ if (GetId() == 52179) // Astral Shift
+ {
+ // Periodic need for remove visual on stun/fear/silence lost
+ if (!(target->GetUInt32Value(UNIT_FIELD_FLAGS)&(UNIT_FLAG_STUNNED|UNIT_FLAG_FLEEING|UNIT_FLAG_SILENCED)))
+ target->RemoveAurasDueToSpell(52179);
+ break;
+ }
+ break;
+ case SPELLFAMILY_DEATHKNIGHT:
+ switch (GetId())
+ {
+ case 49016: // Hysteria
+ uint32 damage = uint32(target->GetMaxHealth()*0.01f);
+ target->DealDamage(target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
+ break;
+ }
+ // Death and Decay
+ if (GetSpellProto()->SpellFamilyFlags[0] & 0x20)
+ {
+ if (caster)
+ caster->CastCustomSpell(target, 52212, &m_amount, NULL, NULL, true, 0, this);
+ break;
+ }
+ // Blood of the North
+ // Reaping
+ // Death Rune Mastery
+ if (GetSpellProto()->SpellIconID == 3041 || GetSpellProto()->SpellIconID == 22 || GetSpellProto()->SpellIconID == 2622)
+ {
+ if (target->GetTypeId() != TYPEID_PLAYER)
+ return;
+ if(((Player*)target)->getClass() != CLASS_DEATH_KNIGHT)
+ return;
+
+ // timer expired - remove death runes
+ ((Player*)target)->RemoveRunesByAuraEffect(this);
+ }
+ break;
+ }
+}
+
+Unit* AuraEffect::GetTriggerTarget(Unit * target) const
+{
+ Unit * triggerTarget = NULL;
+ if (target->GetTypeId() == TYPEID_UNIT)
+ triggerTarget = ((Creature*)target)->AI()->GetAuraEffectTriggerTarget(GetId(), GetEffIndex());
+ return triggerTarget ? triggerTarget : ObjectAccessor::GetUnit(*target, target->GetUInt64Value(UNIT_FIELD_TARGET));
+}
+
+void AuraEffect::TriggerSpell(Unit * target, Unit * caster) const
+{
+ Unit* triggerTarget = GetTriggerTarget(target);
+ if (!triggerTarget)
+ triggerTarget = target;
+
+ if(!caster || !target)
+ return;
+
+ // generic casting code with custom spells and target/caster customs
+ uint32 triggerSpellId = GetSpellProto()->EffectTriggerSpell[GetEffIndex()];
+
+ SpellEntry const *triggeredSpellInfo = sSpellStore.LookupEntry(triggerSpellId);
+ SpellEntry const *auraSpellInfo = GetSpellProto();
+ uint32 auraId = auraSpellInfo->Id;
+
+ // specific code for cases with no trigger spell provided in field
+ if (triggeredSpellInfo == NULL)
+ {
+ switch(auraSpellInfo->SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
+ {
+ switch(auraId)
+ {
+ // Thaumaturgy Channel
+ case 9712:
+ triggerSpellId = 21029;
+ break;
+ // Brood Affliction: Bronze
+ case 23170:
+ target->CastSpell(target, 23171, true, 0, this);
+ return;
+ // Restoration
+ case 23493:
+ {
+ int32 heal = caster->GetMaxHealth() / 10;
+ caster->DealHeal(target, heal, auraSpellInfo);
+
+ int32 mana = caster->GetMaxPower(POWER_MANA);
+ if (mana)
+ {
+ mana /= 10;
+ caster->EnergizeBySpell(caster, 23493, mana, POWER_MANA);
+ }
+ return;
+ }
+ // Nitrous Boost
+ case 27746:
+ if (target->GetPower(POWER_MANA) >= 10)
+ {
+ target->ModifyPower( POWER_MANA, -10 );
+ target->SendEnergizeSpellLog(caster, 27746, -10, POWER_MANA);
+ }
+ else
+ target->RemoveAurasDueToSpell(27746);
+ return;
+ // Frost Blast
+ case 27808:
+ caster->CastCustomSpell(29879, SPELLVALUE_BASE_POINT0, (float)target->GetMaxHealth()*0.26f, target, true, NULL, this);
+ return;
+ // Detonate Mana
+ case 27819:
+ if(int32 mana = (int32)(target->GetMaxPower(POWER_MANA) / 4))
+ {
+ mana = target->ModifyPower(POWER_MANA, -mana);
+ target->CastCustomSpell(27820, SPELLVALUE_BASE_POINT0, -mana*4, NULL, true, NULL, this, caster->GetGUID());
+ }
+ return;
+ // Inoculate Nestlewood Owlkin
+ case 29528:
+ if(triggerTarget->GetTypeId()!=TYPEID_UNIT)// prevent error reports in case ignored player target
+ return;
+ break;
+ // Feed Captured Animal
+ case 29917:
+ triggerSpellId = 29916;
+ break;
+ // Extract Gas
+ case 30427:
+ {
+ // move loot to player inventory and despawn target
+ if(caster->GetTypeId() ==TYPEID_PLAYER &&
+ triggerTarget->GetTypeId() == TYPEID_UNIT &&
+ ((Creature*)triggerTarget)->GetCreatureInfo()->type == CREATURE_TYPE_GAS_CLOUD)
+ {
+ Player* player = (Player*)caster;
+ Creature* creature = (Creature*)triggerTarget;
+ // missing lootid has been reported on startup - just return
+ if (!creature->GetCreatureInfo()->SkinLootId)
+ return;
+
+ player->AutoStoreLoot(creature->GetCreatureInfo()->SkinLootId,LootTemplates_Skinning,true);
+
+ creature->ForcedDespawn();
+ }
+ return;
+ }
+ // Quake
+ case 30576: triggerSpellId = 30571; break;
+ // Doom
+ case 31347:
+ {
+ target->CastSpell(target,31350,true, NULL, this);
+ target->Kill(target);
+ return;
+ }
+ // Spellcloth
+ case 31373:
+ {
+ // Summon Elemental after create item
+ target->SummonCreature(17870, 0, 0, 0, target->GetOrientation(), TEMPSUMMON_DEAD_DESPAWN, 0);
+ return;
+ }
+ // Flame Quills
+ case 34229:
+ {
+ // cast 24 spells 34269-34289, 34314-34316
+ for (uint32 spell_id = 34269; spell_id != 34290; ++spell_id)
+ caster->CastSpell(target,spell_id,true, NULL, this);
+ for (uint32 spell_id = 34314; spell_id != 34317; ++spell_id)
+ caster->CastSpell(target,spell_id,true, NULL, this);
+ return;
+ }
+ // Remote Toy
+ case 37027: triggerSpellId = 37029; break;
+ // Eye of Grillok
+ case 38495:
+ {
+ target->CastSpell(target, 38530, true, NULL, this);
+ return;
+ }
+ // Absorb Eye of Grillok (Zezzak's Shard)
+ case 38554:
+ {
+ if(target->GetTypeId() != TYPEID_UNIT)
+ return;
+
+ caster->CastSpell(caster, 38495, true, NULL, this);
+
+ Creature* creatureTarget = (Creature*)target;
+
+ creatureTarget->ForcedDespawn();
+ return;
+ }
+ // Tear of Azzinoth Summon Channel - it's not really supposed to do anything,and this only prevents the console spam
+ case 39857: triggerSpellId = 39856; break;
+ // Personalized Weather
+ case 46736: triggerSpellId = 46737; break;
+ }
+ break;
+ }
+ case SPELLFAMILY_MAGE:
+ {
+ switch(auraId)
+ {
+ // Invisibility
+ case 66:
+ // Here need periodic triger reducing threat spell (or do it manually)
+ return;
+ }
+ break;
+ }
+ case SPELLFAMILY_DRUID:
+ {
+ switch(auraId)
+ {
+ // Cat Form
+ // triggerSpellId not set and unknown effect triggered in this case, ignoring for while
+ case 768:
+ return;
+ }
+ break;
+ }
+ case SPELLFAMILY_HUNTER:
+ {
+ switch (auraId)
+ {
+ // Sniper training
+ case 53302:
+ case 53303:
+ case 53304:
+ // We are standing at the moment
+ if (GetAmount() != -1)
+ return;
+
+ triggerSpellId = 64418 + auraId - 53302;
+
+ // If aura is active - no need to continue
+ if (target->HasAura(triggerSpellId))
+ return;
+ break;
+ }
+ break;
+ }
+ case SPELLFAMILY_SHAMAN:
+ {
+ switch(auraId)
+ {
+ // Lightning Shield (The Earthshatterer set trigger after cast Lighting Shield)
+ case 28820:
+ {
+ // Need remove self if Lightning Shield not active
+ if (!target->GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN,0x400))
+ target->RemoveAurasDueToSpell(28820);
+ return;
+ }
+ // Totemic Mastery (Skyshatter Regalia (Shaman Tier 6) - bonus)
+ case 38443:
+ {
+ bool all = true;
+ for (int i = SUMMON_SLOT_TOTEM; i < MAX_TOTEM_SLOT; ++i)
+ {
+ if(!target->m_SummonSlot[i])
+ {
+ all = false;
+ break;
+ }
+ }
+
+ if(all)
+ caster->CastSpell(target,38437,true, NULL, this);
+ else
+ target->RemoveAurasDueToSpell(38437);
+ return;
+ }
+ }
+ break;
+ }
+ }
+
+ // Reget trigger spell proto
+ triggeredSpellInfo = sSpellStore.LookupEntry(triggerSpellId);
+ }
+ else
+ {
+ // Spell exist but require custom code
+ switch(auraId)
+ {
+ // Mana Tide
+ case 16191:
+ {
+ caster->CastCustomSpell(triggerTarget, triggerSpellId, &m_amount, NULL, NULL, true, NULL, this);
+ return;
+ }
+ // Negative Energy Periodic
+ case 46284:
+ caster->CastCustomSpell(triggerSpellId, SPELLVALUE_MAX_TARGETS, m_tickNumber / 10 + 1, NULL, true, NULL, this);
+ return;
+ // Poison (Grobbulus)
+ case 28158:
+ case 54362:
+ target->CastCustomSpell(triggerSpellId, SPELLVALUE_RADIUS_MOD, (int32)((((float)m_tickNumber / 60) * 0.9f + 0.1f) * 10000), NULL, true, NULL, this);
+ return;
+ // Mind Sear (target 76/16) if let target cast, will damage caster
+ case 48045:
+ case 53023:
+ // Curse of the Plaguebringer (22/15)
+ case 29213:
+ case 54835:
+ caster->CastSpell(target, triggerSpellId, true, NULL, this);
+ return;
+ // Ground Slam
+ case 33525:
+ target->CastSpell(triggerTarget, triggerSpellId, true);
+ return;
+ }
+ }
+
+ if(triggeredSpellInfo)
+ {
+ if(!caster->GetSpellMaxRangeForTarget(target,sSpellRangeStore.LookupEntry(triggeredSpellInfo->rangeIndex)))
+ triggerTarget = target; //for druid dispel poison
+ target->CastSpell(triggerTarget, triggeredSpellInfo, true, 0, this, GetCasterGUID());
+ }
+ else if(target->GetTypeId()!=TYPEID_UNIT || !Script->EffectDummyCreature(caster, GetId(), GetEffIndex(), (Creature*)target))
+ sLog.outError("AuraEffect::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetId(),GetEffIndex());
+}
+
+void AuraEffect::TriggerSpellWithValue(Unit * target, Unit * caster) const
+{
+ Unit* triggerTarget = GetTriggerTarget(target);
+ if (!triggerTarget)
+ triggerTarget = target;
+
+ if(!caster || !target)
+ return;
+
+ // generic casting code with custom spells and target/caster customs
+ uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
+ int32 basepoints0 = GetAmount();
+
+ caster->CastCustomSpell(triggerTarget, trigger_spell_id, &basepoints0, 0, 0, true, 0, this);
+}
+
+bool AuraEffect::IsAffectedOnSpell(SpellEntry const *spell) const
+{
+ if (!spell)
+ return false;
+ // Check family name
+ if (spell->SpellFamilyName != m_spellProto->SpellFamilyName)
+ return false;
+
+ // Check EffectClassMask
+ if (m_spellProto->EffectSpellClassMask[m_effIndex] & spell->SpellFamilyFlags)
+ return true;
+ return false;
+}
+
+void AuraEffect::CleanupTriggeredSpells(Unit * target)
+{
+ uint32 tSpellId = m_spellProto->EffectTriggerSpell[GetEffIndex()];
+ if(!tSpellId)
+ return;
+
+ SpellEntry const* tProto = sSpellStore.LookupEntry(tSpellId);
+ if(!tProto)
+ return;
+
+ if(GetSpellDuration(tProto) != -1)
+ return;
+
+ // needed for spell 43680, maybe others
+ // TODO: is there a spell flag, which can solve this in a more sophisticated way?
+ if(m_spellProto->EffectApplyAuraName[GetEffIndex()] == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
+ GetSpellDuration(m_spellProto) == m_spellProto->EffectAmplitude[GetEffIndex()])
+ return;
+
+ target->RemoveAurasDueToSpell(tSpellId, GetCasterGUID());
+}
+
+void AuraEffect::HandleShapeshiftBoosts(Unit * target, bool apply) const
+{
+ uint32 spellId = 0;
+ uint32 spellId2 = 0;
+ uint32 spellId3 = 0;
+ uint32 HotWSpellId = 0;
+
+ switch(GetMiscValue())
+ {
+ case FORM_CAT:
+ spellId = 3025;
+ HotWSpellId = 24900;
+ break;
+ case FORM_TREE:
+ spellId = 34123;
+ break;
+ case FORM_TRAVEL:
+ spellId = 5419;
+ break;
+ case FORM_AQUA:
+ spellId = 5421;
+ break;
+ case FORM_BEAR:
+ spellId = 1178;
+ spellId2 = 21178;
+ HotWSpellId = 24899;
+ break;
+ case FORM_DIREBEAR:
+ spellId = 9635;
+ spellId2 = 21178;
+ HotWSpellId = 24899;
+ break;
+ case FORM_BATTLESTANCE:
+ spellId = 21156;
+ break;
+ case FORM_DEFENSIVESTANCE:
+ spellId = 7376;
+ break;
+ case FORM_BERSERKERSTANCE:
+ spellId = 7381;
+ break;
+ case FORM_MOONKIN:
+ spellId = 24905;
+ break;
+ case FORM_FLIGHT:
+ spellId = 33948;
+ spellId2 = 34764;
+ break;
+ case FORM_FLIGHT_EPIC:
+ spellId = 40122;
+ spellId2 = 40121;
+ break;
+ case FORM_METAMORPHOSIS:
+ spellId = 54817;
+ spellId2 = 54879;
+ break;
+ case FORM_SPIRITOFREDEMPTION:
+ spellId = 27792;
+ spellId2 = 27795; // must be second, this important at aura remove to prevent to early iterator invalidation.
+ break;
+ case FORM_SHADOW:
+ spellId = 49868;
+ break;
+ case FORM_GHOSTWOLF:
+ spellId = 67116;
+ break;
+ case FORM_GHOUL:
+ case FORM_AMBIENT:
+ case FORM_STEALTH:
+ case FORM_CREATURECAT:
+ case FORM_CREATUREBEAR:
+ break;
+ }
+
+ if(apply)
+ {
+ // Remove cooldown of spells triggered on stance change - they may share cooldown with stance spell
+ if (spellId)
+ {
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ ((Player *)target)->RemoveSpellCooldown(spellId);
+ target->CastSpell(target, spellId, true, NULL, this );
+ }
+
+ if (spellId2)
+ {
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ ((Player *)target)->RemoveSpellCooldown(spellId2);
+ target->CastSpell(target, spellId2, true, NULL, this);
+ }
+
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ {
+ const PlayerSpellMap& sp_list = ((Player *)target)->GetSpellMap();
+ for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
+ {
+ if(itr->second->state == PLAYERSPELL_REMOVED) continue;
+ if(itr->first==spellId || itr->first==spellId2) continue;
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
+ if (!spellInfo || !(spellInfo->Attributes & (SPELL_ATTR_PASSIVE | (1<<7)))) continue;
+ if (spellInfo->Stances & (1<<(GetMiscValue()-1)))
+ target->CastSpell(target, itr->first, true, NULL, this);
+ }
+ // Leader of the Pack
+ if (((Player*)target)->HasSpell(17007))
+ {
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(24932);
+ if (spellInfo && spellInfo->Stances & (1<<(GetMiscValue()-1)))
+ target->CastSpell(target, 24932, true, NULL, this);
+ }
+ // Improved Barkskin - apply/remove armor bonus due to shapeshift
+ if (((Player*)target)->HasSpell(63410) || ((Player*)target)->HasSpell(63411))
+ {
+ target->RemoveAurasDueToSpell(66530);
+ if (GetMiscValue() == FORM_TRAVEL || GetMiscValue() == FORM_NONE) // "while in Travel Form or while not shapeshifted"
+ target->CastSpell(target, 66530, true);
+ }
+ // Heart of the Wild
+ if (HotWSpellId)
+ {
+ Unit::AuraEffectList const& mModTotalStatPct = target->GetAuraEffectsByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
+ for (Unit::AuraEffectList::const_iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
+ {
+ if ((*i)->GetSpellProto()->SpellIconID == 240 && (*i)->GetMiscValue() == 3)
+ {
+ int32 HotWMod = (*i)->GetAmount();
+ if(GetMiscValue() == FORM_CAT)
+ HotWMod /= 2;
+
+ target->CastCustomSpell(target, HotWSpellId, &HotWMod, NULL, NULL, true, NULL, this);
+ break;
+ }
+ }
+ }
+ switch(GetMiscValue())
+ {
+ case FORM_CAT:
+ // Nurturing Instinct
+ if (AuraEffect const * aurEff = target->GetAuraEffect(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT, SPELLFAMILY_DRUID, 2254,0))
+ {
+ uint32 spellId = 0;
+ switch (aurEff->GetId())
+ {
+ case 33872:
+ spellId = 47179;
+ break;
+ case 33873:
+ spellId = 47180;
+ break;
+ }
+ target->CastSpell(target, spellId, true, NULL, this);
+ }
+ // Master Shapeshifter - Cat
+ if (AuraEffect const * aurEff = target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2851, 0))
+ {
+ int32 bp = aurEff->GetAmount();
+ target->CastCustomSpell(target, 48420, &bp, NULL, NULL, true);
+ }
+ break;
+ case FORM_DIREBEAR:
+ case FORM_BEAR:
+ // Master Shapeshifter - Bear
+ if (AuraEffect const * aurEff = target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2851, 0))
+ {
+ int32 bp = aurEff->GetAmount();
+ target->CastCustomSpell(target, 48418, &bp, NULL, NULL, true);
+ }
+ // Survival of the Fittest
+ if (AuraEffect const * aurEff = target->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE,SPELLFAMILY_DRUID, 961, 0))
+ {
+ int32 bp = target->CalculateSpellDamage(aurEff->GetSpellProto(),2,aurEff->GetSpellProto()->EffectBasePoints[2],target);
+ target->CastCustomSpell(target, 62069,&bp, NULL, NULL, true, 0, this);
+ }
+ break;
+ case FORM_MOONKIN:
+ // Master Shapeshifter - Moonkin
+ if (AuraEffect const * aurEff = target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2851, 0))
+ {
+ int32 bp = aurEff->GetAmount();
+ target->CastCustomSpell(target, 48421, &bp, NULL, NULL, true);
+ }
+ break;
+ // Master Shapeshifter - Tree of Life
+ case FORM_TREE:
+ if (AuraEffect const * aurEff = target->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2851, 0))
+ {
+ int32 bp = aurEff->GetAmount();
+ target->CastCustomSpell(target, 48422, &bp, NULL, NULL, true);
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ if (spellId)
+ target->RemoveAurasDueToSpell(spellId);
+ if (spellId2)
+ target->RemoveAurasDueToSpell(spellId2);
+
+ // Improved Barkskin - apply/remove armor bonus due to shapeshift
+ if (((Player*)target)->HasSpell(63410) || ((Player*)target)->HasSpell(63411))
+ {
+ target->RemoveAurasDueToSpell(66530);
+ target->CastSpell(target,66530,true);
+ }
+
+ Unit::AuraApplicationMap& tAuras = target->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
+ {
+ if (itr->second->GetBase()->IsRemovedOnShapeLost(target))
+ target->RemoveAura(itr);
+ else
+ ++itr;
+ }
+ }
+}
+
+/*********************************************************/
+/*** AURA EFFECT HANDLERS ***/
+/*********************************************************/
+
+/**************************************/
+/*** VISIBILITY & PHASES ***/
+/**************************************/
+
+void AuraEffect::HandleInvisibilityDetect(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(apply)
+ {
+ target->m_detectInvisibilityMask |= (1 << GetMiscValue());
+ }
+ else
+ {
+ // recalculate value at modifier remove (current aura already removed)
+ target->m_detectInvisibilityMask = 0;
+ Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
+ for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ target->m_detectInvisibilityMask |= (1 << GetMiscValue());
+ }
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ target->SetToNotify();
+}
+
+void AuraEffect::HandleInvisibility(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(apply)
+ {
+ target->m_invisibilityMask |= (1 << GetMiscValue());
+
+ if (mode & AURA_EFFECT_HANDLE_REAL)
+ {
+ // drop flag at invisibiliy in bg
+ target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
+ }
+
+ // apply glow vision
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ target->SetFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
+
+ target->SetToNotify();
+ }
+ else
+ {
+ // recalculate value at modifier remove (current aura already removed)
+ target->m_invisibilityMask = 0;
+ Unit::AuraEffectList const& auras = target->GetAuraEffectsByType(SPELL_AURA_MOD_INVISIBILITY);
+ for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ target->m_invisibilityMask |= (1 << GetMiscValue());
+
+ // if not have different invisibility auras.
+ // remove glow vision
+ if(!target->m_invisibilityMask && target->GetTypeId() == TYPEID_PLAYER)
+ target->RemoveFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
+
+ target->SetToNotify();
+ }
+}
+
+void AuraEffect::HandleModStealth(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(apply)
+ {
+ if (mode & AURA_EFFECT_HANDLE_REAL)
+ {
+ // drop flag at stealth in bg
+ target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
+ }
+
+ target->SetStandFlags(UNIT_STAND_FLAGS_CREEP);
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000);
+
+ // apply only if not in GM invisibility (and overwrite invisibility state)
+ if(target->GetVisibility() != VISIBILITY_OFF)
+ target->SetVisibility(VISIBILITY_GROUP_STEALTH);
+ }
+ else if(!target->HasAuraType(SPELL_AURA_MOD_STEALTH)) // if last SPELL_AURA_MOD_STEALTH
+ {
+ target->RemoveStandFlags(UNIT_STAND_FLAGS_CREEP);
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000);
+
+ if(target->GetVisibility() != VISIBILITY_OFF)
+ target->SetVisibility(VISIBILITY_ON);
+ }
+}
+
+void AuraEffect::HandleSpiritOfRedemption(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ // prepare spirit state
+ if(apply)
+ {
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ {
+ // disable breath/etc timers
+ ((Player*)target)->StopMirrorTimers();
+
+ // set stand state (expected in this form)
+ if(!target->IsStandState())
+ target->SetStandState(UNIT_STAND_STATE_STAND);
+ }
+
+ target->SetHealth(1);
+ }
+ // die at aura end
+ else
+ target->setDeathState(JUST_DIED);
+}
+
+void AuraEffect::HandleAuraGhost(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if(apply)
+ target->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST);
+ else
+ {
+ if (target->HasAuraType(SPELL_AURA_GHOST))
+ return;
+ target->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST);
+ }
+}
+
+void AuraEffect::HandlePhase(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ // no-phase is also phase state so same code for apply and remove
+
+ // phase auras normally not expected at BG but anyway better check
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ {
+ // drop flag at invisible in bg
+ if(((Player*)target)->InBattleGround())
+ if(BattleGround *bg = ((Player*)target)->GetBattleGround())
+ bg->EventPlayerDroppedFlag((Player*)target);
+
+ // GM-mode have mask 0xFFFFFFFF
+ if(!((Player*)target)->isGameMaster())
+ target->SetPhaseMask((apply) ? GetMiscValue() : PHASEMASK_NORMAL,false);
+
+ ((Player*)target)->GetSession()->SendSetPhaseShift((apply) ? GetMiscValue() : PHASEMASK_NORMAL);
+ }
+ else
+ target->SetPhaseMask((apply) ? GetMiscValue() : PHASEMASK_NORMAL,false);
+
+ // need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)
+ if(target->GetVisibility()!=VISIBILITY_OFF)
+ target->SetVisibility(target->GetVisibility());
+}
+
+/**********************/
+/*** UNIT MODEL ***/
+/**********************/
+
+void AuraEffect::HandleAuraModShapeshift(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ uint32 modelid = 0;
+ Powers PowerType = POWER_MANA;
+ ShapeshiftForm form = ShapeshiftForm(GetMiscValue());
+ switch(form)
+ {
+ case FORM_CAT:
+ case FORM_GHOUL:
+ PowerType = POWER_ENERGY;
+ break;
+ case FORM_BEAR:
+ case FORM_DIREBEAR:
+ case FORM_BATTLESTANCE:
+ case FORM_BERSERKERSTANCE:
+ case FORM_DEFENSIVESTANCE:
+ PowerType = POWER_RAGE;
+ break;
+ case FORM_TRAVEL:
+ case FORM_AQUA:
+ case FORM_CREATUREBEAR:
+ case FORM_GHOSTWOLF:
+ case FORM_FLIGHT:
+ case FORM_MOONKIN:
+ case FORM_FLIGHT_EPIC:
+ case FORM_METAMORPHOSIS:
+ case FORM_MASTER_ANGLER:
+ case FORM_AMBIENT:
+ case FORM_SHADOW:
+ case FORM_STEALTH:
+ case FORM_UNDEAD:
+ case FORM_SHADOW_DANCE:
+ case FORM_TREE:
+ case FORM_SPIRITOFREDEMPTION:
+ break;
+ default:
+ sLog.outError("Auras: Unknown Shapeshift Type: %u", GetMiscValue());
+ }
+
+ modelid = target->GetModelForForm(form);
+
+ // remove polymorph before changing display id to keep new display id
+ switch ( form )
+ {
+ case FORM_CAT:
+ case FORM_TREE:
+ case FORM_TRAVEL:
+ case FORM_AQUA:
+ case FORM_BEAR:
+ case FORM_DIREBEAR:
+ case FORM_FLIGHT_EPIC:
+ case FORM_FLIGHT:
+ case FORM_MOONKIN:
+ {
+ // remove movement affects
+ target->RemoveMovementImpairingAuras();
+
+ // and polymorphic affects
+ if(target->IsPolymorphed())
+ target->RemoveAurasDueToSpell(target->getTransForm());
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (apply)
+ {
+ // remove other shapeshift before applying a new one
+ if(target->m_ShapeShiftFormSpellId)
+ target->RemoveAurasDueToSpell(target->m_ShapeShiftFormSpellId);
+
+ target->SetByteValue(UNIT_FIELD_BYTES_2, 3, form);
+
+ if (modelid > 0)
+ target->SetDisplayId(modelid);
+
+ if (PowerType != POWER_MANA)
+ {
+ uint32 oldPower = target->GetPower(PowerType);
+ // reset power to default values only at power change
+ if(target->getPowerType() != PowerType)
+ target->setPowerType(PowerType);
+
+ switch (form)
+ {
+ case FORM_CAT:
+ case FORM_BEAR:
+ case FORM_DIREBEAR:
+ {
+ // get furor proc chance
+ uint32 FurorChance = 0;
+ if (AuraEffect const *dummy = target->GetDummyAuraEffect(SPELLFAMILY_DRUID, 238, 0))
+ FurorChance = std::max(dummy->GetAmount(), 0);
+
+ switch (GetMiscValue())
+ {
+ case FORM_CAT:
+ {
+ int32 basePoints = int32(std::min(oldPower, FurorChance));
+ target->CastCustomSpell(target, 17099, &basePoints, NULL, NULL, true, NULL, this);
+ }
+ break;
+ case FORM_BEAR:
+ case FORM_DIREBEAR:
+ if (urand(0,99) < FurorChance)
+ target->CastSpell(target, 17057, true);
+ default:
+ {
+ uint32 newEnergy = std::min(target->GetPower(POWER_ENERGY), FurorChance);
+ target->SetPower(POWER_ENERGY, newEnergy);
+ }
+ break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ target->m_ShapeShiftFormSpellId = GetId();
+ target->m_form = form;
+ }
+ else
+ {
+ if(modelid > 0)
+ target->SetDisplayId(target->GetNativeDisplayId());
+ target->SetByteValue(UNIT_FIELD_BYTES_2, 3, FORM_NONE);
+ if(target->getClass() == CLASS_DRUID)
+ target->setPowerType(POWER_MANA);
+ target->m_ShapeShiftFormSpellId = 0;
+ target->m_form = FORM_NONE;
+
+ switch(form)
+ {
+ // Nordrassil Harness - bonus
+ case FORM_BEAR:
+ case FORM_DIREBEAR:
+ case FORM_CAT:
+ if(AuraEffect* dummy = target->GetAuraEffect(37315, 0) )
+ target->CastSpell(target,37316,true,NULL,dummy);
+ break;
+ // Nordrassil Regalia - bonus
+ case FORM_MOONKIN:
+ if(AuraEffect* dummy = target->GetAuraEffect(37324, 0) )
+ target->CastSpell(target,37325,true,NULL,dummy);
+ break;
+ case FORM_BATTLESTANCE:
+ case FORM_DEFENSIVESTANCE:
+ case FORM_BERSERKERSTANCE:
+ {
+ uint32 Rage_val = 0;
+ // Defensive Tactics
+ if (form == FORM_DEFENSIVESTANCE)
+ {
+ if (AuraEffect const * aurEff = target->IsScriptOverriden(m_spellProto,831))
+ Rage_val += aurEff->GetAmount() * 10;
+ }
+ // Stance mastery + Tactical mastery (both passive, and last have aura only in defense stance, but need apply at any stance switch)
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ {
+ PlayerSpellMap const& sp_list = ((Player *)target)->GetSpellMap();
+ for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
+ {
+ if(itr->second->state == PLAYERSPELL_REMOVED) continue;
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
+ if (spellInfo && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && spellInfo->SpellIconID == 139)
+ Rage_val += target->CalculateSpellDamage(spellInfo,0,spellInfo->EffectBasePoints[0],target) * 10;
+ }
+ }
+ if (target->GetPower(POWER_RAGE) > Rage_val)
+ target->SetPower(POWER_RAGE,Rage_val);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ // adding/removing linked auras
+ // add/remove the shapeshift aura's boosts
+ HandleShapeshiftBoosts(target, apply);
+
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)target)->InitDataForForm();
+
+ if(target->getClass() == CLASS_DRUID)
+ {
+ // Dash
+ if(AuraEffect * aurEff =target->GetAuraEffect(SPELL_AURA_MOD_INCREASE_SPEED, SPELLFAMILY_DRUID, 0, 0, 0x8))
+ aurEff->RecalculateAmount();
+ }
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ {
+ SpellShapeshiftEntry const *shapeInfo = sSpellShapeshiftStore.LookupEntry(form);
+ // Learn spells for shapeshift form - no need to send action bars or add spells to spellbook
+ for (uint8 i = 0; i<MAX_SHAPESHIFT_SPELLS; ++i)
+ {
+ if (!shapeInfo->stanceSpell[i])
+ continue;
+ if (apply)
+ ((Player*)target)->AddTemporarySpell(shapeInfo->stanceSpell[i]);
+ else
+ ((Player*)target)->RemoveTemporarySpell(shapeInfo->stanceSpell[i]);
+ }
+ }
+}
+
+void AuraEffect::HandleAuraTransform(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if (apply)
+ {
+ // special case (spell specific functionality)
+ if(GetMiscValue()==0)
+ {
+ // player applied only
+ if (target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ switch (GetId())
+ {
+ // Orb of Deception
+ case 16739:
+ {
+ uint32 orb_model = target->GetNativeDisplayId();
+ switch(orb_model)
+ {
+ // Troll Female
+ case 1479: target->SetDisplayId(10134); break;
+ // Troll Male
+ case 1478: target->SetDisplayId(10135); break;
+ // Tauren Male
+ case 59: target->SetDisplayId(10136); break;
+ // Human Male
+ case 49: target->SetDisplayId(10137); break;
+ // Human Female
+ case 50: target->SetDisplayId(10138); break;
+ // Orc Male
+ case 51: target->SetDisplayId(10139); break;
+ // Orc Female
+ case 52: target->SetDisplayId(10140); break;
+ // Dwarf Male
+ case 53: target->SetDisplayId(10141); break;
+ // Dwarf Female
+ case 54: target->SetDisplayId(10142); break;
+ // NightElf Male
+ case 55: target->SetDisplayId(10143); break;
+ // NightElf Female
+ case 56: target->SetDisplayId(10144); break;
+ // Undead Female
+ case 58: target->SetDisplayId(10145); break;
+ // Undead Male
+ case 57: target->SetDisplayId(10146); break;
+ // Tauren Female
+ case 60: target->SetDisplayId(10147); break;
+ // Gnome Male
+ case 1563: target->SetDisplayId(10148); break;
+ // Gnome Female
+ case 1564: target->SetDisplayId(10149); break;
+ // BloodElf Female
+ case 15475: target->SetDisplayId(17830); break;
+ // BloodElf Male
+ case 15476: target->SetDisplayId(17829); break;
+ // Dranei Female
+ case 16126: target->SetDisplayId(17828); break;
+ // Dranei Male
+ case 16125: target->SetDisplayId(17827); break;
+ default: break;
+ }
+ break;
+ }
+ // Murloc costume
+ case 42365: target->SetDisplayId(21723); break;
+ default: break;
+ }
+ }
+ else
+ {
+ CreatureInfo const * ci = objmgr.GetCreatureTemplate(GetMiscValue());
+ if(!ci)
+ {
+ target->SetDisplayId(16358); // pig pink ^_^
+ sLog.outError("Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d", GetMiscValue(), GetId());
+ }
+ else
+ {
+ uint32 model_id;
+
+ if (uint32 modelid = ci->GetRandomValidModelId())
+ model_id = modelid; // Will use the default model here
+
+ // Polymorph (sheep)
+ if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_MAGE && GetSpellProto()->SpellIconID == 82 && GetSpellProto()->SpellVisual[0] == 12978)
+ if (Unit * caster = GetCaster())
+ if (caster->HasAura(52648)) // Glyph of the Penguin
+ model_id = 26452;
+
+ target->SetDisplayId(model_id);
+
+ // Dragonmaw Illusion (set mount model also)
+ if(GetId()==42016 && target->GetMountID() && !target->GetAuraEffectsByType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED).empty())
+ target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
+ }
+ }
+
+ // update active transform spell only not set or not overwriting negative by positive case
+ if (!target->getTransForm() || !IsPositiveSpell(GetId()) || IsPositiveSpell(target->getTransForm()))
+ target->setTransForm(GetId());
+
+ // polymorph case
+ if ((mode & AURA_EFFECT_HANDLE_REAL) && target->GetTypeId() == TYPEID_PLAYER && target->IsPolymorphed())
+ {
+ // for players, start regeneration after 1s (in polymorph fast regeneration case)
+ // only if caster is Player (after patch 2.4.2)
+ if (IS_PLAYER_GUID(GetCasterGUID()) )
+ ((Player*)target)->setRegenTimerCount(1*IN_MILISECONDS);
+
+ //dismount polymorphed target (after patch 2.4.2)
+ if (target->IsMounted())
+ target->RemoveAurasByType(SPELL_AURA_MOUNTED);
+ }
+ }
+ else
+ {
+ // HandleEffect(this, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true) will reapply it if need
+ target->setTransForm(0);
+ target->SetDisplayId(target->GetNativeDisplayId());
+
+ // re-aplly some from still active with preference negative cases
+ Unit::AuraEffectList const& otherTransforms = target->GetAuraEffectsByType(SPELL_AURA_TRANSFORM);
+ if (!otherTransforms.empty())
+ {
+ // look for other transform auras
+ AuraEffect* handledAura = *otherTransforms.begin();
+ for (Unit::AuraEffectList::const_iterator i = otherTransforms.begin(); i != otherTransforms.end(); ++i)
+ {
+ // negative auras are preferred
+ if (!IsPositiveSpell((*i)->GetSpellProto()->Id))
+ {
+ handledAura = *i;
+ break;
+ }
+ }
+ handledAura->HandleEffect(target, AURA_EFFECT_HANDLE_SEND_FOR_CLIENT, true);
+ }
+
+ // Dragonmaw Illusion (restore mount model)
+ if (GetId() == 42016 && target->GetMountID() == 16314)
+ {
+ if (!target->GetAuraEffectsByType(SPELL_AURA_MOUNTED).empty())
+ {
+ uint32 cr_id = target->GetAuraEffectsByType(SPELL_AURA_MOUNTED).front()->GetMiscValue();
+ if(CreatureInfo const* ci = objmgr.GetCreatureTemplate(cr_id))
+ {
+ uint32 team = 0;
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ team = ((Player*)target)->GetTeam();
+
+ uint32 display_id = objmgr.ChooseDisplayId(team,ci);
+ CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
+ if (minfo)
+ display_id = minfo->modelid;
+
+ target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,display_id);
+ }
+ }
+ }
+ }
+}
+
+void AuraEffect::HandleAuraModScale(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,GetAmount(),apply);
+}
+
+void AuraEffect::HandleAuraCloneCaster(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if (apply)
+ {
+ Unit * caster = GetCaster();
+ if (!caster)
+ return;
+ // Set display id (probably for portrait?)
+ target->SetDisplayId(caster->GetDisplayId());
+ target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_MIRROR_IMAGE);
+ }
+ else
+ {
+ target->SetDisplayId(target->GetNativeDisplayId());
+ target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_MIRROR_IMAGE);
+ }
+}
+
+/************************/
+/*** FIGHT ***/
+/************************/
+
+void AuraEffect::HandleFeignDeath(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if( apply )
+ {
+ /*
+ WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
+ data<<target->GetGUID();
+ data<<uint8(0);
+ target->SendMessageToSet(&data,true);
+ */
+
+ UnitList targets;
+ Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(target, target, target->GetMap()->GetVisibilityDistance());
+ Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(target, targets, u_check);
+ target->VisitNearbyObject(target->GetMap()->GetVisibilityDistance(), searcher);
+ for (UnitList::iterator iter = targets.begin(); iter != targets.end(); ++iter)
+ {
+ if(!(*iter)->hasUnitState(UNIT_STAT_CASTING))
+ continue;
+
+ for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++)
+ {
+ if((*iter)->GetCurrentSpell(i)
+ && (*iter)->GetCurrentSpell(i)->m_targets.getUnitTargetGUID() == target->GetGUID())
+ {
+ (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
+ }
+ }
+ }
+ // blizz like 2.0.x
+ target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
+ // blizz like 2.0.x
+ target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
+ // blizz like 2.0.x
+ target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
+
+ target->addUnitState(UNIT_STAT_DIED);
+ target->CombatStop();
+ target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
+
+ // prevent interrupt message
+ if(GetCasterGUID()==target->GetGUID() && target->GetCurrentSpell(CURRENT_GENERIC_SPELL))
+ target->FinishSpell(CURRENT_GENERIC_SPELL, false);
+ target->InterruptNonMeleeSpells(true);
+ target->getHostilRefManager().deleteReferences();
+ }
+ else
+ {
+ /*
+ WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
+ data<<target->GetGUID();
+ data<<uint8(1);
+ target->SendMessageToSet(&data,true);
+ */
+ // blizz like 2.0.x
+ target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
+ // blizz like 2.0.x
+ target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
+ // blizz like 2.0.x
+ target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
+
+ target->clearUnitState(UNIT_STAT_DIED);
+ }
+}
+
+void AuraEffect::HandleModUnattackable(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(apply)
+ {
+ if (mode & AURA_EFFECT_HANDLE_REAL)
+ {
+ target->CombatStop();
+ target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
+ }
+ }
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ else if (target->HasAuraType(SPELL_AURA_MOD_UNATTACKABLE))
+ return;
+
+ target->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE, apply);
+}
+
+void AuraEffect::HandleAuraModDisarm(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ AuraType type = GetAuraType();
+
+ //Prevent handling aura twice
+ if((apply) ? target->GetAuraEffectsByType(type).size() > 1 : target->HasAuraType(type))
+ return;
+
+ uint32 field, flag, slot;
+ WeaponAttackType attType;
+ switch (type)
+ {
+ case SPELL_AURA_MOD_DISARM:
+ field=UNIT_FIELD_FLAGS;
+ flag=UNIT_FLAG_DISARMED;
+ slot=EQUIPMENT_SLOT_MAINHAND;
+ attType=BASE_ATTACK;
+ break;
+ case SPELL_AURA_MOD_DISARM_OFFHAND:
+ field=UNIT_FIELD_FLAGS_2;
+ flag=UNIT_FLAG2_DISARM_OFFHAND;
+ slot=EQUIPMENT_SLOT_OFFHAND;
+ attType=OFF_ATTACK;
+ break;
+ case SPELL_AURA_MOD_DISARM_RANGED:
+ field=UNIT_FIELD_FLAGS_2;
+ flag=UNIT_FLAG2_DISARM_RANGED;
+ slot=EQUIPMENT_SLOT_RANGED;
+ attType=RANGED_ATTACK;
+ break;
+ default:
+ return;
+ }
+
+ if(!(apply))
+ target->RemoveFlag(field, flag);
+
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ {
+ // This is between the two because there is a check in _ApplyItemMods
+ // we must make sure that flag is always removed when call that function
+ // refer to DurabilityPointsLoss
+ if(Item *pItem = ((Player*)target)->GetItemByPos( INVENTORY_SLOT_BAG_0, slot ))
+ ((Player*)target)->_ApplyItemMods(pItem, slot, !apply);
+ }
+
+ if(apply)
+ target->SetFlag(field, flag);
+
+ if (target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->GetCurrentEquipmentId())
+ target->UpdateDamagePhysical(attType);
+}
+
+void AuraEffect::HandleAuraModSilence(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(apply)
+ {
+ target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED);
+ // Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE
+ for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i)
+ if (Spell* spell = target->GetCurrentSpell(CurrentSpellTypes(i)))
+ if(spell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
+ // Stop spells on prepare or casting state
+ target->InterruptSpell(CurrentSpellTypes(i), false);
+ }
+ else
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if(target->HasAuraType(SPELL_AURA_MOD_SILENCE) || target->HasAuraType(SPELL_AURA_MOD_PACIFY_SILENCE))
+ return;
+
+ target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED);
+ }
+}
+
+void AuraEffect::HandleAuraModPacify(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(apply)
+ target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
+ else
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if(target->HasAuraType(SPELL_AURA_MOD_PACIFY) || target->HasAuraType(SPELL_AURA_MOD_PACIFY_SILENCE))
+ return;
+ target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
+ }
+}
+
+void AuraEffect::HandleAuraModPacifyAndSilence(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ // Vengeance of the Blue Flight (TODO: REMOVE THIS!)
+ if(m_spellProto->Id == 45839)
+ {
+ if(apply)
+ target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ else
+ target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
+ }
+ if(!(apply))
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if(target->HasAuraType(SPELL_AURA_MOD_PACIFY_SILENCE))
+ return;
+ }
+ HandleAuraModPacify(aurApp, mode, apply);
+ HandleAuraModSilence(aurApp, mode, apply);
+}
+
+void AuraEffect::HandleAuraAllowOnlyAbility(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (apply)
+ target->SetFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY);
+ else
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if(target->HasAuraType(SPELL_AURA_ALLOW_ONLY_ABILITY))
+ return;
+ target->RemoveFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY);
+ }
+ }
+}
+
+/****************************/
+/*** TRACKING ***/
+/****************************/
+
+void AuraEffect::HandleAuraTrackCreatures(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ target->SetUInt32Value(PLAYER_TRACK_CREATURES, (apply) ? ((uint32)1)<<(GetMiscValue()-1) : 0 );
+}
+
+void AuraEffect::HandleAuraTrackResources(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ target->SetUInt32Value(PLAYER_TRACK_RESOURCES, (apply) ? ((uint32)1)<<(GetMiscValue()-1): 0 );
+}
+
+void AuraEffect::HandleAuraTrackStealthed(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if(!(apply))
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if(target->HasAuraType(GetAuraType()))
+ return;
+ }
+ target->ApplyModFlag(PLAYER_FIELD_BYTES,PLAYER_FIELD_BYTE_TRACK_STEALTHED,apply);
+}
+
+void AuraEffect::HandleAuraModStalked(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ // used by spells: Hunter's Mark, Mind Vision, Syndicate Tracker (MURP) DND
+ if(apply)
+ target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT);
+ else
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if(target->HasAuraType(GetAuraType()))
+ return;
+
+ target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT);
+ }
+}
+
+void AuraEffect::HandleAuraUntrackable(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(apply)
+ target->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_UNTRACKABLE);
+ else
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if(target->HasAuraType(GetAuraType()))
+ return;
+ target->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_UNTRACKABLE);
+ }
+}
+
+/****************************/
+/*** SKILLS & TALENTS ***/
+/****************************/
+
+void AuraEffect::HandleAuraModPetTalentsPoints(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ // Recalculate pet talent points
+ if (Pet *pet = ((Player*)target)->GetPet())
+ pet->InitTalentForLevel();
+}
+
+void AuraEffect::HandleAuraModSkill(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ uint32 prot = GetSpellProto()->EffectMiscValue[m_effIndex];
+ int32 points = GetAmount();
+
+ ((Player*)target)->ModifySkillBonus(prot,((apply) ? points: -points),GetAuraType() == SPELL_AURA_MOD_SKILL_TALENT);
+ if(prot == SKILL_DEFENSE)
+ ((Player*)target)->UpdateDefenseBonusesMod();
+}
+
+/****************************/
+/*** MOVEMENT ***/
+/****************************/
+
+void AuraEffect::HandleAuraMounted(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(apply)
+ {
+ CreatureInfo const* ci = objmgr.GetCreatureTemplate(GetMiscValue());
+ if(!ci)
+ {
+ sLog.outErrorDb("AuraMounted: `creature_template`='%u' not found in database (only need it modelid)",GetMiscValue());
+ return;
+ }
+
+ uint32 team = 0;
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ team = ((Player*)target)->GetTeam();
+
+ uint32 display_id = objmgr.ChooseDisplayId(team,ci);
+ CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
+ if (minfo)
+ display_id = minfo->modelid;
+
+ //some spell has one aura of mount and one of vehicle
+ for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if(GetSpellProto()->Effect[i] == SPELL_EFFECT_SUMMON
+ && GetSpellProto()->EffectMiscValue[i] == GetMiscValue())
+ display_id = 0;
+ target->Mount(display_id);
+ }
+ else
+ {
+ target->Unmount();
+ //some mounts like Headless Horseman's Mount or broom stick are skill based spell
+ // need to remove ALL arura related to mounts, this will stop client crash with broom stick
+ // and never endless flying after using Headless Horseman's Mount
+ if(mode & AURA_EFFECT_HANDLE_REAL)
+ target->RemoveAurasByType(SPELL_AURA_MOUNTED);
+ }
+}
+
+void AuraEffect::HandleAuraAllowFlight(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(!apply)
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if(target->HasAuraType(GetAuraType()) || target->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED))
+ return;
+ }
+
+ if(target->GetTypeId() == TYPEID_UNIT)
+ target->SetFlying(apply);
+
+ if(Player *plr = target->m_movedPlayer)
+ {
+ // allow fly
+ WorldPacket data;
+ if(apply)
+ data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);
+ else
+ data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12);
+ data.append(target->GetPackGUID());
+ data << uint32(0); // unk
+ plr->SendDirectMessage(&data);
+ }
+}
+
+void AuraEffect::HandleAuraWaterWalk(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(!(apply))
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if(target->HasAuraType(GetAuraType()))
+ return;
+ }
+
+ WorldPacket data;
+ if(apply)
+ data.Initialize(SMSG_MOVE_WATER_WALK, 8+4);
+ else
+ data.Initialize(SMSG_MOVE_LAND_WALK, 8+4);
+ data.append(target->GetPackGUID());
+ data << uint32(0);
+ target->SendMessageToSet(&data,true);
+}
+
+void AuraEffect::HandleAuraFeatherFall(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(!(apply))
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if(target->HasAuraType(GetAuraType()))
+ return;
+ }
+
+ WorldPacket data;
+ if (apply)
+ data.Initialize(SMSG_MOVE_FEATHER_FALL, 8+4);
+ else
+ data.Initialize(SMSG_MOVE_NORMAL_FALL, 8+4);
+ data.append(target->GetPackGUID());
+ data << uint32(0);
+ target->SendMessageToSet(&data, true);
+
+ // start fall from current height
+ if(!apply && target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)target)->SetFallInformation(0, target->GetPositionZ());
+}
+
+void AuraEffect::HandleAuraHover(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(!(apply))
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if(target->HasAuraType(GetAuraType()))
+ return;
+ }
+
+ WorldPacket data;
+ if(apply)
+ data.Initialize(SMSG_MOVE_SET_HOVER, 8+4);
+ else
+ data.Initialize(SMSG_MOVE_UNSET_HOVER, 8+4);
+ data.append(target->GetPackGUID());
+ data << uint32(0);
+ target->SendMessageToSet(&data,true);
+}
+
+void AuraEffect::HandleWaterBreathing(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ // update timers in client
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)target)->UpdateMirrorTimers();
+}
+
+void AuraEffect::HandleForceMoveForward(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if(apply)
+ target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE);
+ else
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if(target->HasAuraType(GetAuraType()))
+ return;
+ target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE);
+ }
+}
+
+/****************************/
+/*** THREAT ***/
+/****************************/
+
+void AuraEffect::HandleModThreat(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if (!target->isAlive())
+ return;
+
+ Unit * caster = GetCaster();
+ if (!caster || !caster->isAlive())
+ return;
+
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ for (int8 x=0; x < MAX_SPELL_SCHOOL; x++)
+ if (GetMiscValue() & int32(1<<x))
+ ApplyPercentModFloatVar(target->m_threatModifier[x], GetAmount(), apply);
+}
+
+void AuraEffect::HandleAuraModTotalThreat(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if (!target->isAlive() || target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Unit * caster = GetCaster();
+ if (!caster || !caster->isAlive())
+ return;
+
+ float threatMod = (apply) ? float(GetAmount()) : float(-GetAmount());
+
+ target->getHostilRefManager().threatAssist(caster, threatMod);
+}
+
+void AuraEffect::HandleModTaunt(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if (!target->isAlive() || !target->CanHaveThreatList())
+ return;
+
+ Unit * caster = GetCaster();
+ if (!caster || !caster->isAlive())
+ return;
+
+ if (apply)
+ target->TauntApply(caster);
+ else
+ {
+ // When taunt aura fades out, mob will switch to previous target if current has less than 1.1 * secondthreat
+ target->TauntFadeOut(caster);
+ }
+}
+
+/*****************************/
+/*** CONTROL ***/
+/*****************************/
+
+void AuraEffect::HandleModConfuse(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->SetControlled(apply, UNIT_STAT_CONFUSED);
+}
+
+void AuraEffect::HandleModFear(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->SetControlled(apply, UNIT_STAT_FLEEING);
+}
+
+void AuraEffect::HandleAuraModStun(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->SetControlled(apply, UNIT_STAT_STUNNED);
+}
+
+void AuraEffect::HandleAuraModRoot(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->SetControlled(apply, UNIT_STAT_ROOT);
+}
+
+void AuraEffect::HandlePreventFleeing(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ Unit::AuraEffectList const& fearAuras = target->GetAuraEffectsByType(SPELL_AURA_MOD_FEAR);
+ if( !fearAuras.empty() )
+ target->SetControlled(!(apply), UNIT_STAT_FLEEING);
+}
+
+/***************************/
+/*** CHARM ***/
+/***************************/
+
+void AuraEffect::HandleModPossess(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ Unit * caster = GetCaster();
+ if(caster && caster->GetTypeId() == TYPEID_UNIT)
+ {
+ HandleModCharm(aurApp, mode, apply);
+ return;
+ }
+
+ if(apply)
+ target->SetCharmedBy(caster, CHARM_TYPE_POSSESS);
+ else
+ target->RemoveCharmedBy(caster);
+}
+
+// only one spell has this aura
+void AuraEffect::HandleModPossessPet(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ Unit * caster = GetCaster();
+ if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ //seems it may happen that when removing it is no longer owner's pet
+ //if(((Player*)caster)->GetPet() != target)
+ // return;
+
+ if(apply)
+ {
+ if(((Player*)caster)->GetPet() != target)
+ return;
+
+ target->SetCharmedBy(caster, CHARM_TYPE_POSSESS);
+ }
+ else
+ {
+ target->RemoveCharmedBy(caster);
+
+ // Reinitialize the pet bar and make the pet come back to the owner
+ ((Player*)caster)->PetSpellInitialize();
+ if(!target->getVictim())
+ {
+ target->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, target->GetFollowAngle());
+ //if(target->GetCharmInfo())
+ // target->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
+ }
+ }
+}
+
+void AuraEffect::HandleModCharm(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ Unit * caster = GetCaster();
+
+ if(apply)
+ target->SetCharmedBy(caster, CHARM_TYPE_CHARM);
+ else
+ target->RemoveCharmedBy(caster);
+}
+
+void AuraEffect::HandleCharmConvert(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ Unit * caster = GetCaster();
+
+ if(apply)
+ target->SetCharmedBy(caster, CHARM_TYPE_CONVERT);
+ else
+ target->RemoveCharmedBy(caster);
+}
+
+/**
+ * Such auras are applied from a caster(=player) to a vehicle.
+ * This has been verified using spell #49256
+ */
+void AuraEffect::HandleAuraControlVehicle(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(!target->IsVehicle())
+ return;
+
+ Unit * caster = GetCaster();
+
+ if(!caster || caster == target)
+ return;
+
+ if (apply)
+ {
+ //if(caster->GetTypeId() == TYPEID_PLAYER)
+ // if(Pet *pet = ((Player*)caster)->GetPet())
+ // pet->Remove(PET_SAVE_AS_CURRENT);
+ caster->EnterVehicle(target->GetVehicleKit(), m_amount - 1);
+ }
+ else
+ {
+ if(GetId() == 53111) // Devour Humanoid
+ {
+ target->Kill(caster);
+ if(caster->GetTypeId() == TYPEID_UNIT)
+ ((Creature*)caster)->RemoveCorpse();
+ }
+
+ // some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
+ caster->RemoveAurasDueToSpell(GetId());
+ caster->ExitVehicle();
+ }
+}
+
+/*********************************************************/
+/*** MODIFY SPEED ***/
+/*********************************************************/
+void AuraEffect::HandleAuraModIncreaseSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->UpdateSpeed(MOVE_RUN, true);
+}
+
+void AuraEffect::HandleAuraModIncreaseMountedSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->UpdateSpeed(MOVE_RUN, true);
+}
+
+void AuraEffect::HandleAuraModIncreaseFlightSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ // Enable Fly mode for flying mounts
+ if (GetAuraType() == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED)
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if (mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK && (apply || (!target->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !target->HasAuraType(SPELL_AURA_FLY))))
+ {
+ WorldPacket data;
+ if(apply)
+ data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);
+ else
+ data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12);
+ data.append(target->GetPackGUID());
+ data << uint32(0); // unknown
+ target->SendMessageToSet(&data, true);
+ }
+
+ if (mode & AURA_EFFECT_HANDLE_REAL)
+ {
+ //Players on flying mounts must be immune to polymorph
+ if (target->GetTypeId() == TYPEID_PLAYER)
+ target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_POLYMORPH,apply);
+
+ // Dragonmaw Illusion (overwrite mount model, mounted aura already applied)
+ if( apply && target->HasAuraEffect(42016,0) && target->GetMountID())
+ target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
+ }
+ }
+
+ if(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK)
+ target->UpdateSpeed(MOVE_FLIGHT, true);
+}
+
+void AuraEffect::HandleAuraModIncreaseSwimSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->UpdateSpeed(MOVE_SWIM, true);
+}
+
+void AuraEffect::HandleAuraModDecreaseSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->UpdateSpeed(MOVE_RUN, true);
+ target->UpdateSpeed(MOVE_SWIM, true);
+ target->UpdateSpeed(MOVE_FLIGHT, true);
+ target->UpdateSpeed(MOVE_RUN_BACK, true);
+ target->UpdateSpeed(MOVE_SWIM_BACK, true);
+ target->UpdateSpeed(MOVE_FLIGHT_BACK, true);
+}
+
+void AuraEffect::HandleAuraModUseNormalSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->UpdateSpeed(MOVE_RUN, true);
+ target->UpdateSpeed(MOVE_SWIM, true);
+ target->UpdateSpeed(MOVE_FLIGHT, true);
+}
+
+/*********************************************************/
+/*** IMMUNITY ***/
+/*********************************************************/
+
+void AuraEffect::HandleModStateImmunityMask(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ std::list <AuraType> immunity_list;
+ if (GetMiscValue() & (1<<10))
+ immunity_list.push_back(SPELL_AURA_MOD_STUN);
+ if (GetMiscValue() & (1<<7))
+ immunity_list.push_back(SPELL_AURA_MOD_DISARM);
+ if (GetMiscValue() & (1<<1))
+ immunity_list.push_back(SPELL_AURA_TRANSFORM);
+
+ // These flag can be recognized wrong:
+ if (GetMiscValue() & (1<<6))
+ immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
+ if (GetMiscValue() & (1<<0))
+ immunity_list.push_back(SPELL_AURA_MOD_ROOT);
+ if (GetMiscValue() & (1<<2))
+ immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
+ if (GetMiscValue() & (1<<9))
+ immunity_list.push_back(SPELL_AURA_MOD_FEAR);
+
+ // Patch 3.0.3 Bladestorm now breaks all snares and roots on the warrior when activated.
+ // however not all mechanic specified in immunity
+ if (apply && GetId()==46924)
+ {
+ target->RemoveAurasByType(SPELL_AURA_MOD_ROOT);
+ target->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
+ }
+
+ if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
+ {
+ for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter)
+ {
+ target->RemoveAurasByType(*iter);
+ }
+ }
+ for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter)
+ {
+ target->ApplySpellImmune(GetId(),IMMUNITY_STATE,*iter, apply);
+ }
+}
+
+void AuraEffect::HandleModMechanicImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ uint32 mechanic;
+ mechanic = 1 << GetMiscValue();
+
+ //immune movement impairment and loss of control
+ if(GetId()==42292 || GetId()==59752)
+ mechanic=IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;
+ // Forbearance
+ // in DBC wrong mechanic immune since 3.0.x
+ else if (GetId() == 25771)
+ mechanic = 1 << MECHANIC_IMMUNE_SHIELD;
+
+ if (!mechanic)
+ return;
+
+ if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
+ {
+ Unit::AuraApplicationMap& Auras = target->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
+ {
+ SpellEntry const *spell = iter->second->GetBase()->GetSpellProto();
+ if (spell->Id != GetId())
+ {
+ //check for mechanic mask
+ if(GetAllSpellMechanicMask(spell) & mechanic)
+ {
+ target->RemoveAura(iter);
+ }
+ else
+ ++iter;
+ }
+ else
+ ++iter;
+ }
+ }
+
+ target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,GetMiscValue(), apply);
+
+ // Demonic Empowerment -- voidwalker -- missing movement impairing effects immunity
+ if (GetId() == 54508)
+ {
+ if (apply)
+ target->RemoveMovementImpairingAuras();
+
+ target->ApplySpellImmune(GetId(),IMMUNITY_STATE,SPELL_AURA_MOD_ROOT, apply);
+ target->ApplySpellImmune(GetId(),IMMUNITY_STATE,SPELL_AURA_MOD_DECREASE_SPEED, apply);
+ }
+}
+
+void AuraEffect::HandleAuraModEffectImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ // when removing flag aura, handle flag drop
+ if( !(apply) && target->GetTypeId() == TYPEID_PLAYER
+ && (GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION) )
+ {
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(((Player*)target)->InBattleGround())
+ {
+ if( BattleGround *bg = ((Player*)target)->GetBattleGround() )
+ bg->EventPlayerDroppedFlag(((Player*)target));
+ }
+ else
+ sOutdoorPvPMgr.HandleDropFlag((Player*)target,GetSpellProto()->Id);
+ }
+ }
+
+ target->ApplySpellImmune(GetId(),IMMUNITY_EFFECT,GetMiscValue(),apply);
+}
+
+void AuraEffect::HandleAuraModStateImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if((apply) && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
+ {
+ target->RemoveAurasByType(AuraType(GetMiscValue()), NULL , GetBase());
+ }
+
+ target->ApplySpellImmune(GetId(), IMMUNITY_STATE, GetMiscValue(), apply);
+}
+
+void AuraEffect::HandleAuraModSchoolImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if((apply) && GetMiscValue() == SPELL_SCHOOL_MASK_NORMAL)
+ target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
+
+ target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,GetMiscValue(),(apply));
+
+ // remove all flag auras (they are positive, but they must be removed when you are immune)
+ if( GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY
+ && GetSpellProto()->AttributesEx2 & SPELL_ATTR_EX2_DAMAGE_REDUCED_SHIELD )
+ target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
+
+ // TODO: optimalize this cycle - use RemoveAurasWithInterruptFlags call or something else
+ if((apply)
+ && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY
+ && IsPositiveSpell(GetId()) ) //Only positive immunity removes auras
+ {
+ uint32 school_mask = GetMiscValue();
+ Unit::AuraApplicationMap& Auras = target->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
+ {
+ SpellEntry const *spell = iter->second->GetBase()->GetSpellProto();
+ if((GetSpellSchoolMask(spell) & school_mask)//Check for school mask
+ && IsDispelableBySpell(GetSpellProto(),spell->Id, true)
+ && !iter->second->IsPositive() //Don't remove positive spells
+ && spell->Id != GetId() ) //Don't remove self
+ {
+ target->RemoveAura(iter);
+ }
+ else
+ ++iter;
+ }
+ }
+ if(GetSpellProto()->Mechanic == MECHANIC_BANISH)
+ {
+ if( apply )
+ target->addUnitState(UNIT_STAT_ISOLATED);
+ else
+ {
+ bool banishFound = false;
+ Unit::AuraEffectList const& banishAuras = target->GetAuraEffectsByType(GetAuraType());
+ for (Unit::AuraEffectList::const_iterator i = banishAuras.begin(); i != banishAuras.end(); ++i)
+ if ((*i)->GetSpellProto()->Mechanic == MECHANIC_BANISH)
+ {
+ banishFound = true;
+ break;
+ }
+ if (!banishFound)
+ target->clearUnitState(UNIT_STAT_ISOLATED);
+ }
+ }
+}
+
+void AuraEffect::HandleAuraModDmgImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->ApplySpellImmune(GetId(),IMMUNITY_DAMAGE,GetMiscValue(), apply);
+}
+
+void AuraEffect::HandleAuraModDispelImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->ApplySpellDispelImmunity(m_spellProto, DispelType(GetMiscValue()), (apply));
+}
+
+/*********************************************************/
+/*** MODIFY STATS ***/
+/*********************************************************/
+
+/********************************/
+/*** RESISTANCE ***/
+/********************************/
+
+void AuraEffect::HandleAuraModResistanceExclusive(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
+ {
+ if(GetMiscValue() & int32(1<<x))
+ {
+ target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_VALUE, float(GetAmount()), apply);
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ target->ApplyResistanceBuffModsMod(SpellSchools(x),aurApp->IsPositive(),GetAmount(), apply);
+ }
+ }
+}
+
+void AuraEffect::HandleAuraModResistance(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
+ {
+ if(GetMiscValue() & int32(1<<x))
+ {
+ target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(GetAmount()), apply);
+ if(target->GetTypeId() == TYPEID_PLAYER || ((Creature*)target)->isPet())
+ target->ApplyResistanceBuffModsMod(SpellSchools(x),GetAmount() > 0,GetAmount(), apply);
+ }
+ }
+}
+
+void AuraEffect::HandleAuraModBaseResistancePCT(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ // only players have base stats
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ {
+ //pets only have base armor
+ if(((Creature*)target)->isPet() && (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
+ target->HandleStatModifier(UNIT_MOD_ARMOR, BASE_PCT, float(GetAmount()), apply);
+ }
+ else
+ {
+ for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
+ {
+ if(GetMiscValue() & int32(1<<x))
+ target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(GetAmount()), apply);
+ }
+ }
+}
+
+void AuraEffect::HandleModResistancePercent(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ for (int8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
+ {
+ if(GetMiscValue() & int32(1<<i))
+ {
+ target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, float(GetAmount()), apply);
+ if(target->GetTypeId() == TYPEID_PLAYER || ((Creature*)target)->isPet())
+ {
+ target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,GetAmount(), apply);
+ target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,GetAmount(), apply);
+ }
+ }
+ }
+}
+
+void AuraEffect::HandleModBaseResistance(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ // only players have base stats
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ {
+ //only pets have base stats
+ if(((Creature*)target)->isPet() && (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
+ target->HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(GetAmount()), apply);
+ }
+ else
+ {
+ for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
+ if(GetMiscValue() & (1<<i))
+ target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(GetAmount()), apply);
+ }
+}
+
+void AuraEffect::HandleModTargetResistance(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ // applied to damage as HandleNoImmediateEffect in Unit::CalcAbsorbResist and Unit::CalcArmorReducedDamage
+
+ // show armor penetration
+ if (target->GetTypeId() == TYPEID_PLAYER && (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
+ target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,GetAmount(), apply);
+
+ // show as spell penetration only full spell penetration bonuses (all resistances except armor and holy
+ if (target->GetTypeId() == TYPEID_PLAYER && (GetMiscValue() & SPELL_SCHOOL_MASK_SPELL)==SPELL_SCHOOL_MASK_SPELL)
+ target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE,GetAmount(), apply);
+}
+
+/********************************/
+/*** STAT ***/
+/********************************/
+
+void AuraEffect::HandleAuraModStat(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if (GetMiscValue() < -2 || GetMiscValue() > 4)
+ {
+ sLog.outError("WARNING: Spell %u effect %u have unsupported misc value (%i) for SPELL_AURA_MOD_STAT ",GetId(),GetEffIndex(),GetMiscValue());
+ return;
+ }
+
+ for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
+ {
+ // -1 or -2 is all stats ( misc < -2 checked in function beginning )
+ if (GetMiscValue() < 0 || GetMiscValue() == i)
+ {
+ //target->ApplyStatMod(Stats(i), m_amount,apply);
+ target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(GetAmount()), apply);
+ if(target->GetTypeId() == TYPEID_PLAYER || ((Creature*)target)->isPet())
+ target->ApplyStatBuffMod(Stats(i),GetAmount(),apply);
+ }
+ }
+}
+
+void AuraEffect::HandleModPercentStat(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if (GetMiscValue() < -1 || GetMiscValue() > 4)
+ {
+ sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
+ return;
+ }
+
+ // only players have base stats
+ if (target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
+ {
+ if(GetMiscValue() == i || GetMiscValue() == -1)
+ target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(m_amount), apply);
+ }
+}
+
+void AuraEffect::HandleModSpellDamagePercentFromStat(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ // Magic damage modifiers implemented in Unit::SpellDamageBonus
+ // This information for client side use only
+ // Recalculate bonus
+ ((Player*)target)->UpdateSpellDamageAndHealingBonus();
+}
+
+void AuraEffect::HandleModSpellHealingPercentFromStat(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ // Recalculate bonus
+ ((Player*)target)->UpdateSpellDamageAndHealingBonus();
+}
+
+void AuraEffect::HandleModSpellDamagePercentFromAttackPower(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ // Magic damage modifiers implemented in Unit::SpellDamageBonus
+ // This information for client side use only
+ // Recalculate bonus
+ ((Player*)target)->UpdateSpellDamageAndHealingBonus();
+}
+
+void AuraEffect::HandleModSpellHealingPercentFromAttackPower(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ // Recalculate bonus
+ ((Player*)target)->UpdateSpellDamageAndHealingBonus();
+}
+
+void AuraEffect::HandleModHealingDone(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+ // implemented in Unit::SpellHealingBonus
+ // this information is for client side only
+ ((Player*)target)->UpdateSpellDamageAndHealingBonus();
+}
+
+void AuraEffect::HandleModTotalPercentStat(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if (GetMiscValue() < -1 || GetMiscValue() > 4)
+ {
+ sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
+ return;
+ }
+
+ //save current and max HP before applying aura
+ uint32 curHPValue = target->GetHealth();
+ uint32 maxHPValue = target->GetMaxHealth();
+
+ for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
+ {
+ if(GetMiscValue() == i || GetMiscValue() == -1)
+ {
+ target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(GetAmount()), apply);
+ if(target->GetTypeId() == TYPEID_PLAYER || ((Creature*)target)->isPet())
+ target->ApplyStatPercentBuffMod(Stats(i), GetAmount(), apply );
+ }
+ }
+
+ //recalculate current HP/MP after applying aura modifications (only for spells with 0x10 flag)
+ if ((GetMiscValue() == STAT_STAMINA) && (maxHPValue > 0) && (m_spellProto->Attributes & 0x10))
+ {
+ // newHP = (curHP / maxHP) * newMaxHP = (newMaxHP * curHP) / maxHP -> which is better because no int -> double -> int conversion is needed
+ uint32 newHPValue = (target->GetMaxHealth() * curHPValue) / maxHPValue;
+ target->SetHealth(newHPValue);
+ }
+}
+
+void AuraEffect::HandleAuraModResistenceOfStatPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ if(GetMiscValue() != SPELL_SCHOOL_MASK_NORMAL)
+ {
+ // support required adding replace UpdateArmor by loop by UpdateResistence at intellect update
+ // and include in UpdateResistence same code as in UpdateArmor for aura mod apply.
+ sLog.outError("Aura SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT(182) need adding support for non-armor resistances!");
+ return;
+ }
+
+ // Recalculate Armor
+ target->UpdateArmor();
+}
+
+void AuraEffect::HandleAuraModExpertise(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ ((Player*)target)->UpdateExpertise(BASE_ATTACK);
+ ((Player*)target)->UpdateExpertise(OFF_ATTACK);
+}
+
+/********************************/
+/*** HEAL & ENERGIZE ***/
+/********************************/
+void AuraEffect::HandleModPowerRegen(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if (target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ // Update manaregen value
+ if (GetMiscValue() == POWER_MANA)
+ ((Player*)target)->UpdateManaRegen();
+ // other powers are not immediate effects - implemented in Player::Regenerate, Creature::Regenerate
+}
+
+void AuraEffect::HandleModPowerRegenPCT(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if (target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ // Update manaregen value
+ if (GetMiscValue() == POWER_MANA)
+ ((Player*)target)->UpdateManaRegen();
+ // other powers are not immediate effects - implemented in Player::Regenerate, Creature::Regenerate
+}
+
+void AuraEffect::HandleModManaRegen(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if (target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ //Note: an increase in regen does NOT cause threat.
+ ((Player*)target)->UpdateManaRegen();
+}
+
+void AuraEffect::HandleAuraModIncreaseHealth(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(apply)
+ {
+ target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
+ target->ModifyHealth(GetAmount());
+ }
+ else
+ {
+ if (int32(target->GetHealth()) > GetAmount())
+ target->ModifyHealth(-GetAmount());
+ else
+ target->SetHealth(1);
+ target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
+ }
+}
+
+void AuraEffect::HandleAuraModIncreaseMaxHealth(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ uint32 oldhealth = target->GetHealth();
+ double healthPercentage = (double)oldhealth / (double)target->GetMaxHealth();
+
+ target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(GetAmount()), apply);
+
+ // refresh percentage
+ if(oldhealth > 0)
+ {
+ uint32 newhealth = uint32(ceil((double)target->GetMaxHealth() * healthPercentage));
+ if(newhealth==0)
+ newhealth = 1;
+
+ target->SetHealth(newhealth);
+ }
+}
+
+void AuraEffect::HandleAuraModIncreaseEnergy(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ Powers powerType = target->getPowerType();
+ if(int32(powerType) != GetMiscValue())
+ return;
+
+ UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
+
+ // Special case with temporary increase max/current power (percent)
+ if (GetId()==64904) // Hymn of Hope
+ {
+ if(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK)
+ target->SetPower(powerType, apply ? GetAmount() + target->GetPower(powerType) : target->GetPower(powerType) - GetAmount());
+ }
+
+ // generic flat case
+ target->HandleStatModifier(unitMod, TOTAL_VALUE, float(GetAmount()), apply);
+}
+
+void AuraEffect::HandleAuraModIncreaseEnergyPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ Powers powerType = target->getPowerType();
+ if(int32(powerType) != GetMiscValue())
+ return;
+
+ UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
+
+ target->HandleStatModifier(unitMod, TOTAL_PCT, float(GetAmount()), apply);
+}
+
+void AuraEffect::HandleAuraModIncreaseHealthPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ // Unit will keep hp% after MaxHealth being modified if unit is alive.
+ float percent = ((float)target->GetHealth()) / target->GetMaxHealth();
+ target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(GetAmount()), apply);
+ if (target->isAlive())
+ target->SetHealth(uint32(target->GetMaxHealth()*percent));
+}
+
+void AuraEffect::HandleAuraIncreaseBaseHealthPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->HandleStatModifier(UNIT_MOD_HEALTH, BASE_PCT, float(GetAmount()), apply);
+}
+
+/********************************/
+/*** FIGHT ***/
+/********************************/
+
+void AuraEffect::HandleAuraModParryPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ ((Player*)target)->UpdateParryPercentage();
+}
+
+void AuraEffect::HandleAuraModDodgePercent(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ ((Player*)target)->UpdateDodgePercentage();
+}
+
+void AuraEffect::HandleAuraModBlockPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ ((Player*)target)->UpdateBlockPercentage();
+}
+
+void AuraEffect::HandleAuraModRegenInterrupt(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ ((Player*)target)->UpdateManaRegen();
+}
+
+void AuraEffect::HandleAuraModWeaponCritPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ for (int i = 0; i < MAX_ATTACK; ++i)
+ if(Item* pItem = ((Player*)target)->GetWeaponForAttack(WeaponAttackType(i)))
+ ((Player*)target)->_ApplyWeaponDependentAuraCritMod(pItem,WeaponAttackType(i),this,apply);
+
+ // mods must be applied base at equipped weapon class and subclass comparison
+ // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
+ // GetMiscValue() comparison with item generated damage types
+
+ if (GetSpellProto()->EquippedItemClass == -1)
+ {
+ ((Player*)target)->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
+ ((Player*)target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
+ ((Player*)target)->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
+ }
+ else
+ {
+ // done in Player::_ApplyWeaponDependentAuraMods
+ }
+}
+
+void AuraEffect::HandleModHitChance(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ {
+ ((Player*)target)->UpdateMeleeHitChances();
+ ((Player*)target)->UpdateRangedHitChances();
+ }
+ else
+ {
+ target->m_modMeleeHitChance += (apply) ? GetAmount() : (-GetAmount());
+ target->m_modRangedHitChance += (apply) ? GetAmount() : (-GetAmount());
+ }
+}
+
+void AuraEffect::HandleModSpellHitChance(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)target)->UpdateSpellHitChances();
+ else
+ target->m_modSpellHitChance += (apply) ? GetAmount(): (-GetAmount());
+}
+
+void AuraEffect::HandleModSpellCritChance(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)target)->UpdateAllSpellCritChances();
+ else
+ target->m_baseSpellCritChance += (apply) ? GetAmount():-GetAmount();
+}
+
+void AuraEffect::HandleModSpellCritChanceShool(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ for (int school = SPELL_SCHOOL_NORMAL; school < MAX_SPELL_SCHOOL; ++school)
+ if (GetMiscValue() & (1<<school))
+ ((Player*)target)->UpdateSpellCritChance(school);
+}
+
+void AuraEffect::HandleAuraModCritPct(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ {
+ target->m_baseSpellCritChance += (apply) ? GetAmount():-GetAmount();
+ return;
+ }
+
+ ((Player*)target)->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
+ ((Player*)target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
+ ((Player*)target)->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (GetAmount()), apply);
+
+ // included in Player::UpdateSpellCritChance calculation
+ ((Player*)target)->UpdateAllSpellCritChances();
+}
+
+/********************************/
+/*** ATTACK SPEED ***/
+/********************************/
+
+void AuraEffect::HandleModCastingSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->ApplyCastTimePercentMod(GetAmount(),apply);
+}
+
+void AuraEffect::HandleModMeleeRangedSpeedPct(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->ApplyAttackTimePercentMod(BASE_ATTACK,GetAmount(),apply);
+ target->ApplyAttackTimePercentMod(OFF_ATTACK,GetAmount(),apply);
+ target->ApplyAttackTimePercentMod(RANGED_ATTACK, GetAmount(), apply);
+}
+
+void AuraEffect::HandleModCombatSpeedPct(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->ApplyCastTimePercentMod(m_amount,apply);
+ target->ApplyAttackTimePercentMod(BASE_ATTACK,GetAmount(),apply);
+ target->ApplyAttackTimePercentMod(OFF_ATTACK,GetAmount(),apply);
+ target->ApplyAttackTimePercentMod(RANGED_ATTACK, GetAmount(), apply);
+}
+
+void AuraEffect::HandleModAttackSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->ApplyAttackTimePercentMod(BASE_ATTACK,GetAmount(),apply);
+ target->UpdateDamagePhysical(BASE_ATTACK);
+}
+
+void AuraEffect::HandleHaste(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->ApplyAttackTimePercentMod(BASE_ATTACK, GetAmount(),apply);
+ target->ApplyAttackTimePercentMod(OFF_ATTACK, GetAmount(),apply);
+ target->ApplyAttackTimePercentMod(RANGED_ATTACK,GetAmount(),apply);
+}
+
+void AuraEffect::HandleAuraModRangedHaste(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->ApplyAttackTimePercentMod(RANGED_ATTACK, GetAmount(), apply);
+}
+
+void AuraEffect::HandleRangedAmmoHaste(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ target->ApplyAttackTimePercentMod(RANGED_ATTACK, GetAmount(), apply);
+}
+
+/********************************/
+/*** COMBAT RATING ***/
+/********************************/
+
+void AuraEffect::HandleModRating(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
+ if (GetMiscValue() & (1 << rating))
+ ((Player*)target)->ApplyRatingMod(CombatRating(rating), GetAmount(), apply);
+}
+
+void AuraEffect::HandleModRatingFromStat(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ // Just recalculate ratings
+ for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
+ if (GetMiscValue() & (1 << rating))
+ ((Player*)target)->ApplyRatingMod(CombatRating(rating), 0, apply);
+}
+
+/********************************/
+/*** ATTACK POWER ***/
+/********************************/
+
+void AuraEffect::HandleAuraModAttackPower(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(GetAmount()), apply);
+}
+
+void AuraEffect::HandleAuraModRangedAttackPower(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if((target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
+ return;
+
+ target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(GetAmount()), apply);
+}
+
+void AuraEffect::HandleAuraModAttackPowerPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ //UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
+ target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(GetAmount()), apply);
+}
+
+void AuraEffect::HandleAuraModRangedAttackPowerPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if((target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
+ return;
+
+ //UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
+ target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(GetAmount()), apply);
+}
+
+void AuraEffect::HandleAuraModRangedAttackPowerOfStatPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ // Recalculate bonus
+ if(target->GetTypeId() == TYPEID_PLAYER && !(target->getClassMask() & CLASSMASK_WAND_USERS))
+ ((Player*)target)->UpdateAttackPowerAndDamage(true);
+}
+
+void AuraEffect::HandleAuraModAttackPowerOfStatPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ // Recalculate bonus
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)target)->UpdateAttackPowerAndDamage(false);
+}
+
+void AuraEffect::HandleAuraModAttackPowerOfArmor(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ // Recalculate bonus
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)target)->UpdateAttackPowerAndDamage(false);
+}
+/********************************/
+/*** DAMAGE BONUS ***/
+/********************************/
+void AuraEffect::HandleModDamageDone(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ // apply item specific bonuses for already equipped weapon
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ {
+ for (int i = 0; i < MAX_ATTACK; ++i)
+ if(Item* pItem = ((Player*)target)->GetWeaponForAttack(WeaponAttackType(i)))
+ ((Player*)target)->_ApplyWeaponDependentAuraDamageMod(pItem,WeaponAttackType(i),this,apply);
+ }
+
+ // GetMiscValue() is bitmask of spell schools
+ // 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
+ // 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wands
+ // 127 - full bitmask any damages
+ //
+ // mods must be applied base at equipped weapon class and subclass comparison
+ // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
+ // GetMiscValue() comparison with item generated damage types
+
+ if((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) != 0)
+ {
+ // apply generic physical damage bonuses including wand case
+ if (GetSpellProto()->EquippedItemClass == -1 || target->GetTypeId() != TYPEID_PLAYER)
+ {
+ target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(GetAmount()), apply);
+ target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(GetAmount()), apply);
+ target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(GetAmount()), apply);
+ }
+ else
+ {
+ // done in Player::_ApplyWeaponDependentAuraMods
+ }
+
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(GetAmount() > 0)
+ target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,GetAmount(),apply);
+ else
+ target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,GetAmount(),apply);
+ }
+ }
+
+ // Skip non magic case for speedup
+ if((GetMiscValue() & SPELL_SCHOOL_MASK_MAGIC) == 0)
+ return;
+
+ if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 )
+ {
+ // wand magic case (skip generic to all item spell bonuses)
+ // done in Player::_ApplyWeaponDependentAuraMods
+
+ // Skip item specific requirements for not wand magic damage
+ return;
+ }
+
+ // Magic damage modifiers implemented in Unit::SpellDamageBonus
+ // This information for client side use only
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(GetAmount() > 0)
+ {
+ for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
+ {
+ if((GetMiscValue() & (1<<i)) != 0)
+ target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i,GetAmount(),apply);
+ }
+ }
+ else
+ {
+ for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
+ {
+ if((GetMiscValue() & (1<<i)) != 0)
+ target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i,GetAmount(),apply);
+ }
+ }
+ if(Guardian* pet = ((Player*)target)->GetGuardianPet())
+ pet->UpdateAttackPowerAndDamage();
+ }
+}
+
+void AuraEffect::HandleModDamagePercentDone(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ sLog.outDebug("AURA MOD DAMAGE type:%u negative:%u", GetMiscValue(), GetAmount() > 0);
+
+ // apply item specific bonuses for already equipped weapon
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ {
+ for (int i = 0; i < MAX_ATTACK; ++i)
+ if(Item* pItem = ((Player*)target)->GetWeaponForAttack(WeaponAttackType(i)))
+ ((Player*)target)->_ApplyWeaponDependentAuraDamageMod(pItem,WeaponAttackType(i),this,apply);
+ }
+
+ // GetMiscValue() is bitmask of spell schools
+ // 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
+ // 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wand
+ // 127 - full bitmask any damages
+ //
+ // mods must be applied base at equipped weapon class and subclass comparison
+ // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
+ // GetMiscValue() comparison with item generated damage types
+
+ if((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) != 0)
+ {
+ // apply generic physical damage bonuses including wand case
+ if (GetSpellProto()->EquippedItemClass == -1 || target->GetTypeId() != TYPEID_PLAYER)
+ {
+ target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(GetAmount()), apply);
+ target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(GetAmount()), apply);
+ target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(GetAmount()), apply);
+ }
+ else
+ {
+ // done in Player::_ApplyWeaponDependentAuraMods
+ }
+ // For show in client
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT,GetAmount()/100.0f,apply);
+ }
+
+ // Skip non magic case for speedup
+ if((GetMiscValue() & SPELL_SCHOOL_MASK_MAGIC) == 0)
+ return;
+
+ if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 )
+ {
+ // wand magic case (skip generic to all item spell bonuses)
+ // done in Player::_ApplyWeaponDependentAuraMods
+
+ // Skip item specific requirements for not wand magic damage
+ return;
+ }
+
+ // Magic damage percent modifiers implemented in Unit::SpellDamageBonus
+ // Send info to client
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
+ target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT+i,GetAmount()/100.0f,apply);
+}
+
+void AuraEffect::HandleModOffhandDamagePercent(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(GetAmount()), apply);
+}
+
+void AuraEffect::HandleShieldBlockValue(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_STAT)))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ BaseModType modType = FLAT_MOD;
+ if(GetAuraType() == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT)
+ modType = PCT_MOD;
+
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)target)->HandleBaseModValue(SHIELD_BLOCK_VALUE, modType, float(GetAmount()), apply);
+}
+
+/********************************/
+/*** POWER COST ***/
+/********************************/
+
+void AuraEffect::HandleModPowerCostPCT(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ float amount = GetAmount() /100.0f;
+ for (int i = 0; i < MAX_SPELL_SCHOOL; ++i)
+ if(GetMiscValue() & (1<<i))
+ target->ApplyModSignedFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,amount,apply);
+}
+
+void AuraEffect::HandleModPowerCost(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ for (int i = 0; i < MAX_SPELL_SCHOOL; ++i)
+ if(GetMiscValue() & (1<<i))
+ target->ApplyModInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,GetAmount(),apply);
+}
+
+void AuraEffect::HandleArenaPreparation(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(apply)
+ target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);
+ else
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if(target->HasAuraType(GetAuraType()))
+ return;
+ target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);
+ }
+}
+
+void AuraEffect::HandleNoReagentUseAura(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ flag96 mask;
+ Unit::AuraEffectList const& noReagent = target->GetAuraEffectsByType(SPELL_AURA_NO_REAGENT_USE);
+ for (Unit::AuraEffectList::const_iterator i = noReagent.begin(); i != noReagent.end(); ++i)
+ mask |= (*i)->m_spellProto->EffectSpellClassMask[(*i)->m_effIndex];
+
+ target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1 , mask[0]);
+ target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+1, mask[1]);
+ target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+2, mask[2]);
+}
+
+void AuraEffect::HandleAuraRetainComboPoints(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ // combo points was added in SPELL_EFFECT_ADD_COMBO_POINTS handler
+ // remove only if aura expire by time (in case combo points amount change aura removed without combo points lost)
+ if( !(apply) && GetBase()->GetDuration()==0 && ((Player*)target)->GetComboTarget())
+ if(Unit* unit = ObjectAccessor::GetUnit(*target,((Player*)target)->GetComboTarget()))
+ ((Player*)target)->AddComboPoints(unit, -GetAmount());
+}
+
+/*********************************************************/
+/*** OTHERS ***/
+/*********************************************************/
+
+void AuraEffect::HandleAuraDummy(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ Unit * caster = GetCaster();
+
+ if (mode & AURA_EFFECT_HANDLE_REAL)
+ {
+ // AT APPLY
+ if(apply)
+ {
+ // Overpower
+ if (caster && m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR &&
+ m_spellProto->SpellFamilyFlags[0] & 0x4)
+ {
+ // Must be casting target
+ if (target->IsNonMeleeSpellCasted(false, false, true))
+ {
+ if (AuraEffect * aurEff = caster->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARRIOR, 2775, 0))
+ {
+ switch (aurEff->GetId())
+ {
+ // Unrelenting Assault, rank 1
+ case 46859:
+ target->CastSpell(target,64849,true,NULL,aurEff);
+ break;
+ // Unrelenting Assault, rank 2
+ case 46860:
+ target->CastSpell(target,64850,true,NULL,aurEff);
+ break;
+ }
+ }
+ }
+ }
+ switch(GetId())
+ {
+ case 1515: // Tame beast
+ // FIX_ME: this is 2.0.12 threat effect replaced in 2.1.x by dummy aura, must be checked for correctness
+ if( caster && target->CanHaveThreatList())
+ target->AddThreat(caster, 10.0f);
+ break;
+ case 13139: // net-o-matic
+ // root to self part of (root_target->charge->root_self sequence
+ if(caster)
+ caster->CastSpell(caster,13138,true,NULL,this);
+ break;
+ case 34026: // kill command
+ {
+ Unit * pet = target->GetGuardianPet();
+ if (!pet)
+ break;
+
+ target->CastSpell(target,34027,true,NULL,this);
+
+ // set 3 stacks and 3 charges (to make all auras not disappear at once)
+ Aura * owner_aura = target->GetAura(34027,GetCasterGUID());
+ Aura * pet_aura = pet->GetAura(58914, GetCasterGUID());
+ if( owner_aura )
+ {
+ owner_aura->SetStackAmount(owner_aura->GetSpellProto()->StackAmount);
+ }
+ if( pet_aura )
+ {
+ pet_aura->SetCharges(0);
+ pet_aura->SetStackAmount(owner_aura->GetSpellProto()->StackAmount);
+ }
+ break;
+ }
+ case 37096: // Blood Elf Illusion
+ {
+ if(caster)
+ {
+ switch(caster->getGender())
+ {
+ case GENDER_FEMALE:
+ caster->CastSpell(target,37095,true,NULL,this); // Blood Elf Disguise
+ break;
+ case GENDER_MALE:
+ caster->CastSpell(target,37093,true,NULL,this);
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ }
+ case 55198: // Tidal Force
+ {
+ target->CastSpell(target,55166,true,NULL,this);
+ // set 3 stacks and 3 charges (to make all auras not disappear at once)
+ Aura * owner_aura = target->GetAura(55166,GetCasterGUID());
+ if( owner_aura )
+ {
+ // This aura lasts 2 sec, need this hack to properly proc spells
+ // TODO: drop aura charges for ApplySpellMod in ProcDamageAndSpell
+ GetBase()->SetDuration(owner_aura->GetDuration());
+ // Make aura be not charged-this prevents removing charge on not crit spells
+ owner_aura->SetCharges(0);
+ owner_aura->SetStackAmount(owner_aura->GetSpellProto()->StackAmount);
+ }
+ break;
+ }
+ case 39850: // Rocket Blast
+ if(roll_chance_i(20)) // backfire stun
+ target->CastSpell(target, 51581, true, NULL, this);
+ break;
+ case 43873: // Headless Horseman Laugh
+ target->PlayDistanceSound(11965);
+ break;
+ case 46354: // Blood Elf Illusion
+ if(caster)
+ {
+ switch(caster->getGender())
+ {
+ case GENDER_FEMALE:
+ caster->CastSpell(target,46356,true,NULL,this);
+ break;
+ case GENDER_MALE:
+ caster->CastSpell(target,46355,true,NULL,this);
+ break;
+ }
+ }
+ break;
+ case 46699: // Requires No Ammo
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)target)->RemoveAmmo(); // not use ammo and not allow use
+ break;
+ case 49028:
+ GetBase()->SetDuration(GetBase()->GetDuration() + (caster->GetPower(POWER_RUNIC_POWER) * 10));
+ caster->SetPower(POWER_RUNIC_POWER, 0);
+ break;
+ case 62061: // Festive Holiday Mount
+ if(target->HasAuraType(SPELL_AURA_MOUNTED))
+ target->CastSpell(target, 25860, true, NULL, this); // Reindeer Transformation
+ break;
+ case 52916: // Honor Among Thieves
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ if (Unit * spellTarget = ObjectAccessor::GetUnit(*target,((Player*)target)->GetComboTarget()))
+ target->CastSpell(spellTarget, 51699, true);
+ break;
+ case 28832: // Mark of Korth'azz
+ case 28833: // Mark of Blaumeux
+ case 28834: // Mark of Rivendare
+ case 28835: // Mark of Zeliek
+ if(caster) // actually we can also use cast(this, originalcasterguid)
+ {
+ int32 damage;
+ switch(GetBase()->GetStackAmount())
+ {
+ case 1: damage = 0; break;
+ case 2: damage = 500; break;
+ case 3: damage = 1000; break;
+ case 4: damage = 1500; break;
+ case 5: damage = 4000; break;
+ case 6: damage = 12000; break;
+ default:damage = 20000 + 1000 * (GetBase()->GetStackAmount() - 7); break;
+ }
+ if(damage)
+ caster->CastCustomSpell(28836, SPELLVALUE_BASE_POINT0, damage, target);
+ }
+ break;
+ }
+ }
+ // AT REMOVE
+ else
+ {
+ if( (IsQuestTameSpell(GetId())) && caster && caster->isAlive() && target->isAlive())
+ {
+ uint32 finalSpelId = 0;
+ switch(GetId())
+ {
+ case 19548: finalSpelId = 19597; break;
+ case 19674: finalSpelId = 19677; break;
+ case 19687: finalSpelId = 19676; break;
+ case 19688: finalSpelId = 19678; break;
+ case 19689: finalSpelId = 19679; break;
+ case 19692: finalSpelId = 19680; break;
+ case 19693: finalSpelId = 19684; break;
+ case 19694: finalSpelId = 19681; break;
+ case 19696: finalSpelId = 19682; break;
+ case 19697: finalSpelId = 19683; break;
+ case 19699: finalSpelId = 19685; break;
+ case 19700: finalSpelId = 19686; break;
+ case 30646: finalSpelId = 30647; break;
+ case 30653: finalSpelId = 30648; break;
+ case 30654: finalSpelId = 30652; break;
+ case 30099: finalSpelId = 30100; break;
+ case 30102: finalSpelId = 30103; break;
+ case 30105: finalSpelId = 30104; break;
+ }
+
+ if(finalSpelId)
+ caster->CastSpell(target,finalSpelId,true,NULL,this);
+ }
+
+ switch(m_spellProto->SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
+ switch(GetId())
+ {
+ case 2584: // Waiting to Resurrect
+ // Waiting to resurrect spell cancel, we must remove player from resurrect queue
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ if(BattleGround *bg = ((Player*)target)->GetBattleGround())
+ bg->RemovePlayerFromResurrectQueue(target->GetGUID());
+ break;
+ case 28169: // Mutating Injection
+ {
+ // Mutagen Explosion
+ target->CastSpell(target, 28206, true, NULL, this);
+ // Poison Cloud
+ target->CastSpell(target, 28240, true, NULL, this);
+ return;
+ }
+ case 36730: // Flame Strike
+ {
+ target->CastSpell(target, 36731, true, NULL, this);
+ break;
+ }
+ case 44191: // Flame Strike
+ {
+ if (target->GetMap()->IsDungeon())
+ {
+ uint32 spellId = target->GetMap()->IsHeroic() ? 46163 : 44190;
+
+ target->CastSpell(target, spellId, true, NULL, this);
+ }
+ break;
+ }
+ case 42783: // Wrath of the Astromancer
+ target->CastSpell(target,GetAmount(),true,NULL,this);
+ break;
+ case 46308: // Burning Winds casted only at creatures at spawn
+ target->CastSpell(target,47287,true,NULL,this);
+ break;
+ case 52172: // Coyote Spirit Despawn Aura
+ case 60244: // Blood Parrot Despawn Aura
+ target->CastSpell((Unit*)NULL, GetAmount(), true, NULL, this);
+ break;
+ }
+ break;
+ case SPELLFAMILY_MAGE:
+ // Living Bomb
+ if(m_spellProto->SpellFamilyFlags[1] & 0x20000)
+ {
+ AuraRemoveMode mode = aurApp->GetRemoveMode();
+ if(caster && (mode == AURA_REMOVE_BY_ENEMY_SPELL || mode == AURA_REMOVE_BY_EXPIRE))
+ caster->CastSpell(target, GetAmount(), true);
+ }
+ break;
+ case SPELLFAMILY_WARLOCK:
+ // Haunt
+ if(m_spellProto->SpellFamilyFlags[1] & 0x40000)
+ {
+ if(caster)
+ caster->CastCustomSpell(caster, 48210, &m_amount, 0, 0, true, NULL, this);
+ }
+ break;
+ case SPELLFAMILY_DRUID:
+ // Lifebloom
+ if ( GetSpellProto()->SpellFamilyFlags[1] & 0x10 )
+ {
+ if (!apply)
+ {
+ // Final heal only on dispelled or duration end
+ if (aurApp->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && aurApp->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
+ return;
+
+ // final heal
+ target->CastCustomSpell(target,33778,&m_amount,NULL,NULL,true,NULL,this,GetCasterGUID());
+
+ // restore mana
+ if (caster)
+ {
+ int32 returnmana = (GetSpellProto()->ManaCostPercentage * caster->GetCreateMana() / 100) * GetBase()->GetStackAmount() / 2;
+ caster->CastCustomSpell(caster, 64372, &returnmana, NULL, NULL, true, NULL, this, GetCasterGUID());
+ }
+ }
+ }
+ break;
+ case SPELLFAMILY_PRIEST:
+ // Vampiric Touch
+ if (m_spellProto->SpellFamilyFlags[1] & 0x0400 && aurApp->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL)
+ {
+ if (AuraEffect const * aurEff = GetBase()->GetEffect(1))
+ {
+ int32 damage = aurEff->GetAmount()*4;
+ // backfire damage
+ target->CastCustomSpell(target, 64085, &damage, NULL, NULL, true, NULL, NULL,GetCasterGUID());
+ }
+ }
+ break;
+ case SPELLFAMILY_HUNTER:
+ // Misdirection
+ if(GetId()==34477)
+ target->SetReducedThreatPercent(0, 0);
+ break;
+ case SPELLFAMILY_DEATHKNIGHT:
+ // Summon Gargoyle ( will start feeding gargoyle )
+ if(GetId()==61777)
+ target->CastSpell(target,m_spellProto->EffectTriggerSpell[m_effIndex],true);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ // AT APPLY & REMOVE
+
+ switch(m_spellProto->SpellFamilyName)
+ {
+ case SPELLFAMILY_GENERIC:
+ {
+ if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ break;
+ switch(GetId())
+ {
+ // Recently Bandaged
+ case 11196:
+ target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, GetMiscValue(), apply);
+ break;
+ // Unstable Power
+ case 24658:
+ {
+ uint32 spellId = 24659;
+ if (apply && caster)
+ {
+ SpellEntry const * spell = sSpellStore.LookupEntry(spellId);
+
+ for (int i=0; i < spell->StackAmount; ++i)
+ caster->CastSpell(target, spell->Id, true, NULL, NULL, GetCasterGUID());
+ break;
+ }
+ target->RemoveAurasDueToSpell(spellId);
+ break;
+ }
+ // Restless Strength
+ case 24661:
+ {
+ uint32 spellId = 24662;
+ if (apply && caster)
+ {
+ SpellEntry const * spell = sSpellStore.LookupEntry(spellId);
+ for (int i=0; i < spell->StackAmount; ++i)
+ caster->CastSpell(target, spell->Id, true, NULL, NULL, GetCasterGUID());
+ break;
+ }
+ target->RemoveAurasDueToSpell(spellId);
+ break;
+ }
+ //Summon Fire Elemental
+ case 40133:
+ {
+ if (!caster)
+ break;
+
+ Unit *owner = caster->GetOwner();
+ if (owner && owner->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(apply)
+ owner->CastSpell(owner,8985,true);
+ else
+ ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
+ }
+ break;
+ }
+ //Summon Earth Elemental
+ case 40132 :
+ {
+ if (!caster)
+ break;
+
+ Unit *owner = caster->GetOwner();
+ if (owner && owner->GetTypeId() == TYPEID_PLAYER)
+ {
+ if(apply)
+ owner->CastSpell(owner,19704,true);
+ else
+ ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
+ }
+ break;
+ }
+ case 57723: // Exhaustion
+ case 57724: // Sated
+ {
+ switch(GetId())
+ {
+ case 57723: target->ApplySpellImmune(GetId(), IMMUNITY_ID, 32182, apply); break; // Heroism
+ case 57724: target->ApplySpellImmune(GetId(), IMMUNITY_ID, 2825, apply); break; // Bloodlust
+ }
+ break;
+ }
+ case 57819: // Argent Champion
+ case 57820: // Ebon Champion
+ case 57821: // Champion of the Kirin Tor
+ case 57822: // Wyrmrest Champion
+ {
+ if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
+ break;
+
+ uint32 FactionID = 0;
+
+ if(apply)
+ {
+ switch(m_spellProto->Id)
+ {
+ case 57819: FactionID = 1106; break; // Argent Crusade
+ case 57820: FactionID = 1098; break; // Knights of the Ebon Blade
+ case 57821: FactionID = 1090; break; // Kirin Tor
+ case 57822: FactionID = 1091; break; // The Wyrmrest Accord
+ }
+ }
+ ((Player*)caster)->SetChampioningFaction(FactionID);
+ break;
+ }
+ // LK Intro VO (1)
+ case 58204:
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ {
+ // Play part 1
+ if(apply)
+ target->PlayDirectSound(14970, (Player *)target);
+ // continue in 58205
+ else
+ target->CastSpell(target, 58205, true);
+ }
+ break;
+ // LK Intro VO (2)
+ case 58205:
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ {
+ // Play part 2
+ if(apply)
+ target->PlayDirectSound(14971, (Player *)target);
+ // Play part 3
+ else
+ target->PlayDirectSound(14972, (Player *)target);
+ }
+ break;
+ }
+
+ break;
+ }
+ case SPELLFAMILY_MAGE:
+ {
+ //if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ //break;
+ break;
+ }
+ case SPELLFAMILY_PRIEST:
+ {
+ //if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ //break;
+ break;
+ }
+ case SPELLFAMILY_DRUID:
+ {
+ if (!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
+ break;
+ switch(GetId())
+ {
+ case 61336: // Survival Instincts
+ {
+ if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ break;
+ if(apply)
+ {
+ if (!target->IsInFeralForm())
+ break;
+
+ int32 bp0 = int32(target->GetMaxHealth() * GetAmount() / 100);
+ target->CastCustomSpell(target, 50322, &bp0, NULL, NULL, true);
+ }
+ else
+ target-> RemoveAurasDueToSpell(50322);
+ break;
+ }
+ }
+ // Predatory Strikes
+ if(target->GetTypeId() == TYPEID_PLAYER && GetSpellProto()->SpellIconID == 1563)
+ {
+ ((Player*)target)->UpdateAttackPowerAndDamage();
+ }
+ break;
+ }
+ case SPELLFAMILY_SHAMAN:
+ {
+ if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ break;
+ // Sentry Totem
+ if (GetId() == 6495 && caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (apply)
+ {
+ uint64 guid = caster->m_SummonSlot[3];
+ if (guid)
+ {
+ Creature *totem = caster->GetMap()->GetCreature(guid);
+ if (totem && totem->isTotem())
+ ((Player*)caster)->CastSpell(totem, 6277, true);
+ }
+ }
+ else
+ ((Player*)caster)->StopCastingBindSight();
+ return;
+ }
+ break;
+ }
+ case SPELLFAMILY_PALADIN:
+ switch (GetSpellProto()->SpellIconID)
+ {
+ // Blessing of Sanctuary
+ // Greater Blessing of Sanctuary
+ case 19:
+ case 1804:
+ {
+ if (!caster || !target)
+ return;
+
+ if (apply)
+ {
+ // Greater Blessing of Sanctuary does not provide strength bonus
+ int32 bp1 = 0;
+ caster->CastCustomSpell(target, 67480, NULL, (GetSpellProto()->SpellIconID == 1804) ? &bp1 : NULL, NULL, true);
+ }
+ else
+ target->RemoveAura(67480, GetCasterGUID());
+
+ return;
+ }
+ }
+ break;
+ }
+
+ if (mode & AURA_EFFECT_HANDLE_REAL)
+ {
+ // pet auras
+ if(PetAura const* petSpell = spellmgr.GetPetAura(GetId(), m_effIndex))
+ {
+ if(apply)
+ target->AddPetAura(petSpell);
+ else
+ target->RemovePetAura(petSpell);
+ }
+ }
+}
+
+void AuraEffect::HandleChannelDeathItem(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(!(apply))
+ {
+ Unit * caster = GetCaster();
+
+ if(!caster || caster->GetTypeId() != TYPEID_PLAYER)// || m_removeMode!=AURA_REMOVE_BY_DEATH)
+ return;
+
+ //we cannot check removemode = death
+ //talent will remove the caster's aura->interrupt channel->remove victim aura
+ if(target->GetHealth() > 0)
+ return;
+ // Item amount
+ if (GetAmount() <= 0)
+ return;
+
+ if(GetSpellProto()->EffectItemType[m_effIndex] == 0)
+ return;
+
+ // Soul Shard only from non-grey units
+ if( GetSpellProto()->EffectItemType[m_effIndex] == 6265 &&
+ (target->getLevel() <= Trinity::XP::GetGrayLevel(caster->getLevel()) ||
+ target->GetTypeId() == TYPEID_UNIT && !((Player*)caster)->isAllowedToLoot((Creature*)target)) )
+ return;
+ //Adding items
+ uint32 noSpaceForCount = 0;
+ uint32 count = m_amount;
+
+ ItemPosCountVec dest;
+ uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, GetSpellProto()->EffectItemType[m_effIndex], count, &noSpaceForCount);
+ if( msg != EQUIP_ERR_OK )
+ {
+ count-=noSpaceForCount;
+ ((Player*)caster)->SendEquipError( msg, NULL, NULL );
+ if (count==0)
+ return;
+ }
+
+ Item* newitem = ((Player*)caster)->StoreNewItem(dest, GetSpellProto()->EffectItemType[m_effIndex], true);
+ ((Player*)caster)->SendNewItem(newitem, count, true, false);
+ }
+}
+
+void AuraEffect::HandleBindSight(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ Unit * caster = GetCaster();
+
+ if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ ((Player*)caster)->SetViewpoint(target, (apply));
+}
+
+void AuraEffect::HandleForceReaction(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Player* player = (Player*)target;
+
+ uint32 faction_id = GetMiscValue();
+ ReputationRank faction_rank = ReputationRank(m_amount);
+
+ player->GetReputationMgr().ApplyForceReaction(faction_id,faction_rank,apply);
+ player->GetReputationMgr().SendForceReactions();
+
+ // stop fighting if at apply forced rank friendly or at remove real rank friendly
+ if (apply && faction_rank >= REP_FRIENDLY || !apply && player->GetReputationRank(faction_id) >= REP_FRIENDLY)
+ player->StopAttackFaction(faction_id);
+}
+
+void AuraEffect::HandleAuraEmpathy(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if (target->GetTypeId() != TYPEID_UNIT)
+ return;
+
+ if(!(apply))
+ {
+ // do not remove unit flag if there are more than this auraEffect of that kind on unit on unit
+ if(target->HasAuraType(GetAuraType()))
+ return;
+ }
+
+ CreatureInfo const * ci = objmgr.GetCreatureTemplate(target->GetEntry());
+ if(ci && ci->type == CREATURE_TYPE_BEAST)
+ target->ApplyModUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO, apply);
+}
+
+void AuraEffect::HandleComprehendLanguage(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(apply)
+ target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_COMPREHEND_LANG);
+ else
+ {
+ if (target->HasAuraType(GetAuraType()))
+ return;
+
+ target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_COMPREHEND_LANG);
+ }
+}
+
+void AuraEffect::HandleAuraConvertRune(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if(target->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ Player *plr = (Player*)target;
+
+ if(plr->getClass() != CLASS_DEATH_KNIGHT)
+ return;
+
+ uint32 runes = m_amount;
+ // convert number of runes specified in aura amount of rune type in miscvalue to runetype in miscvalueb
+ if(apply)
+ {
+ for (uint32 i = 0; i < MAX_RUNES && runes; ++i)
+ {
+ if (GetMiscValue() != plr->GetCurrentRune(i))
+ continue;
+ if(!plr->GetRuneCooldown(i))
+ {
+ // ConvertRune(i,
+ plr->AddRuneByAuraEffect(i, RuneType(GetMiscValueB()), this);
+ --runes;
+ }
+ }
+ }
+ else
+ plr->RemoveRunesByAuraEffect(this);
+}
+
+void AuraEffect::HandleAuraLinked(AuraApplication const * aurApp, uint8 mode, bool apply) const
+{
+ if(!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Unit * target = aurApp->GetTarget();
+
+ if (apply)
+ {
+ Unit * caster = GetCaster();
+
+ if (!caster)
+ return;
+ // If amount avalible cast with basepoints (Crypt Fever for example)
+ if (GetAmount())
+ caster->CastCustomSpell(target, m_spellProto->EffectTriggerSpell[m_effIndex], &m_amount, NULL, NULL, true, NULL, this);
+ else
+ caster->CastSpell(target, m_spellProto->EffectTriggerSpell[m_effIndex],true, NULL, this);
+ }
+ else
+ target->RemoveAura(m_spellProto->EffectTriggerSpell[m_effIndex], GetCasterGUID(), 0, AuraRemoveMode(aurApp->GetRemoveMode()));
+}
diff --git a/src/game/SpellAuraEffects.h b/src/game/SpellAuraEffects.h
new file mode 100644
index 00000000000..75e061da5fe
--- /dev/null
+++ b/src/game/SpellAuraEffects.h
@@ -0,0 +1,263 @@
+
+#ifndef TRINITY_SPELLAURAEFFECTS_H
+#define TRINITY_SPELLAURAEFFECTS_H
+
+class Unit;
+class DynamicObject;
+class AuraEffect;
+class Aura;
+
+#include "SpellAuras.h"
+
+#define AURA_EFFECT_HANDLE_DEFAULT 0
+#define AURA_EFFECT_HANDLE_REAL 0x01
+#define AURA_EFFECT_HANDLE_SEND_FOR_CLIENT 0x02
+#define AURA_EFFECT_HANDLE_CHANGE_AMOUNT 0x04
+#define AURA_EFFECT_HANDLE_STAT 0x08
+#define AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK (AURA_EFFECT_HANDLE_SEND_FOR_CLIENT | AURA_EFFECT_HANDLE_REAL)
+#define AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK (AURA_EFFECT_HANDLE_CHANGE_AMOUNT | AURA_EFFECT_HANDLE_REAL)
+#define AURA_EFFECT_HANDLE_CHANGE_AMOUNT_SEND_FOR_CLIENT_MASK (AURA_EFFECT_HANDLE_CHANGE_AMOUNT_MASK | AURA_EFFECT_HANDLE_SEND_FOR_CLIENT_MASK)
+
+typedef void(AuraEffect::*pAuraEffectHandler)(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+
+class TRINITY_DLL_SPEC AuraEffect
+{
+ friend Aura::Aura(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID);
+ friend Aura::~Aura();
+ private:
+ ~AuraEffect();
+ explicit AuraEffect(Aura * base, uint8 effIndex, int32 *baseAmount, Unit * caster);
+ public:
+ Unit * GetCaster() const { return GetBase()->GetCaster(); }
+ uint64 GetCasterGUID() const { return GetBase()->GetCasterGUID(); }
+ Aura * GetBase() const { return m_base; }
+ void GetTargetList(std::list<Unit*> & targetList) const;
+
+ SpellEntry const * GetSpellProto() const { return m_spellProto; }
+ uint32 GetId() const { return m_spellProto->Id; }
+ uint32 GetEffIndex() const { return m_effIndex; }
+ int32 GetBaseAmount() const { return m_baseAmount; }
+ int32 GetAmplitude() const { return m_amplitude; }
+
+ int32 GetMiscValueB() const { return m_spellProto->EffectMiscValueB[m_effIndex]; }
+ int32 GetMiscValue() const { return m_spellProto->EffectMiscValue[m_effIndex]; }
+ AuraType GetAuraType() const { return (AuraType)m_spellProto->EffectApplyAuraName[m_effIndex]; }
+ int32 GetAmount() const { return m_amount; }
+ void SetAmount(int32 amount) { m_amount = amount; m_canBeRecalculated = false;}
+
+ int32 CalculateAmount(Unit * caster);
+ void CalculatePeriodic(Unit * caster, bool create = false);
+ void CalculateSpellMod();
+ void ChangeAmount(int32 newAmount, bool mark = true);
+ void RecalculateAmount() { if(!CanBeRecalculated()) return; ChangeAmount(CalculateAmount(GetCaster()), false); }
+ void RecalculateAmount(Unit * caster) { if(!CanBeRecalculated()) return; ChangeAmount(CalculateAmount(caster), false); }
+ bool CanBeRecalculated() const { return m_canBeRecalculated; }
+ void SetCanBeRecalculated(bool val) { m_canBeRecalculated = val; }
+ void HandleEffect(AuraApplication const * aurApp, uint8 mode, bool apply);
+ void HandleEffect(Unit * target, uint8 mode, bool apply);
+ void ApplySpellMod(Unit * target, bool apply);
+
+ void Update(uint32 diff, Unit * caster);
+ void UpdatePeriodic(Unit * caster);
+
+ uint32 GetTickNumber() const { return m_tickNumber; }
+ int32 GetTotalTicks() const { return m_amplitude ? (GetBase()->GetMaxDuration() / m_amplitude) : 1;}
+ void ResetPeriodic() {m_periodicTimer = m_amplitude; m_tickNumber = 0;}
+
+ bool IsPeriodic() const { return m_isPeriodic; }
+ bool IsAffectedOnSpell(SpellEntry const *spell) const;
+
+ void PeriodicTick(Unit * target, Unit * caster) const;
+ void PeriodicDummyTick(Unit * target, Unit * caster) const;
+ Unit* GetTriggerTarget(Unit * target) const;
+ void TriggerSpell(Unit * target, Unit * caster) const;
+ void TriggerSpellWithValue(Unit * target, Unit * caster) const;
+
+ void CleanupTriggeredSpells(Unit * target);
+
+ static bool IsPeriodicAuraType(uint32 type);
+ // add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras
+ void HandleShapeshiftBoosts(Unit * target, bool apply) const;
+ private:
+ Aura * const m_base;
+
+ SpellEntry const * const m_spellProto;
+ uint8 const m_effIndex;
+ int32 const m_baseAmount;
+
+ int32 m_amount;
+ bool m_canBeRecalculated:1;
+
+ SpellModifier *m_spellmod;
+
+ bool m_isPeriodic:1;
+ int32 m_periodicTimer;
+ int32 m_amplitude;
+ uint32 m_tickNumber;
+ private:
+ bool IsPeriodicTickCrit(Unit * target, Unit const * caster) const;
+
+ public:
+ // aura effect handlers
+ void HandleNULL(AuraApplication const * aurApp, uint8 mode, bool apply) const
+ {
+ // not implemented
+ }
+ void HandleUnused(AuraApplication const * aurApp, uint8 mode, bool apply) const
+ {
+ // useless
+ }
+ void HandleNoImmediateEffect(AuraApplication const * aurApp, uint8 mode, bool apply) const
+ {
+ // aura type not have immediate effect at add/remove and handled by ID in other code place
+ }
+ // visibility & phases
+ void HandleInvisibilityDetect(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleInvisibility(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModStealth(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleSpiritOfRedemption(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraGhost(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandlePhase(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // unit model
+ void HandleAuraModShapeshift(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraTransform(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModScale(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraCloneCaster(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // fight
+ void HandleFeignDeath(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModUnattackable(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModDisarm(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModSilence(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModPacify(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModPacifyAndSilence(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraAllowOnlyAbility(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // tracking
+ void HandleAuraTrackResources(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraTrackCreatures(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraTrackStealthed(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModStalked(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraUntrackable(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // skills & talents
+ void HandleAuraModPetTalentsPoints(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModSkill(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // movement
+ void HandleAuraMounted(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraAllowFlight(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraWaterWalk(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraFeatherFall(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraHover(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleWaterBreathing(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleForceMoveForward(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // threat
+ void HandleModThreat(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModTotalThreat(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModTaunt(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // control
+ void HandleModConfuse(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModFear(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModStun(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModRoot(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandlePreventFleeing(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // charm
+ void HandleModPossess(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModPossessPet(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModCharm(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleCharmConvert(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraControlVehicle(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // modify speed
+ void HandleAuraModIncreaseSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModIncreaseMountedSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModIncreaseFlightSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModIncreaseSwimSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModDecreaseSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModUseNormalSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // immunity
+ void HandleModStateImmunityMask(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModMechanicImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModEffectImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModStateImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModSchoolImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModDmgImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModDispelImmunity(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // modify stats
+ // resistance
+ void HandleAuraModResistanceExclusive(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModResistance(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModBaseResistancePCT(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModResistancePercent(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModBaseResistance(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModTargetResistance(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // stat
+ void HandleAuraModStat(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModPercentStat(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModSpellDamagePercentFromStat(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModSpellHealingPercentFromStat(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModSpellDamagePercentFromAttackPower(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModSpellHealingPercentFromAttackPower(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModHealingDone(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModTotalPercentStat(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModResistenceOfStatPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModExpertise(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // heal and energize
+ void HandleModPowerRegen(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModPowerRegenPCT(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModManaRegen(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModIncreaseHealth(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModIncreaseMaxHealth(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModIncreaseEnergy(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModIncreaseEnergyPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModIncreaseHealthPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraIncreaseBaseHealthPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // fight
+ void HandleAuraModParryPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModDodgePercent(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModBlockPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModRegenInterrupt(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModWeaponCritPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModHitChance(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModSpellHitChance(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModSpellCritChance(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModSpellCritChanceShool(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModCritPct(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // attack speed
+ void HandleModCastingSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModMeleeRangedSpeedPct(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModCombatSpeedPct(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModAttackSpeed(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleHaste(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModRangedHaste(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleRangedAmmoHaste(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // combat rating
+ void HandleModRating(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModRatingFromStat(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // attack power
+ void HandleAuraModAttackPower(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModRangedAttackPower(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModAttackPowerPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModRangedAttackPowerPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModRangedAttackPowerOfStatPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModAttackPowerOfStatPercent(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraModAttackPowerOfArmor(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // damage bonus
+ void HandleModDamageDone(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModDamagePercentDone(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModOffhandDamagePercent(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleShieldBlockValue(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // power cost
+ void HandleModPowerCostPCT(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleModPowerCost(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleArenaPreparation(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleNoReagentUseAura(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraRetainComboPoints(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ // others
+ void HandleAuraDummy(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleChannelDeathItem(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleBindSight(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleForceReaction(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraEmpathy(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleComprehendLanguage(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraConvertRune(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+ void HandleAuraLinked(AuraApplication const * aurApp, uint8 mode, bool apply) const;
+};
+
+#endif \ No newline at end of file
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 36490425400..19d484c0a4b 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -19,1664 +19,469 @@
*/
#include "Common.h"
-#include "Database/DatabaseEnv.h"
#include "WorldPacket.h"
-#include "WorldSession.h"
#include "Opcodes.h"
#include "Log.h"
-#include "UpdateMask.h"
-#include "World.h"
#include "ObjectMgr.h"
#include "SpellMgr.h"
#include "Player.h"
#include "Unit.h"
#include "Spell.h"
+#include "SpellAuraEffects.h"
#include "SpellId.h"
#include "DynamicObject.h"
-#include "Group.h"
-#include "UpdateData.h"
#include "ObjectAccessor.h"
-#include "Policies/SingletonImp.h"
-#include "Totem.h"
-#include "Creature.h"
-#include "Formulas.h"
-#include "BattleGround.h"
-#include "OutdoorPvP.h"
-#include "OutdoorPvPMgr.h"
-#include "CreatureAI.h"
-#include "ScriptCalls.h"
#include "Util.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
-#include "Vehicle.h"
#include "CellImpl.h"
-#define Aura AuraEffect
-pAuraHandler AuraHandler[TOTAL_AURAS]=
+AuraApplication::AuraApplication(Unit * target, Unit * caster, Aura * aura)
+ : m_target(target), m_base(aura), m_slot(MAX_AURAS), m_flags(AFLAG_NONE), m_needClientUpdate(false), m_removeMode(AURA_REMOVE_NONE), m_canBeRemoved(false)
{
- &Aura::HandleNULL, // 0 SPELL_AURA_NONE
- &Aura::HandleBindSight, // 1 SPELL_AURA_BIND_SIGHT
- &Aura::HandleModPossess, // 2 SPELL_AURA_MOD_POSSESS
- &Aura::HandlePeriodicDamage, // 3 SPELL_AURA_PERIODIC_DAMAGE
- &Aura::HandleAuraDummy, // 4 SPELL_AURA_DUMMY
- &Aura::HandleModConfuse, // 5 SPELL_AURA_MOD_CONFUSE
- &Aura::HandleModCharm, // 6 SPELL_AURA_MOD_CHARM
- &Aura::HandleModFear, // 7 SPELL_AURA_MOD_FEAR
- &Aura::HandlePeriodicHeal, // 8 SPELL_AURA_PERIODIC_HEAL
- &Aura::HandleModAttackSpeed, // 9 SPELL_AURA_MOD_ATTACKSPEED
- &Aura::HandleModThreat, // 10 SPELL_AURA_MOD_THREAT
- &Aura::HandleModTaunt, // 11 SPELL_AURA_MOD_TAUNT
- &Aura::HandleAuraModStun, // 12 SPELL_AURA_MOD_STUN
- &Aura::HandleModDamageDone, // 13 SPELL_AURA_MOD_DAMAGE_DONE
- &Aura::HandleNoImmediateEffect, // 14 SPELL_AURA_MOD_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
- &Aura::HandleNoImmediateEffect, // 15 SPELL_AURA_DAMAGE_SHIELD implemented in Unit::DoAttackDamage
- &Aura::HandleModStealth, // 16 SPELL_AURA_MOD_STEALTH
- &Aura::HandleNoImmediateEffect, // 17 SPELL_AURA_MOD_STEALTH_DETECT
- &Aura::HandleInvisibility, // 18 SPELL_AURA_MOD_INVISIBILITY
- &Aura::HandleInvisibilityDetect, // 19 SPELL_AURA_MOD_INVISIBILITY_DETECTION
- &Aura::HandleAuraModTotalHealthPercentRegen, // 20 SPELL_AURA_OBS_MOD_HEALTH
- &Aura::HandleAuraModTotalEnergyPercentRegen, // 21 SPELL_AURA_OBS_MOD_POWER
- &Aura::HandleAuraModResistance, // 22 SPELL_AURA_MOD_RESISTANCE
- &Aura::HandlePeriodicTriggerSpell, // 23 SPELL_AURA_PERIODIC_TRIGGER_SPELL
- &Aura::HandlePeriodicEnergize, // 24 SPELL_AURA_PERIODIC_ENERGIZE
- &Aura::HandleAuraModPacify, // 25 SPELL_AURA_MOD_PACIFY
- &Aura::HandleAuraModRoot, // 26 SPELL_AURA_MOD_ROOT
- &Aura::HandleAuraModSilence, // 27 SPELL_AURA_MOD_SILENCE
- &Aura::HandleNoImmediateEffect, // 28 SPELL_AURA_REFLECT_SPELLS implement in Unit::SpellHitResult
- &Aura::HandleAuraModStat, // 29 SPELL_AURA_MOD_STAT
- &Aura::HandleAuraModSkill, // 30 SPELL_AURA_MOD_SKILL
- &Aura::HandleAuraModIncreaseSpeed, // 31 SPELL_AURA_MOD_INCREASE_SPEED
- &Aura::HandleAuraModIncreaseMountedSpeed, // 32 SPELL_AURA_MOD_INCREASE_MOUNTED_SPEED
- &Aura::HandleAuraModDecreaseSpeed, // 33 SPELL_AURA_MOD_DECREASE_SPEED
- &Aura::HandleAuraModIncreaseHealth, // 34 SPELL_AURA_MOD_INCREASE_HEALTH
- &Aura::HandleAuraModIncreaseEnergy, // 35 SPELL_AURA_MOD_INCREASE_ENERGY
- &Aura::HandleAuraModShapeshift, // 36 SPELL_AURA_MOD_SHAPESHIFT
- &Aura::HandleAuraModEffectImmunity, // 37 SPELL_AURA_EFFECT_IMMUNITY
- &Aura::HandleAuraModStateImmunity, // 38 SPELL_AURA_STATE_IMMUNITY
- &Aura::HandleAuraModSchoolImmunity, // 39 SPELL_AURA_SCHOOL_IMMUNITY
- &Aura::HandleAuraModDmgImmunity, // 40 SPELL_AURA_DAMAGE_IMMUNITY
- &Aura::HandleAuraModDispelImmunity, // 41 SPELL_AURA_DISPEL_IMMUNITY
- &Aura::HandleAuraProcTriggerSpell, // 42 SPELL_AURA_PROC_TRIGGER_SPELL implemented in Unit::ProcDamageAndSpellFor and Unit::HandleProcTriggerSpell
- &Aura::HandleNoImmediateEffect, // 43 SPELL_AURA_PROC_TRIGGER_DAMAGE implemented in Unit::ProcDamageAndSpellFor
- &Aura::HandleAuraTrackCreatures, // 44 SPELL_AURA_TRACK_CREATURES
- &Aura::HandleAuraTrackResources, // 45 SPELL_AURA_TRACK_RESOURCES
- &Aura::HandleNULL, // 46 SPELL_AURA_46 (used in test spells 54054 and 54058, and spell 48050) (3.0.8a)
- &Aura::HandleAuraModParryPercent, // 47 SPELL_AURA_MOD_PARRY_PERCENT
- &Aura::HandleNULL, // 48 SPELL_AURA_48 spell Napalm (area damage spell with additional delayed damage effect)
- &Aura::HandleAuraModDodgePercent, // 49 SPELL_AURA_MOD_DODGE_PERCENT
- &Aura::HandleNoImmediateEffect, // 50 SPELL_AURA_MOD_CRITICAL_HEALING_AMOUNT implemented in Unit::SpellCriticalHealingBonus
- &Aura::HandleAuraModBlockPercent, // 51 SPELL_AURA_MOD_BLOCK_PERCENT
- &Aura::HandleAuraModWeaponCritPercent, // 52 SPELL_AURA_MOD_WEAPON_CRIT_PERCENT
- &Aura::HandlePeriodicLeech, // 53 SPELL_AURA_PERIODIC_LEECH
- &Aura::HandleModHitChance, // 54 SPELL_AURA_MOD_HIT_CHANCE
- &Aura::HandleModSpellHitChance, // 55 SPELL_AURA_MOD_SPELL_HIT_CHANCE
- &Aura::HandleAuraTransform, // 56 SPELL_AURA_TRANSFORM
- &Aura::HandleModSpellCritChance, // 57 SPELL_AURA_MOD_SPELL_CRIT_CHANCE
- &Aura::HandleAuraModIncreaseSwimSpeed, // 58 SPELL_AURA_MOD_INCREASE_SWIM_SPEED
- &Aura::HandleNoImmediateEffect, // 59 SPELL_AURA_MOD_DAMAGE_DONE_CREATURE implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
- &Aura::HandleAuraModPacifyAndSilence, // 60 SPELL_AURA_MOD_PACIFY_SILENCE
- &Aura::HandleAuraModScale, // 61 SPELL_AURA_MOD_SCALE
- &Aura::HandlePeriodicHealthFunnel, // 62 SPELL_AURA_PERIODIC_HEALTH_FUNNEL
- &Aura::HandleNULL, // 63 unused (3.0.8a) old SPELL_AURA_PERIODIC_MANA_FUNNEL
- &Aura::HandlePeriodicManaLeech, // 64 SPELL_AURA_PERIODIC_MANA_LEECH
- &Aura::HandleModCastingSpeed, // 65 SPELL_AURA_MOD_CASTING_SPEED_NOT_STACK
- &Aura::HandleFeignDeath, // 66 SPELL_AURA_FEIGN_DEATH
- &Aura::HandleAuraModDisarm, // 67 SPELL_AURA_MOD_DISARM
- &Aura::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED
- &Aura::HandleNoImmediateEffect, // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist
- &Aura::HandleUnused, // 70 SPELL_AURA_EXTRA_ATTACKS Useless, used by only one spell that has only visual effect
- &Aura::HandleModSpellCritChanceShool, // 71 SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL
- &Aura::HandleModPowerCostPCT, // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
- &Aura::HandleModPowerCost, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
- &Aura::HandleNoImmediateEffect, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL implemented in Unit::SpellHitResult
- &Aura::HandleNoImmediateEffect, // 75 SPELL_AURA_MOD_LANGUAGE
- &Aura::HandleFarSight, // 76 SPELL_AURA_FAR_SIGHT
- &Aura::HandleModMechanicImmunity, // 77 SPELL_AURA_MECHANIC_IMMUNITY
- &Aura::HandleAuraMounted, // 78 SPELL_AURA_MOUNTED
- &Aura::HandleModDamagePercentDone, // 79 SPELL_AURA_MOD_DAMAGE_PERCENT_DONE
- &Aura::HandleModPercentStat, // 80 SPELL_AURA_MOD_PERCENT_STAT
- &Aura::HandleNoImmediateEffect, // 81 SPELL_AURA_SPLIT_DAMAGE_PCT
- &Aura::HandleWaterBreathing, // 82 SPELL_AURA_WATER_BREATHING
- &Aura::HandleModBaseResistance, // 83 SPELL_AURA_MOD_BASE_RESISTANCE
- &Aura::HandleModRegen, // 84 SPELL_AURA_MOD_REGEN
- &Aura::HandleModPowerRegen, // 85 SPELL_AURA_MOD_POWER_REGEN
- &Aura::HandleChannelDeathItem, // 86 SPELL_AURA_CHANNEL_DEATH_ITEM
- &Aura::HandleNoImmediateEffect, // 87 SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN implemented in Unit::MeleeDamageBonus and Unit::SpellDamageBonus
- &Aura::HandleNoImmediateEffect, // 88 SPELL_AURA_MOD_HEALTH_REGEN_PERCENT
- &Aura::HandlePeriodicDamagePCT, // 89 SPELL_AURA_PERIODIC_DAMAGE_PERCENT
- &Aura::HandleUnused, // 90 unused (3.0.8a) old SPELL_AURA_MOD_RESIST_CHANCE
- &Aura::HandleNoImmediateEffect, // 91 SPELL_AURA_MOD_DETECT_RANGE implemented in Creature::GetAttackDistance
- &Aura::HandlePreventFleeing, // 92 SPELL_AURA_PREVENTS_FLEEING
- &Aura::HandleModUnattackable, // 93 SPELL_AURA_MOD_UNATTACKABLE
- &Aura::HandleNoImmediateEffect, // 94 SPELL_AURA_INTERRUPT_REGEN implemented in Player::RegenerateAll
- &Aura::HandleAuraGhost, // 95 SPELL_AURA_GHOST
- &Aura::HandleNoImmediateEffect, // 96 SPELL_AURA_SPELL_MAGNET implemented in Unit::SelectMagnetTarget
- &Aura::HandleNoImmediateEffect, // 97 SPELL_AURA_MANA_SHIELD implemented in Unit::CalcAbsorbResist
- &Aura::HandleAuraModSkill, // 98 SPELL_AURA_MOD_SKILL_TALENT
- &Aura::HandleAuraModAttackPower, // 99 SPELL_AURA_MOD_ATTACK_POWER
- &Aura::HandleUnused, //100 SPELL_AURA_AURAS_VISIBLE obsolete? all player can see all auras now, but still have spells including GM-spell
- &Aura::HandleModResistancePercent, //101 SPELL_AURA_MOD_RESISTANCE_PCT
- &Aura::HandleNoImmediateEffect, //102 SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
- &Aura::HandleAuraModTotalThreat, //103 SPELL_AURA_MOD_TOTAL_THREAT
- &Aura::HandleAuraWaterWalk, //104 SPELL_AURA_WATER_WALK
- &Aura::HandleAuraFeatherFall, //105 SPELL_AURA_FEATHER_FALL
- &Aura::HandleAuraHover, //106 SPELL_AURA_HOVER
- &Aura::HandleAddModifier, //107 SPELL_AURA_ADD_FLAT_MODIFIER
- &Aura::HandleAddModifier, //108 SPELL_AURA_ADD_PCT_MODIFIER
- &Aura::HandleNoImmediateEffect, //109 SPELL_AURA_ADD_TARGET_TRIGGER
- &Aura::HandleModPowerRegenPCT, //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT
- &Aura::HandleNoImmediateEffect, //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER implemented in Unit::SelectMagnetTarget
- &Aura::HandleNoImmediateEffect, //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS
- &Aura::HandleNoImmediateEffect, //113 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //114 SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //115 SPELL_AURA_MOD_HEALING implemented in Unit::SpellBaseHealingBonusForVictim
- &Aura::HandleNoImmediateEffect, //116 SPELL_AURA_MOD_REGEN_DURING_COMBAT
- &Aura::HandleNoImmediateEffect, //117 SPELL_AURA_MOD_MECHANIC_RESISTANCE implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //118 SPELL_AURA_MOD_HEALING_PCT implemented in Unit::SpellHealingBonus
- &Aura::HandleUnused, //119 unused (3.0.8a) old SPELL_AURA_SHARE_PET_TRACKING
- &Aura::HandleAuraUntrackable, //120 SPELL_AURA_UNTRACKABLE
- &Aura::HandleAuraEmpathy, //121 SPELL_AURA_EMPATHY
- &Aura::HandleModOffhandDamagePercent, //122 SPELL_AURA_MOD_OFFHAND_DAMAGE_PCT
- &Aura::HandleModTargetResistance, //123 SPELL_AURA_MOD_TARGET_RESISTANCE
- &Aura::HandleAuraModRangedAttackPower, //124 SPELL_AURA_MOD_RANGED_ATTACK_POWER
- &Aura::HandleNoImmediateEffect, //125 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN implemented in Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //126 SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT implemented in Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //127 SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
- &Aura::HandleModPossessPet, //128 SPELL_AURA_MOD_POSSESS_PET
- &Aura::HandleAuraModIncreaseSpeed, //129 SPELL_AURA_MOD_SPEED_ALWAYS
- &Aura::HandleAuraModIncreaseMountedSpeed, //130 SPELL_AURA_MOD_MOUNTED_SPEED_ALWAYS
- &Aura::HandleNoImmediateEffect, //131 SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS implemented in Unit::MeleeDamageBonus
- &Aura::HandleAuraModIncreaseEnergyPercent, //132 SPELL_AURA_MOD_INCREASE_ENERGY_PERCENT
- &Aura::HandleAuraModIncreaseHealthPercent, //133 SPELL_AURA_MOD_INCREASE_HEALTH_PERCENT
- &Aura::HandleAuraModRegenInterrupt, //134 SPELL_AURA_MOD_MANA_REGEN_INTERRUPT
- &Aura::HandleModHealingDone, //135 SPELL_AURA_MOD_HEALING_DONE
- &Aura::HandleNoImmediateEffect, //136 SPELL_AURA_MOD_HEALING_DONE_PERCENT implemented in Unit::SpellHealingBonus
- &Aura::HandleModTotalPercentStat, //137 SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE
- &Aura::HandleHaste, //138 SPELL_AURA_MOD_HASTE
- &Aura::HandleForceReaction, //139 SPELL_AURA_FORCE_REACTION
- &Aura::HandleAuraModRangedHaste, //140 SPELL_AURA_MOD_RANGED_HASTE
- &Aura::HandleRangedAmmoHaste, //141 SPELL_AURA_MOD_RANGED_AMMO_HASTE
- &Aura::HandleAuraModBaseResistancePCT, //142 SPELL_AURA_MOD_BASE_RESISTANCE_PCT
- &Aura::HandleAuraModResistanceExclusive, //143 SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE
- &Aura::HandleNoImmediateEffect, //144 SPELL_AURA_SAFE_FALL implemented in WorldSession::HandleMovementOpcodes
- &Aura::HandleAuraModPetTalentsPoints, //145 SPELL_AURA_MOD_PET_TALENT_POINTS
- &Aura::HandleNoImmediateEffect, //146 SPELL_AURA_ALLOW_TAME_PET_TYPE
- &Aura::HandleModStateImmunityMask, //147 SPELL_AURA_MECHANIC_IMMUNITY_MASK
- &Aura::HandleAuraRetainComboPoints, //148 SPELL_AURA_RETAIN_COMBO_POINTS
- &Aura::HandleNoImmediateEffect, //149 SPELL_AURA_REDUCE_PUSHBACK
- &Aura::HandleShieldBlockValue, //150 SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT
- &Aura::HandleAuraTrackStealthed, //151 SPELL_AURA_TRACK_STEALTHED
- &Aura::HandleNoImmediateEffect, //152 SPELL_AURA_MOD_DETECTED_RANGE implemented in Creature::GetAttackDistance
- &Aura::HandleNoImmediateEffect, //153 SPELL_AURA_SPLIT_DAMAGE_FLAT
- &Aura::HandleNoImmediateEffect, //154 SPELL_AURA_MOD_STEALTH_LEVEL
- &Aura::HandleNoImmediateEffect, //155 SPELL_AURA_MOD_WATER_BREATHING
- &Aura::HandleNoImmediateEffect, //156 SPELL_AURA_MOD_REPUTATION_GAIN
- &Aura::HandleNULL, //157 SPELL_AURA_PET_DAMAGE_MULTI
- &Aura::HandleShieldBlockValue, //158 SPELL_AURA_MOD_SHIELD_BLOCKVALUE
- &Aura::HandleNoImmediateEffect, //159 SPELL_AURA_NO_PVP_CREDIT only for Honorless Target spell
- &Aura::HandleNoImmediateEffect, //160 SPELL_AURA_MOD_AOE_AVOIDANCE implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //161 SPELL_AURA_MOD_HEALTH_REGEN_IN_COMBAT
- &Aura::HandleAuraPowerBurn, //162 SPELL_AURA_POWER_BURN_MANA
- &Aura::HandleNoImmediateEffect, //163 SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE
- &Aura::HandleUnused, //164 unused (3.0.8a), only one test spell
- &Aura::HandleNoImmediateEffect, //165 SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS implemented in Unit::MeleeDamageBonus
- &Aura::HandleAuraModAttackPowerPercent, //166 SPELL_AURA_MOD_ATTACK_POWER_PCT
- &Aura::HandleAuraModRangedAttackPowerPercent, //167 SPELL_AURA_MOD_RANGED_ATTACK_POWER_PCT
- &Aura::HandleNoImmediateEffect, //168 SPELL_AURA_MOD_DAMAGE_DONE_VERSUS implemented in Unit::SpellDamageBonus, Unit::MeleeDamageBonus
- &Aura::HandleNoImmediateEffect, //169 SPELL_AURA_MOD_CRIT_PERCENT_VERSUS implemented in Unit::DealDamageBySchool, Unit::DoAttackDamage, Unit::SpellCriticalBonus
- &Aura::HandleNULL, //170 SPELL_AURA_DETECT_AMORE various spells that change visual of units for aura target (clientside?)
- &Aura::HandleAuraModIncreaseSpeed, //171 SPELL_AURA_MOD_SPEED_NOT_STACK
- &Aura::HandleAuraModIncreaseMountedSpeed, //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK
- &Aura::HandleUnused, //173 unused (3.0.8a) no spells, old SPELL_AURA_ALLOW_CHAMPION_SPELLS only for Proclaim Champion spell
- &Aura::HandleModSpellDamagePercentFromStat, //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT implemented in Unit::SpellBaseDamageBonus
- &Aura::HandleModSpellHealingPercentFromStat, //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus
- &Aura::HandleSpiritOfRedemption, //176 SPELL_AURA_SPIRIT_OF_REDEMPTION only for Spirit of Redemption spell, die at aura end
- &Aura::HandleCharmConvert, //177 SPELL_AURA_AOE_CHARM
- &Aura::HandleNoImmediateEffect, //178 SPELL_AURA_MOD_DEBUFF_RESISTANCE implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //179 SPELL_AURA_MOD_ATTACKER_SPELL_CRIT_CHANCE implemented in Unit::SpellCriticalBonus
- &Aura::HandleNoImmediateEffect, //180 SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS implemented in Unit::SpellDamageBonus
- &Aura::HandleUnused, //181 unused (3.0.8a) old SPELL_AURA_MOD_FLAT_SPELL_CRIT_DAMAGE_VERSUS
- &Aura::HandleAuraModResistenceOfStatPercent, //182 SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT
- &Aura::HandleNULL, //183 SPELL_AURA_MOD_CRITICAL_THREAT only used in 28746 - miscvalue - spell school
- &Aura::HandleNoImmediateEffect, //184 SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
- &Aura::HandleNoImmediateEffect, //185 SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
- &Aura::HandleNoImmediateEffect, //186 SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //187 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
- &Aura::HandleNoImmediateEffect, //188 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_CHANCE implemented in Unit::GetUnitCriticalChance
- &Aura::HandleModRating, //189 SPELL_AURA_MOD_RATING
- &Aura::HandleNoImmediateEffect, //190 SPELL_AURA_MOD_FACTION_REPUTATION_GAIN implemented in Player::CalculateReputationGain
- &Aura::HandleAuraModUseNormalSpeed, //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED
- &Aura::HandleModMeleeRangedSpeedPct, //192 SPELL_AURA_HASTE_MELEE
- &Aura::HandleModCombatSpeedPct, //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct)
- &Aura::HandleNoImmediateEffect, //194 SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
- &Aura::HandleNoImmediateEffect, //195 SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL implemented in Unit::CalcAbsorbResist
- &Aura::HandleNULL, //196 SPELL_AURA_MOD_COOLDOWN - flat mod of spell cooldowns
- &Aura::HandleNoImmediateEffect, //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance
- &Aura::HandleUnused, //198 unused (3.0.8a) old SPELL_AURA_MOD_ALL_WEAPON_SKILLS
- &Aura::HandleNoImmediateEffect, //199 SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT implemented in Unit::MagicSpellHitResult
- &Aura::HandleNoImmediateEffect, //200 SPELL_AURA_MOD_XP_PCT implemented in Player::RewardPlayerAndGroupAtKill
- &Aura::HandleAuraAllowFlight, //201 SPELL_AURA_FLY this aura enable flight mode...
- &Aura::HandleNoImmediateEffect, //202 SPELL_AURA_CANNOT_BE_DODGED implemented in Unit::RollPhysicalOutcomeAgainst
- &Aura::HandleNoImmediateEffect, //203 SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
- &Aura::HandleNoImmediateEffect, //204 SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE implemented in Unit::CalculateMeleeDamage and Unit::CalculateSpellDamage
- &Aura::HandleNoImmediateEffect, //205 SPELL_AURA_MOD_SCHOOL_CRIT_DMG_TAKEN
- &Aura::HandleAuraModIncreaseFlightSpeed, //206 SPELL_AURA_MOD_INCREASE_VEHICLE_FLIGHT_SPEED
- &Aura::HandleAuraModIncreaseFlightSpeed, //207 SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED
- &Aura::HandleAuraModIncreaseFlightSpeed, //208 SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED
- &Aura::HandleAuraModIncreaseFlightSpeed, //209 SPELL_AURA_MOD_MOUNTED_FLIGHT_SPEED_ALWAYS
- &Aura::HandleAuraModIncreaseFlightSpeed, //210 SPELL_AURA_MOD_VEHICLE_SPEED_ALWAYS
- &Aura::HandleAuraModIncreaseFlightSpeed, //211 SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK
- &Aura::HandleAuraModRangedAttackPowerOfStatPercent, //212 SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT
- &Aura::HandleNoImmediateEffect, //213 SPELL_AURA_MOD_RAGE_FROM_DAMAGE_DEALT implemented in Player::RewardRage
- &Aura::HandleNULL, //214 Tamed Pet Passive
- &Aura::HandleArenaPreparation, //215 SPELL_AURA_ARENA_PREPARATION
- &Aura::HandleModCastingSpeed, //216 SPELL_AURA_HASTE_SPELLS
- &Aura::HandleUnused, //217 unused (3.0.8a)
- &Aura::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED
- &Aura::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT
- &Aura::HandleModRatingFromStat, //220 SPELL_AURA_MOD_RATING_FROM_STAT
- &Aura::HandleNULL, //221 SPELL_AURA_MOD_DETAUNT
- &Aura::HandleUnused, //222 unused (3.0.8a) only for spell 44586 that not used in real spell cast
- &Aura::HandleNoImmediateEffect, //223 SPELL_AURA_RAID_PROC_FROM_CHARGE
- &Aura::HandleUnused, //224 unused (3.0.8a)
- &Aura::HandleNoImmediateEffect, //225 SPELL_AURA_RAID_PROC_FROM_CHARGE_WITH_VALUE
- &Aura::HandleAuraPeriodicDummy, //226 SPELL_AURA_PERIODIC_DUMMY
- &Aura::HandlePeriodicTriggerSpellWithValue, //227 SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE
- &Aura::HandleNoImmediateEffect, //228 SPELL_AURA_DETECT_STEALTH stealth detection
- &Aura::HandleNoImmediateEffect, //229 SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE
- &Aura::HandleAuraModIncreaseHealth, //230 SPELL_AURA_MOD_INCREASE_HEALTH_2
- &Aura::HandleNoImmediateEffect, //231 SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE
- &Aura::HandleNoImmediateEffect, //232 SPELL_AURA_MECHANIC_DURATION_MOD implement in Unit::CalculateSpellDuration
- &Aura::HandleUnused, //233 set model id to the one of the creature with id GetMiscValue() - clientside
- &Aura::HandleNoImmediateEffect, //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration
- &Aura::HandleNoImmediateEffect, //235 SPELL_AURA_MOD_DISPEL_RESIST implement in Unit::MagicSpellHitResult
- &Aura::HandleAuraControlVehicle, //236 SPELL_AURA_CONTROL_VEHICLE
- &Aura::HandleModSpellDamagePercentFromAttackPower, //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER implemented in Unit::SpellBaseDamageBonus
- &Aura::HandleModSpellHealingPercentFromAttackPower, //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus
- &Aura::HandleAuraModScale, //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61
- &Aura::HandleAuraModExpertise, //240 SPELL_AURA_MOD_EXPERTISE
- &Aura::HandleForceMoveForward, //241 SPELL_AURA_FORCE_MOVE_FORWARD Forces the player to move forward
- &Aura::HandleUnused, //242 SPELL_AURA_MOD_SPELL_DAMAGE_FROM_HEALING - 2 test spells: 44183 and 44182
- &Aura::HandleNULL, //243 faction reaction override spells
- &Aura::HandleComprehendLanguage, //244 SPELL_AURA_COMPREHEND_LANGUAGE
- &Aura::HandleNoImmediateEffect, //245 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL
- &Aura::HandleNoImmediateEffect, //246 SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK implemented in Spell::EffectApplyAura
- &Aura::HandleAuraCloneCaster, //247 SPELL_AURA_CLONE_CASTER
- &Aura::HandleNoImmediateEffect, //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE implemented in Unit::RollMeleeOutcomeAgainst
- &Aura::HandleAuraConvertRune, //249 SPELL_AURA_CONVERT_RUNE
- &Aura::HandleAuraModIncreaseHealth, //250 SPELL_AURA_MOD_INCREASE_HEALTH_2
- &Aura::HandleNoImmediateEffect, //251 SPELL_AURA_MOD_ENEMY_DODGE
- &Aura::HandleModCombatSpeedPct, //252 SPELL_AURA_252 Is there any difference between this and SPELL_AURA_MELEE_SLOW ? maybe not stacking mod?
- &Aura::HandleNoImmediateEffect, //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE implemented in Unit::isBlockCritical
- &Aura::HandleAuraModDisarm, //254 SPELL_AURA_MOD_DISARM_OFFHAND
- &Aura::HandleNoImmediateEffect, //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT implemented in Unit::SpellDamageBonus
- &Aura::HandleNoReagentUseAura, //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select
- &Aura::HandleNULL, //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select
- &Aura::HandleNULL, //258 SPELL_AURA_MOD_SPELL_VISUAL
- &Aura::HandleNoImmediateEffect, //259 SPELL_AURA_MOD_HOT_PCT implemented in Unit::SpellHealingBonus
- &Aura::HandleNoImmediateEffect, //260 SPELL_AURA_SCREEN_EFFECT (miscvalue = id in ScreenEffect.dbc) not required any code
- &Aura::HandlePhase, //261 SPELL_AURA_PHASE undetactable invisibility? implemented in Unit::isVisibleForOrDetect
- &Aura::HandleNoImmediateEffect, //262 SPELL_AURA_ABILITY_IGNORE_AURASTATE implemented in spell::cancast
- &Aura::HandleAuraAllowOnlyAbility, //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilities set in SpellClassMask
- &Aura::HandleUnused, //264 unused (3.0.8a)
- &Aura::HandleUnused, //265 unused (3.0.8a)
- &Aura::HandleUnused, //266 unused (3.0.8a)
- &Aura::HandleNoImmediateEffect, //267 SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL implemented in Unit::IsImmunedToSpellEffect
- &Aura::HandleAuraModAttackPowerOfStatPercent, //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT
- &Aura::HandleNoImmediateEffect, //269 SPELL_AURA_MOD_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
- &Aura::HandleNoImmediateEffect, //270 SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST implemented in Unit::CalcAbsorbResist and CalcArmorReducedDamage
- &Aura::HandleNoImmediateEffect, //271 SPELL_AURA_MOD_DAMAGE_FROM_CASTER implemented in Unit::SpellDamageBonus
- &Aura::HandleNULL, //272 unknown
- &Aura::HandleNoImmediateEffect, //273 SPELL_AURA_X_RAY (client side implementation)
- &Aura::HandleNoImmediateEffect, //274 SPELL_AURA_CONSUME_NO_AMMO implemented in spell::CalculateDamageDoneForAllTargets
- &Aura::HandleNoImmediateEffect, //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select
- &Aura::HandleNULL, //276 mod damage % mechanic?
- &Aura::HandleNoImmediateEffect, //277 SPELL_AURA_MOD_ABILITY_AFFECTED_TARGETS implemented in spell::settargetmap
- &Aura::HandleAuraModDisarm, //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon
- &Aura::HandleAuraInitializeImages, //279 SPELL_AURA_INITIALIZE_IMAGES
- &Aura::HandleNoImmediateEffect, //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT
- &Aura::HandleNoImmediateEffect, //281 SPELL_AURA_MOD_HONOR_GAIN_PCT implemented in Player::RewardHonor
- &Aura::HandleAuraIncreaseBaseHealthPercent, //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT
- &Aura::HandleNoImmediateEffect, //283 SPELL_AURA_MOD_HEALING_RECEIVED implemented in Unit::SpellHealingBonus
- &Aura::HandleAuraLinked, //284 SPELL_AURA_LINKED 51 spells using
- &Aura::HandleAuraModAttackPowerOfArmor, //285 SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR implemented in Player::UpdateAttackPowerAndDamage
- &Aura::HandleNoImmediateEffect, //286 SPELL_AURA_ABILITY_PERIODIC_CRIT implemented in AuraEffect::PeriodicTick
- &Aura::HandleNoImmediateEffect, //287 SPELL_AURA_DEFLECT_SPELLS implemented in Unit::MagicSpellHitResult and Unit::MeleeSpellHitResult
- &Aura::HandleNoImmediateEffect, //288 SPELL_AURA_IGNORE_HIT_DIRECTION implemented in Unit::MagicSpellHitResult and Unit::MeleeSpellHitResult Unit::RollMeleeOutcomeAgainst
- &Aura::HandleUnused, //289 unused (3.2.2a)
- &Aura::HandleAuraModCritPct, //290 SPELL_AURA_MOD_CRIT_PCT
- &Aura::HandleNoImmediateEffect, //291 SPELL_AURA_MOD_XP_QUEST_PCT implemented in Player::RewardQuest
- &Aura::HandleNULL, //292 call stabled pet
- &Aura::HandleNULL, //293 2 test spells
- &Aura::HandleNoImmediateEffect, //294 SPELL_AURA_PREVENT_REGENERATE_POWER implemented in Player::Regenerate(Powers power)
- &Aura::HandleNULL, //295 unused
- &Aura::HandleNULL, //296 2 spells
- &Aura::HandleNULL, //297 1 spell (counter spell school?)
- &Aura::HandleNULL, //298 unused
- &Aura::HandleNULL, //299 unused
- &Aura::HandleNULL, //300 3 spells (share damage?)
- &Aura::HandleNULL, //301 5 spells
- &Aura::HandleNULL, //302 unused
- &Aura::HandleNULL, //303 17 spells
- &Aura::HandleAuraModInebriation, //304 2 spells
- &Aura::HandleAuraModIncreaseSpeed, //305 SPELL_AURA_MOD_MINIMUM_SPEED
- &Aura::HandleNULL //306 1 spell
-};
-#undef Aura
-
-Aura::Aura(SpellEntry const* spellproto, uint32 effMask, Unit *target, WorldObject *source, Unit *caster, int32 *currentBasePoints, Item* castItem) :
- m_spellProto(spellproto),
- m_target(target), m_sourceGuid(source->GetGUID()), m_casterGuid(caster->GetGUID()), m_castItemGuid(castItem ? castItem->GetGUID() : 0),
- m_applyTime(time(NULL)),
- m_timeCla(0), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE),
- m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1), m_isRemoved(false)
-{
- assert(target);
- assert(spellproto && spellproto == sSpellStore.LookupEntry( spellproto->Id ) && "`info` must be pointer to sSpellStore element");
-
- m_auraFlags = effMask;
-
- if(m_spellProto->manaPerSecond || m_spellProto->manaPerSecondPerLevel)
- m_timeCla = 1000;
-
- m_isPassive = IsPassiveSpell(GetId());
-
- m_isSingleTargetAura = IsSingleTargetSpell(m_spellProto);
-
- //damage = caster->CalculateSpellDamage(m_spellProto,m_effIndex,m_currentBasePoints,target);
- m_maxduration = caster->CalcSpellDuration(m_spellProto);
-
- if(m_maxduration == -1 || m_isPassive && m_spellProto->DurationIndex == 0)
- m_permanent = true;
- else
- m_permanent = false;
-
- Player* modOwner = caster->GetSpellModOwner();
-
- if(!m_permanent && modOwner)
- {
- modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, m_maxduration);
- // Get zero duration aura after - need set m_maxduration > 0 for apply/remove aura work
- if (m_maxduration<=0)
- m_maxduration = 1;
- }
-
- m_duration = m_maxduration;
-
- m_isDeathPersist = IsDeathPersistentSpell(m_spellProto);
-
- m_procCharges = m_spellProto->procCharges;
- if(modOwner)
- modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
+ assert(GetTarget() && GetBase());
- m_isRemovedOnShapeLost = (caster == target &&
- m_spellProto->Stances &&
- !(m_spellProto->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) &&
- !(m_spellProto->Attributes & SPELL_ATTR_NOT_SHAPESHIFT));
-
- for (uint8 i=0 ; i<MAX_SPELL_EFFECTS; ++i)
+ if(GetBase()->IsVisible())
{
- if (m_auraFlags & (uint8(1) << i))
+ // Try find slot for aura
+ uint8 slot = MAX_AURAS;
+ // Lookup for auras already applied from spell
+ if (AuraApplication * foundAura = m_target->GetAuraApplication(m_base->GetId(), m_base->GetCasterGUID()))
{
- if(!(m_partAuras[i] = CreateAuraEffect(this, i, currentBasePoints ? currentBasePoints + i : NULL)))
- m_auraFlags &= uint8(~(1<< i)); // correct flags if aura couldn't be created
+ // allow use single slot only by auras from same caster
+ slot = foundAura->GetSlot();
}
else
{
- m_partAuras[i] = NULL;
+ Unit::VisibleAuraMap const * visibleAuras = m_target->GetVisibleAuras();
+ // lookup for free slots in units visibleAuras
+ Unit::VisibleAuraMap::const_iterator itr = visibleAuras->find(0);
+ for (uint32 freeSlot = 0; freeSlot < MAX_AURAS; ++itr , ++freeSlot)
+ {
+ if(itr == visibleAuras->end() || itr->first != freeSlot)
+ {
+ slot = freeSlot;
+ break;
+ }
+ }
}
- }
- // Aura is positive when it is casted by friend and at least one aura is positive
- // or when it is casted by enemy and at least one aura is negative
- bool swap = false;
- if (caster == target) // caster == target - 1 negative effect is enough for aura to be negative
- m_positive = false;
- else
- m_positive = !caster->IsHostileTo(m_target);
-
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- {
- if((1<<i & GetEffectMask()) && m_positive == IsPositiveEffect(GetId(), i))
+ // Register Visible Aura
+ if(slot < MAX_AURAS)
{
- swap = true;
- break;
+ m_slot = slot;
+ m_target->SetVisibleAura(slot, this);
+ SetNeedClientUpdate();
+ sLog.outDebug("Aura: %u Effect: %d put to unit visible auras slot: %u", GetBase()->GetId(), GetEffectMask(), slot);
}
+ else
+ sLog.outDebug("Aura: %u Effect: %d could not find empty unit visible slot", GetBase()->GetId(), GetEffectMask());
}
- if (!swap)
- m_positive = !m_positive;
-}
+ m_flags |= (_CheckPositive(caster) ? AFLAG_POSITIVE : AFLAG_NEGATIVE) |
+ (GetBase()->GetCasterGUID() == GetTarget()->GetGUID() ? AFLAG_CASTER : AFLAG_NONE);
-Aura::~Aura()
-{
- // free part auras memory
- for (uint8 i=0 ; i<MAX_SPELL_EFFECTS; ++i)
- if (m_partAuras[i])
- delete m_partAuras[i];
+ m_isNeedManyNegativeEffects = false;
+ if (GetBase()->GetCasterGUID() == GetTarget()->GetGUID()) // caster == target - 1 negative effect is enough for aura to be negative
+ m_isNeedManyNegativeEffects = false;
+ else if (caster)
+ m_isNeedManyNegativeEffects = caster->IsFriendlyTo(m_target);
}
-AuraEffect::AuraEffect(Aura *parentAura, uint8 effIndex, int32 *currentBasePoints) :
-m_parentAura(parentAura), m_spellmod(NULL), m_periodicTimer(0), m_isPeriodic(false), m_isAreaAura(false), m_isPersistent(false),
-m_target(parentAura->GetTarget()), m_tickNumber(0)
-, m_spellProto(parentAura->GetSpellProto()), m_effIndex(effIndex), m_auraName(AuraType(m_spellProto->EffectApplyAuraName[m_effIndex]))
+void AuraApplication::_Remove()
{
- assert(m_auraName < TOTAL_AURAS);
-
- if(currentBasePoints)
- m_currentBasePoints = *currentBasePoints;
- else
- m_currentBasePoints = m_spellProto->EffectBasePoints[m_effIndex];
-
- Unit *caster = GetParentAura()->GetCaster();
- if(caster)
- m_amount = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target);
- else
- m_amount = m_currentBasePoints + m_spellProto->EffectBaseDice[m_effIndex];
+ uint8 slot = GetSlot();
- if (int32 amount = CalculateCrowdControlAuraAmount(caster))
- m_amount = amount;
+ if (slot >= MAX_AURAS)
+ return;
- if(!m_amount && caster)
- if(uint64 itemGUID = GetParentAura()->GetCastItemGUID())
- if(Player *playerCaster = dynamic_cast<Player*>(caster))
- if(Item *castItem = playerCaster->GetItemByGuid(itemGUID))
- if (castItem->GetItemSuffixFactor())
+ if (AuraApplication * foundAura = m_target->GetAuraApplication(GetBase()->GetId(), GetBase()->GetCasterGUID()))
{
- ItemRandomSuffixEntry const *item_rand_suffix = sItemRandomSuffixStore.LookupEntry(abs(castItem->GetItemRandomPropertyId()));
- if(item_rand_suffix)
+ // Reuse visible aura slot by aura which is still applied - prevent storing dead pointers
+ if (slot == foundAura->GetSlot())
{
- for (int k=0; k<3; k++)
+ if (GetTarget()->GetVisibleAura(slot) == this)
{
- SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(item_rand_suffix->enchant_id[k]);
- if(pEnchant)
- {
- for (int t=0; t<3; t++)
- if(pEnchant->spellid[t] == m_spellProto->Id)
- {
- m_amount = uint32((item_rand_suffix->prefix[k]*castItem->GetItemSuffixFactor()) / 10000 );
- break;
- }
- }
-
- if(m_amount)
- break;
+ GetTarget()->SetVisibleAura(slot, foundAura);
+ foundAura->SetNeedClientUpdate();
}
+ // set not valid slot for aura - prevent removing other visible aura
+ slot = MAX_AURAS;
}
}
- Player* modOwner = caster ? caster->GetSpellModOwner() : NULL;
- m_amplitude = m_spellProto->EffectAmplitude[m_effIndex];
-
- //apply casting time mods for channeled spells
- if (modOwner && m_amplitude && IsChanneledSpell(m_spellProto))
- modOwner->ModSpellCastTime(m_spellProto, m_amplitude);
-
- // Apply periodic time mod
- if(modOwner && m_amplitude)
- modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_amplitude);
-
- // Start periodic on next tick or at aura apply
- if (!(m_spellProto->AttributesEx5 & SPELL_ATTR_EX5_START_PERIODIC_AT_APPLY))
- m_periodicTimer += m_amplitude;
-
- m_isApplied = false;
+ // update for out of range group members
+ if (slot < MAX_AURAS)
+ {
+ GetTarget()->RemoveVisibleAura(slot);
+ ClientUpdate(true);
+ }
}
-AreaAuraEffect::AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 *currentBasePoints)
-: AuraEffect(parentAura, effIndex, currentBasePoints)
+bool AuraApplication::_CheckPositive(Unit * caster) const
{
- m_removeTime = FRIENDLY_AA_REMOVE_TIME;
- m_isAreaAura = true;
-
- if (m_spellProto->Effect[effIndex] == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY)
- m_radius = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
- else
- m_radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[m_effIndex]));
-
- Unit *source = GetSource();
- assert(source);
- if(Player* modOwner = source->GetSpellModOwner()) // source or caster? should be the same
- modOwner->ApplySpellMod(GetId(), SPELLMOD_RADIUS, m_radius);
+ // Aura is positive when it is casted by friend and at least one aura is positive
+ // or when it is casted by enemy and at least one aura is negative
- switch(m_spellProto->Effect[effIndex])
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
- m_areaAuraType = AREA_AURA_PARTY;
- if(m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->isTotem())
- *const_cast<AuraType*>(&m_auraName) = SPELL_AURA_NONE;
- break;
- case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
- m_areaAuraType = AREA_AURA_RAID;
- if(m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->isTotem())
- *const_cast<AuraType*>(&m_auraName) = SPELL_AURA_NONE;
- break;
- case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
- m_areaAuraType = AREA_AURA_FRIEND;
- break;
- case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
- m_areaAuraType = AREA_AURA_ENEMY;
- if(m_target == source)
- *const_cast<AuraType*>(&m_auraName) = SPELL_AURA_NONE; // Do not do any effect on self
- break;
- case SPELL_EFFECT_APPLY_AREA_AURA_PET:
- m_areaAuraType = AREA_AURA_PET;
- break;
- case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
- m_areaAuraType = AREA_AURA_OWNER;
- if(m_target == source)
- *const_cast<AuraType*>(&m_auraName) = SPELL_AURA_NONE;
- break;
- default:
- sLog.outError("Wrong spell effect in AreaAura constructor");
- ASSERT(false);
- break;
+ if((1<<i & GetEffectMask()))
+ {
+ if (m_isNeedManyNegativeEffects == IsPositiveEffect(GetBase()->GetId(), i))
+ return m_isNeedManyNegativeEffects;
+ }
}
+ return !m_isNeedManyNegativeEffects;
}
-PersistentAreaAuraEffect::PersistentAreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 *currentBasePoints)
-: AuraEffect(parentAura, effIndex, currentBasePoints)
+void AuraApplication::_HandleEffect(uint8 effIndex, bool apply)
{
- m_isPersistent = true;
-}
+ AuraEffect * aurEff = GetBase()->GetEffect(effIndex);
+ assert(aurEff);
+ assert(HasEffect(effIndex) == (!apply));
+ sLog.outDebug("AuraApplication::_HandleEffect: %u, apply: %u: amount: %u", aurEff->GetAuraType(), apply, aurEff->GetAmount());
-DynamicObject *PersistentAreaAuraEffect::GetSource() const
-{
- uint64 guid = GetParentAura()->GetSourceGUID();
- if(IS_DYNAMICOBJECT_GUID(guid))
- return ObjectAccessor::GetObjectInWorld(guid, (DynamicObject*)NULL);
- return NULL;
-}
+ Unit * caster = GetBase()->GetCaster();
+ m_flags &= ~(AFLAG_POSITIVE | AFLAG_NEGATIVE);
-AuraEffect* CreateAuraEffect(Aura * parentAura, uint32 effIndex, int32 *currentBasePoints)
-{
- // TODO: source should belong to aura, but not areaeffect. multiple areaaura/persistent aura should use one source
- assert(parentAura);
- uint64 sourceGuid = parentAura->GetSourceGUID();
- //assert(source);
- if (IsAreaAuraEffect(parentAura->GetSpellProto()->Effect[effIndex]))
+ if (apply)
{
- //assert(source->isType(TYPEMASK_UNIT));
- assert(IS_UNIT_GUID(sourceGuid));
- if(!parentAura->GetUnitSource())
- {
- // TODO: there is a crash here when a new aura is added by source aura update, confirmed
- sLog.outCrash("CreateAuraEffect: cannot find source " I64FMT " in world for spell %u", sourceGuid, parentAura->GetId());
- return NULL;
- }
- return new AreaAuraEffect(parentAura, effIndex, currentBasePoints);
+ m_flags |= 1<<effIndex;
+ m_flags |=_CheckPositive(caster) ? AFLAG_POSITIVE : AFLAG_NEGATIVE;
+ GetTarget()->_HandleAuraEffect(aurEff, true);
+ aurEff->HandleEffect(this, AURA_EFFECT_HANDLE_REAL, true);
}
- else if (parentAura->GetSpellProto()->Effect[effIndex] == SPELL_EFFECT_APPLY_AURA)
- return new AuraEffect(parentAura, effIndex, currentBasePoints);
- else if (parentAura->GetSpellProto()->Effect[effIndex] == SPELL_EFFECT_PERSISTENT_AREA_AURA)
+ else
{
- //assert(source->isType(TYPEMASK_DYNAMICOBJECT));
- // TODO: creature addon or save? may add persistent AA without correct source
- if(IS_DYNAMICOBJECT_GUID(sourceGuid))
- return new PersistentAreaAuraEffect(parentAura, effIndex, currentBasePoints);
- }
- return NULL;
-}
+ m_flags &= ~(1<<effIndex);
+ m_flags |=_CheckPositive(caster) ? AFLAG_POSITIVE : AFLAG_NEGATIVE;
-Unit* Aura::GetCaster() const
-{
- if(m_casterGuid == m_target->GetGUID())
- return m_target;
+ // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order)
+ GetTarget()->_HandleAuraEffect(aurEff, false);
+ aurEff->HandleEffect(this, AURA_EFFECT_HANDLE_REAL, false);
- //return ObjectAccessor::GetUnit(*m_target,m_casterGuid);
- //must return caster even if it's in another grid/map
- return ObjectAccessor::GetObjectInWorld(m_casterGuid, (Unit*)NULL);
+ // Remove all triggered by aura spells vs unlimited duration
+ aurEff->CleanupTriggeredSpells(GetTarget());
+ }
+ SetNeedClientUpdate();
}
-Unit* Aura::GetUnitSource() const
+void AuraApplication::ClientUpdate(bool remove)
{
- if(m_sourceGuid == m_target->GetGUID())
- return m_target;
+ m_needClientUpdate = false;
- return ObjectAccessor::GetObjectInWorld(m_sourceGuid, (Unit*)NULL);
-}
-
-void Aura::Update(uint32 diff)
-{
- // TODO: store pointer to caster in aura class for update/mod handling code
+ WorldPacket data(SMSG_AURA_UPDATE);
+ data.append(GetTarget()->GetPackGUID());
+ data << uint8(m_slot);
- if (m_duration > 0)
+ if(remove)
{
- m_duration -= diff;
- if (m_duration < 0)
- m_duration = 0;
-
- // all spells with manaPerSecond/manaPerSecondPerLevel have aura in effect 0
- if(m_timeCla)
- {
- if(m_timeCla > diff)
- m_timeCla -= diff;
- else if(Unit* caster = GetCaster())
- {
- if(int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel())
- {
- m_timeCla += 1000 - diff;
-
- Powers powertype = Powers(m_spellProto->powerType);
- if(powertype == POWER_HEALTH)
- {
- if (caster->GetHealth() > manaPerSecond)
- caster->ModifyHealth(-manaPerSecond);
- else
- {
- m_target->RemoveAura(this);
- return;
- }
- }
- else
- {
- if (caster->GetPower(powertype) >= manaPerSecond)
- caster->ModifyPower(powertype, -manaPerSecond);
- else
- {
- m_target->RemoveAura(this);
- return;
- }
- }
- }
- }
- }
+ assert(!m_target->GetVisibleAura(m_slot));
+ data << uint32(0);
+ sLog.outDebug("Aura %u removed slot %u",GetBase()->GetId(), m_slot);
+ m_target->SendMessageToSet(&data, true);
+ return;
}
+ assert(m_target->GetVisibleAura(m_slot));
- // Apply charged spellmods for channeled auras
- // used for example when triggered spell of spell:10 is modded
- Spell *modSpell = NULL;
- Player *modOwner = NULL;
- if(IS_PLAYER_GUID(GetCasterGUID()) && (modOwner = (Player*)GetCaster())
- && (modSpell = modOwner->FindCurrentSpellBySpellId(GetId())))
- modOwner->SetSpellModTakingSpell(modSpell, true);
-
- for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if (m_partAuras[i])
- m_partAuras[i]->Update(diff);
+ Aura const * aura = GetBase();
+ data << uint32(aura->GetId());
+ uint32 flags = m_flags;
+ if (aura->GetMaxDuration() > 0)
+ flags |= AFLAG_DURATION;
+ data << uint8(flags);
+ data << uint8(aura->GetCasterLevel());
+ data << uint8(aura->GetStackAmount() > 1 ? aura->GetStackAmount() : (aura->GetCharges()) ? aura->GetCharges() : 1);
- if (modOwner)
- modOwner->SetSpellModTakingSpell(modSpell, false);
-}
+ if(!(flags & AFLAG_CASTER))
+ data.appendPackGUID(aura->GetCasterGUID());
-void AuraEffect::Update(uint32 diff)
-{
- if (m_isPeriodic && (GetParentAura()->GetAuraDuration() >=0 || GetParentAura()->IsPassive() || GetParentAura()->IsPermanent()))
+ if(flags & AFLAG_DURATION)
{
- if(m_periodicTimer > diff)
- m_periodicTimer -= diff;
- else // tick also at m_periodicTimer==0 to prevent lost last tick in case max m_duration == (max m_periodicTimer)*N
- {
- ++m_tickNumber;
-
- // update before applying (aura can be removed in TriggerSpell or PeriodicTick calls)
- m_periodicTimer += m_amplitude - diff;
-
- if(!m_target->hasUnitState(UNIT_STAT_ISOLATED))
- PeriodicTick();
- }
+ data << uint32(aura->GetMaxDuration());
+ data << uint32(aura->GetDuration());
}
+
+ m_target->SendMessageToSet(&data, true);
}
-void AreaAuraEffect::Update(uint32 diff)
+Aura * Aura::TryCreate(SpellEntry const* spellproto, uint8 tryEffMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID)
{
- // update for the source of the aura
- if(GetParentAura()->GetSourceGUID() == m_target->GetGUID())
+ assert(spellproto);
+ assert(owner);
+ assert(caster || casterGUID);
+ assert(tryEffMask <= MAX_EFFECT_MASK);
+ uint8 effMask = 0;
+ switch(owner->GetTypeId())
{
- Unit *source = m_target;
- Unit *caster = GetCaster();
- if (!caster)
- {
- m_target->RemoveAura(GetParentAura());
- return;
- }
-
- if( !source->hasUnitState(UNIT_STAT_ISOLATED) )
- {
- std::list<Unit *> targets;
-
- switch(m_areaAuraType)
+ case TYPEID_UNIT:
+ case TYPEID_PLAYER:
+ for(uint8 i = 0; i< MAX_SPELL_EFFECTS; ++i)
{
- case AREA_AURA_PARTY:
- source->GetPartyMemberInDist(targets, m_radius);
- break;
- case AREA_AURA_RAID:
- source->GetRaidMember(targets, m_radius);
- break;
- case AREA_AURA_FRIEND:
- {
- Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(source, caster, m_radius);
- Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(source, targets, u_check);
- source->VisitNearbyObject(m_radius, searcher);
- break;
- }
- case AREA_AURA_ENEMY:
- {
- Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(source, caster, m_radius); // No GetCharmer in searcher
- Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(source, targets, u_check);
- source->VisitNearbyObject(m_radius, searcher);
- break;
- }
- case AREA_AURA_OWNER:
- case AREA_AURA_PET:
- {
- if(Unit *owner = caster->GetCharmerOrOwner())
- if (caster->IsWithinDistInMap(owner, m_radius))
- targets.push_back(owner);
- break;
- }
+ if (IsUnitOwnedAuraEffect(spellproto->Effect[i]))
+ effMask |= 1 << i;
}
-
- for (std::list<Unit*>::iterator tIter = targets.begin(); tIter != targets.end(); tIter++)
+ break;
+ case TYPEID_DYNAMICOBJECT:
+ for(uint8 i = 0; i< MAX_SPELL_EFFECTS; ++i)
{
- if(Aura *aur = (*tIter)->GetAura(GetId(), GetCasterGUID()))
- {
- if(aur->HasEffect(GetEffIndex()))
- continue;
- }
- else
- {
- bool skip = false;
- for (Unit::AuraMap::iterator iter = (*tIter)->GetAuras().begin(); iter != (*tIter)->GetAuras().end(); ++iter)
- {
- if(!spellmgr.CanAurasStack(GetSpellProto(), iter->second->GetSpellProto(), iter->second->GetCasterGUID() == GetCasterGUID()))
- {
- skip = true;
- break;
- }
- }
- if(skip)
- continue;
- }
-
- // Select lower rank of aura if needed
- if(SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel()))
- {
- int32 newBp = m_currentBasePoints;
- // Check if basepoints can be safely reduced
- if (newBp == m_spellProto->EffectBasePoints[m_effIndex])
- newBp = actualSpellInfo->EffectBasePoints[m_effIndex];
- (*tIter)->AddAuraEffect(actualSpellInfo, GetEffIndex(), source, caster, &newBp);
-
- if(m_areaAuraType == AREA_AURA_ENEMY)
- caster->CombatStart(*tIter);
- }
+ if (spellproto->Effect[i] == SPELL_EFFECT_PERSISTENT_AREA_AURA)
+ effMask |= 1 << i;
}
- }
- AuraEffect::Update(diff);
+ break;
}
- else // aura at non-caster
- {
- // WARNING: the aura may get deleted during the update
- // DO NOT access its members after update!
- AuraEffect::Update(diff);
-
- // Speedup - no need to do more checks
- if (GetParentAura()->IsRemoved())
- return;
-
- // Caster may be deleted due to update
- Unit *caster = GetCaster();
- Unit *source = GetSource();
+ if (uint8 realMask = effMask & tryEffMask)
+ return Create(spellproto,realMask,owner,caster,baseAmount,castItem,casterGUID);
+ return NULL;
+}
- // remove aura if out-of-range from caster (after teleport for example)
- // or caster is isolated or caster no longer has the aura
- // or caster is (no longer) friendly
- bool needFriendly = (m_areaAuraType == AREA_AURA_ENEMY ? false : true);
- if( !source || !caster ||
- source->hasUnitState(UNIT_STAT_ISOLATED) || !source->HasAuraEffect(GetId(), m_effIndex) ||
- caster->IsFriendlyTo(m_target) != needFriendly
- )
- {
- m_target->RemoveAura(GetParentAura());
- }
- else if (!source->IsWithinDistInMap(m_target, m_radius))
- {
- if (needFriendly && source->isMoving())
- {
- m_removeTime -= diff;
- if (m_removeTime < 0)
- m_target->RemoveAura(GetParentAura());
- }
- else
- m_target->RemoveAura(GetParentAura());
- }
- else
- {
- // Reset aura remove timer
- m_removeTime = FRIENDLY_AA_REMOVE_TIME;
- if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group
- {
- if(!m_target->IsInPartyWith(caster))
- m_target->RemoveAura(GetParentAura());
- }
- else if( m_areaAuraType == AREA_AURA_RAID)
+Aura * Aura::TryCreate(SpellEntry const* spellproto, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID)
+{
+ assert(spellproto);
+ assert(owner);
+ assert(caster || casterGUID);
+ uint8 effMask = 0;
+ switch(owner->GetTypeId())
+ {
+ case TYPEID_UNIT:
+ case TYPEID_PLAYER:
+ for(uint8 i = 0; i< MAX_SPELL_EFFECTS; ++i)
{
- if(!m_target->IsInRaidWith(caster))
- m_target->RemoveAura(GetParentAura());
+ if (IsUnitOwnedAuraEffect(spellproto->Effect[i]))
+ effMask |= 1 << i;
}
- else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
+ break;
+ case TYPEID_DYNAMICOBJECT:
+ for(uint8 i = 0; i< MAX_SPELL_EFFECTS; ++i)
{
- if( m_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
- m_target->RemoveAura(GetParentAura());
+ if (spellproto->Effect[i] == SPELL_EFFECT_PERSISTENT_AREA_AURA)
+ effMask |= 1 << i;
}
- }
+ break;
}
+ if (effMask)
+ return Create(spellproto,effMask,owner,caster,baseAmount,castItem,casterGUID);
+ return NULL;
}
-void PersistentAreaAuraEffect::Update(uint32 diff)
+Aura * Aura::Create(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID)
{
- /*
- if(Unit *caster = GetParentAura()->GetCaster())
- {
- if(DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex()))
- {
- if(m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
- {
- AuraEffect::Update(diff);
- return;
- }
- }
- }
- */
- if(DynamicObject *dynObj = GetSource())
+ assert(effMask);
+ assert(spellproto);
+ assert(owner);
+ assert(caster || casterGUID);
+ assert(effMask <= MAX_EFFECT_MASK);
+ switch(owner->GetTypeId())
{
- if(m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
- {
- AuraEffect::Update(diff);
- return;
- }
+ case TYPEID_UNIT:
+ case TYPEID_PLAYER:
+ return new UnitAura(spellproto,effMask,owner,caster,baseAmount,castItem, casterGUID);
+ case TYPEID_DYNAMICOBJECT:
+ return new DynObjAura(spellproto,effMask,owner,caster,baseAmount,castItem, casterGUID);
+ default:
+ assert(false);
+ return NULL;
}
-
- // remove the aura if its caster or the dynamic object causing it was removed
- // or if the target moves too far from the dynamic object
- m_target->RemoveAura(GetParentAura());
}
-void AuraEffect::ApplyModifier(bool apply, bool Real, bool changeAmount)
+Aura::Aura(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID) :
+m_spellProto(spellproto), m_owner(owner), m_casterGuid(casterGUID ? casterGUID : caster->GetGUID()), m_castItemGuid(castItem ? castItem->GetGUID() : 0),
+ m_applyTime(time(NULL)), m_timeCla(0),
+ m_procCharges(0), m_stackAmount(1), m_isRemoved(false), m_casterLevel(caster ? caster->getLevel() : m_spellProto->spellLevel)
{
- if (GetParentAura()->IsRemoved())
- return;
-
- if (apply)
- HandleAuraEffectSpecificMods(true, Real, changeAmount);
-
- (*this.*AuraHandler [m_auraName])(apply,Real, changeAmount);
+ if(m_spellProto->manaPerSecond || m_spellProto->manaPerSecondPerLevel)
+ m_timeCla = 1 * IN_MILISECONDS;
- if (!apply)
- HandleAuraEffectSpecificMods(false, Real, changeAmount);
-}
+ Player* modOwner = NULL;
-void AuraEffect::RecalculateAmount(bool applied)
-{
- Unit *caster = GetParentAura()->GetCaster();
- int32 amount = GetParentAura()->GetStackAmount() * (caster ? (caster->CalculateSpellDamage(m_spellProto, GetEffIndex(), GetBasePoints(), NULL)) : (m_currentBasePoints + m_spellProto->EffectBaseDice[m_effIndex]));
- // Reapply if amount change
- if (amount!=GetAmount())
+ if (caster)
{
- // Auras which are applying spellmod should have removed spellmods for real
- if (applied)
- ApplyModifier(false,false,true);
- SetAmount(amount);
- if (applied)
- ApplyModifier(true,false,true);
+ modOwner = caster->GetSpellModOwner();
+ m_maxDuration = caster->CalcSpellDuration(m_spellProto);
}
-}
+ else
+ m_maxDuration = GetSpellDuration(m_spellProto);
-void AuraEffect::CleanupTriggeredSpells()
-{
- uint32 tSpellId = m_spellProto->EffectTriggerSpell[GetEffIndex()];
- if(!tSpellId)
- return;
+ if(IsPassive() && m_spellProto->DurationIndex == 0)
+ m_maxDuration = -1;
- SpellEntry const* tProto = sSpellStore.LookupEntry(tSpellId);
- if(!tProto)
- return;
+ if(!IsPermanent() && modOwner)
+ modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, m_maxDuration);
- if(GetSpellDuration(tProto) != -1)
- return;
+ m_duration = m_maxDuration;
- // needed for spell 43680, maybe others
- // TODO: is there a spell flag, which can solve this in a more sophisticated way?
- if(m_spellProto->EffectApplyAuraName[GetEffIndex()] == SPELL_AURA_PERIODIC_TRIGGER_SPELL &&
- GetSpellDuration(m_spellProto) == m_spellProto->EffectAmplitude[GetEffIndex()])
- return;
+ m_procCharges = m_spellProto->procCharges;
+ if(modOwner)
+ modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, m_procCharges);
- m_target->RemoveAurasDueToSpell(tSpellId, GetCasterGUID());
-}
+ for (uint8 i=0 ; i<MAX_SPELL_EFFECTS; ++i)
+ {
+ if (effMask & (uint8(1) << i))
+ m_effects[i] = new AuraEffect(this, i, baseAmount ? baseAmount + i : NULL, caster);
+ else
+ m_effects[i] = NULL;
+ }
-void Aura::ApplyAllModifiers(bool apply, bool Real)
-{
- for (uint8 i = 0; i<MAX_SPELL_EFFECTS; ++i)
- if (m_partAuras[i])
- m_partAuras[i]->ApplyModifier(apply, Real);
+ m_isSingleTarget = IsSingleTargetSpell(GetSpellProto());
}
-void Aura::HandleAuraSpecificMods(bool apply)
+Aura::~Aura()
{
- //**************************************************************************************
- // Function called after applying all mods from aura or after removing all mods from it
- //**************************************************************************************
+ // free effects memory
+ for (uint8 i = 0 ; i < MAX_SPELL_EFFECTS; ++i)
+ if (m_effects[i])
+ delete m_effects[i];
- //********************
- // MODS AT AURA APPLY
- //********************
- if (apply)
- {
- // Update auras for specific phase
- if(IsAuraType(SPELL_AURA_PHASE))
- {
- SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAuraMapBounds(GetId());
- if(saBounds.first != saBounds.second)
- {
- uint32 zone, area;
- m_target->GetZoneAndAreaId(zone,area);
-
- for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
- {
- // some auras remove at aura remove
- if(!itr->second->IsFitToRequirements((Player*)m_target,zone,area))
- m_target->RemoveAurasDueToSpell(itr->second->spellId);
- // some auras applied at aura apply
- else if(itr->second->autocast)
- {
- if( !m_target->HasAura(itr->second->spellId) )
- m_target->CastSpell(m_target,itr->second->spellId,true);
- }
- }
- }
- }
+ assert(m_applications.empty());
+ _DeleteRemovedApplications();
+}
- if (m_spellProto->SpellFamilyName == SPELLFAMILY_MAGE)
- {
- if (m_spellProto->SpellFamilyFlags[1] & 0x00000002 && m_spellProto->SpellFamilyFlags[2] & 0x00000008)
- {
- // Arcane Potency
- if (Unit * caster = GetCaster())
- {
- if (AuraEffect* aureff = caster->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_MAGE, 2120, 0))
- {
- if (roll_chance_i(aureff->GetAmount()))
- {
- uint32 spell_id = 0;
+Unit* Aura::GetCaster() const
+{
+ if (GetOwner()->GetGUID() == GetCasterGUID())
+ return GetUnitOwner();
+ if(AuraApplication const * aurApp = GetApplicationOfTarget(GetCasterGUID()))
+ return aurApp->GetTarget();
- switch (aureff->GetId())
- {
- case 31571: spell_id = 57529; break;
- case 31572: spell_id = 57531; break;
- default: return;
- }
- if(spell_id)
- caster->CastSpell(caster,spell_id,true);
- }
- }
- }
- }
- else if (m_spellProto->SpellFamilyFlags[0] & 0x00000001 && m_spellProto->SpellFamilyFlags[2] & 0x00000008)
- {
- // Glyph of Fireball
- if (Unit * caster = GetCaster())
- if (caster->HasAura(56368))
- SetAuraDuration(0);
- }
- else if (m_spellProto->SpellFamilyFlags[0] & 0x00000020 && m_spellProto->SpellVisual[0] == 13)
- {
- // Glyph of Frostbolt
- if (Unit * caster = GetCaster())
- if (caster->HasAura(56370))
- SetAuraDuration(0);
- }
- // Todo: This should be moved to similar function in spell::hit
- else if (m_spellProto->SpellFamilyFlags[0] & 0x01000000)
- {
- Unit * caster = GetCaster();
- if (!caster)
- return;
+ return ObjectAccessor::GetUnit(*GetOwner(), GetCasterGUID());
+}
- // Polymorph Sound - Sheep && Penguin
- if (m_spellProto->SpellIconID == 82 && m_spellProto->SpellVisual[0] == 12978)
- {
- // Glyph of the Penguin
- if (caster->HasAura(52648))
- caster->CastSpell(m_target,61635,true);
- else
- caster->CastSpell(m_target,61634,true);
- }
- }
- }
- else if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST)
- {
- // Devouring Plague
- if (GetSpellProto()->SpellFamilyFlags[0] & 0x02000000 && GetPartAura(0))
- {
- Unit * caster = GetCaster();
- if (!caster)
- return;
+AuraObjectType Aura::GetType() const
+{
+ return (m_owner->GetTypeId() == TYPEID_DYNAMICOBJECT) ? DYNOBJ_AURA_TYPE : UNIT_AURA_TYPE;
+}
- // Improved Devouring Plague
- if (AuraEffect const * aurEff = caster->GetDummyAura(SPELLFAMILY_PRIEST, 3790, 1))
- {
- int32 basepoints0 = aurEff->GetAmount() * GetPartAura(0)->GetTotalTicks() * GetPartAura(0)->GetAmount() / 100;
- caster->CastCustomSpell(m_target, 63675, &basepoints0, NULL, NULL, true, NULL, GetPartAura(0));
- }
- }
- // Renew
- else if (GetSpellProto()->SpellFamilyFlags[0] & 0x00000040 && GetPartAura(0))
- {
- Unit * caster = GetCaster();
- if (!caster)
- return;
+void Aura::_ApplyForTarget(Unit * target, Unit * caster, AuraApplication * auraApp)
+{
+ assert(target);
+ assert(auraApp);
+ // aura mustn't be already applied
+ assert (m_applications.find(target->GetGUID()) == m_applications.end());
- // Empowered Renew
- if (AuraEffect const * aurEff = caster->GetDummyAura(SPELLFAMILY_PRIEST, 3021, 1))
- {
- int32 basepoints0 = aurEff->GetAmount() * GetPartAura(0)->GetTotalTicks() * caster->SpellHealingBonus(m_target, GetSpellProto(), GetPartAura(0)->GetAmount(), HEAL) / 100;
- caster->CastCustomSpell(m_target, 63544, &basepoints0, NULL, NULL, true, NULL, GetPartAura(0));
- }
- }
- }
- else if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_ROGUE)
- {
- // Sprint (skip non player casted spells by category)
- if(GetSpellProto()->SpellFamilyFlags[0] & 0x40 && GetSpellProto()->Category == 44)
- // in official maybe there is only one icon?
- if(m_target->HasAura(58039)) // Glyph of Blurred Speed
- m_target->CastSpell(m_target, 61922, true); // Sprint (waterwalk)
- }
- else if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT)
- {
- // Frost Fever and Blood Plague
- if(GetSpellProto()->SpellFamilyFlags[2] & 0x2)
- {
- // Can't proc on self
- if (GetCasterGUID() == m_target->GetGUID())
- return;
- Unit * caster = GetCaster();
- if (!caster)
- return;
+ m_applications[target->GetGUID()] = auraApp;
- AuraEffect * aurEff = NULL;
- // Ebon Plaguebringer / Crypt Fever
- Unit::AuraEffectList const& TalentAuras = caster->GetAurasByType(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
- if ((*itr)->GetSpellProto()->SpellIconID == 1766)
- 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:
- sLog.outError("Unknown rank of Crypt Fever/Ebon Plague %d", aurEff->GetId());
- }
- caster->CastSpell(m_target, spellId, true, 0, GetPartAura(0));
- }
- }
- }
- else
+ // set infinity cooldown state for spells
+ if(caster && caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (m_spellProto->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE)
{
- switch(GetId())
- {
- case 32474: // Buffeting Winds of Susurrus
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->ActivateTaxiPathTo(506, GetId());
- break;
- case 33572: // Gronn Lord's Grasp, becomes stoned
- if(GetStackAmount() >= 5 && !m_target->HasAura(33652))
- m_target->CastSpell(m_target, 33652, true);
- break;
- case 48020: // Demonic Circle
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- if(GameObject* obj = m_target->GetGameObject(48018))
- ((Player*)m_target)->TeleportTo(obj->GetMapId(),obj->GetPositionX(),obj->GetPositionY(),obj->GetPositionZ(),obj->GetOrientation());
- break;
- case 60970: // Heroic Fury (remove Intercept cooldown)
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->RemoveSpellCooldown(20252, true);
- break;
- }
+ Item* castItem = m_castItemGuid ? ((Player*)caster)->GetItemByGuid(m_castItemGuid) : NULL;
+ ((Player*)caster)->AddSpellAndCategoryCooldowns(m_spellProto,castItem ? castItem->GetEntry() : 0, NULL,true);
}
}
+}
- //*******************************
- // MODS AT AURA APPLY AND REMOVE
- //*******************************
+void Aura::_UnapplyForTarget(Unit * target, Unit * caster, AuraApplication * auraApp)
+{
+ assert(target);
+ assert(auraApp->GetRemoveMode());
+ assert(auraApp);
- // 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
- if (m_spellProto->Id == 19746 || m_spellProto->Id == 31821)
+ ApplicationMap::iterator itr = m_applications.find(target->GetGUID());
+ // aura has to be already applied
+ assert(itr->second == auraApp);
+ m_applications.erase(itr);
+ m_removedApplications.push_back(auraApp);
+
+ // reset cooldown state for spells
+ if(caster && caster->GetTypeId() == TYPEID_PLAYER)
{
- if (GetCasterGUID() != m_target->GetGUID())
- return;
- if (apply)
- {
- if ((m_spellProto->Id == 31821 && m_target->HasAura(19746, GetCasterGUID())) || (m_spellProto->Id == 19746 && m_target->HasAura(31821)))
- {
- m_target->CastSpell(m_target,64364,true);
- return;
- }
- }
- else
- {
- m_target->RemoveAurasDueToSpell(64364, GetCasterGUID());
- return;
- }
+ if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE )
+ // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
+ ((Player*)caster)->SendCooldownEvent(GetSpellProto());
}
+}
- // Bestial Wrath
- if (GetSpellProto()->Id == 19574)
+// removes aura from all targets
+// and marks aura as removed
+void Aura::_Remove(AuraRemoveMode removeMode)
+{
+ assert (!m_isRemoved);
+ m_isRemoved = true;
+ for (ApplicationMap::iterator appItr = m_applications.begin() ; appItr != m_applications.end() ;)
{
- // The Beast Within cast on owner if talent present
- if ( Unit* owner = m_target->GetOwner() )
- {
- // Search talent
- if (owner->HasAura(34692))
- {
- if (apply)
- owner->CastSpell(owner, 34471, true, 0, GetPartAura(0));
- else
- owner->RemoveAurasDueToSpell(34471);
- }
- }
+ AuraApplication * aurApp = appItr->second;
+ Unit * target = aurApp->GetTarget();
+ ++appItr;
+ target->_UnapplyAura(aurApp, removeMode);
}
+}
- if (GetSpellSpecific(m_spellProto->Id) == SPELL_PRESENCE)
- {
- AuraEffect *bloodPresenceAura=0; // healing by damage done
- AuraEffect *frostPresenceAura=0; // increased health
- AuraEffect *unholyPresenceAura=0; // increased movement speed, faster rune recovery
+void Aura::UpdateTargetMap(Unit * caster)
+{
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if(m_effects[i] && !IsRemoved())
+ UpdateTargetMapForEffect(caster, i);
+}
- // Improved Presences
- Unit::AuraEffectList const& vDummyAuras = m_target->GetAurasByType(SPELL_AURA_DUMMY);
- for (Unit::AuraEffectList::const_iterator itr = vDummyAuras.begin(); itr != vDummyAuras.end(); ++itr)
- {
- switch((*itr)->GetId())
- {
- // 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;
- }
- }
- }
+void Aura::UpdateOwner(uint32 diff, WorldObject * owner)
+{
+ assert(owner == m_owner);
- uint32 presence=GetId();
- if (apply)
- {
- // Blood Presence bonus
- if (presence == SPELL_ID_BLOOD_PRESENCE)
- m_target->CastSpell(m_target,63611,true);
- else if (bloodPresenceAura)
- {
- int32 basePoints1=bloodPresenceAura->GetAmount();
- m_target->CastCustomSpell(m_target,63611,NULL,&basePoints1,NULL,true,0,bloodPresenceAura);
- }
- // Frost Presence bonus
- if (presence == SPELL_ID_FROST_PRESENCE)
- m_target->CastSpell(m_target,61261,true);
- else if (frostPresenceAura)
- {
- int32 basePoints0=frostPresenceAura->GetAmount();
- m_target->CastCustomSpell(m_target,61261,&basePoints0,NULL,NULL,true,0,frostPresenceAura);
- }
- // Unholy Presence bonus
- if (presence == SPELL_ID_UNHOLY_PRESENCE)
- {
- if(unholyPresenceAura)
- {
- // Not listed as any effect, only base points set
- int32 basePoints0 = unholyPresenceAura->GetSpellProto()->EffectBasePoints[1];
- //m_target->CastCustomSpell(m_target,63622,&basePoints0 ,NULL,NULL,true,0,unholyPresenceAura);
- m_target->CastCustomSpell(m_target,65095,&basePoints0 ,NULL,NULL,true,0,unholyPresenceAura);
- }
- m_target->CastSpell(m_target,49772, true);
- }
- else if (unholyPresenceAura)
- {
- int32 basePoints0=unholyPresenceAura->GetAmount();
- m_target->CastCustomSpell(m_target,49772,&basePoints0,NULL,NULL,true,0,unholyPresenceAura);
- }
- }
- else
- {
- // Remove passive auras
- if (presence == SPELL_ID_BLOOD_PRESENCE || bloodPresenceAura)
- m_target->RemoveAurasDueToSpell(63611);
- if (presence == SPELL_ID_FROST_PRESENCE || frostPresenceAura)
- m_target->RemoveAurasDueToSpell(61261);
- if (presence == SPELL_ID_UNHOLY_PRESENCE || unholyPresenceAura)
- {
- if(presence == SPELL_ID_UNHOLY_PRESENCE && unholyPresenceAura)
- {
- //m_target->RemoveAurasDueToSpell(63622);
- m_target->RemoveAurasDueToSpell(65095);
- }
- m_target->RemoveAurasDueToSpell(49772);
- }
- }
- }
+ Unit * caster = GetCaster();
+ // Apply spellmods for channeled auras
+ // used for example when triggered spell of spell:10 is modded
+ Spell * modSpell = NULL;
+ Player * modOwner = NULL;
+ if(caster)
+ if ((modOwner = caster->GetSpellModOwner())
+ && (modSpell = modOwner->FindCurrentSpellBySpellId(GetId())))
+ modOwner->SetSpellModTakingSpell(modSpell, true);
- //*********************
- // MODS AT AURA REMOVE
- //*********************
+ Update(diff, caster);
- if(!apply)
- {
- // Spell Reflection
- if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags[1] & 0x2
- && GetRemoveMode() != AURA_REMOVE_BY_DEFAULT)
- {
- if (Unit * caster = GetCaster())
- {
- // Improved Spell Reflection
- if (caster->GetDummyAura(SPELLFAMILY_WARRIOR,1935, 1))
- {
- // aura remove - remove auras from all party members
- std::list<Unit*> PartyMembers;
- m_target->GetPartyMembers(PartyMembers);
- for (std::list<Unit*>::iterator itr = PartyMembers.begin(); itr!=PartyMembers.end(); ++itr)
- {
- if ((*itr)!= m_target)
- (*itr)->RemoveAurasWithFamily(SPELLFAMILY_WARRIOR, 0, 0x2, 0, GetCasterGUID());
- }
- }
- }
- }
- // Guardian Spirit
- else if(m_spellProto->Id == 47788)
- {
- if (GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
- return;
- Unit *caster = GetCaster();
- if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
- return;
+ UpdateTargetMap(caster);
- Player *player = ((Player*)caster);
- // Glyph of Guardian Spirit
- if(AuraEffect * aurEff = player->GetAuraEffect(63231, 0))
- {
- if (!player->HasSpellCooldown(47788))
- return;
+ // update aura effects
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
+ if (m_effects[i])
+ m_effects[i]->Update(diff, caster);
- player->RemoveSpellCooldown(m_spellProto->Id, true);
- player->AddSpellCooldown(m_spellProto->Id, 0, uint32(time(NULL) + aurEff->GetAmount()));
+ // remove spellmods after effects update
+ if (modSpell)
+ modOwner->SetSpellModTakingSpell(modSpell, false);
- WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4+4);
- data << uint64(player->GetGUID());
- data << uint8(0x0); // flags (0x1, 0x2)
- data << uint32(m_spellProto->Id);
- data << uint32(aurEff->GetAmount()*IN_MILISECONDS);
- player->SendDirectMessage(&data);
- }
- }
- // Invisibility
- else if (m_spellProto->Id == 66)
- {
- if (GetRemoveMode() != AURA_REMOVE_BY_EXPIRE)
- return;
- m_target->CastSpell(m_target, 32612, true, NULL, GetPartAura(1));
- }
- // Summon Gargoyle
- else if (m_spellProto->Id == 50514)
- {
- m_target->CastSpell(m_target, GetPartAura(0)->GetAmount(), true, NULL, GetPartAura(0));
- }
- // Curse of Doom
- else if (m_spellProto->SpellFamilyName==SPELLFAMILY_WARLOCK && m_spellProto->SpellFamilyFlags[1] & 0x02)
- {
- if (GetRemoveMode()==AURA_REMOVE_BY_DEATH)
- {
- if (Unit * caster = GetCaster())
- {
- if (caster->GetTypeId() == TYPEID_PLAYER && ((Player*)caster)->isHonorOrXPTarget(m_target))
- caster->CastSpell(m_target, 18662, true, NULL, GetPartAura(0));
- }
- }
- }
- // Improved Fear
- else if (m_spellProto->SpellFamilyName==SPELLFAMILY_WARLOCK && m_spellProto->SpellFamilyFlags[1] & 0x00000400)
- {
- if (Unit * caster = GetCaster())
- {
- if (caster->GetTypeId() != TYPEID_PLAYER)
- {
- if (AuraEffect* aureff = caster->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_WARLOCK, 98, 0))
- {
- uint32 spell_id = 0;
- switch (aureff->GetId())
- {
- case 53759: spell_id = 60947; break;
- case 53754: spell_id = 60946; break;
- default: return;
- }
- if (spell_id)
- caster->CastSpell(caster,spell_id,true);
- }
- }
- }
- }
- }
+ _DeleteRemovedApplications();
}
-void AuraEffect::HandleAuraEffectSpecificMods(bool apply, bool Real, bool changeAmount)
+void Aura::Update(uint32 diff, Unit * caster)
{
- //***********************************************************************
- // Function called before aura effect handler apply or after it's remove
- //***********************************************************************
-
- if(!Real && !changeAmount)
- return;
-
- Unit* caster = GetCaster();
-
- if (!caster)
- return;
-
- if(apply)
+ if (m_duration > 0)
{
- // prevent double apply bonuses
- if (!m_target->isBeingLoaded())
- if(caster)
+ m_duration -= diff;
+ if (m_duration < 0)
+ m_duration = 0;
+
+ // handle manaPerSecond/manaPerSecondPerLevel
+ if(m_timeCla)
{
- float DoneActualBenefit = 0.0f;
- float BenefitMod = 1.0f;
- switch(m_spellProto->SpellFamilyName)
+ if(m_timeCla > diff)
+ m_timeCla -= diff;
+ else if(caster)
{
- case SPELLFAMILY_GENERIC:
- // Replenishment (0.25% from max)
- // Infinite Replenishment
- if (m_spellProto->SpellIconID == 3184 && m_spellProto->SpellVisual[0] == 12495 && GetAuraName() == SPELL_AURA_PERIODIC_ENERGIZE)
- m_amount = m_target->GetMaxPower(POWER_MANA) * 20 / 10000;
- break;
- case SPELLFAMILY_MAGE:
- // Mana Shield
- if(m_spellProto->SpellFamilyFlags[0] & 0x8000 && m_spellProto->SpellFamilyFlags[2] & 0x8 && GetAuraName() == SPELL_AURA_MANA_SHIELD)
- {
- // +80.53% from +spd bonus
- DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.8053f;;
- }
- // Ice Barrier
- else if(m_spellProto->SpellFamilyFlags[1] & 0x1 && m_spellProto->SpellFamilyFlags[2] & 0x8 && GetAuraName() == SPELL_AURA_SCHOOL_ABSORB)
- {
- // +80.67% from sp bonus
- DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.8067f;
- }
- // Frost Ward, Fire Ward
- else if (m_spellProto->SpellFamilyFlags[0] & 0x00000108 && GetAuraName() == SPELL_AURA_SCHOOL_ABSORB)
- {
- //+10% from +spell bonus
- DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.1f;
- }
- break;
- case SPELLFAMILY_WARRIOR:
- {
- // Rend
- if (m_spellProto->SpellFamilyFlags[0] & 0x20 && GetAuraName() == SPELL_AURA_PERIODIC_DAMAGE)
- {
- // $0.2*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
- float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
- int32 mws = caster->GetAttackTime(BASE_ATTACK);
- float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE);
- float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE);
- m_amount+=int32(((mwb_min+mwb_max)/2+ap*mws/14000)*0.2f);
- // "If used while your target is above 75% health, Rend does 35% more damage."
- // as for 3.1.3 only ranks above 9 (wrong tooltip?)
- if (spellmgr.GetSpellRank(m_spellProto->Id) >= 9)
- {
- if (m_target->HasAuraState(AURA_STATE_HEALTH_ABOVE_75_PERCENT, m_spellProto, caster))
- m_amount += int32(m_amount*0.35);
- }
- }
- break;
- }
- case SPELLFAMILY_WARLOCK:
- // shadow ward
- if(m_spellProto->SpellFamilyFlags[2]& 0x40 && GetAuraName() == SPELL_AURA_SCHOOL_ABSORB)
- {
- // +30% from sp bonus
- DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.3f;
- }
- // Drain Soul - If the target is at or below 25% health, Drain Soul causes four times the normal damage
- else if (m_spellProto->SpellFamilyFlags[0] & 0x00004000 && GetAuraName() == SPELL_AURA_PERIODIC_DAMAGE)
- {
- // if victim is below 25% of hp
- if (m_target->GetMaxHealth() / 4 > m_target->GetHealth())
- m_amount *= 4;
- }
- break;
- case SPELLFAMILY_PRIEST:
- {
- // Power Word: Shield
- if(m_spellProto->SpellFamilyFlags[0] & 0x1 && m_spellProto->SpellFamilyFlags[2] & 0x400 && GetAuraName() == SPELL_AURA_SCHOOL_ABSORB)
- {
- //+80.68% from sp bonus
- DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * 0.8068f;
- // Borrowed Time
- if (AuraEffect* aureff = caster->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_PRIEST, 2899, 1))
- DoneActualBenefit += caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * (aureff->GetAmount() / 100.0f);
- }
- // Lightwell Renew
- else if (m_spellProto->SpellFamilyFlags[2] & UI64LIT(0x4000) && GetAuraName() == SPELL_AURA_PERIODIC_HEAL)
- {
- if (caster->GetTypeId() == TYPEID_PLAYER)
- // Bonus from Glyph of Lightwell
- if (AuraEffect* modHealing = caster->GetAuraEffect(55673, 0))
- m_amount *= (100.0f + modHealing->GetAmount()) / 100.0f;
- }
- break;
- }
- case SPELLFAMILY_DRUID:
- {
- // Rip
- if (m_spellProto->SpellFamilyFlags[0] & 0x00800000 && GetAuraName() == SPELL_AURA_PERIODIC_DAMAGE)
- {
- // 0.01*$AP*cp
- if (caster->GetTypeId() != TYPEID_PLAYER)
- return;
-
- uint8 cp = ((Player*)caster)->GetComboPoints();
-
- // Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
- if (AuraEffect const * aurEff = caster->GetAuraEffect(34241,0))
- m_amount += cp * aurEff->GetAmount();
-
- m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
- }
- // TODO: i do not know what is this for so i simply disable it
- // Lifebloom
- //else if (m_spellProto->SpellFamilyFlags[1] & 0x10 && GetAuraName() == SPELL_AURA_PERIODIC_HEAL)
- // m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_amount, SPELL_DIRECT_DAMAGE);
- // Innervate
- else if (m_spellProto->Id == 29166 && GetAuraName() == SPELL_AURA_PERIODIC_ENERGIZE)
- m_amount = m_target->GetCreatePowers(POWER_MANA) * m_amount / (GetTotalTicks() * 100.0f);
- // Owlkin Frenzy
- else if (m_spellProto->Id == 48391 && GetAuraName() == SPELL_AURA_PERIODIC_ENERGIZE)
- m_amount = m_target->GetCreatePowers(POWER_MANA) * m_amount / 100.0f;
- // Thorns
- else if (m_spellProto->SpellFamilyFlags[0] & 0x100 && GetAuraName() == SPELL_AURA_DAMAGE_SHIELD)
- // 3.3% from sp bonus
- DoneActualBenefit = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.033f;
- break;
- }
- case SPELLFAMILY_ROGUE:
+ if(int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel())
{
- // Rupture
- if (m_spellProto->SpellFamilyFlags[0] & 0x100000 && GetAuraName() == SPELL_AURA_PERIODIC_DAMAGE)
- {
- if (caster->GetTypeId() != TYPEID_PLAYER)
- return;
- //1 point : ${($m1+$b1*1+0.015*$AP)*4} damage over 8 secs
- //2 points: ${($m1+$b1*2+0.024*$AP)*5} damage over 10 secs
- //3 points: ${($m1+$b1*3+0.03*$AP)*6} damage over 12 secs
- //4 points: ${($m1+$b1*4+0.03428571*$AP)*7} damage over 14 secs
- //5 points: ${($m1+$b1*5+0.0375*$AP)*8} damage over 16 secs
- float AP_per_combo[6] = {0.0f, 0.015f, 0.024f, 0.03f, 0.03428571f, 0.0375f};
- uint8 cp = ((Player*)caster)->GetComboPoints();
- if (cp > 5) cp = 5;
- m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * AP_per_combo[cp]);
- }
- break;
- }
- case SPELLFAMILY_PALADIN:
- // Sacred Shield
- if (m_spellProto->SpellFamilyFlags[1] & 0x80000 && GetAuraName() == SPELL_AURA_SCHOOL_ABSORB)
- {
- // 0.75 from sp bonus
- float koef = 1.0f;
- if (caster->HasAura(53527))
- koef = 1.1f;
- if (caster->HasAura(53530))
- koef = 1.2f;
+ m_timeCla += 1000 - diff;
- DoneActualBenefit = caster->SpellBaseHealingBonus(GetSpellSchoolMask(m_spellProto)) * 0.75f * koef;
- }
- break;
- case SPELLFAMILY_SHAMAN:
- // Earth Shield
- if (m_spellProto->SpellFamilyFlags[1] & 0x400 && GetAuraName() == SPELL_AURA_DUMMY)
- m_amount = caster->SpellHealingBonus(m_target, GetSpellProto(), m_amount, SPELL_DIRECT_DAMAGE);
- break;
- case SPELLFAMILY_DEATHKNIGHT:
- {
- // Vampiric Blood
- if(GetSpellProto()->Id == 55233 && GetAuraName() == SPELL_AURA_MOD_INCREASE_HEALTH)
- m_amount = m_target->GetMaxHealth() * m_amount / 100;
- // Icebound Fortitude
- else if (m_spellProto->SpellFamilyFlags[0] & 0x00100000 && GetAuraName() == SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN)
+ Powers powertype = Powers(m_spellProto->powerType);
+ if(powertype == POWER_HEALTH)
{
- if (caster->GetTypeId() == TYPEID_PLAYER)
+ if (caster->GetHealth() > manaPerSecond)
+ caster->ModifyHealth(-manaPerSecond);
+ else
{
- int32 value = int32((m_amount*-1)-10);
- uint32 defva = uint32(((Player*)caster)->GetSkillValue(SKILL_DEFENSE) + ((Player*)caster)->GetRatingBonusValue(CR_DEFENSE_SKILL));
-
- if(defva > 400)
- value += int32((defva-400)*0.15);
-
- // Glyph of Icebound Fortitude
- if (AuraEffect *auradummy = caster->GetAuraEffect(58625,0))
- {
- uint32 valmax = auradummy->GetAmount();
- if(value < valmax)
- value = valmax;
- }
- m_amount = -value;
+ Remove();
+ return;
}
}
- break;
- }
- default:
- break;
- }
-
- if (DoneActualBenefit != 0.0f)
- {
- // Handle SPELL_AURA_ADD_PCT_MODIFIERs
- Unit::AuraEffectList const& AuraPctMmodifiers = caster->GetAurasByType(SPELL_AURA_ADD_PCT_MODIFIER);
- for (Unit::AuraEffectList::const_iterator i = AuraPctMmodifiers.begin(); i != AuraPctMmodifiers.end(); ++i)
- {
- if ((*i)->isAffectedOnSpell(m_spellProto) && (*i)->GetMiscValue() == SPELLMOD_ALL_EFFECTS)
- BenefitMod += (*i)->GetAmount() / 100.0f;
- }
-
- DoneActualBenefit *= BenefitMod;
- DoneActualBenefit *= caster->CalculateLevelPenalty(GetSpellProto());
- m_amount += (int32)DoneActualBenefit;
- }
- }
- }
- else
- {
- if (caster &&
- // Power Word: Shield
- m_spellProto->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellProto->Mechanic == MECHANIC_SHIELD &&
- (m_spellProto->SpellFamilyFlags[0] & 0x00000001) &&
- // completely absorbed or dispelled
- ((m_parentAura->GetRemoveMode() == AURA_REMOVE_BY_DEFAULT && m_amount) || m_parentAura->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE))
- {
- Unit::AuraEffectList const& vDummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
- for(Unit::AuraEffectList::const_iterator itr = vDummyAuras.begin(); itr != vDummyAuras.end(); ++itr)
- {
- SpellEntry const* vSpell = (*itr)->GetSpellProto();
-
- // Rapture (main spell)
- if(vSpell->SpellFamilyName == SPELLFAMILY_PRIEST && vSpell->SpellIconID == 2894 && vSpell->Effect[1])
- {
- switch((*itr)->m_effIndex)
+ else
{
- case 0:
- {
- // energize caster
- int32 manapct1000 = 5 * ((*itr)->m_amount + spellmgr.GetSpellRank(vSpell->Id));
- int32 basepoints0 = caster->GetMaxPower(POWER_MANA) * manapct1000 / 1000;
- caster->CastCustomSpell(caster, 47755, &basepoints0, NULL, NULL, true);
- break;
- }
- case 1:
+ if (caster->GetPower(powertype) >= manaPerSecond)
+ caster->ModifyPower(powertype, -manaPerSecond);
+ else
{
- // energize target
- if (!roll_chance_i((*itr)->m_amount) || caster->HasAura(63853))
- break;
-
- switch(m_target->getPowerType())
- {
- case POWER_RUNIC_POWER:
- m_target->CastSpell(m_target, 63652, true, NULL, NULL, GetCasterGUID());
- break;
- case POWER_RAGE:
- m_target->CastSpell(m_target, 63653, true, NULL, NULL, GetCasterGUID());
- break;
- case POWER_MANA:
- {
- int32 basepoints0 = m_target->GetMaxPower(POWER_MANA) * 2 / 100;
- m_target->CastCustomSpell(m_target, 63654, &basepoints0, NULL, NULL, true);
- break;
- }
- case POWER_ENERGY:
- m_target->CastSpell(m_target, 63655, true, NULL, NULL, GetCasterGUID());
- break;
- default:
- break;
- }
-
- //cooldwon aura
- caster->CastSpell(caster, 63853, true);
- break;
+ Remove();
+ return;
}
- default:
- sLog.outError("Changes in R-dummy spell???: effect 3");
- break;
}
}
}
@@ -1684,304 +489,66 @@ void AuraEffect::HandleAuraEffectSpecificMods(bool apply, bool Real, bool change
}
}
-void Aura::SendAuraUpdate()
+void Aura::SetDuration(int32 duration, bool withMods)
{
- if (m_auraSlot>=MAX_AURAS)
- return;
- WorldPacket data(SMSG_AURA_UPDATE);
-
- data.append(m_target->GetPackGUID());
- data << uint8(m_auraSlot);
-
- if(!m_target->GetVisibleAura(m_auraSlot))
- {
- data << uint32(0);
- sLog.outDebug("Aura %u removed slot %u",GetId(), m_auraSlot);
- m_target->SendMessageToSet(&data, true);
- return;
- }
-
- data << uint32(GetId());
- data << uint8(m_auraFlags);
- data << uint8(m_auraLevel);
- data << uint8(m_stackAmount > 1 ? m_stackAmount : (m_procCharges) ? m_procCharges : 1);
-
- if(!(m_auraFlags & AFLAG_CASTER))
+ if (withMods)
{
if (Unit * caster = GetCaster())
- data.append(caster->GetPackGUID());
- else
- data << uint8(0);
- }
-
- if(m_auraFlags & AFLAG_DURATION)
- {
- data << uint32(m_maxduration);
- data << uint32(m_duration);
+ if (Player * modOwner = caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, duration);
}
-
- m_target->SendMessageToSet(&data, true);
+ m_duration = duration;
+ SetNeedClientUpdateForTargets();
}
-bool Aura::IsVisible() const
+void Aura::RefreshDuration()
{
- // passive auras (except totem auras) do not get placed in the slots
- // area auras with SPELL_AURA_NONE are not shown on target
- //(m_spellProto->Attributes & 0x80 && GetTalentSpellPos(GetId()))
-
- if(!m_isPassive)
- return true;
-
- bool noneAreaAura = true;
+ SetDuration(GetMaxDuration());
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- {
- if(m_partAuras[i])
- {
- if(m_partAuras[i]->IsAreaAura())
- {
- if(Unit *source = ((AreaAuraEffect*)m_partAuras[i])->GetSource())
- if(source->isTotem())
- return true;
+ if(m_effects[i])
+ m_effects[i]->ResetPeriodic();
- if(m_partAuras[i]->GetAuraName() != SPELL_AURA_NONE)
- noneAreaAura = false;
- }
- else
- noneAreaAura = false;
- }
- }
-
- if(noneAreaAura)
- return false;
-
- return IsAuraType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
+ if(m_spellProto->manaPerSecond || m_spellProto->manaPerSecondPerLevel)
+ m_timeCla = 1 * IN_MILISECONDS;
}
-void Aura::_AddAura()
+void Aura::SetCharges(uint8 charges)
{
- if (!GetId())
- return;
- if(!m_target)
+ if (m_procCharges == charges)
return;
-
- Unit* caster = GetCaster();
-
- // set infinity cooldown state for spells
- if(caster && caster->GetTypeId() == TYPEID_PLAYER)
- {
- if (m_spellProto->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE)
- {
- Item* castItem = m_castItemGuid ? ((Player*)caster)->GetItemByGuid(m_castItemGuid) : NULL;
- ((Player*)caster)->AddSpellAndCategoryCooldowns(m_spellProto,castItem ? castItem->GetEntry() : 0, NULL,true);
- }
- }
-
- if(IsVisible())
- {
- // Try find slot for aura
- uint8 slot = MAX_AURAS;
- // Lookup for auras already applied from spell
- if (Aura * foundAura = m_target->GetAura(GetId(), GetCasterGUID()))
- {
- // allow use single slot only by auras from same caster
- slot = foundAura->GetAuraSlot();
- }
- else
- {
- Unit::VisibleAuraMap const * visibleAuras= m_target->GetVisibleAuras();
- // lookup for free slots in units visibleAuras
- Unit::VisibleAuraMap::const_iterator itr = visibleAuras->find(0);
- for (uint32 freeSlot = 0; freeSlot < MAX_AURAS; ++itr , ++freeSlot)
- {
- if(itr == visibleAuras->end() || itr->first != freeSlot)
- {
- slot = freeSlot;
- break;
- }
- }
- }
-
- // Register Visible Aura
- if(slot < MAX_AURAS)
- {
- m_auraFlags |= (IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE) |
- (GetCasterGUID() == m_target->GetGUID() ? AFLAG_CASTER : AFLAG_NONE) |
- (GetAuraMaxDuration() > 0 ? AFLAG_DURATION : AFLAG_NONE);
- m_auraLevel = (caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
- SetAuraSlot( slot );
- m_target->SetVisibleAura(slot, this);
- m_target->UpdateAuraForGroup(slot);
- SendAuraUpdate();
- sLog.outDebug("Aura: %u Effect: %d put to unit visible auras slot: %u",GetId(), GetEffectMask(), slot);
- }
- else
- sLog.outDebug("Aura: %u Effect: %d could not find empty unit visible slot",GetId(), GetEffectMask());
- }
-
- // Sitdown on apply aura req seated
- if (m_spellProto->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && !m_target->IsSitState())
- m_target->SetStandState(UNIT_STAND_STATE_SIT);
-
- // register aura diminishing on apply
- if (getDiminishGroup() != DIMINISHING_NONE )
- m_target->ApplyDiminishingAura(getDiminishGroup(),true);
-
- // Apply linked auras (On first aura apply)
- uint32 id = GetId();
- if(spellmgr.GetSpellCustomAttr(id) & SPELL_ATTR_CU_LINK_AURA)
- {
- if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(id + SPELL_LINK_AURA))
- for (std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
- {
- if(*itr < 0)
- m_target->ApplySpellImmune(id, IMMUNITY_ID, -(*itr), true);
- else if(Unit* caster = GetCaster())
- caster->AddAura(*itr, m_target);
- }
- }
-
- HandleAuraSpecificMods(true);
-}
-
-bool Aura::SetPartAura(AuraEffect* aurEff, uint8 effIndex)
-{
- if (IsRemoved())
- return false;
- if (m_auraFlags & (1<<effIndex))
- return false;
- m_auraFlags |= 1<<effIndex;
- m_partAuras[effIndex]=aurEff;
- m_target->HandleAuraEffect(aurEff, true);
- SendAuraUpdate();
- return true;
+ m_procCharges = charges;
+ SetNeedClientUpdateForTargets();
}
-void Aura::_RemoveAura()
+bool Aura::DropCharge()
{
- Unit* caster = GetCaster();
-
- uint8 slot = GetAuraSlot();
-
- if (Aura * foundAura = m_target->GetAura(GetId(), GetCasterGUID()))
- {
- // allow use single slot only by auras from same caster
- slot = foundAura->GetAuraSlot();
- if(slot < MAX_AURAS) // slot not set
- if (Aura *entry = m_target->GetVisibleAura(slot))
- {
- // set not valid slot for aura - prevent removing other visible aura
- slot = MAX_AURAS;
- }
- }
-
- // update for out of range group members
- if (slot < MAX_AURAS)
- {
- m_target->RemoveVisibleAura(slot);
- m_target->UpdateAuraForGroup(slot);
- SendAuraUpdate();
- }
-
- // unregister aura diminishing (and store last time)
- if (getDiminishGroup() != DIMINISHING_NONE )
- m_target->ApplyDiminishingAura(getDiminishGroup(),false);
-
- // since now aura cannot apply/remove it's modifiers
- m_isRemoved = true;
- // disable client server communication for removed aura
- SetAuraSlot(MAX_AURAS);
-
- // reset cooldown state for spells
- if(caster && caster->GetTypeId() == TYPEID_PLAYER)
- {
- if ( GetSpellProto()->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE )
- // note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
- ((Player*)caster)->SendCooldownEvent(GetSpellProto());
- }
- uint32 id = GetId();
- // Remove Linked Auras
- if(m_removeMode != AURA_REMOVE_BY_STACK && m_removeMode != AURA_REMOVE_BY_DEATH)
- {
- if(uint32 customAttr = spellmgr.GetSpellCustomAttr(id))
- {
- if(customAttr & SPELL_ATTR_CU_LINK_REMOVE)
- {
- if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(-(int32)id))
- for (std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
- {
- if(*itr < 0)
- m_target->RemoveAurasDueToSpell(-(*itr));
- else if (m_removeMode != AURA_REMOVE_BY_DEFAULT)
- m_target->CastSpell(m_target, *itr, true, 0, 0, GetCasterGUID());
- }
- }
- if(customAttr & SPELL_ATTR_CU_LINK_AURA)
- {
- if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(id + SPELL_LINK_AURA))
- for (std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
- {
- if(*itr < 0)
- m_target->ApplySpellImmune(id, IMMUNITY_ID, -(*itr), false);
- else
- m_target->RemoveAurasDueToSpell(*itr);
- }
- }
- }
- }
-
- // Proc on aura remove (only spell flags for now)
- if (caster)
+ if(m_procCharges) //auras without charges always have charge = 0
{
- uint32 procEx=0;
- if (m_removeMode == AURA_REMOVE_BY_ENEMY_SPELL)
- procEx = PROC_EX_AURA_REMOVE_DESTROY;
- else if (m_removeMode == AURA_REMOVE_BY_EXPIRE || m_removeMode == AURA_REMOVE_BY_CANCEL)
- procEx = PROC_EX_AURA_REMOVE_EXPIRE;
- if (procEx)
+ if(--m_procCharges) // Send charge change
+ SetNeedClientUpdateForTargets();
+ else // Last charge dropped
{
- uint32 ProcCaster, ProcVictim;
- if (IsPositive())
- {
- ProcCaster = PROC_FLAG_SUCCESSFUL_POSITIVE_MAGIC_SPELL | PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL_HIT;
- ProcVictim = PROC_FLAG_TAKEN_POSITIVE_MAGIC_SPELL | PROC_FLAG_TAKEN_POSITIVE_SPELL;
- }
- else
- {
- ProcCaster = PROC_FLAG_SUCCESSFUL_NEGATIVE_MAGIC_SPELL | PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT;
- ProcVictim = PROC_FLAG_TAKEN_NEGATIVE_MAGIC_SPELL | PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT;
- }
- caster->ProcDamageAndSpell(m_target,ProcCaster, ProcVictim, procEx, m_procDamage, BASE_ATTACK, m_spellProto);
+ Remove(AURA_REMOVE_BY_EXPIRE);
+ return true;
}
}
- HandleAuraSpecificMods(false);
+ return false;
}
void Aura::SetStackAmount(uint8 stackAmount, bool applied)
{
- bool refresh = stackAmount >= m_stackAmount;
if (stackAmount != m_stackAmount)
{
m_stackAmount = stackAmount;
- for (uint8 i=0; i<MAX_SPELL_EFFECTS; ++i)
- {
- if (AuraEffect * part = GetPartAura(i))
- {
- part->RecalculateAmount(applied);
- }
- }
+ RecalculateAmountOfEffects();
}
-
- if (refresh)
- RefreshAura();
- else
- SendAuraUpdate();
+ SetNeedClientUpdateForTargets();
}
-// TODO: lifebloom should bloom when each stack is dispelled
-bool Aura::modStackAmount(int32 num)
+bool Aura::ModStackAmount(int32 num)
{
// Can`t mod
- if (!m_spellProto->StackAmount)
+ if (!m_spellProto->StackAmount || !GetStackAmount())
return true;
// Modify stack but limit it
@@ -1993,48 +560,27 @@ bool Aura::modStackAmount(int32 num)
m_stackAmount = 0;
return true; // need remove aura
}
+ bool refresh = stackAmount >= GetStackAmount();
// Update stack amount
SetStackAmount(stackAmount);
+
+ if (refresh)
+ RefreshDuration();
+ SetNeedClientUpdateForTargets();
+
return false;
}
-void Aura::SetAuraDuration(int32 duration, bool withMods)
-{
- if (withMods)
- {
- if (Player * modOwner = m_target->GetSpellModOwner())
- modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, duration);
- }
- m_duration = duration;
- //if (duration<0)
- //m_permanent=true;
- //else
- //m_permanent=false;
- SendAuraUpdate();
-}
-void Aura::SetAuraCharges(uint8 charges)
+bool Aura::IsPassive() const
{
- if (m_procCharges == charges)
- return;
- m_procCharges = charges;
- SendAuraUpdate();
+ return IsPassiveSpell(GetSpellProto());
}
-bool Aura::DropAuraCharge()
+bool Aura::IsDeathPersistent() const
{
- if(m_procCharges) //auras without charges always have charge = 0
- {
- if(--m_procCharges) // Send charge change
- SendAuraUpdate();
- else // Last charge dropped
- {
- m_target->RemoveAura(this, AURA_REMOVE_BY_EXPIRE);
- return true;
- }
- }
- return false;
+ return IsDeathPersistentSpell(GetSpellProto());
}
bool Aura::CanBeSaved() const
@@ -2042,5294 +588,924 @@ bool Aura::CanBeSaved() const
if (IsPassive())
return false;
- if(IsPersistent())
- return false;
-
- if (GetCasterGUID() != m_target->GetGUID())
- if (IsSingleTargetSpell(GetSpellProto()) || IsAreaAura())
+ if (GetCasterGUID() != GetOwner()->GetGUID())
+ if (IsSingleTargetSpell(GetSpellProto()))
return false;
// Can't be saved - aura handler relies on calculated amount and changes it
- if (IsAuraType(SPELL_AURA_CONVERT_RUNE))
+ if (HasEffectType(SPELL_AURA_CONVERT_RUNE))
return false;
return true;
}
-bool Aura::IsPersistent() const
+bool Aura::HasEffectType(AuraType type) const
{
- return IS_DYNAMICOBJECT_GUID(m_sourceGuid);
- /*
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if(m_partAuras[i] && m_partAuras[i]->IsPersistent())
+ {
+ if(m_effects[i] && m_effects[i]->GetAuraType() == type)
return true;
+ }
return false;
- */
}
-bool Aura::IsAreaAura() const
+void Aura::RecalculateAmountOfEffects()
{
+ assert (!IsRemoved());
+ Unit * caster = GetCaster();
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if(m_partAuras[i] && m_partAuras[i]->IsAreaAura())
- return true;
- return false;
+ if(m_effects[i])
+ m_effects[i]->RecalculateAmount(caster);
}
-bool Aura::IsAuraType(AuraType type) const
+void Aura::HandleAllEffects(AuraApplication const * aurApp, uint8 mode, bool apply)
{
+ assert (!IsRemoved());
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- {
- if(m_partAuras[i] && m_partAuras[i]->GetAuraName() == type)
- return true;
- }
- return false;
+ if(m_effects[i] && !IsRemoved())
+ m_effects[i]->HandleEffect(aurApp, mode, apply);
}
-void Aura::SetLoadedState(uint64 caster_guid,int32 maxduration,int32 duration,int32 charges, uint8 stackamount, int32 * amount)
+bool Aura::IsVisible() const
{
- *const_cast<uint64*>(&m_casterGuid) = caster_guid;
- m_maxduration = maxduration;
+ // Is this blizzlike? show totem passive auras
+ if (GetOwner()->GetTypeId() == TYPEID_UNIT && ((Creature*)m_owner)->isTotem() && IsPassive())
+ return true;
+ return !IsPassive() || HasEffectType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
+}
+
+void Aura::SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint8 stackamount, uint8 recalculateMask, int32 * amount)
+{
+ m_maxDuration = maxduration;
m_duration = duration;
m_procCharges = charges;
m_stackAmount = stackamount;
+ Unit * caster = GetCaster();
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if(m_partAuras[i])
- m_partAuras[i]->SetAmount(amount[i]);
+ if(m_effects[i])
+ {
+ m_effects[i]->SetAmount(amount[i]);
+ m_effects[i]->SetCanBeRecalculated(recalculateMask & (1<<i));
+ m_effects[i]->CalculatePeriodic(caster);
+ m_effects[i]->CalculateSpellMod();
+ m_effects[i]->RecalculateAmount(caster);
+ }
}
-void AuraEffect::HandleShapeshiftBoosts(bool apply)
+// trigger effects on real aura apply/remove
+void Aura::HandleAuraSpecificMods(AuraApplication const * aurApp, Unit * caster, bool apply)
{
- uint32 spellId = 0;
- uint32 spellId2 = 0;
- uint32 spellId3 = 0;
- uint32 HotWSpellId = 0;
-
- switch(GetMiscValue())
- {
- case FORM_CAT:
- spellId = 3025;
- HotWSpellId = 24900;
- break;
- case FORM_TREE:
- spellId = 34123;
- break;
- case FORM_TRAVEL:
- spellId = 5419;
- break;
- case FORM_AQUA:
- spellId = 5421;
- break;
- case FORM_BEAR:
- spellId = 1178;
- spellId2 = 21178;
- HotWSpellId = 24899;
- break;
- case FORM_DIREBEAR:
- spellId = 9635;
- spellId2 = 21178;
- HotWSpellId = 24899;
- break;
- case FORM_BATTLESTANCE:
- spellId = 21156;
- break;
- case FORM_DEFENSIVESTANCE:
- spellId = 7376;
- break;
- case FORM_BERSERKERSTANCE:
- spellId = 7381;
- break;
- case FORM_MOONKIN:
- spellId = 24905;
- break;
- case FORM_FLIGHT:
- spellId = 33948;
- spellId2 = 34764;
- break;
- case FORM_FLIGHT_EPIC:
- spellId = 40122;
- spellId2 = 40121;
- break;
- case FORM_METAMORPHOSIS:
- spellId = 54817;
- spellId2 = 54879;
- break;
- case FORM_SPIRITOFREDEMPTION:
- spellId = 27792;
- spellId2 = 27795; // must be second, this important at aura remove to prevent to early iterator invalidation.
- break;
- case FORM_SHADOW:
- spellId = 49868;
- break;
- case FORM_GHOSTWOLF:
- spellId = 67116;
- break;
- case FORM_GHOUL:
- case FORM_AMBIENT:
- case FORM_STEALTH:
- case FORM_CREATURECAT:
- case FORM_CREATUREBEAR:
- break;
- }
-
- uint32 form = GetMiscValue()-1;
-
- if(apply)
+ Unit * target = aurApp->GetTarget();
+ AuraRemoveMode removeMode = aurApp->GetRemoveMode();
+ // spell_area table
+ SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAuraMapBounds(GetId());
+ if(saBounds.first != saBounds.second)
{
- // Remove cooldown of spells triggered on stance change - they may share cooldown with stance spell
- if (spellId)
- {
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player *)m_target)->RemoveSpellCooldown(spellId);
- m_target->CastSpell(m_target, spellId, true, NULL, this );
- }
+ uint32 zone, area;
+ target->GetZoneAndAreaId(zone,area);
- if (spellId2)
+ for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
{
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player *)m_target)->RemoveSpellCooldown(spellId2);
- m_target->CastSpell(m_target, spellId2, true, NULL, this);
- }
-
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- {
- const PlayerSpellMap& sp_list = ((Player *)m_target)->GetSpellMap();
- for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
- {
- if(itr->second->state == PLAYERSPELL_REMOVED) continue;
- if(itr->first==spellId || itr->first==spellId2) continue;
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
- if (!spellInfo || !(spellInfo->Attributes & (SPELL_ATTR_PASSIVE | (1<<7)))) continue;
- if (spellInfo->Stances & (1<<(form)))
- m_target->CastSpell(m_target, itr->first, true, NULL, this);
- }
- // Leader of the Pack
- if (((Player*)m_target)->HasSpell(17007))
- {
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(24932);
- if (spellInfo && spellInfo->Stances & (1<<(form)))
- m_target->CastSpell(m_target, 24932, true, NULL, this);
- }
- // Improved Barkskin - apply/remove armor bonus due to shapeshift
- if (((Player*)m_target)->HasSpell(63410) || ((Player*)m_target)->HasSpell(63411))
- {
- m_target->RemoveAurasDueToSpell(66530);
- if (form == FORM_TRAVEL || form == FORM_NONE) // "while in Travel Form or while not shapeshifted"
- m_target->CastSpell(m_target, 66530, true);
- }
- // Heart of the Wild
- if (HotWSpellId)
- {
- Unit::AuraEffectList const& mModTotalStatPct = m_target->GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
- for (Unit::AuraEffectList::const_iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
- {
- if ((*i)->GetSpellProto()->SpellIconID == 240 && (*i)->GetMiscValue() == 3)
- {
- int32 HotWMod = (*i)->GetAmount();
- if(GetMiscValue() == FORM_CAT)
- HotWMod /= 2;
-
- m_target->CastCustomSpell(m_target, HotWSpellId, &HotWMod, NULL, NULL, true, NULL, this);
- break;
- }
- }
- }
- switch(GetMiscValue())
+ // some auras remove at aura remove
+ if(!itr->second->IsFitToRequirements((Player*)target,zone,area))
+ target->RemoveAurasDueToSpell(itr->second->spellId);
+ // some auras applied at aura apply
+ else if(itr->second->autocast)
{
- case FORM_CAT:
- // Nurturing Instinct
- if (AuraEffect const * aurEff = m_target->GetAuraEffect(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT, SPELLFAMILY_DRUID, 2254,0))
- {
- uint32 spellId = 0;
- switch (aurEff->GetId())
- {
- case 33872:
- spellId = 47179;
- break;
- case 33873:
- spellId = 47180;
- break;
- }
- m_target->CastSpell(m_target, spellId, true, NULL, this);
- }
- // Master Shapeshifter - Cat
- if (AuraEffect const * aurEff = m_target->GetDummyAura(SPELLFAMILY_GENERIC, 2851, 0))
- {
- int32 bp = aurEff->GetAmount();
- m_target->CastCustomSpell(m_target, 48420, &bp, NULL, NULL, true);
- }
- break;
- case FORM_DIREBEAR:
- case FORM_BEAR:
- // Master Shapeshifter - Bear
- if (AuraEffect const * aurEff = m_target->GetDummyAura(SPELLFAMILY_GENERIC, 2851, 0))
- {
- int32 bp = aurEff->GetAmount();
- m_target->CastCustomSpell(m_target, 48418, &bp, NULL, NULL, true);
- }
- // Survival of the Fittest
- if (AuraEffect const * aurEff = m_target->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE,SPELLFAMILY_DRUID, 961, 0))
- {
- int32 bp = m_target->CalculateSpellDamage(aurEff->GetSpellProto(),2,aurEff->GetSpellProto()->EffectBasePoints[2],m_target);
- m_target->CastCustomSpell(m_target, 62069,&bp, NULL, NULL, true, 0, this);
- }
- break;
- case FORM_MOONKIN:
- // Master Shapeshifter - Moonkin
- if (AuraEffect const * aurEff = m_target->GetDummyAura(SPELLFAMILY_GENERIC, 2851, 0))
- {
- int32 bp = aurEff->GetAmount();
- m_target->CastCustomSpell(m_target, 48421, &bp, NULL, NULL, true);
- }
- break;
- // Master Shapeshifter - Tree of Life
- case FORM_TREE:
- if (AuraEffect const * aurEff = m_target->GetDummyAura(SPELLFAMILY_GENERIC, 2851, 0))
- {
- int32 bp = aurEff->GetAmount();
- m_target->CastCustomSpell(m_target, 48422, &bp, NULL, NULL, true);
- }
- break;
+ if( !target->HasAura(itr->second->spellId) )
+ target->CastSpell(target,itr->second->spellId,true);
}
}
}
- else
- {
- if (spellId)
- m_target->RemoveAurasDueToSpell(spellId);
- if (spellId2)
- m_target->RemoveAurasDueToSpell(spellId2);
-
- // Improved Barkskin - apply/remove armor bonus due to shapeshift
- if (((Player*)m_target)->HasSpell(63410) || ((Player*)m_target)->HasSpell(63411))
- {
- m_target->RemoveAurasDueToSpell(66530);
- m_target->CastSpell(m_target,66530,true);
- }
-
- Unit::AuraMap& tAuras = m_target->GetAuras();
- for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
- {
- if (itr->second->IsRemovedOnShapeLost())
- m_target->RemoveAura(itr);
- else
- ++itr;
- }
- }
-}
-
-bool AuraEffect::isAffectedOnSpell(SpellEntry const *spell) const
-{
- if (!spell)
- return false;
- // Check family name
- if (spell->SpellFamilyName != m_spellProto->SpellFamilyName)
- return false;
-
- // Check EffectClassMask
- if (m_spellProto->EffectSpellClassMask[m_effIndex] & spell->SpellFamilyFlags)
- return true;
- return false;
-}
-
-void Aura::UnregisterSingleCastAura()
-{
- if (IsSingleTarget())
- {
- Unit* caster = NULL;
- caster = GetCaster();
- if(caster)
- {
- caster->GetSingleCastAuras().remove(this);
- }
- else
- {
- sLog.outCrash("Couldn't find the caster (guid: "UI64FMTD") of the single target aura %u which is on unit entry %u class %u, may crash later!", GetCasterGUID(), GetId(), m_target->GetEntry(), m_target->getClass());
- assert(false);
- }
- m_isSingleTargetAura = false;
- }
-}
-
-/*********************************************************/
-/*** BASIC AURA FUNCTION ***/
-/*********************************************************/
-void AuraEffect::HandleAddModifier(bool apply, bool Real, bool changeAmount)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER || (!Real && !changeAmount))
- return;
-
- uint32 modOp = GetMiscValue();
-
- if(modOp >= MAX_SPELLMOD)
- return;
-
+ // mods at aura apply
if (apply)
{
- SpellModifier *mod = new SpellModifier(GetParentAura());
- mod->op = SpellModOp(modOp);
- mod->value = m_amount;
- mod->type = SpellModType(m_auraName); // SpellModType value == spell aura types
- mod->spellId = GetId();
- mod->mask = m_spellProto->EffectSpellClassMask[m_effIndex];
- mod->charges = GetParentAura()->GetAuraCharges();
-
- m_spellmod = mod;
- }
-
- ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
-
- // Auras with charges do not mod amount of passive auras
- if (GetParentAura()->GetAuraCharges())
- return;
-
- // reapply some passive spells after add/remove related spellmods
- // Warning: it is a dead loop if 2 auras each other amount-shouldn't happen
- switch (modOp)
- {
- case SPELLMOD_ALL_EFFECTS:
- case SPELLMOD_EFFECT1:
- case SPELLMOD_EFFECT2:
- case SPELLMOD_EFFECT3:
+ // Apply linked auras (On first aura apply)
+ if(spellmgr.GetSpellCustomAttr(GetId()) & SPELL_ATTR_CU_LINK_AURA)
{
- uint64 guid = m_target->GetGUID();
- Unit::AuraMap & auras = m_target->GetAuras();
- for (Unit::AuraMap::iterator iter = auras.begin(); iter != auras.end(); ++iter)
- {
- Aura * aur = iter->second;
- // only passive auras-active auras should have amount set on spellcast and not be affected
- // if aura is casted by others, it will not be affected
- if (aur->IsPassive() && aur->GetCasterGUID() == guid && spellmgr.IsAffectedByMod(aur->GetSpellProto(), m_spellmod))
+ if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(GetId() + SPELL_LINK_AURA))
+ for (std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
{
- if (modOp == SPELLMOD_ALL_EFFECTS)
- {
- for (uint8 i = 0; i<MAX_SPELL_EFFECTS; ++i)
- {
- if (AuraEffect * aurEff = aur->GetPartAura(i))
- aurEff->RecalculateAmount();
- }
- }
- else if (modOp ==SPELLMOD_EFFECT1)
- {
- if (AuraEffect * aurEff = aur->GetPartAura(0))
- aurEff->RecalculateAmount();
- }
- else if (modOp ==SPELLMOD_EFFECT2)
- {
- if (AuraEffect * aurEff = aur->GetPartAura(1))
- aurEff->RecalculateAmount();
- }
- else //if (modOp ==SPELLMOD_EFFECT3)
- {
- if (AuraEffect * aurEff = aur->GetPartAura(2))
- aurEff->RecalculateAmount();
- }
+ if(*itr < 0)
+ target->ApplySpellImmune(GetId(), IMMUNITY_ID, -(*itr), true);
+ else if(caster)
+ caster->AddAura(*itr, target);
}
- }
}
- default:
- break;
- }
- if (m_spellProto->Id == 11129 && !apply)
- {
- m_target->RemoveAurasDueToSpell(28682);
- }
-}
-
-void AuraEffect::TriggerSpell()
-{
- Unit* caster = GetCaster();
- Unit* target = GetTriggerTarget();
-
- if(!caster || !target)
- return;
-
- // generic casting code with custom spells and target/caster customs
- uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
-
- SpellEntry const *triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
- SpellEntry const *auraSpellInfo = GetSpellProto();
- uint32 auraId = auraSpellInfo->Id;
-
- // specific code for cases with no trigger spell provided in field
- if (triggeredSpellInfo == NULL)
- {
- switch(auraSpellInfo->SpellFamilyName)
+ switch (GetSpellProto()->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
- {
- switch(auraId)
+ switch(GetId())
{
- // Firestone Passive (1-5 ranks)
- case 758:
- case 17945:
- case 17947:
- case 17949:
- case 27252:
- {
- if (caster->GetTypeId() != TYPEID_PLAYER)
- return;
- Item* item = ((Player*)caster)->GetWeaponForAttack(BASE_ATTACK);
- if (!item)
- return;
- uint32 enchant_id = 0;
- switch (GetId())
- {
- case 758: enchant_id = 1803; break; // Rank 1
- case 17945: enchant_id = 1823; break; // Rank 2
- case 17947: enchant_id = 1824; break; // Rank 3
- case 17949: enchant_id = 1825; break; // Rank 4
- case 27252: enchant_id = 2645; break; // Rank 5
- default:
- return;
- }
- // remove old enchanting before applying new
- ((Player*)caster)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,false);
- item->SetEnchantment(TEMP_ENCHANTMENT_SLOT, enchant_id, m_amplitude+1000, 0);
- // add new enchanting
- ((Player*)caster)->ApplyEnchantment(item,TEMP_ENCHANTMENT_SLOT,true);
- return;
- }
- // Thaumaturgy Channel
- case 9712: trigger_spell_id = 21029; break;
- case 23170:
- {
- m_target->CastSpell(m_target, 23171, true, 0, this);
- return;
- }
- // Restoration
- case 23493:
- {
- int32 heal = caster->GetMaxHealth() / 10;
- caster->DealHeal(m_target, heal, auraSpellInfo);
-
- int32 mana = caster->GetMaxPower(POWER_MANA);
- if (mana)
- {
- mana /= 10;
- caster->EnergizeBySpell(caster, 23493, mana, POWER_MANA);
- }
- return;
- }
- // Nitrous Boost
- case 27746:
- {
- if (caster->GetPower(POWER_MANA) >= 10)
- {
- caster->ModifyPower( POWER_MANA, -10 );
- caster->SendEnergizeSpellLog(caster, 27746, -10, POWER_MANA);
- } else
- {
- caster->RemoveAurasDueToSpell(27746);
- return;
- }
- } break;
- // Frost Blast
- case 27808:
- caster->CastCustomSpell(29879, SPELLVALUE_BASE_POINT0, (float)m_target->GetMaxHealth()*0.26f, m_target, true, NULL, this);
- return;
- // Detonate Mana
- case 27819:
- if(int32 mana = (int32)(m_target->GetMaxPower(POWER_MANA) / 4))
- {
- mana = m_target->ModifyPower(POWER_MANA, -mana);
- m_target->CastCustomSpell(27820, SPELLVALUE_BASE_POINT0, -mana*4, NULL, true, NULL, this, caster->GetGUID());
- }
- return;
- // Inoculate Nestlewood Owlkin
- case 29528:
- if(target->GetTypeId()!=TYPEID_UNIT)// prevent error reports in case ignored player target
- return;
+ case 32474: // Buffeting Winds of Susurrus
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)target)->ActivateTaxiPathTo(506, GetId());
break;
- // Feed Captured Animal
- case 29917: trigger_spell_id = 29916; break;
- // Extract Gas
- case 30427:
- {
- // move loot to player inventory and despawn target
- if(caster->GetTypeId() ==TYPEID_PLAYER &&
- target->GetTypeId() == TYPEID_UNIT &&
- ((Creature*)target)->GetCreatureInfo()->type == CREATURE_TYPE_GAS_CLOUD)
- {
- Player* player = (Player*)caster;
- Creature* creature = (Creature*)target;
- // missing lootid has been reported on startup - just return
- if (!creature->GetCreatureInfo()->SkinLootId)
- return;
-
- player->AutoStoreLoot(creature->GetCreatureInfo()->SkinLootId,LootTemplates_Skinning,true);
-
- creature->ForcedDespawn();
- }
- return;
- }
- // Quake
- case 30576: trigger_spell_id = 30571; break;
- // Doom
- case 31347:
- {
- m_target->CastSpell(m_target,31350,true, NULL, this);
- m_target->Kill(m_target);
- return;
- }
- // Spellcloth
- case 31373:
- {
- // Summon Elemental after create item
- caster->SummonCreature(17870, 0, 0, 0, caster->GetOrientation(), TEMPSUMMON_DEAD_DESPAWN, 0);
- return;
- }
- // Flame Quills
- case 34229:
- {
- // cast 24 spells 34269-34289, 34314-34316
- for (uint32 spell_id = 34269; spell_id != 34290; ++spell_id)
- caster->CastSpell(m_target,spell_id,true, NULL, this);
- for (uint32 spell_id = 34314; spell_id != 34317; ++spell_id)
- caster->CastSpell(m_target,spell_id,true, NULL, this);
- return;
- }
- // Remote Toy
- case 37027: trigger_spell_id = 37029; break;
- // Eye of Grillok
- case 38495:
- {
- m_target->CastSpell(m_target, 38530, true, NULL, this);
- return;
- }
- // Absorb Eye of Grillok (Zezzak's Shard)
- case 38554:
- {
- if(m_target->GetTypeId() != TYPEID_UNIT)
- return;
-
- caster->CastSpell(caster, 38495, true, NULL, this);
-
- Creature* creatureTarget = (Creature*)m_target;
-
- creatureTarget->ForcedDespawn();
- return;
- }
- // Tear of Azzinoth Summon Channel - it's not really supposed to do anything,and this only prevents the console spam
- case 39857: trigger_spell_id = 39856; break;
- // Aura of Desire
- case 41350:
- {
- AuraEffect * aurEff = GetParentAura()->GetPartAura(1);
- aurEff->ApplyModifier(false, false, true);
- aurEff->SetAmount(aurEff->GetAmount()-5);
- aurEff->ApplyModifier(true, false, true);
+ case 33572: // Gronn Lord's Grasp, becomes stoned
+ if(GetStackAmount() >= 5 && !target->HasAura(33652))
+ target->CastSpell(target, 33652, true);
break;
- }
- case 46736: trigger_spell_id = 46737; break;
- default:
+ case 60970: // Heroic Fury (remove Intercept cooldown)
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)target)->RemoveSpellCooldown(20252, true);
break;
}
break;
- }
case SPELLFAMILY_MAGE:
- {
- switch(auraId)
- {
- // Invisibility
- case 66:
- // Here need periodic triger reducing threat spell (or do it manually)
- return;
- default:
- break;
- }
- break;
- }
- case SPELLFAMILY_DRUID:
- {
- switch(auraId)
+ if (!caster)
+ break;
+ if (GetSpellProto()->SpellFamilyFlags[0] & 0x00000001 && GetSpellProto()->SpellFamilyFlags[2] & 0x00000008)
{
- // Cat Form
- // trigger_spell_id not set and unknown effect triggered in this case, ignoring for while
- case 768:
- return;
- default:
- break;
+ // Glyph of Fireball
+ if (caster->HasAura(56368))
+ SetDuration(0);
}
- break;
- }
- case SPELLFAMILY_HUNTER:
- {
- switch (auraId)
+ else if (GetSpellProto()->SpellFamilyFlags[0] & 0x00000020 && GetSpellProto()->SpellVisual[0] == 13)
{
- // Sniper training
- case 53302:
- case 53303:
- case 53304:
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- if (((Player*)m_target)->isMoving())
- {
- m_amount = m_target->CalculateSpellDamage(m_spellProto,m_effIndex,m_currentBasePoints,m_target);
- return;
- }
-
- // We are standing at the moment
- if (m_amount > 0)
- {
- --m_amount;
- return;
- }
-
- trigger_spell_id = 64418 + auraId - 53302;
-
- // If aura is active - no need to continue
- if (target->HasAura(trigger_spell_id))
- return;
-
- break;
- default:
- break;
+ // Glyph of Frostbolt
+ if (caster->HasAura(56370))
+ SetDuration(0);
}
- break;
- }
- case SPELLFAMILY_SHAMAN:
- {
- switch(auraId)
+ // Todo: This should be moved to similar function in spell::hit
+ else if (GetSpellProto()->SpellFamilyFlags[0] & 0x01000000)
{
- // Lightning Shield (The Earthshatterer set trigger after cast Lighting Shield)
- case 28820:
+ // Polymorph Sound - Sheep && Penguin
+ if (GetSpellProto()->SpellIconID == 82 && GetSpellProto()->SpellVisual[0] == 12978)
{
- // Need remove self if Lightning Shield not active
- if (!target->GetAura(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN,0x400))
- target->RemoveAurasDueToSpell(28820);
- return;
+ // Glyph of the Penguin
+ if (caster->HasAura(52648))
+ caster->CastSpell(target,61635,true);
+ else
+ caster->CastSpell(target,61634,true);
}
- // Totemic Mastery (Skyshatter Regalia (Shaman Tier 6) - bonus)
- case 38443:
- {
- bool all = true;
- for (int i = SUMMON_SLOT_TOTEM; i < MAX_TOTEM_SLOT; ++i)
+ }
+ switch(GetId())
+ {
+ case 12536: // Clearcasting
+ case 12043: // Presence of Mind
+ // Arcane Potency
+ if (AuraEffect const * aurEff = caster->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_MAGE, 2120, 0))
{
- if(!caster->m_SummonSlot[i])
+ if (roll_chance_i(aurEff->GetAmount()))
{
- all = false;
- break;
+ uint32 spellId = 0;
+
+ switch (aurEff->GetId())
+ {
+ case 31571: spellId = 57529; break;
+ case 31572: spellId = 57531; break;
+ default:
+ sLog.outError("Aura::HandleAuraSpecificMods: Unknown rank of Arcane Potency (%d) found", aurEff->GetId());
+ }
+ if(spellId)
+ caster->CastSpell(caster, spellId, true);
}
}
-
- if(all)
- caster->CastSpell(caster,38437,true, NULL, this);
- else
- caster->RemoveAurasDueToSpell(38437);
- return;
- }
- default:
break;
}
break;
- }
- default:
- break;
- }
-
- // Reget trigger spell proto
- triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
- }
- else
- {
- // Spell exist but require custom code
- switch(auraId)
- {
- // Mana Tide
- case 16191:
- {
- caster->CastCustomSpell(target, trigger_spell_id, &m_amount, NULL, NULL, true, NULL, this);
- return;
- }
- // Negative Energy Periodic
- case 46284:
- caster->CastCustomSpell(trigger_spell_id, SPELLVALUE_MAX_TARGETS, m_tickNumber / 10 + 1, NULL, true, NULL, this);
- return;
- // Poison (Grobbulus)
- case 28158:
- case 54362:
- m_target->CastCustomSpell(trigger_spell_id, SPELLVALUE_RADIUS_MOD, (int32)((((float)m_tickNumber / 60) * 0.9f + 0.1f) * 10000), NULL, true, NULL, this);
- return;
- // Mind Sear (target 76/16) if let m_target cast, will damage caster
- case 48045:
- case 53023:
- // Curse of the Plaguebringer (22/15)
- case 29213:
- case 54835:
- caster->CastSpell(m_target, trigger_spell_id, true, NULL, this);
- return;
- // Ground Slam
- case 33525:
- target->CastSpell(target, trigger_spell_id, true);
- return;
- }
- }
-
- if(triggeredSpellInfo)
- {
- if(!caster->GetSpellMaxRangeForTarget(m_target,sSpellRangeStore.LookupEntry(triggeredSpellInfo->rangeIndex)))
- target = m_target; //for druid dispel poison
- m_target->CastSpell(target, triggeredSpellInfo, true, 0, this, GetCasterGUID());
- }
- else if(target->GetTypeId()!=TYPEID_UNIT || !Script->EffectDummyCreature(caster, GetId(), GetEffIndex(), (Creature*)target))
- sLog.outError("AuraEffect::TriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",GetId(),GetEffIndex());
-}
-
-Unit* AuraEffect::GetTriggerTarget() const
-{
- Unit* target = ObjectAccessor::GetUnit(*m_target, m_target->GetUInt64Value(UNIT_FIELD_TARGET));
- return target ? target : m_target;
-}
-
-void AuraEffect::TriggerSpellWithValue()
-{
- Unit* caster = GetCaster();
- Unit* target = GetTriggerTarget();
-
- if(!caster || !target)
- return;
-
- // generic casting code with custom spells and target/caster customs
- uint32 trigger_spell_id = GetSpellProto()->EffectTriggerSpell[m_effIndex];
- int32 basepoints0 = this->GetAmount();
-
- caster->CastCustomSpell(target, trigger_spell_id, &basepoints0, 0, 0, true, 0, this);
-}
-
-/*********************************************************/
-/*** AURA EFFECTS ***/
-/*********************************************************/
-
-void AuraEffect::HandleAuraDummy(bool apply, bool Real, bool changeAmount)
-{
- Unit* caster = GetCaster();
-
- // spells required only Real aura add/remove
- if (Real)
- {
- // AT APPLY
- if(apply)
- {
- // Overpower
- if (caster && m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR &&
- m_spellProto->SpellFamilyFlags[0] & 0x4)
- {
- // Must be casting target
- if (!m_target->IsNonMeleeSpellCasted(false, false, true))
- return;
- if (AuraEffect * aurEff = caster->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARRIOR, 2775, 0))
- {
- switch (aurEff->GetId())
+ case SPELLFAMILY_WARLOCK:
+ switch(GetId())
{
- // Unrelenting Assault, rank 1
- case 46859:
- m_target->CastSpell(m_target,64849,true,NULL,aurEff);
- break;
- // Unrelenting Assault, rank 2
- case 46860:
- m_target->CastSpell(m_target,64850,true,NULL,aurEff);
+ case 48020: // Demonic Circle
+ if(target->GetTypeId() == TYPEID_PLAYER)
+ if(GameObject* obj = target->GetGameObject(48018))
+ ((Player*)target)->TeleportTo(obj->GetMapId(),obj->GetPositionX(),obj->GetPositionY(),obj->GetPositionZ(),obj->GetOrientation());
break;
}
- }
- return;
- }
- switch(GetId())
- {
- // Haunting Spirits - perdiodic trigger demon
- case 7057:
- m_isPeriodic = true;
- m_amplitude = irand (0, 60) + 30;
- m_amplitude *= IN_MILISECONDS;
- return;
- case 1515: // Tame beast
- // FIX_ME: this is 2.0.12 threat effect replaced in 2.1.x by dummy aura, must be checked for correctness
- if( caster && m_target->CanHaveThreatList())
- m_target->AddThreat(caster, 10.0f);
- return;
- case 13139: // net-o-matic
- // root to self part of (root_target->charge->root_self sequence
- if(caster)
- caster->CastSpell(caster,13138,true,NULL,this);
- return;
- case 34026: // kill command
- {
- Unit * pet = m_target->GetGuardianPet();
- if (!pet)
- return;
-
- m_target->CastSpell(m_target,34027,true,NULL,this);
-
- // set 3 stacks and 3 charges (to make all auras not disappear at once)
- Aura* owner_aura = m_target->GetAura(34027,GetCasterGUID());
- Aura* pet_aura = pet->GetAura(58914, GetCasterGUID());
- if( owner_aura )
- {
- owner_aura->SetStackAmount(owner_aura->GetSpellProto()->StackAmount);
- }
- if( pet_aura )
+ break;
+ case SPELLFAMILY_PRIEST:
+ if (!caster)
+ break;
+ // Devouring Plague
+ if (GetSpellProto()->SpellFamilyFlags[0] & 0x02000000 && GetEffect(0))
{
- pet_aura->SetAuraCharges(0);
- pet_aura->SetStackAmount(owner_aura->GetSpellProto()->StackAmount);
+ // Improved Devouring Plague
+ if (AuraEffect const * aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 3790, 1))
+ {
+ int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * GetEffect(0)->GetAmount() / 100;
+ caster->CastCustomSpell(target, 63675, &basepoints0, NULL, NULL, true, NULL, GetEffect(0));
+ }
}
- return;
- }
- case 37096: // Blood Elf Illusion
- {
- if(caster)
+ // Renew
+ else if (GetSpellProto()->SpellFamilyFlags[0] & 0x00000040 && GetEffect(0))
{
- switch(caster->getGender())
+ // Empowered Renew
+ if (AuraEffect const * aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 3021, 1))
{
- case GENDER_FEMALE:
- caster->CastSpell(m_target,37095,true,NULL,this); // Blood Elf Disguise
- break;
- case GENDER_MALE:
- caster->CastSpell(m_target,37093,true,NULL,this);
- break;
- default:
- break;
+ int32 basepoints0 = aurEff->GetAmount() * GetEffect(0)->GetTotalTicks() * caster->SpellHealingBonus(target, GetSpellProto(), GetEffect(0)->GetAmount(), HEAL) / 100;
+ caster->CastCustomSpell(target, 63544, &basepoints0, NULL, NULL, true, NULL, GetEffect(0));
}
}
- return;
- }
- case 55198: // Tidal Force
- {
- m_target->CastSpell(m_target,55166,true,NULL,this);
- // set 3 stacks and 3 charges (to make all auras not disappear at once)
- Aura* owner_aura = m_target->GetAura(55166,GetCasterGUID());
- if( owner_aura )
+ // Power Word: Shield
+ else if (m_spellProto->SpellFamilyFlags[0] & 0x1 && m_spellProto->SpellFamilyFlags[2] & 0x400 && GetEffect(0))
{
- // This aura lasts 2 sec, need this hack to properly proc spells
- // TODO: drop aura charges for ApplySpellMod in ProcDamageAndSpell
- GetParentAura()->SetAuraDuration(owner_aura->GetAuraDuration());
- // Make aura be not charged-this prevents removing charge on not crit spells
- owner_aura->SetAuraCharges(0);
- owner_aura->SetStackAmount(owner_aura->GetSpellProto()->StackAmount);
+ // Glyph of Power Word: Shield
+ if (AuraEffect* glyph = caster->GetAuraEffect(55672,0))
+ {
+ // 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));
+ }
}
- return;
- }
- case 49028:
- GetParentAura()->SetAuraDuration(GetParentAura()->GetAuraDuration() + (caster->GetPower(POWER_RUNIC_POWER) * 10));
- caster->SetPower(POWER_RUNIC_POWER, 0);
break;
- case 39850: // Rocket Blast
- if(roll_chance_i(20)) // backfire stun
- m_target->CastSpell(m_target, 51581, true, NULL, this);
- return;
- case 43873: // Headless Horseman Laugh
- m_target->PlayDistanceSound(11965);
- return;
- case 46354: // Blood Elf Illusion
- if(caster)
+ case SPELLFAMILY_ROGUE:
+ // Sprint (skip non player casted spells by category)
+ if(GetSpellProto()->SpellFamilyFlags[0] & 0x40 && GetSpellProto()->Category == 44)
+ // in official maybe there is only one icon?
+ if(target->HasAura(58039)) // Glyph of Blurred Speed
+ target->CastSpell(target, 61922, true); // Sprint (waterwalk)
+ break;
+ case SPELLFAMILY_DEATHKNIGHT:
+ if (!caster)
+ break;
+ // Frost Fever and Blood Plague
+ if(GetSpellProto()->SpellFamilyFlags[2] & 0x2)
{
- switch(caster->getGender())
+ // Can't proc on self
+ if (GetCasterGUID() == target->GetGUID())
+ break;
+
+ AuraEffect * aurEff = NULL;
+ // 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)
{
- case GENDER_FEMALE:
- caster->CastSpell(m_target,46356,true,NULL,this);
- break;
- case GENDER_MALE:
- caster->CastSpell(m_target,46355,true,NULL,this);
- break;
- default:
- break;
+ if ((*itr)->GetMiscValue() == 7282)
+ {
+ aurEff = *itr;
+ // Ebon Plaguebringer - end search if found
+ if ((*itr)->GetSpellProto()->SpellIconID == 1766)
+ 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:
+ sLog.outError("Aura::HandleAuraSpecificMods: Unknown rank of Crypt Fever/Ebon Plague (%d) found", aurEff->GetId());
+ }
+ caster->CastSpell(target, spellId, true, 0, GetEffect(0));
}
}
- return;
- case 46699: // Requires No Ammo
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->RemoveAmmo(); // not use ammo and not allow use
- return;
- case 62061: // Festive Holiday Mount
- if(m_target->HasAuraType(SPELL_AURA_MOUNTED))
- m_target->CastSpell(m_target, 25860, true, NULL, this); // Reindeer Transformation
- return;
- case 52916: // Honor Among Thieves
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- if (Unit * target = ObjectAccessor::GetUnit(*m_target,((Player*)m_target)->GetComboTarget()))
- m_target->CastSpell(target, 51699, true);
- return;
- }
-
- //Druid, Survival Instincts
- if(GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID && GetSpellProto()->SpellFamilyFlags[2]& 0x40 )
- {
- if(!m_target)
- return;
-
- int32 bp0 = int32(m_target->GetMaxHealth() * m_amount / 100);
- m_target->CastCustomSpell(m_target, 50322, &bp0, NULL, NULL, true);
+ break;
}
}
- // AT REMOVE
+ // mods at aura remove
else
{
- if( (IsQuestTameSpell(GetId())) && caster && caster->isAlive() && m_target->isAlive())
+ // Remove Linked Auras
+ if(removeMode != AURA_REMOVE_BY_STACK && removeMode != AURA_REMOVE_BY_DEATH)
{
- uint32 finalSpelId = 0;
- switch(GetId())
+ if(uint32 customAttr = spellmgr.GetSpellCustomAttr(GetId()))
{
- case 19548: finalSpelId = 19597; break;
- case 19674: finalSpelId = 19677; break;
- case 19687: finalSpelId = 19676; break;
- case 19688: finalSpelId = 19678; break;
- case 19689: finalSpelId = 19679; break;
- case 19692: finalSpelId = 19680; break;
- case 19693: finalSpelId = 19684; break;
- case 19694: finalSpelId = 19681; break;
- case 19696: finalSpelId = 19682; break;
- case 19697: finalSpelId = 19683; break;
- case 19699: finalSpelId = 19685; break;
- case 19700: finalSpelId = 19686; break;
- case 30646: finalSpelId = 30647; break;
- case 30653: finalSpelId = 30648; break;
- case 30654: finalSpelId = 30652; break;
- case 30099: finalSpelId = 30100; break;
- case 30102: finalSpelId = 30103; break;
- case 30105: finalSpelId = 30104; break;
- }
-
- if(finalSpelId)
- caster->CastSpell(m_target,finalSpelId,true,NULL,this);
- return;
- }
-
- switch(m_spellProto->SpellFamilyName)
- {
- case SPELLFAMILY_GENERIC:
- switch(GetId())
+ if(customAttr & SPELL_ATTR_CU_LINK_REMOVE)
{
- case 2584: // Waiting to Resurrect
- {
- // Waiting to resurrect spell cancel, we must remove player from resurrect queue
- if (m_target->GetTypeId() == TYPEID_PLAYER)
- if (BattleGround *bg = ((Player*)m_target)->GetBattleGround())
- bg->RemovePlayerFromResurrectQueue(m_target->GetGUID());
- return;
- }
- case 28169: // Mutating Injection
- {
- // Mutagen Explosion
- m_target->CastSpell(m_target, 28206, true, NULL, this);
- // Poison Cloud
- m_target->CastSpell(m_target, 28240, true, NULL, this);
- return;
- }
- case 36730: // Flame Strike
- {
- m_target->CastSpell(m_target, 36731, true, NULL, this);
- return;
- }
- case 44191: // Flame Strike
- {
- if (m_target->GetMap()->IsDungeon())
+ if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(-(int32)GetId()))
+ for (std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
{
- uint32 spellId = ((InstanceMap*)m_target->GetMap())->GetDifficulty() == REGULAR_DIFFICULTY ? 44190 : 46163;
-
- m_target->CastSpell(m_target, spellId, true, NULL, this);
+ if(*itr < 0)
+ target->RemoveAurasDueToSpell(-(*itr));
+ else if (removeMode != AURA_REMOVE_BY_DEFAULT)
+ target->CastSpell(target, *itr, true, 0, 0, GetCasterGUID());
}
- return;
- }
- case 42783: // Wrath of the Astromancer
- m_target->CastSpell(m_target,m_amount,true,NULL,this);
- return;
- case 46308: // Burning Winds casted only at creatures at spawn
- m_target->CastSpell(m_target,47287,true,NULL,this);
- return;
- case 52172: // Coyote Spirit Despawn Aura
- case 60244: // Blood Parrot Despawn Aura
- m_target->CastSpell((Unit*)NULL, GetAmount(), true, NULL, this);
- return;
- }
- break;
- case SPELLFAMILY_MAGE:
- // Living Bomb
- if(m_spellProto->SpellFamilyFlags[1] & 0x20000)
- {
- if(caster && (GetParentAura()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL || GetParentAura()->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE))
- caster->CastSpell(m_target, GetAmount(), true);
- return;
- }
- break;
- case SPELLFAMILY_WARLOCK:
- // Haunt
- if(m_spellProto->SpellFamilyFlags[1] & 0x40000)
- {
- int32 bp0 = GetParentAura()->GetProcDamage() * m_amount / 100;
- if(caster)
- caster->CastCustomSpell(caster, 48210, &bp0, 0, 0, true, NULL, this);
- return;
}
- break;
- case SPELLFAMILY_PALADIN:
- switch (GetSpellProto()->SpellIconID)
- {
- // Blessing of Sanctuary
- // Greater Blessing of Sanctuary
- case 19:
- case 1804:
+ if(customAttr & SPELL_ATTR_CU_LINK_AURA)
{
- if (!caster || !m_target)
- return;
-
- if (apply)
- {
- // Greater Blessing of Sanctuary does not provide strength bonus
- int32 bp1 = 0;
- caster->CastCustomSpell(m_target, 67480, NULL, (GetSpellProto()->SpellIconID == 1804) ? &bp1 : NULL, NULL, true);
- }
- else
- m_target->RemoveAurasDueToSpell(67480);
-
- return;
+ if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(GetId() + SPELL_LINK_AURA))
+ for (std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
+ {
+ if(*itr < 0)
+ target->ApplySpellImmune(GetId(), IMMUNITY_ID, -(*itr), false);
+ else
+ target->RemoveAurasDueToSpell(*itr);
+ }
}
}
- break;
- case SPELLFAMILY_PRIEST:
- // Vampiric Touch
- if (m_spellProto->SpellFamilyFlags[1] & 0x0400 && GetParentAura()->GetRemoveMode() == AURA_REMOVE_BY_ENEMY_SPELL)
+ }
+ switch(GetSpellProto()->SpellFamilyName)
+ {
+ case SPELLFAMILY_MAGE:
+ switch(GetId())
{
- if (AuraEffect const * aurEff = GetParentAura()->GetPartAura(1))
- {
- int32 damage = aurEff->GetAmount()*4;
- // backfire damage
- m_target->CastCustomSpell(m_target, 64085, &damage, NULL, NULL, true, NULL, NULL,GetCasterGUID());
- }
+ case 66: // Invisibility
+ if (removeMode != AURA_REMOVE_BY_EXPIRE)
+ break;
+ target->CastSpell(target, 32612, true, NULL, GetEffect(1));
+ break;
}
- break;
- case SPELLFAMILY_HUNTER:
- // Misdirection
- if(GetId()==34477)
+ if (!caster)
+ break;
+ // Ice barrier - dispel/absorb remove
+ if (removeMode == AURA_REMOVE_BY_ENEMY_SPELL && GetSpellProto()->SpellFamilyFlags[1] & 0x1)
{
- m_target->SetReducedThreatPercent(0, 0);
- return;
+ // Shattered Barrier
+ if (caster->GetDummyAuraEffect(SPELLFAMILY_MAGE, 2945, 0))
+ caster->CastSpell(target, 55080, true, NULL, GetEffect(0));
}
break;
- case SPELLFAMILY_DEATHKNIGHT:
- // Summon Gargoyle ( will start feeding gargoyle )
- if(GetId()==61777)
+ case SPELLFAMILY_WARRIOR:
+ if (!caster)
+ break;
+ // Spell Reflection
+ if (GetSpellProto()->SpellFamilyFlags[1] & 0x2)
{
- m_target->CastSpell(m_target,m_spellProto->EffectTriggerSpell[m_effIndex],true);
- return;
+ if (removeMode != AURA_REMOVE_BY_DEFAULT)
+ {
+ // Improved Spell Reflection
+ if (caster->GetDummyAuraEffect(SPELLFAMILY_WARRIOR,1935, 1))
+ {
+ // aura remove - remove auras from all party members
+ std::list<Unit*> PartyMembers;
+ target->GetPartyMembers(PartyMembers);
+ for (std::list<Unit*>::iterator itr = PartyMembers.begin(); itr!=PartyMembers.end(); ++itr)
+ {
+ if ((*itr)!= target)
+ (*itr)->RemoveAurasWithFamily(SPELLFAMILY_WARRIOR, 0, 0x2, 0, GetCasterGUID());
+ }
+ }
+ }
}
break;
- default:
- break;
- }
- }
- }
-
- // AT APPLY & REMOVE
-
- switch(m_spellProto->SpellFamilyName)
- {
- case SPELLFAMILY_GENERIC:
- {
- if (!Real)
- break;
- switch(GetId())
- {
- // Recently Bandaged
- case 11196:
- m_target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, GetMiscValue(), apply);
- return;
- // Unstable Power
- case 24658:
+ case SPELLFAMILY_WARLOCK:
+ if (!caster)
+ break;
+ // Curse of Doom
+ if (GetSpellProto()->SpellFamilyFlags[1] & 0x02)
{
- uint32 spellId = 24659;
- if (apply && caster)
+ if (removeMode == AURA_REMOVE_BY_DEATH)
{
- const SpellEntry *spell = sSpellStore.LookupEntry(spellId);
- if (!spell)
- return;
-
- for (int i=0; i < spell->StackAmount; ++i)
- caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID());
- return;
+ if (caster->GetTypeId() == TYPEID_PLAYER && ((Player*)caster)->isHonorOrXPTarget(target))
+ caster->CastSpell(target, 18662, true, NULL, GetEffect(0));
}
- m_target->RemoveAurasDueToSpell(spellId);
- return;
}
- // Restless Strength
- case 24661:
+ // Improved Fear
+ else if (GetSpellProto()->SpellFamilyFlags[1] & 0x00000400)
{
- uint32 spellId = 24662;
- if (apply && caster)
+ if (caster->GetTypeId() == TYPEID_UNIT)
{
- const SpellEntry *spell = sSpellStore.LookupEntry(spellId);
- if (!spell)
- return;
- for (int i=0; i < spell->StackAmount; ++i)
- caster->CastSpell(m_target, spell->Id, true, NULL, NULL, GetCasterGUID());
- return;
+ if (AuraEffect* aurEff = caster->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_WARLOCK, 98, 0))
+ {
+ uint32 spellId = 0;
+ switch (aurEff->GetId())
+ {
+ case 53759: spellId = 60947; break;
+ case 53754: spellId = 60946; break;
+ default:
+ sLog.outError("Aura::HandleAuraSpecificMods: Unknown rank of Improved Fear (%d) found", aurEff->GetId());
+ }
+ if (spellId)
+ caster->CastSpell(caster, spellId, true);
+ }
}
- m_target->RemoveAurasDueToSpell(spellId);
- return;
}
- //Summon Fire Elemental
- case 40133:
+ switch(GetId())
{
- if (!caster)
- return;
-
- Unit *owner = caster->GetOwner();
- if (owner && owner->GetTypeId() == TYPEID_PLAYER)
- {
- if(apply)
- owner->CastSpell(owner,8985,true);
- else
- ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
- }
- return;
+ case 48018: // Demonic Circle
+ // Do not remove GO when aura is removed by stack
+ // to prevent remove GO added by new spell
+ // old one is already removed
+ if (removeMode!=AURA_REMOVE_BY_STACK)
+ target->RemoveGameObject(GetId(), true);
+ target->RemoveAura(62388);
+ break;
}
- //Summon Earth Elemental
- case 40132 :
+ break;
+ case SPELLFAMILY_PRIEST:
+ if (!caster)
+ break;
+ // Shadow word: Pain // Vampiric Touch
+ if (removeMode == AURA_REMOVE_BY_ENEMY_SPELL && (GetSpellProto()->SpellFamilyFlags[0] & 0x00008000 || GetSpellProto()->SpellFamilyFlags[1] & 0x00000400))
{
- if (!caster)
- return;
-
- Unit *owner = caster->GetOwner();
- if (owner && owner->GetTypeId() == TYPEID_PLAYER)
+ // Shadow Affinity
+ if (AuraEffect const * aurEff = target->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 178, 1))
{
- if(apply)
- owner->CastSpell(owner,19704,true);
- else
- ((Player*)owner)->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true);
+ int32 basepoints0 = aurEff->GetAmount() * target->GetCreateMana() / 100;
+ caster->CastCustomSpell(caster, 64103, &basepoints0, NULL, NULL, true, NULL, GetEffect(0));
}
- return;
}
- case 57723: // Exhaustion
- case 57724: // Sated
+ // Power word: shield
+ else if (removeMode == AURA_REMOVE_BY_ENEMY_SPELL && GetSpellProto()->SpellFamilyFlags[0] & 0x00000001)
{
- switch(GetId())
+ // Rapture
+ if (Aura const * aura = caster->GetAuraOfRankedSpell(47535))
{
- case 57723: m_target->ApplySpellImmune(GetId(), IMMUNITY_ID, 32182, apply); break; // Heroism
- case 57724: m_target->ApplySpellImmune(GetId(), IMMUNITY_ID, 2825, apply); break; // Bloodlust
+ // check cooldown
+ if (caster->GetTypeId() == TYPEID_PLAYER)
+ {
+ if (((Player*)caster)->HasSpellCooldown(aura->GetId()))
+ break;
+ // and add if needed
+ ((Player*)caster)->AddSpellCooldown(aura->GetId(), 0, uint32(time(NULL) + 12));
+ }
+ // effect on caster
+ if (AuraEffect const * aurEff = aura->GetEffect(0))
+ {
+ float multiplier = aurEff->GetAmount();
+ if (aurEff->GetId() == 47535)
+ multiplier -= 0.5f;
+ else if (aurEff->GetId() == 47537)
+ multiplier += 0.5f;
+
+ int32 basepoints0 = (multiplier * caster->GetMaxPower(POWER_MANA) / 100);
+ caster->CastCustomSpell(caster, 47755, &basepoints0, NULL, NULL, true);
+ }
+ // effect on aura target
+ if (AuraEffect const * aurEff = aura->GetEffect(1))
+ {
+ if (!roll_chance_i(aurEff->GetAmount()))
+ break;
+
+ int32 triggeredSpellId = 0;
+ switch(target->getPowerType())
+ {
+ case POWER_MANA:
+ {
+ int32 basepoints0 = 2 * (target->GetMaxPower(POWER_MANA) / 100);
+ caster->CastCustomSpell(target, 63654, &basepoints0, NULL, NULL, true);
+ break;
+ }
+ case POWER_RAGE: triggeredSpellId = 63653; break;
+ case POWER_ENERGY: triggeredSpellId = 63655; break;
+ case POWER_RUNIC_POWER: triggeredSpellId = 63652; break;
+ }
+ if (triggeredSpellId)
+ caster->CastSpell(target, triggeredSpellId, true);
+ }
}
- return;
}
- case 57819: // Argent Champion
- case 57820: // Ebon Champion
- case 57821: // Champion of the Kirin Tor
- case 57822: // Wyrmrest Champion
+ switch(GetId())
{
- if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
- return;
-
- uint32 FactionID = 0;
+ case 47788: // Guardian Spirit
+ if (removeMode != AURA_REMOVE_BY_EXPIRE)
+ break;
+ if(caster->GetTypeId() != TYPEID_PLAYER)
+ break;
- if(apply)
- {
- switch(m_spellProto->Id)
+ Player *player = ((Player*)caster);
+ // Glyph of Guardian Spirit
+ if(AuraEffect * aurEff = player->GetAuraEffect(63231, 0))
{
- case 57819: FactionID = 1106; break; // Argent Crusade
- case 57820: FactionID = 1098; break; // Knights of the Ebon Blade
- case 57821: FactionID = 1090; break; // Kirin Tor
- case 57822: FactionID = 1091; break; // The Wyrmrest Accord
+ if (!player->HasSpellCooldown(47788))
+ break;
+
+ player->RemoveSpellCooldown(GetSpellProto()->Id, true);
+ player->AddSpellCooldown(GetSpellProto()->Id, 0, uint32(time(NULL) + aurEff->GetAmount()));
+
+ WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+4+4);
+ data << uint64(player->GetGUID());
+ data << uint8(0x0); // flags (0x1, 0x2)
+ data << uint32(GetSpellProto()->Id);
+ data << uint32(aurEff->GetAmount()*IN_MILISECONDS);
+ player->SendDirectMessage(&data);
}
- }
- ((Player*)caster)->SetChampioningFaction(FactionID);
- return;
+ break;
}
- // LK Intro VO (1)
- case 58204:
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- {
- // Play part 1
- if(apply)
- m_target->PlayDirectSound(14970, (Player *)m_target);
- // continue in 58205
- else
- m_target->CastSpell(m_target, 58205, true);
- }
- return;
- // LK Intro VO (2)
- case 58205:
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- {
- // Play part 2
- if(apply)
- m_target->PlayDirectSound(14971, (Player *)m_target);
- // Play part 3
- else
- m_target->PlayDirectSound(14972, (Player *)m_target);
- }
- return;
- }
-
- break;
- }
- case SPELLFAMILY_MAGE:
- {
- //if (!Real)
- //break;
- break;
- }
- case SPELLFAMILY_PRIEST:
- {
- if (!Real && !changeAmount)
break;
- // Pain and Suffering
- if( m_spellProto->SpellIconID == 2874 && m_target->GetTypeId() == TYPEID_PLAYER )
- {
- if(apply)
+ case SPELLFAMILY_DEATHKNIGHT:
+ switch(GetId())
{
- // Reduce backfire damage (dot damage) from Shadow Word: Death
- SpellModifier *mod = new SpellModifier;
- mod->op = SPELLMOD_DOT;
- mod->value = m_amount;
- mod->type = SPELLMOD_PCT;
- mod->spellId = GetId();
- mod->mask[1] = 0x00002000;
- m_spellmod = mod;
+ case 50514: // Summon Gargoyle
+ if (removeMode != AURA_REMOVE_BY_EXPIRE)
+ break;
+ target->CastSpell(target, GetEffect(0)->GetAmount(), true, NULL, GetEffect(0));
+ break;
}
- ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
- return;
- }
- break;
- }
- case SPELLFAMILY_DRUID:
- {
- if (!Real && !changeAmount)
break;
- switch(GetId())
+ }
+ }
+
+ // mods at aura apply or remove
+ switch (GetSpellProto()->SpellFamilyName)
+ {
+ case SPELLFAMILY_ROGUE:
+ // Stealth
+ if (GetSpellProto()->SpellFamilyFlags[0] & 0x00400000)
{
- case 34246: // Idol of the Emerald Queen
- case 60779: // Idol of Lush Moss
+ // Master of subtlety
+ if (AuraEffect const * aurEff = target->GetAuraEffectOfRankedSpell(31221, 0))
{
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- if(apply)
+ if (!apply)
+ target->CastSpell(target,31666,true);
+ else
{
- SpellModifier *mod = new SpellModifier;
- mod->op = SPELLMOD_DOT;
- mod->value = m_amount/7;
- mod->type = SPELLMOD_FLAT;
- mod->spellId = GetId();
- mod->mask[1] = 0x0010;
-
- m_spellmod = mod;
+ int32 basepoints0 = aurEff->GetAmount();
+ target->CastCustomSpell(target,31665, &basepoints0, NULL, NULL ,true);
}
-
- ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
- return;
}
- case 61336: // Survival Instincts
+ // Overkill
+ if (target->HasAura(58426))
{
- if (!Real)
- break;
- if(apply)
- {
- if (!m_target->IsInFeralForm())
- return;
-
- int32 bp0 = int32(m_target->GetMaxHealth() * m_amount / 100);
- m_target->CastCustomSpell(m_target, 50322, &bp0, NULL, NULL, true);
- }
+ if (!apply)
+ target->CastSpell(target,58428,true);
else
- m_target-> RemoveAurasDueToSpell(50322);
- return;
+ target->CastSpell(target,58427,true);
}
- }
- // Predatory Strikes
- if(m_target->GetTypeId() == TYPEID_PLAYER && GetSpellProto()->SpellIconID == 1563)
- {
- ((Player*)m_target)->UpdateAttackPowerAndDamage();
- return;
- }
- if (!Real)
break;
- // Lifebloom
- if ( GetSpellProto()->SpellFamilyFlags[1] & 0x10 )
- {
- if (!apply)
- {
- // Final heal only on dispelled or duration end
- if (GetParentAura()->GetRemoveMode() != AURA_REMOVE_BY_EXPIRE && GetParentAura()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL)
- return;
-
- // final heal
- //if(m_target->IsInWorld())
- // This may be a hack, but we need a way to count healing bonus three times
- //for (uint8 i = 0; i < GetParentAura()->GetStackAmount(); ++i)
- // Update: apparently not anymore, it should only count once, so.. commented out.
- m_target->CastCustomSpell(m_target,33778,&m_amount,NULL,NULL,true,NULL,this,GetCasterGUID());
-
- // restore mana
- if (caster)
- {
- int32 returnmana = (GetSpellProto()->ManaCostPercentage * caster->GetCreateMana() / 100) * GetParentAura()->GetStackAmount() / 2;
- caster->CastCustomSpell(caster, 64372, &returnmana, NULL, NULL, true, NULL, this, GetCasterGUID());
- }
- }
- return;
}
break;
- }
- case SPELLFAMILY_SHAMAN:
- {
- if (!Real)
- break;
- // Sentry Totem
- if (GetId() == 6495 && caster->GetTypeId() == TYPEID_PLAYER)
+ case SPELLFAMILY_HUNTER:
+ switch(GetId())
{
- if (apply)
- {
- uint64 guid = caster->m_SummonSlot[3];
- if (guid)
+ case 19574: // Bestial Wrath
+ // The Beast Within cast on owner if talent present
+ if ( Unit* owner = target->GetOwner() )
{
- Creature *totem = caster->GetMap()->GetCreature(guid);
- if (totem && totem->isTotem())
- ((Player*)caster)->CastSpell(totem, 6277, true);
+ // Search talent
+ if (owner->HasAura(34692))
+ {
+ if (apply)
+ owner->CastSpell(owner, 34471, true, 0, GetEffect(0));
+ else
+ owner->RemoveAurasDueToSpell(34471);
+ }
}
- }
- else
- ((Player*)caster)->StopCastingBindSight();
- return;
+ break;
}
break;
- }
- }
-
- if (Real)
- {
- // pet auras
- if(PetAura const* petSpell = spellmgr.GetPetAura(GetId(), m_effIndex))
- {
- if(apply)
- m_target->AddPetAura(petSpell);
- else
- m_target->RemovePetAura(petSpell);
- return;
- }
-
- if(GetEffIndex()==0 && m_target->GetTypeId() == TYPEID_PLAYER)
- {
- SpellAreaForAreaMapBounds saBounds = spellmgr.GetSpellAreaForAuraMapBounds(GetId());
- if(saBounds.first != saBounds.second)
+ case SPELLFAMILY_PALADIN:
+ switch(GetId())
{
- uint32 zone, area;
- m_target->GetZoneAndAreaId(zone,area);
-
- for (SpellAreaForAreaMap::const_iterator itr = saBounds.first; itr != saBounds.second; ++itr)
- {
- // some auras remove at aura remove
- if(!itr->second->IsFitToRequirements((Player*)m_target,zone,area))
- m_target->RemoveAurasDueToSpell(itr->second->spellId);
- // some auras applied at aura apply
- else if(itr->second->autocast)
+ 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)
{
- if( !m_target->HasAuraEffect(itr->second->spellId,0) )
- m_target->CastSpell(m_target,itr->second->spellId,true);
+ if ((GetSpellProto()->Id == 31821 && target->HasAura(19746, GetCasterGUID())) || (GetSpellProto()->Id == 19746 && target->HasAura(31821)))
+ target->CastSpell(target,64364,true);
}
- }
+ else
+ target->RemoveAurasDueToSpell(64364, GetCasterGUID());
+ break;
}
- }
- }
-}
-
-void AuraEffect::HandleAuraMounted(bool apply, bool Real, bool /*changeAmount*/)
-{
- // only at real add/remove aura
- if(!Real)
- return;
-
- if(apply)
- {
- CreatureInfo const* ci = objmgr.GetCreatureTemplate(GetMiscValue());
- if(!ci)
- {
- sLog.outErrorDb("AuraMounted: `creature_template`='%u' not found in database (only need it modelid)",GetMiscValue());
- return;
- }
-
- uint32 team = 0;
- if (m_target->GetTypeId() == TYPEID_PLAYER)
- team = ((Player*)m_target)->GetTeam();
-
- uint32 display_id = objmgr.ChooseDisplayId(team,ci);
- CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
- if (minfo)
- display_id = minfo->modelid;
-
- //some spell has one aura of mount and one of vehicle
- for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
- if(GetSpellProto()->Effect[i] == SPELL_EFFECT_SUMMON
- && GetSpellProto()->EffectMiscValue[i] == GetMiscValue())
- display_id = 0;
- m_target->Mount(display_id);
- }
- else
- {
- m_target->Unmount();
- //some mounts like Headless Horseman's Mount or broom stick are skill based spell
- // need to remove ALL arura related to mounts, this will stop client crash with broom stick
- // and never endless flying after using Headless Horseman's Mount
- m_target->RemoveAurasByType(SPELL_AURA_MOUNTED);
- }
-}
-
-void AuraEffect::HandleAuraWaterWalk(bool apply, bool Real, bool /*changeAmount*/)
-{
- // only at real add/remove aura
- if(!Real)
- return;
-
- WorldPacket data;
- if(apply)
- data.Initialize(SMSG_MOVE_WATER_WALK, 8+4);
- else
- data.Initialize(SMSG_MOVE_LAND_WALK, 8+4);
- data.append(m_target->GetPackGUID());
- data << uint32(0);
- m_target->SendMessageToSet(&data,true);
-}
-
-void AuraEffect::HandleAuraFeatherFall(bool apply, bool Real, bool /*changeAmount*/)
-{
- // only at real add/remove aura
- if (!Real)
- return;
-
- if (!m_target)
- return;
-
- WorldPacket data;
- if (apply)
- data.Initialize(SMSG_MOVE_FEATHER_FALL, 8+4);
- else
- data.Initialize(SMSG_MOVE_NORMAL_FALL, 8+4);
- data.append(m_target->GetPackGUID());
- data << uint32(0);
- m_target->SendMessageToSet(&data, true);
-
- // start fall from current height
- if(!apply && m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->SetFallInformation(0, m_target->GetPositionZ());
-}
-
-void AuraEffect::HandleAuraHover(bool apply, bool Real, bool /*changeAmount*/)
-{
- // only at real add/remove aura
- if(!Real)
- return;
-
- WorldPacket data;
- if(apply)
- data.Initialize(SMSG_MOVE_SET_HOVER, 8+4);
- else
- data.Initialize(SMSG_MOVE_UNSET_HOVER, 8+4);
- data.append(m_target->GetPackGUID());
- data << uint32(0);
- m_target->SendMessageToSet(&data,true);
-}
-
-void AuraEffect::HandleWaterBreathing(bool apply, bool Real, bool /*changeAmount*/)
-{
- // update timers in client
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->UpdateMirrorTimers();
-}
-
-void AuraEffect::HandleAuraModShapeshift(bool apply, bool Real, bool changeAmount)
-{
- if(!Real && !changeAmount)
- return;
-
- uint32 modelid = 0;
- Powers PowerType = POWER_MANA;
- ShapeshiftForm form = ShapeshiftForm(GetMiscValue());
- switch(form)
- {
- case FORM_CAT:
- case FORM_GHOUL:
- PowerType = POWER_ENERGY;
- break;
- case FORM_BEAR:
- case FORM_DIREBEAR:
- case FORM_BATTLESTANCE:
- case FORM_BERSERKERSTANCE:
- case FORM_DEFENSIVESTANCE:
- PowerType = POWER_RAGE;
- break;
- case FORM_TRAVEL:
- case FORM_AQUA:
- case FORM_CREATUREBEAR:
- case FORM_GHOSTWOLF:
- case FORM_FLIGHT:
- case FORM_MOONKIN:
- case FORM_FLIGHT_EPIC:
- case FORM_METAMORPHOSIS:
- case FORM_MASTER_ANGLER:
- case FORM_AMBIENT:
- case FORM_SHADOW:
- case FORM_STEALTH:
- case FORM_UNDEAD:
- case FORM_SHADOW_DANCE:
- case FORM_TREE:
- case FORM_SPIRITOFREDEMPTION:
- break;
- default:
- sLog.outError("Auras: Unknown Shapeshift Type: %u", GetMiscValue());
- }
- modelid = m_target->GetModelForForm(form);
-
- // remove polymorph before changing display id to keep new display id
- switch ( form )
- {
- case FORM_CAT:
- case FORM_TREE:
- case FORM_TRAVEL:
- case FORM_AQUA:
- case FORM_BEAR:
- case FORM_DIREBEAR:
- case FORM_FLIGHT_EPIC:
- case FORM_FLIGHT:
- case FORM_MOONKIN:
- {
- // remove movement affects
- m_target->RemoveMovementImpairingAuras();
-
- // and polymorphic affects
- if(m_target->IsPolymorphed())
- m_target->RemoveAurasDueToSpell(m_target->getTransForm());
break;
- }
- default:
- break;
- }
-
- if (apply)
- {
- // remove other shapeshift before applying a new one
- if(m_target->m_ShapeShiftFormSpellId)
- m_target->RemoveAurasDueToSpell(m_target->m_ShapeShiftFormSpellId);
-
- m_target->SetByteValue(UNIT_FIELD_BYTES_2, 3, form);
-
- if (modelid > 0)
- m_target->SetDisplayId(modelid);
-
- if (PowerType != POWER_MANA)
- {
- uint32 oldPower = m_target->GetPower(PowerType);
- // reset power to default values only at power change
- if(m_target->getPowerType() != PowerType)
- m_target->setPowerType(PowerType);
-
- switch (form)
+ case SPELLFAMILY_DEATHKNIGHT:
+ if (GetSpellSpecific(GetId()) == SPELL_SPECIFIC_PRESENCE)
{
- case FORM_CAT:
- case FORM_BEAR:
- case FORM_DIREBEAR:
- {
- // get furor proc chance
- uint32 FurorChance = 0;
- if (AuraEffect const *dummy = m_target->GetDummyAura(SPELLFAMILY_DRUID, 238, 0))
- FurorChance = std::max(dummy->GetAmount(), 0);
+ AuraEffect *bloodPresenceAura=0; // healing by damage done
+ AuraEffect *frostPresenceAura=0; // increased health
+ AuraEffect *unholyPresenceAura=0; // increased movement speed, faster rune recovery
- switch (GetMiscValue())
+ // Improved Presences
+ Unit::AuraEffectList const& vDummyAuras = target->GetAuraEffectsByType(SPELL_AURA_DUMMY);
+ for (Unit::AuraEffectList::const_iterator itr = vDummyAuras.begin(); itr != vDummyAuras.end(); ++itr)
+ {
+ switch((*itr)->GetId())
{
- case FORM_CAT:
+ // Improved Blood Presence
+ case 50365:
+ case 50371:
{
- int32 basePoints = int32(std::min(oldPower, FurorChance));
- m_target->CastCustomSpell(m_target, 17099, &basePoints, NULL, NULL, true, NULL, this);
+ bloodPresenceAura = (*itr);
+ break;
}
- break;
- case FORM_BEAR:
- case FORM_DIREBEAR:
- if (urand(0,99) < FurorChance)
+ // Improved Frost Presence
+ case 50384:
+ case 50385:
{
- int32 basePoints = 100; // Not sure if 100 is correct basePoints, maybe it should be 10?
- m_target->CastCustomSpell(m_target, 17057, &basePoints, NULL, NULL, true, NULL, this);
+ frostPresenceAura = (*itr);
+ break;
}
- default:
+ // Improved Unholy Presence
+ case 50391:
+ case 50392:
{
- uint32 newEnergy = std::min(m_target->GetPower(POWER_ENERGY), FurorChance);
- m_target->SetPower(POWER_ENERGY, newEnergy);
+ unholyPresenceAura = (*itr);
+ break;
}
- break;
}
- break;
}
- default:
- break;
- }
- }
- m_target->m_ShapeShiftFormSpellId = GetId();
- m_target->m_form = form;
- }
- else
- {
- if(modelid > 0)
- m_target->SetDisplayId(m_target->GetNativeDisplayId());
- m_target->SetByteValue(UNIT_FIELD_BYTES_2, 3, FORM_NONE);
- if(m_target->getClass() == CLASS_DRUID)
- m_target->setPowerType(POWER_MANA);
- m_target->m_ShapeShiftFormSpellId = 0;
- m_target->m_form = FORM_NONE;
-
- switch(form)
- {
- // Nordrassil Harness - bonus
- case FORM_BEAR:
- case FORM_DIREBEAR:
- case FORM_CAT:
- if(AuraEffect* dummy = m_target->GetAuraEffect(37315, 0) )
- m_target->CastSpell(m_target,37316,true,NULL,dummy);
- break;
- // Nordrassil Regalia - bonus
- case FORM_MOONKIN:
- if(AuraEffect* dummy = m_target->GetAuraEffect(37324, 0) )
- m_target->CastSpell(m_target,37325,true,NULL,dummy);
- break;
- case FORM_BATTLESTANCE:
- case FORM_DEFENSIVESTANCE:
- case FORM_BERSERKERSTANCE:
- {
- uint32 Rage_val = 0;
- // Defensive Tactics
- if (form == FORM_DEFENSIVESTANCE)
- {
- if (AuraEffect const * aurEff = m_target->IsScriptOverriden(m_spellProto,831))
- Rage_val += aurEff->GetAmount() * 10;
- }
- // Stance mastery + Tactical mastery (both passive, and last have aura only in defense stance, but need apply at any stance switch)
- if(m_target->GetTypeId() == TYPEID_PLAYER)
+ uint32 presence=GetId();
+ if (apply)
{
- PlayerSpellMap const& sp_list = ((Player *)m_target)->GetSpellMap();
- for (PlayerSpellMap::const_iterator itr = sp_list.begin(); itr != sp_list.end(); ++itr)
+ // Blood Presence bonus
+ if (presence == SPELL_ID_BLOOD_PRESENCE)
+ target->CastSpell(target,63611,true);
+ else if (bloodPresenceAura)
{
- if(itr->second->state == PLAYERSPELL_REMOVED) continue;
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(itr->first);
- if (spellInfo && spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR && spellInfo->SpellIconID == 139)
- Rage_val += m_target->CalculateSpellDamage(spellInfo,0,spellInfo->EffectBasePoints[0],m_target) * 10;
+ int32 basePoints1=bloodPresenceAura->GetAmount();
+ target->CastCustomSpell(target,63611,NULL,&basePoints1,NULL,true,0,bloodPresenceAura);
}
- }
- if (m_target->GetPower(POWER_RAGE) > Rage_val)
- m_target->SetPower(POWER_RAGE,Rage_val);
- break;
- }
- default:
- break;
- }
- }
-
- // adding/removing linked auras
- // add/remove the shapeshift aura's boosts
- HandleShapeshiftBoosts(apply);
-
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->InitDataForForm();
-
- if(m_target->getClass() == CLASS_DRUID)
- {
- if(form == FORM_CAT && apply)
- {
- // add dash if in cat-from
- Unit::AuraMap & auras = m_target->GetAuras();
- for (Unit::AuraMap::iterator iter = auras.begin(); iter != auras.end(); ++iter)
- {
- Aura * aur = iter->second;
- if (aur->GetSpellProto()->SpellFamilyName==SPELLFAMILY_DRUID && aur->GetSpellProto()->SpellFamilyFlags[2] & 0x8)
- {
- m_target->HandleAuraEffect(aur->GetPartAura(0), true);
- }
- }
- }
- else // remove dash effect(not buff) if out of cat-from
- {
- if(AuraEffect * aurEff =m_target->GetAura(SPELL_AURA_MOD_INCREASE_SPEED, SPELLFAMILY_DRUID, 0, 0, 0x8))
- m_target->HandleAuraEffect(aurEff, false);
- }
- }
- if (m_target->GetTypeId() == TYPEID_PLAYER)
- {
- SpellShapeshiftEntry const *shapeInfo = sSpellShapeshiftStore.LookupEntry(form);
- // Learn spells for shapeshift form - no need to send action bars or add spells to spellbook
- for (uint8 i = 0; i<MAX_SHAPESHIFT_SPELLS; ++i)
- {
- if (!shapeInfo->stanceSpell[i])
- continue;
- if (apply)
- ((Player*)m_target)->AddTemporarySpell(shapeInfo->stanceSpell[i]);
- else
- ((Player*)m_target)->RemoveTemporarySpell(shapeInfo->stanceSpell[i]);
- }
- }
-}
-
-void AuraEffect::HandleAuraTransform(bool apply, bool Real, bool /*changeAmount*/)
-{
- if (apply)
- {
- // special case (spell specific functionality)
- if(GetMiscValue()==0)
- {
- // player applied only
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- switch (GetId())
- {
- // Orb of Deception
- case 16739:
- {
- uint32 orb_model = m_target->GetNativeDisplayId();
- switch(orb_model)
+ // Frost Presence bonus
+ if (presence == SPELL_ID_FROST_PRESENCE)
+ target->CastSpell(target,61261,true);
+ else if (frostPresenceAura)
{
- // Troll Female
- case 1479: m_target->SetDisplayId(10134); break;
- // Troll Male
- case 1478: m_target->SetDisplayId(10135); break;
- // Tauren Male
- case 59: m_target->SetDisplayId(10136); break;
- // Human Male
- case 49: m_target->SetDisplayId(10137); break;
- // Human Female
- case 50: m_target->SetDisplayId(10138); break;
- // Orc Male
- case 51: m_target->SetDisplayId(10139); break;
- // Orc Female
- case 52: m_target->SetDisplayId(10140); break;
- // Dwarf Male
- case 53: m_target->SetDisplayId(10141); break;
- // Dwarf Female
- case 54: m_target->SetDisplayId(10142); break;
- // NightElf Male
- case 55: m_target->SetDisplayId(10143); break;
- // NightElf Female
- case 56: m_target->SetDisplayId(10144); break;
- // Undead Female
- case 58: m_target->SetDisplayId(10145); break;
- // Undead Male
- case 57: m_target->SetDisplayId(10146); break;
- // Tauren Female
- case 60: m_target->SetDisplayId(10147); break;
- // Gnome Male
- case 1563: m_target->SetDisplayId(10148); break;
- // Gnome Female
- case 1564: m_target->SetDisplayId(10149); break;
- // BloodElf Female
- case 15475: m_target->SetDisplayId(17830); break;
- // BloodElf Male
- case 15476: m_target->SetDisplayId(17829); break;
- // Dranei Female
- case 16126: m_target->SetDisplayId(17828); break;
- // Dranei Male
- case 16125: m_target->SetDisplayId(17827); break;
- default: break;
+ int32 basePoints0=frostPresenceAura->GetAmount();
+ target->CastCustomSpell(target,61261,&basePoints0,NULL,NULL,true,0,frostPresenceAura);
+ }
+ // Unholy Presence bonus
+ if (presence == SPELL_ID_UNHOLY_PRESENCE)
+ {
+ if(unholyPresenceAura)
+ {
+ // Not listed as any effect, only base points set
+ int32 basePoints0 = unholyPresenceAura->GetSpellProto()->EffectBasePoints[1];
+ //target->CastCustomSpell(target,63622,&basePoints0 ,NULL,NULL,true,0,unholyPresenceAura);
+ target->CastCustomSpell(target,65095,&basePoints0 ,NULL,NULL,true,0,unholyPresenceAura);
+ }
+ target->CastSpell(target,49772, true);
+ }
+ else if (unholyPresenceAura)
+ {
+ int32 basePoints0=unholyPresenceAura->GetAmount();
+ target->CastCustomSpell(target,49772,&basePoints0,NULL,NULL,true,0,unholyPresenceAura);
}
- break;
- }
- // Murloc costume
- case 42365: m_target->SetDisplayId(21723); break;
- default: break;
- }
- }
- else
- {
- CreatureInfo const * ci = objmgr.GetCreatureTemplate(GetMiscValue());
- if(!ci)
- {
- m_target->SetDisplayId(16358); // pig pink ^_^
- sLog.outError("Auras: unknown creature id = %d (only need its modelid) Form Spell Aura Transform in Spell ID = %d", GetMiscValue(), GetId());
- }
- else
- {
- uint32 model_id;
-
- if (uint32 modelid = ci->GetRandomValidModelId())
- model_id = modelid; // Will use the default model here
-
- // Polymorph (sheep)
- if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_MAGE && GetSpellProto()->SpellIconID == 82 && GetSpellProto()->SpellVisual[0] == 12978)
- if (Unit * caster = GetCaster())
- if (caster->HasAura(52648)) // Glyph of the Penguin
- model_id = 26452;
-
- m_target->SetDisplayId(model_id);
-
- // Dragonmaw Illusion (set mount model also)
- if(GetId()==42016 && m_target->GetMountID() && !m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED).empty())
- m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
- }
- }
-
- // update active transform spell only not set or not overwriting negative by positive case
- if (!m_target->getTransForm() || !IsPositiveSpell(GetId()) || IsPositiveSpell(m_target->getTransForm()))
- m_target->setTransForm(GetId());
-
- // polymorph case
- if (Real && m_target->GetTypeId() == TYPEID_PLAYER && m_target->IsPolymorphed())
- {
- // for players, start regeneration after 1s (in polymorph fast regeneration case)
- // only if caster is Player (after patch 2.4.2)
- if (IS_PLAYER_GUID(GetCasterGUID()) )
- ((Player*)m_target)->setRegenTimerCount(1*IN_MILISECONDS);
-
- //dismount polymorphed target (after patch 2.4.2)
- if (m_target->IsMounted())
- m_target->RemoveAurasByType(SPELL_AURA_MOUNTED);
- }
- }
- else
- {
- // ApplyModifier(true) will reapply it if need
- m_target->setTransForm(0);
- m_target->SetDisplayId(m_target->GetNativeDisplayId());
-
- // re-aplly some from still active with preference negative cases
- Unit::AuraEffectList const& otherTransforms = m_target->GetAurasByType(SPELL_AURA_TRANSFORM);
- if (!otherTransforms.empty())
- {
- // look for other transform auras
- AuraEffect* handledAura = *otherTransforms.begin();
- for (Unit::AuraEffectList::const_iterator i = otherTransforms.begin(); i != otherTransforms.end(); ++i)
- {
- // negative auras are preferred
- if (!IsPositiveSpell((*i)->GetSpellProto()->Id))
- {
- handledAura = *i;
- break;
}
- }
- handledAura->ApplyModifier(true);
- }
-
- // Dragonmaw Illusion (restore mount model)
- if (GetId()==42016 && m_target->GetMountID()==16314)
- {
- if (!m_target->GetAurasByType(SPELL_AURA_MOUNTED).empty())
- {
- uint32 cr_id = m_target->GetAurasByType(SPELL_AURA_MOUNTED).front()->GetMiscValue();
- if(CreatureInfo const* ci = objmgr.GetCreatureTemplate(cr_id))
+ else
{
- uint32 team = 0;
- if (m_target->GetTypeId() == TYPEID_PLAYER)
- team = ((Player*)m_target)->GetTeam();
-
- uint32 display_id = objmgr.ChooseDisplayId(team,ci);
- CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(display_id);
- if (minfo)
- display_id = minfo->modelid;
-
- m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,display_id);
+ // Remove passive auras
+ if (presence == SPELL_ID_BLOOD_PRESENCE || bloodPresenceAura)
+ target->RemoveAurasDueToSpell(63611);
+ if (presence == SPELL_ID_FROST_PRESENCE || frostPresenceAura)
+ target->RemoveAurasDueToSpell(61261);
+ if (presence == SPELL_ID_UNHOLY_PRESENCE || unholyPresenceAura)
+ {
+ if(presence == SPELL_ID_UNHOLY_PRESENCE && unholyPresenceAura)
+ {
+ //target->RemoveAurasDueToSpell(63622);
+ target->RemoveAurasDueToSpell(65095);
+ }
+ target->RemoveAurasDueToSpell(49772);
+ }
}
}
- }
+ break;
}
}
-void AuraEffect::HandleForceReaction(bool apply, bool Real, bool changeAmount)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- if(!Real && !changeAmount)
- return;
-
- Player* player = (Player*)m_target;
-
- uint32 faction_id = GetMiscValue();
- ReputationRank faction_rank = ReputationRank(m_amount);
-
- player->GetReputationMgr().ApplyForceReaction(faction_id,faction_rank,apply);
- player->GetReputationMgr().SendForceReactions();
-
- // stop fighting if at apply forced rank friendly or at remove real rank friendly
- if (apply && faction_rank >= REP_FRIENDLY || !apply && player->GetReputationRank(faction_id) >= REP_FRIENDLY)
- player->StopAttackFaction(faction_id);
-}
-
-void AuraEffect::HandleAuraModSkill(bool apply, bool Real, bool /*changeAmount*/)
+void Aura::SetNeedClientUpdateForTargets() const
{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- uint32 prot=GetSpellProto()->EffectMiscValue[m_effIndex];
- int32 points = m_amount;
-
- ((Player*)m_target)->ModifySkillBonus(prot,(apply ? points: -points),m_auraName==SPELL_AURA_MOD_SKILL_TALENT);
- if(prot == SKILL_DEFENSE)
- ((Player*)m_target)->UpdateDefenseBonusesMod();
+ for (ApplicationMap::const_iterator appIter = m_applications.begin(); appIter != m_applications.end(); ++appIter)
+ appIter->second->SetNeedClientUpdate();
}
-void AuraEffect::HandleChannelDeathItem(bool apply, bool Real, bool /*changeAmount*/)
+void Aura::_DeleteRemovedApplications()
{
- if(Real && !apply)
+ while(!m_removedApplications.empty())
{
- Unit* caster = GetCaster();
- Unit* victim = m_target;
- if(!caster || caster->GetTypeId() != TYPEID_PLAYER || !victim)// || m_removeMode!=AURA_REMOVE_BY_DEATH)
- return;
-
- //we cannot check removemode = death
- //talent will remove the caster's aura->interrupt channel->remove victim aura
- if(victim->GetHealth() > 0)
- return;
- // Item amount
- if (m_amount <= 0)
- return;
-
- SpellEntry const *spellInfo = GetSpellProto();
- if(spellInfo->EffectItemType[m_effIndex] == 0)
- return;
-
- // Soul Shard only from non-grey units
- if( spellInfo->EffectItemType[m_effIndex] == 6265 &&
- (victim->getLevel() <= Trinity::XP::GetGrayLevel(caster->getLevel()) ||
- victim->GetTypeId() == TYPEID_UNIT && !((Player*)caster)->isAllowedToLoot((Creature*)victim)) )
- return;
- //Adding items
- uint32 noSpaceForCount = 0;
- uint32 count = m_amount;
-
- ItemPosCountVec dest;
- uint8 msg = ((Player*)caster)->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, spellInfo->EffectItemType[m_effIndex], count, &noSpaceForCount);
- if( msg != EQUIP_ERR_OK )
- {
- count-=noSpaceForCount;
- ((Player*)caster)->SendEquipError( msg, NULL, NULL );
- if (count==0)
- return;
- }
-
- Item* newitem = ((Player*)caster)->StoreNewItem(dest, spellInfo->EffectItemType[m_effIndex], true);
- ((Player*)caster)->SendNewItem(newitem, count, true, false);
+ delete m_removedApplications.front();
+ m_removedApplications.pop_front();
}
}
-void AuraEffect::HandleBindSight(bool apply, bool Real, bool /*changeAmount*/)
-{
- if (!Real)
- return;
- Unit* caster = GetCaster();
- if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
- return;
-
- ((Player*)caster)->SetViewpoint(m_target, apply);
-}
-
-void AuraEffect::HandleFarSight(bool apply, bool Real, bool /*changeAmount*/)
-{
- //Handled by client
-}
-
-void AuraEffect::HandleAuraTrackCreatures(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- m_target->SetUInt32Value(PLAYER_TRACK_CREATURES, apply ? ((uint32)1)<<(GetMiscValue()-1) : 0 );
-}
-
-void AuraEffect::HandleAuraTrackResources(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- m_target->SetUInt32Value(PLAYER_TRACK_RESOURCES, apply ? ((uint32)1)<<(GetMiscValue()-1): 0 );
-}
-
-void AuraEffect::HandleAuraTrackStealthed(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- m_target->ApplyModFlag(PLAYER_FIELD_BYTES,PLAYER_FIELD_BYTE_TRACK_STEALTHED,apply);
-}
-
-void AuraEffect::HandleAuraModScale(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_target->ApplyPercentModFloatValue(OBJECT_FIELD_SCALE_X,m_amount,apply);
-}
-
-void AuraEffect::HandleAuraModPetTalentsPoints(bool Apply, bool Real, bool changeAmount)
+UnitAura::UnitAura(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID)
+ : Aura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID)
{
- if(!Real && !changeAmount)
- return;
-
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Recalculate pet tlaent points
- if (Pet *pet = ((Player*)m_target)->GetPet())
- pet->InitTalentForLevel();
-}
+ m_AuraDRGroup = DIMINISHING_NONE;
+ GetUnitOwner()->_AddAura(this);
+};
-void AuraEffect::HandleModConfuse(bool apply, bool Real, bool /*changeAmount*/)
+void UnitAura::_ApplyForTarget(Unit * target, Unit * caster, AuraApplication * aurApp)
{
- if(!Real)
- return;
+ Aura::_ApplyForTarget(target, caster, aurApp);
- //m_target->SetConfused(apply, GetCasterGUID(), GetId());
- m_target->SetControlled(apply, UNIT_STAT_CONFUSED);
+ // register aura diminishing on apply
+ if (DiminishingGroup group = GetDiminishGroup())
+ target->ApplyDiminishingAura(group,true);
}
-void AuraEffect::HandleModFear(bool apply, bool Real, bool /*changeAmount*/)
+void UnitAura::_UnapplyForTarget(Unit * target, Unit * caster, AuraApplication * aurApp)
{
- if (!Real)
- return;
+ Aura::_UnapplyForTarget(target, caster, aurApp);
- //m_target->SetFeared(apply, GetCasterGUID(), GetId());
- m_target->SetControlled(apply, UNIT_STAT_FLEEING);
+ // unregister aura diminishing (and store last time)
+ if (DiminishingGroup group = GetDiminishGroup())
+ target->ApplyDiminishingAura(group,false);
}
-void AuraEffect::HandleFeignDeath(bool apply, bool Real, bool /*changeAmount*/)
+void UnitAura::Remove(AuraRemoveMode removeMode)
{
- if(!Real)
- return;
-
- if(m_target->GetTypeId() != TYPEID_PLAYER)
+ if (IsRemoved())
return;
-
- if( apply )
- {
- /*
- WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
- data<<m_target->GetGUID();
- data<<uint8(0);
- m_target->SendMessageToSet(&data,true);
- */
-
- std::list<Unit*> targets;
- Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(m_target, m_target, m_target->GetMap()->GetVisibilityDistance());
- Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(m_target, targets, u_check);
- m_target->VisitNearbyObject(m_target->GetMap()->GetVisibilityDistance(), searcher);
- for (std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
- {
- if(!(*iter)->hasUnitState(UNIT_STAT_CASTING))
- continue;
-
- for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++)
- {
- if((*iter)->GetCurrentSpell(i)
- && (*iter)->GetCurrentSpell(i)->m_targets.getUnitTargetGUID() == m_target->GetGUID())
- {
- (*iter)->InterruptSpell(CurrentSpellTypes(i), false);
- }
- }
- }
- // blizz like 2.0.x
- m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
- // blizz like 2.0.x
- m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
- // blizz like 2.0.x
- m_target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
-
- m_target->addUnitState(UNIT_STAT_DIED);
- m_target->CombatStop();
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
-
- // prevent interrupt message
- if(GetCasterGUID()==m_target->GetGUID() && m_target->GetCurrentSpell(CURRENT_GENERIC_SPELL))
- m_target->FinishSpell(CURRENT_GENERIC_SPELL, false);
- m_target->InterruptNonMeleeSpells(true);
- m_target->getHostilRefManager().deleteReferences();
- }
- else
- {
- /*
- WorldPacket data(SMSG_FEIGN_DEATH_RESISTED, 9);
- data<<m_target->GetGUID();
- data<<uint8(1);
- m_target->SendMessageToSet(&data,true);
- */
- // blizz like 2.0.x
- m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_29);
- // blizz like 2.0.x
- m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FEIGN_DEATH);
- // blizz like 2.0.x
- m_target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD);
-
- m_target->clearUnitState(UNIT_STAT_DIED);
- }
+ GetUnitOwner()->RemoveOwnedAura(this, removeMode);
}
-void AuraEffect::HandleAuraModDisarm(bool apply, bool Real, bool /*changeAmount*/)
+void UnitAura::UpdateTargetMapForEffect(Unit * caster, uint8 effIndex)
{
- if (!Real)
- return;
- AuraType type = AuraType(GetAuraName());
-
- //Prevent handling aura twice
- if(apply ? m_target->GetAurasByType(type).size() > 1 : m_target->HasAuraType(type))
- return;
-
- uint32 field, flag, slot;
- WeaponAttackType attType;
- switch (type)
+ if (GetSpellProto()->Effect[effIndex] == SPELL_EFFECT_APPLY_AURA)
{
- case SPELL_AURA_MOD_DISARM:
- field=UNIT_FIELD_FLAGS;
- flag=UNIT_FLAG_DISARMED;
- slot=EQUIPMENT_SLOT_MAINHAND;
- attType=BASE_ATTACK;
- break;
- case SPELL_AURA_MOD_DISARM_OFFHAND:
- field=UNIT_FIELD_FLAGS_2;
- flag=UNIT_FLAG2_DISARM_OFFHAND;
- slot=EQUIPMENT_SLOT_OFFHAND;
- attType=OFF_ATTACK;
- break;
- case SPELL_AURA_MOD_DISARM_RANGED:
- field=UNIT_FIELD_FLAGS_2;
- flag=UNIT_FLAG2_DISARM_RANGED;
- slot=EQUIPMENT_SLOT_RANGED;
- attType=RANGED_ATTACK;
- break;
- default:
- return;
- }
-
- if(!apply)
- m_target->RemoveFlag(field, flag);
-
- if (m_target->GetTypeId() == TYPEID_PLAYER)
- {
- // This is between the two because there is a check in _ApplyItemMods
- // we must make sure that flag is always removed when call that function
- // refer to DurabilityPointsLoss
- if(Item *pItem = ((Player*)m_target)->GetItemByPos( INVENTORY_SLOT_BAG_0, slot ))
- ((Player*)m_target)->_ApplyItemMods(pItem, slot, !apply);
- }
-
- if(apply)
- m_target->SetFlag(field, flag);
-
- if (m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->GetCurrentEquipmentId())
- m_target->UpdateDamagePhysical(attType);
-}
-
-void AuraEffect::HandleModStealth(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(!Real)
+ AuraApplication * aurApp = GetApplicationOfTarget(GetOwner()->GetGUID());
+ if (!aurApp || !aurApp->HasEffect(effIndex))
+ GetUnitOwner()->_ApplyAuraEffect(this, effIndex);
return;
-
- if(apply)
- {
- // drop flag at stealth in bg
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
-
- m_target->SetStandFlags(UNIT_STAND_FLAGS_CREEP);
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- m_target->SetFlag(PLAYER_FIELD_BYTES2, 0x2000);
-
- // apply only if not in GM invisibility (and overwrite invisibility state)
- if(m_target->GetVisibility() != VISIBILITY_OFF)
- m_target->SetVisibility(VISIBILITY_GROUP_STEALTH);
- }
- else if(!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH)) // if last SPELL_AURA_MOD_STEALTH
- {
- m_target->RemoveStandFlags(UNIT_STAND_FLAGS_CREEP);
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- m_target->RemoveFlag(PLAYER_FIELD_BYTES2, 0x2000);
-
- if(m_target->GetVisibility() != VISIBILITY_OFF)
- m_target->SetVisibility(VISIBILITY_ON);
- }
-}
-
-void AuraEffect::HandleInvisibility(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(apply)
- {
- m_target->m_invisibilityMask |= (1 << GetMiscValue());
-
- if(Real)
- {
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
-
- // apply glow vision
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- m_target->SetFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
-
- m_target->SetToNotify();
- }
- }
- else
- {
- // recalculate value at modifier remove (current aura already removed)
- m_target->m_invisibilityMask = 0;
- Unit::AuraEffectList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
- for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- m_target->m_invisibilityMask |= (1 << GetMiscValue());
-
- // only at real aura remove and if not have different invisibility auras.
- if(Real)
- {
- // remove glow vision
- if(!m_target->m_invisibilityMask && m_target->GetTypeId() == TYPEID_PLAYER)
- m_target->RemoveFlag(PLAYER_FIELD_BYTES2,PLAYER_FIELD_BYTE2_INVISIBILITY_GLOW);
-
- m_target->SetToNotify();
- }
- }
-}
-
-void AuraEffect::HandleInvisibilityDetect(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(apply)
- {
- m_target->m_detectInvisibilityMask |= (1 << GetMiscValue());
}
- else
- {
- // recalculate value at modifier remove (current aura already removed)
- m_target->m_detectInvisibilityMask = 0;
- Unit::AuraEffectList const& auras = m_target->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
- for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
- m_target->m_detectInvisibilityMask |= (1 << GetMiscValue());
- }
- if(Real && m_target->GetTypeId() == TYPEID_PLAYER)
- m_target->SetToNotify();
-}
-void AuraEffect::HandleAuraModSilence(bool apply, bool Real, bool /*changeAmount*/)
-{
- // only at real add/remove aura
- if(!Real)
- return;
-
- if(apply)
- {
- m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED);
- // Stop cast only spells vs PreventionType == SPELL_PREVENTION_TYPE_SILENCE
- for (uint32 i = CURRENT_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i)
- if (Spell* spell = m_target->GetCurrentSpell(CurrentSpellTypes(i)))
- if(spell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
- // Stop spells on prepare or casting state
- m_target->InterruptSpell(CurrentSpellTypes(i), false);
- }
+ float radius;
+ if (GetSpellProto()->Effect[effIndex] == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY)
+ radius = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[effIndex]));
else
- {
- // Real remove called after current aura remove from lists, check if other similar auras active
- if(m_target->HasAuraType(SPELL_AURA_MOD_SILENCE))
- return;
-
- m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SILENCED);
- }
-}
-
-void AuraEffect::HandleModThreat(bool apply, bool Real, bool changeAmount)
-{
- // only at real add/remove aura
- if(!Real && !changeAmount)
- return;
+ radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(GetSpellProto()->EffectRadiusIndex[effIndex]));
- if (!m_target->isAlive())
- return;
-
- Unit* caster = GetCaster();
+ if (caster)
+ if(Player* modOwner = caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(GetId(), SPELLMOD_RADIUS, radius);
- if (!caster || !caster->isAlive())
- return;
+ // fill up to date target list
+ UnitList targets;
- int level_diff = 0;
- int multiplier = 0;
- if (apply && !m_target->isBeingLoaded())
+ if (!GetUnitOwner()->hasUnitState(UNIT_STAT_ISOLATED))
{
- switch (GetId())
+ switch(GetSpellProto()->Effect[effIndex])
{
- // Arcane Shroud
- case 26400:
- level_diff = m_target->getLevel() - 60;
- multiplier = 2;
+ case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
+ targets.push_back(GetUnitOwner());
+ GetUnitOwner()->GetPartyMemberInDist(targets, radius);
break;
- // The Eye of Diminution
- case 28862:
- level_diff = m_target->getLevel() - 60;
- multiplier = 1;
+ case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
+ targets.push_back(GetUnitOwner());
+ GetUnitOwner()->GetRaidMember(targets, radius);
break;
- }
-
- if (level_diff > 0)
- m_amount += multiplier * level_diff;
- }
-
- if (m_target->GetTypeId() == TYPEID_PLAYER)
- for (int8 x=0; x < MAX_SPELL_SCHOOL; x++)
- if (GetMiscValue() & int32(1<<x))
- ApplyPercentModFloatVar(m_target->m_threatModifier[x], m_amount, apply);
-}
-
-void AuraEffect::HandleAuraModTotalThreat(bool apply, bool Real, bool changeAmount)
-{
- // only at real add/remove aura
- if(!Real && !changeAmount)
- return;
-
- if (!m_target->isAlive() || m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- Unit* caster = GetCaster();
-
- if (!caster || !caster->isAlive())
- return;
-
- float threatMod = apply ? float(m_amount) : float(-m_amount);
-
- m_target->getHostilRefManager().threatAssist(caster, threatMod);
-}
-
-void AuraEffect::HandleModTaunt(bool apply, bool Real, bool /*changeAmount*/)
-{
- // only at real add/remove aura
- if (!Real)
- return;
-
- if (!m_target->isAlive() || !m_target->CanHaveThreatList())
- return;
-
- Unit* caster = GetCaster();
-
- if (!caster || !caster->isAlive())
- return;
-
- if (apply)
- m_target->TauntApply(caster);
- else
- {
- // When taunt aura fades out, mob will switch to previous target if current has less than 1.1 * secondthreat
- m_target->TauntFadeOut(caster);
- }
-}
-
-/*********************************************************/
-/*** MODIFY SPEED ***/
-/*********************************************************/
-void AuraEffect::HandleAuraModIncreaseSpeed(bool apply, bool Real, bool changeAmount)
-{
- // all applied/removed only at real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- if(apply) // Dash wont work if you are not in cat form
- if(m_spellProto->SpellFamilyName==SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags[2] & 0x8 && m_target->m_form != FORM_CAT )
- {
- m_target->HandleAuraEffect(this, false);
- return;
- }
-
- m_target->UpdateSpeed(MOVE_RUN, true);
-}
-
-void AuraEffect::HandleAuraModIncreaseMountedSpeed(bool apply, bool Real, bool changeAmount)
-{
- // all applied/removed only at real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- if(apply)
- {
- // Festive Holiday Mount
- if(m_target->HasAura(62061) && GetSpellProto()->SpellIconID != 1794)
- m_target->CastSpell(m_target, 25860, true, NULL, this); // Reindeer Transformation
- }
-
- m_target->UpdateSpeed(MOVE_RUN, true);
-}
-
-void AuraEffect::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real, bool changeAmount)
-{
- // all applied/removed only at real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- // Enable Fly mode for flying mounts
- if (m_auraName == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED)
- {
- WorldPacket data;
- if(apply)
- data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);
- else
- data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12);
- data.append(m_target->GetPackGUID());
- data << uint32(0); // unknown
- m_target->SendMessageToSet(&data, true);
-
- //Players on flying mounts must be immune to polymorph
- if (m_target->GetTypeId() == TYPEID_PLAYER)
- m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,MECHANIC_POLYMORPH,apply);
-
- if(apply)
- {
- // Dragonmaw Illusion (overwrite mount model, mounted aura already applied)
- if(m_target->HasAuraEffect(42016,0) && m_target->GetMountID())
- m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
-
- // Festive Holiday Mount
- if(m_target->HasAura(62061) && GetSpellProto()->SpellIconID != 1794)
- m_target->CastSpell(m_target, 25860, true, NULL, this); // Reindeer Transformation
- }
- }
-
- m_target->UpdateSpeed(MOVE_FLIGHT, true);
-}
-
-void AuraEffect::HandleAuraModIncreaseSwimSpeed(bool /*apply*/, bool Real, bool changeAmount)
-{
- // all applied/removed only at real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- m_target->UpdateSpeed(MOVE_SWIM, true);
-}
-
-void AuraEffect::HandleAuraModDecreaseSpeed(bool apply, bool Real, bool changeAmount)
-{
- // all applied/removed only at real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- m_target->UpdateSpeed(MOVE_RUN, true);
- m_target->UpdateSpeed(MOVE_SWIM, true);
- m_target->UpdateSpeed(MOVE_FLIGHT, true);
- m_target->UpdateSpeed(MOVE_RUN_BACK, true);
- m_target->UpdateSpeed(MOVE_SWIM_BACK, true);
- m_target->UpdateSpeed(MOVE_FLIGHT_BACK, true);
-}
-
-void AuraEffect::HandleAuraModUseNormalSpeed(bool /*apply*/, bool Real, bool changeAmount)
-{
- // all applied/removed only at real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- m_target->UpdateSpeed(MOVE_RUN, true);
- m_target->UpdateSpeed(MOVE_SWIM, true);
- m_target->UpdateSpeed(MOVE_FLIGHT, true);
-}
-
-/*********************************************************/
-/*** IMMUNITY ***/
-/*********************************************************/
-
-void AuraEffect::HandleModStateImmunityMask(bool apply, bool Real, bool /*changeAmount*/)
-{
- if (!Real)
- return;
- std::list <AuraType> immunity_list;
- if (GetMiscValue() & (1<<10))
- immunity_list.push_back(SPELL_AURA_MOD_STUN);
- if (GetMiscValue() & (1<<7))
- immunity_list.push_back(SPELL_AURA_MOD_DISARM);
- if (GetMiscValue() & (1<<1))
- immunity_list.push_back(SPELL_AURA_TRANSFORM);
-
- // These flag can be recognized wrong:
- if (GetMiscValue() & (1<<6))
- immunity_list.push_back(SPELL_AURA_MOD_DECREASE_SPEED);
- if (GetMiscValue() & (1<<0))
- immunity_list.push_back(SPELL_AURA_MOD_ROOT);
- if (GetMiscValue() & (1<<2))
- immunity_list.push_back(SPELL_AURA_MOD_CONFUSE);
- if (GetMiscValue() & (1<<9))
- immunity_list.push_back(SPELL_AURA_MOD_FEAR);
-
- // Patch 3.0.3 Bladestorm now breaks all snares and roots on the warrior when activated.
- // however not all mechanic specified in immunity
- if (apply && GetId()==46924)
- {
- m_target->RemoveAurasByType(SPELL_AURA_MOD_ROOT);
- m_target->RemoveAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
- }
-
- if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
- {
- for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter)
- {
- m_target->RemoveAurasByType(*iter);
- }
- }
- for (std::list <AuraType>::iterator iter = immunity_list.begin(); iter != immunity_list.end(); ++iter)
- {
- m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,*iter,apply);
- }
-}
-
-void AuraEffect::HandleModMechanicImmunity(bool apply, bool Real, bool /*changeAmount*/)
-{
- if (!Real)
- return;
- uint32 mechanic;
- mechanic = 1 << GetMiscValue();
-
- //immune movement impairment and loss of control
- if(GetId()==42292 || GetId()==59752)
- mechanic=IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK;
- // Forbearance
- // in DBC wrong mechanic immune since 3.0.x
- else if (GetId() == 25771)
- mechanic = 1 << MECHANIC_IMMUNE_SHIELD;
-
- if (!mechanic)
- return;
-
- if(apply && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
- {
- Unit::AuraMap& Auras = m_target->GetAuras();
- for (Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end();)
- {
- SpellEntry const *spell = iter->second->GetSpellProto();
- if (spell->Id != GetId())
+ case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
{
- //check for mechanic mask
- if(GetAllSpellMechanicMask(spell) & mechanic)
- {
- m_target->RemoveAura(iter);
- }
- else
- ++iter;
- }
- else
- ++iter;
- }
- }
-
- m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,GetMiscValue(),apply);
-
- // Demonic Empowerment -- voidwalker -- missing movement impairing effects immunity
- if (GetId() == 54508)
- {
- if (apply)
- m_target->RemoveMovementImpairingAuras();
-
- m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,SPELL_AURA_MOD_ROOT,apply);
- m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,SPELL_AURA_MOD_DECREASE_SPEED,apply);
- }
-}
-
-void AuraEffect::HandleAuraModEffectImmunity(bool apply, bool Real, bool /*changeAmount*/)
-{
- // when removing flag aura, handle flag drop
- if( !apply && m_target->GetTypeId() == TYPEID_PLAYER
- && (GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION) )
- {
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- {
- if(((Player*)m_target)->InBattleGround())
- {
- if( BattleGround *bg = ((Player*)m_target)->GetBattleGround() )
- bg->EventPlayerDroppedFlag(((Player*)m_target));
- }
- else
- sOutdoorPvPMgr.HandleDropFlag((Player*)m_target,GetSpellProto()->Id);
- }
- }
-
- m_target->ApplySpellImmune(GetId(),IMMUNITY_EFFECT,GetMiscValue(),apply);
-}
-
-void AuraEffect::HandleAuraModStateImmunity(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(apply && Real && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY)
- {
- m_target->RemoveAurasByType(AuraType(GetMiscValue()), NULL , GetParentAura());
- }
-
- m_target->ApplySpellImmune(GetId(),IMMUNITY_STATE,GetMiscValue(),apply);
-}
-
-void AuraEffect::HandleAuraModSchoolImmunity(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(apply && GetMiscValue() == SPELL_SCHOOL_MASK_NORMAL)
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
-
- m_target->ApplySpellImmune(GetId(),IMMUNITY_SCHOOL,GetMiscValue(),apply);
-
- // remove all flag auras (they are positive, but they must be removed when you are immune)
- if( this->GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY
- && this->GetSpellProto()->AttributesEx2 & SPELL_ATTR_EX2_DAMAGE_REDUCED_SHIELD )
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
-
- // TODO: optimalize this cycle - use RemoveAurasWithInterruptFlags call or something else
- if( Real && apply
- && GetSpellProto()->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY
- && IsPositiveSpell(GetId()) ) //Only positive immunity removes auras
- {
- uint32 school_mask = GetMiscValue();
- Unit::AuraMap& Auras = m_target->GetAuras();
- for (Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end();)
- {
- SpellEntry const *spell = iter->second->GetSpellProto();
- if((GetSpellSchoolMask(spell) & school_mask)//Check for school mask
- && IsDispelableBySpell(GetSpellProto(),spell->Id, true)
- && !iter->second->IsPositive() //Don't remove positive spells
- && spell->Id != GetId() ) //Don't remove self
- {
- m_target->RemoveAura(iter);
- }
- else
- ++iter;
- }
- }
- if( Real && GetSpellProto()->Mechanic == MECHANIC_BANISH )
- {
- if( apply )
- m_target->addUnitState(UNIT_STAT_ISOLATED);
- else
- m_target->clearUnitState(UNIT_STAT_ISOLATED);
- }
-}
-
-void AuraEffect::HandleAuraModDmgImmunity(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_target->ApplySpellImmune(GetId(),IMMUNITY_DAMAGE,GetMiscValue(),apply);
-}
-
-void AuraEffect::HandleAuraModDispelImmunity(bool apply, bool Real, bool /*changeAmount*/)
-{
- // all applied/removed only at real aura add/remove
- if(!Real)
- return;
-
- m_target->ApplySpellDispelImmunity(m_spellProto, DispelType(GetMiscValue()), apply);
-}
-
-void AuraEffect::HandleAuraProcTriggerSpell(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(!Real)
- return;
- // Elemental oath - "while Clearcasting from Elemental Focus is active, you deal 5%/10% more spell damage."
- if (m_target->GetTypeId() == TYPEID_PLAYER && (GetId() == 51466 || GetId() == 51470))
- {
- if (apply)
- {
- SpellModifier *mod = new SpellModifier;
- mod->op = SPELLMOD_EFFECT2;
- mod->value = m_target->CalculateSpellDamage(GetSpellProto(), 1, GetSpellProto()->EffectBasePoints[1], m_target);
- mod->type = SPELLMOD_FLAT;
- mod->spellId = GetId();
- mod->mask[1] = 0x0004000;
- m_spellmod = mod;
- }
- ((Player*)m_target)->AddSpellMod(m_spellmod, apply);
- }
-}
-
-void AuraEffect::HandleAuraModStalked(bool apply, bool Real, bool /*changeAmount*/)
-{
- // used by spells: Hunter's Mark, Mind Vision, Syndicate Tracker (MURP) DND
- if(apply)
- m_target->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT);
- else
- m_target->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TRACK_UNIT);
-}
-
-/*********************************************************/
-/*** PERIODIC ***/
-/*********************************************************/
-
-void AuraEffect::HandlePeriodicTriggerSpell(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_isPeriodic = apply;
- if (!apply)
- {
- switch(m_spellProto->Id)
- {
- case 66: // Invisibility
- m_target->CastSpell(m_target, 32612, true, NULL, this);
-
- return;
- case 42783: //Wrath of the Astrom...
- m_target->CastSpell(m_target, m_spellProto->CalculateSimpleValue(GetEffIndex()+1), true);
- return;
- default:
- break;
- }
- }
-}
-
-void AuraEffect::HandlePeriodicTriggerSpellWithValue(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_isPeriodic = apply;
-}
-
-void AuraEffect::HandlePeriodicEnergize(bool apply, bool Real, bool changeAmount)
-{
- m_isPeriodic = apply;
-}
-
-void AuraEffect::HandleAuraPowerBurn(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_isPeriodic = apply;
-}
-
-void AuraEffect::HandleAuraPeriodicDummy(bool apply, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- Unit* caster = GetCaster();
-
- SpellEntry const*spell = GetSpellProto();
- switch( spell->SpellFamilyName)
- {
- case SPELLFAMILY_GENERIC:
- {
- switch(spell->Id)
- {
- case 62399: // Overload Circuit
- if(m_target->GetMap()->IsDungeon() && m_target->GetAuras().count(62399) >= (m_target->GetMap()->IsHeroic() ? 4 : 2))
- {
- m_target->CastSpell(m_target, 62475, true); // System Shutdown
- if(Unit *veh = m_target->GetVehicleBase())
- veh->CastSpell(m_target, 62475, true);
- }
- break;
- case 58600: // No fly zone - Dalaran
- if (apply && m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player *)m_target)->GetSession()->SendNotification(LANG_ZONE_NOFLYZONE);
- break;
- default:
- break;
- }
- break;
- }
- case SPELLFAMILY_WARLOCK:
- {
- switch (spell->Id)
- {
- // Demonic Circle
- case 48018:
- if (!apply)
- {
- // Do not remove GO when aura is removed by stack
- // to prevent remove GO added by new spell
- // old one is already removed
- if (GetParentAura()->GetRemoveMode()!=AURA_REMOVE_BY_STACK)
- m_target->RemoveGameObject(spell->Id,true);
- m_target->RemoveAura(62388);
- }
+ targets.push_back(GetUnitOwner());
+ Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius);
+ Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetUnitOwner(), targets, u_check);
+ GetUnitOwner()->VisitNearbyObject(radius, searcher);
break;
}
- }
- case SPELLFAMILY_DEATHKNIGHT:
- {
- // Reaping
- // Blood of the North
- // Death Rune Mastery
- if (spell->SpellIconID == 3041 || spell->SpellIconID == 22 || spell->SpellIconID == 2622)
- m_amount = 0;
- break;
- }
- }
-
- m_isPeriodic = apply;
-}
-
-void AuraEffect::HandlePeriodicHeal(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_isPeriodic = apply;
-}
-
-void AuraEffect::HandlePeriodicDamage(bool apply, bool Real, bool changeAmount)
-{
- m_isPeriodic = apply;
-}
-
-void AuraEffect::HandlePeriodicDamagePCT(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_isPeriodic = apply;
-}
-
-void AuraEffect::HandlePeriodicLeech(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_isPeriodic = apply;
-}
-
-void AuraEffect::HandlePeriodicManaLeech(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_isPeriodic = apply;
-}
-
-void AuraEffect::HandlePeriodicHealthFunnel(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_isPeriodic = apply;
-}
-
-/*********************************************************/
-/*** MODIFY STATS ***/
-/*********************************************************/
-
-/********************************/
-/*** RESISTANCE ***/
-/********************************/
-
-void AuraEffect::HandleAuraModResistanceExclusive(bool apply, bool Rea, bool /*changeAmount*/)
-{
- for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
- {
- if(GetMiscValue() & int32(1<<x))
- {
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_VALUE, float(m_amount), apply);
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- m_target->ApplyResistanceBuffModsMod(SpellSchools(x),GetParentAura()->IsPositive(),m_amount, apply);
- }
- }
-}
-
-void AuraEffect::HandleAuraModResistance(bool apply, bool Real, bool /*changeAmount*/)
-{
- for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
- {
- if(GetMiscValue() & int32(1<<x))
- {
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), TOTAL_VALUE, float(m_amount), apply);
- if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
- m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_amount > 0,m_amount, apply);
- }
- }
-}
-
-void AuraEffect::HandleAuraModBaseResistancePCT(bool apply, bool Real, bool /*changeAmount*/)
-{
- // only players have base stats
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- {
- //pets only have base armor
- if(((Creature*)m_target)->isPet() && (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
- m_target->HandleStatModifier(UNIT_MOD_ARMOR, BASE_PCT, float(m_amount), apply);
- }
- else
- {
- for (int8 x = SPELL_SCHOOL_NORMAL; x < MAX_SPELL_SCHOOL; x++)
- {
- if(GetMiscValue() & int32(1<<x))
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + x), BASE_PCT, float(m_amount), apply);
- }
- }
-}
-
-void AuraEffect::HandleModResistancePercent(bool apply, bool Real, bool /*changeAmount*/)
-{
- for (int8 i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
- {
- if(GetMiscValue() & int32(1<<i))
- {
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_PCT, float(m_amount), apply);
- if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
- {
- m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,m_amount, apply);
- m_target->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,m_amount, apply);
- }
- }
- }
-}
-
-void AuraEffect::HandleModBaseResistance(bool apply, bool Real, bool /*changeAmount*/)
-{
- // only players have base stats
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- {
- //only pets have base stats
- if(((Creature*)m_target)->isPet() && (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
- m_target->HandleStatModifier(UNIT_MOD_ARMOR, TOTAL_VALUE, float(m_amount), apply);
- }
- else
- {
- for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++)
- if(GetMiscValue() & (1<<i))
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_RESISTANCE_START + i), TOTAL_VALUE, float(m_amount), apply);
- }
-}
-
-/********************************/
-/*** STAT ***/
-/********************************/
-
-void AuraEffect::HandleAuraModStat(bool apply, bool Real, bool /*changeAmount*/)
-{
- if (GetMiscValue() < -2 || GetMiscValue() > 4)
- {
- sLog.outError("WARNING: Spell %u effect %u have unsupported misc value (%i) for SPELL_AURA_MOD_STAT ",GetId(),GetEffIndex(),GetMiscValue());
- return;
- }
-
- for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
- {
- // -1 or -2 is all stats ( misc < -2 checked in function beginning )
- if (GetMiscValue() < 0 || GetMiscValue() == i)
- {
- //m_target->ApplyStatMod(Stats(i), m_amount,apply);
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_VALUE, float(m_amount), apply);
- if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
- m_target->ApplyStatBuffMod(Stats(i),m_amount,apply);
- }
- }
-}
-
-void AuraEffect::HandleModPercentStat(bool apply, bool Real, bool /*changeAmount*/)
-{
- if (GetMiscValue() < -1 || GetMiscValue() > 4)
- {
- sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
- return;
- }
-
- // only players have base stats
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- for (int32 i = STAT_STRENGTH; i < MAX_STATS; ++i)
- {
- if(GetMiscValue() == i || GetMiscValue() == -1)
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), BASE_PCT, float(m_amount), apply);
- }
-}
-
-void AuraEffect::HandleModSpellDamagePercentFromStat(bool /*apply*/, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Magic damage modifiers implemented in Unit::SpellDamageBonus
- // This information for client side use only
- // Recalculate bonus
- ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
-}
-
-void AuraEffect::HandleModSpellHealingPercentFromStat(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Recalculate bonus
- ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
-}
-
-void AuraEffect::HandleModSpellDamagePercentFromAttackPower(bool /*apply*/, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Magic damage modifiers implemented in Unit::SpellDamageBonus
- // This information for client side use only
- // Recalculate bonus
- ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
-}
-
-void AuraEffect::HandleModSpellHealingPercentFromAttackPower(bool /*apply*/, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Recalculate bonus
- ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
-}
-
-void AuraEffect::HandleModHealingDone(bool /*apply*/, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- // implemented in Unit::SpellHealingBonus
- // this information is for client side only
- ((Player*)m_target)->UpdateSpellDamageAndHealingBonus();
-}
-
-void AuraEffect::HandleModTotalPercentStat(bool apply, bool Real, bool /*changeAmount*/)
-{
- if (GetMiscValue() < -1 || GetMiscValue() > 4)
- {
- sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
- return;
- }
-
- //save current and max HP before applying aura
- uint32 curHPValue = m_target->GetHealth();
- uint32 maxHPValue = m_target->GetMaxHealth();
-
- for (int32 i = STAT_STRENGTH; i < MAX_STATS; i++)
- {
- if(GetMiscValue() == i || GetMiscValue() == -1)
- {
- m_target->HandleStatModifier(UnitMods(UNIT_MOD_STAT_START + i), TOTAL_PCT, float(m_amount), apply);
- if(m_target->GetTypeId() == TYPEID_PLAYER || ((Creature*)m_target)->isPet())
- m_target->ApplyStatPercentBuffMod(Stats(i), m_amount, apply );
- }
- }
-
- //recalculate current HP/MP after applying aura modifications (only for spells with 0x10 flag)
- if ((GetMiscValue() == STAT_STAMINA) && (maxHPValue > 0) && (m_spellProto->Attributes & 0x10))
- {
- // newHP = (curHP / maxHP) * newMaxHP = (newMaxHP * curHP) / maxHP -> which is better because no int -> double -> int conversion is needed
- uint32 newHPValue = (m_target->GetMaxHealth() * curHPValue) / maxHPValue;
- m_target->SetHealth(newHPValue);
- }
-}
-
-void AuraEffect::HandleAuraModResistenceOfStatPercent(bool /*apply*/, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- if(GetMiscValue() != SPELL_SCHOOL_MASK_NORMAL)
- {
- // support required adding replace UpdateArmor by loop by UpdateResistence at intellect update
- // and include in UpdateResistence same code as in UpdateArmor for aura mod apply.
- sLog.outError("Aura SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT(182) need adding support for non-armor resistances!");
- return;
- }
-
- // Recalculate Armor
- m_target->UpdateArmor();
-}
-
-/********************************/
-/*** HEAL & ENERGIZE ***/
-/********************************/
-void AuraEffect::HandleAuraModTotalHealthPercentRegen(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_isPeriodic = apply;
-}
-
-void AuraEffect::HandleAuraModTotalEnergyPercentRegen(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(m_amplitude == 0)
- m_amplitude = 1000;
-
- m_periodicTimer = m_amplitude;
- m_isPeriodic = apply;
-}
-
-void AuraEffect::HandleModRegen(bool apply, bool Real, bool /*changeAmount*/) // eating
-{
- if(m_amplitude == 0)
- m_amplitude = 5000;
-
- m_periodicTimer = 5000;
- m_isPeriodic = apply;
-}
-
-void AuraEffect::HandleModPowerRegen(bool apply, bool Real, bool changeAmount) // drinking
-{
- if(!Real && !changeAmount)
- return;
-
- Powers pt = m_target->getPowerType();
- if(m_amplitude == 0)
- {
- // Anger Management (only spell use this aura for rage)
- if (pt == POWER_RAGE)
- m_amplitude = 3000;
- else
- m_amplitude = 2000;
- }
-
- m_periodicTimer = 5000;
-
- if (m_target->GetTypeId() == TYPEID_PLAYER && GetMiscValue() == POWER_MANA)
- ((Player*)m_target)->UpdateManaRegen();
-
- m_isPeriodic = apply;
-}
-
-void AuraEffect::HandleModPowerRegenPCT(bool /*apply*/, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // Update manaregen value
- if (GetMiscValue() == POWER_MANA)
- ((Player*)m_target)->UpdateManaRegen();
-}
-
-void AuraEffect::HandleModManaRegen(bool /*apply*/, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- //Note: an increase in regen does NOT cause threat.
- ((Player*)m_target)->UpdateManaRegen();
-}
-
-void AuraEffect::HandleComprehendLanguage(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(apply)
- m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_COMPREHEND_LANG);
- else
- m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_COMPREHEND_LANG);
-}
-
-void AuraEffect::HandleAuraModIncreaseHealth(bool apply, bool Real, bool changeAmount)
-{
- if(Real || changeAmount)
- {
- if(apply)
- {
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_amount), apply);
- m_target->ModifyHealth(m_amount);
- }
- else
- {
- if (int32(m_target->GetHealth()) > m_amount)
- m_target->ModifyHealth(-m_amount);
- else
- m_target->SetHealth(1);
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_amount), apply);
- }
- }
-}
-
-void AuraEffect::HandleAuraModIncreaseMaxHealth(bool apply, bool Real, bool /*changeAmount*/)
-{
- uint32 oldhealth = m_target->GetHealth();
- double healthPercentage = (double)oldhealth / (double)m_target->GetMaxHealth();
-
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_VALUE, float(m_amount), apply);
-
- // refresh percentage
- if(oldhealth > 0)
- {
- uint32 newhealth = uint32(ceil((double)m_target->GetMaxHealth() * healthPercentage));
- if(newhealth==0)
- newhealth = 1;
-
- m_target->SetHealth(newhealth);
- }
-}
-
-void AuraEffect::HandleAuraModIncreaseEnergy(bool apply, bool Real, bool /*changeAmount*/)
-{
- Powers powerType = m_target->getPowerType();
- if(int32(powerType) != GetMiscValue())
- return;
-
- UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
-
- // Special case with temporary increase max/current power (percent)
- if (GetId()==64904) // Hymn of Hope
- {
- if(Real)
- {
- uint32 val = m_target->GetPower(powerType);
- m_target->HandleStatModifier(unitMod, TOTAL_PCT, float(m_amount), apply);
- m_target->SetPower(powerType, apply ? val*(100+m_amount)/100 : val*100/(100+m_amount));
- }
- return;
- }
-
- // generic flat case
- m_target->HandleStatModifier(unitMod, TOTAL_VALUE, float(m_amount), apply);
-}
-
-void AuraEffect::HandleAuraModIncreaseEnergyPercent(bool apply, bool /*Real*/, bool /*changeAmount*/)
-{
- Powers powerType = m_target->getPowerType();
- if(int32(powerType) != GetMiscValue())
- return;
-
- UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
-
- m_target->HandleStatModifier(unitMod, TOTAL_PCT, float(m_amount), apply);
-}
-
-void AuraEffect::HandleAuraModIncreaseHealthPercent(bool apply, bool /*Real*/, bool /*changeAmount*/)
-{
- // Unit will keep hp% after MaxHealth being modified if unit is alive.
- float percent = ((float)m_target->GetHealth()) / m_target->GetMaxHealth();
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(m_amount), apply);
- if (m_target->isAlive())
- m_target->SetHealth(uint32(m_target->GetMaxHealth()*percent));
-}
-
-void AuraEffect::HandleAuraIncreaseBaseHealthPercent(bool apply, bool /*Real*/, bool /*changeAmount*/)
-{
- m_target->HandleStatModifier(UNIT_MOD_HEALTH, BASE_PCT, float(m_amount), apply);
-}
-
-/********************************/
-/*** FIGHT ***/
-/********************************/
-
-void AuraEffect::HandleAuraModParryPercent(bool /*apply*/, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- ((Player*)m_target)->UpdateParryPercentage();
-}
-
-void AuraEffect::HandleAuraModDodgePercent(bool /*apply*/, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- ((Player*)m_target)->UpdateDodgePercentage();
- //sLog.outError("BONUS DODGE CHANCE: + %f", float(m_amount));
-}
-
-void AuraEffect::HandleAuraModBlockPercent(bool /*apply*/, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- ((Player*)m_target)->UpdateBlockPercentage();
- //sLog.outError("BONUS BLOCK CHANCE: + %f", float(m_amount));
-}
-
-void AuraEffect::HandleAuraModRegenInterrupt(bool /*apply*/, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- ((Player*)m_target)->UpdateManaRegen();
-}
-
-void AuraEffect::HandleAuraModWeaponCritPercent(bool apply, bool Real, bool changeAmount)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // apply item specific bonuses for already equipped weapon
- if(Real || changeAmount)
- {
- for (int i = 0; i < MAX_ATTACK; ++i)
- if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i)))
- ((Player*)m_target)->_ApplyWeaponDependentAuraCritMod(pItem,WeaponAttackType(i),this,apply);
- }
-
- // mods must be applied base at equipped weapon class and subclass comparison
- // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
- // GetMiscValue() comparison with item generated damage types
-
- if (GetSpellProto()->EquippedItemClass == -1)
- {
- ((Player*)m_target)->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (m_amount), apply);
- ((Player*)m_target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (m_amount), apply);
- ((Player*)m_target)->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (m_amount), apply);
- }
- else
- {
- // done in Player::_ApplyWeaponDependentAuraMods
- }
-}
-
-void AuraEffect::HandleModHitChance(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- {
- ((Player*)m_target)->UpdateMeleeHitChances();
- ((Player*)m_target)->UpdateRangedHitChances();
- }
- else
- {
- m_target->m_modMeleeHitChance += apply ? m_amount : (-m_amount);
- m_target->m_modRangedHitChance += apply ? m_amount : (-m_amount);
- }
-}
-
-void AuraEffect::HandleModSpellHitChance(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->UpdateSpellHitChances();
- else
- m_target->m_modSpellHitChance += apply ? m_amount: (-m_amount);
-}
-
-void AuraEffect::HandleModSpellCritChance(bool apply, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->UpdateAllSpellCritChances();
- else
- m_target->m_baseSpellCritChance += apply ? m_amount:-m_amount;
-}
-
-void AuraEffect::HandleModSpellCritChanceShool(bool /*apply*/, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- for (int school = SPELL_SCHOOL_NORMAL; school < MAX_SPELL_SCHOOL; ++school)
- if (GetMiscValue() & (1<<school))
- ((Player*)m_target)->UpdateSpellCritChance(school);
-}
-
-/********************************/
-/*** ATTACK SPEED ***/
-/********************************/
-
-void AuraEffect::HandleModCastingSpeed(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_target->ApplyCastTimePercentMod(m_amount,apply);
-}
-
-void AuraEffect::HandleModMeleeRangedSpeedPct(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_amount,apply);
- m_target->ApplyAttackTimePercentMod(OFF_ATTACK,m_amount,apply);
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_amount, apply);
-}
-
-void AuraEffect::HandleModCombatSpeedPct(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_target->ApplyCastTimePercentMod(m_amount,apply);
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_amount,apply);
- m_target->ApplyAttackTimePercentMod(OFF_ATTACK,m_amount,apply);
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_amount, apply);
-}
-
-void AuraEffect::HandleModAttackSpeed(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK,m_amount,apply);
- m_target->UpdateDamagePhysical(BASE_ATTACK);
-}
-
-void AuraEffect::HandleHaste(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_target->ApplyAttackTimePercentMod(BASE_ATTACK, m_amount,apply);
- m_target->ApplyAttackTimePercentMod(OFF_ATTACK, m_amount,apply);
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_amount,apply);
-}
-
-void AuraEffect::HandleAuraModRangedHaste(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK, m_amount, apply);
-}
-
-void AuraEffect::HandleRangedAmmoHaste(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- m_target->ApplyAttackTimePercentMod(RANGED_ATTACK,m_amount, apply);
-}
-
-/********************************/
-/*** ATTACK POWER ***/
-/********************************/
-
-void AuraEffect::HandleAuraModAttackPower(bool apply, bool Real, bool /*changeAmount*/)
-{
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_VALUE, float(m_amount), apply);
-}
-
-void AuraEffect::HandleAuraModRangedAttackPower(bool apply, bool Real, bool /*changeAmount*/)
-{
- if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
- return;
-
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_VALUE, float(m_amount), apply);
-}
-
-void AuraEffect::HandleAuraModAttackPowerPercent(bool apply, bool Real, bool /*changeAmount*/)
-{
- //UNIT_FIELD_ATTACK_POWER_MULTIPLIER = multiplier - 1
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER, TOTAL_PCT, float(m_amount), apply);
-}
-
-void AuraEffect::HandleAuraModRangedAttackPowerPercent(bool apply, bool Real, bool /*changeAmount*/)
-{
- if((m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)
- return;
-
- //UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = multiplier - 1
- m_target->HandleStatModifier(UNIT_MOD_ATTACK_POWER_RANGED, TOTAL_PCT, float(m_amount), apply);
-}
-
-void AuraEffect::HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- // Recalculate bonus
- if(m_target->GetTypeId() == TYPEID_PLAYER && !(m_target->getClassMask() & CLASSMASK_WAND_USERS))
- ((Player*)m_target)->UpdateAttackPowerAndDamage(true);
-}
-
-void AuraEffect::HandleAuraModAttackPowerOfStatPercent(bool apply, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- // Recalculate bonus
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->UpdateAttackPowerAndDamage(false);
-}
-
-void AuraEffect::HandleAuraModAttackPowerOfArmor(bool /*apply*/, bool Real, bool /*changeAmount*/)
-{
- // spells required only Real aura add/remove
- if(!Real)
- return;
-
- // Recalculate bonus
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->UpdateAttackPowerAndDamage(false);
-}
-/********************************/
-/*** DAMAGE BONUS ***/
-/********************************/
-void AuraEffect::HandleModDamageDone(bool apply, bool Real, bool changeAmount)
-{
- // apply item specific bonuses for already equipped weapon
- if((Real || changeAmount) && m_target->GetTypeId() == TYPEID_PLAYER)
- {
- for (int i = 0; i < MAX_ATTACK; ++i)
- if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i)))
- ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,WeaponAttackType(i),this,apply);
- }
-
- // GetMiscValue() is bitmask of spell schools
- // 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
- // 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wands
- // 127 - full bitmask any damages
- //
- // mods must be applied base at equipped weapon class and subclass comparison
- // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
- // GetMiscValue() comparison with item generated damage types
-
- if((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) != 0)
- {
- // apply generic physical damage bonuses including wand case
- if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
- {
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_VALUE, float(m_amount), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_VALUE, float(m_amount), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_VALUE, float(m_amount), apply);
- }
- else
- {
- // done in Player::_ApplyWeaponDependentAuraMods
- }
-
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- {
- if(m_amount > 0)
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS,m_amount,apply);
- else
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG,m_amount,apply);
- }
- }
-
- // Skip non magic case for speedup
- if((GetMiscValue() & SPELL_SCHOOL_MASK_MAGIC) == 0)
- return;
-
- if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 )
- {
- // wand magic case (skip generic to all item spell bonuses)
- // done in Player::_ApplyWeaponDependentAuraMods
-
- // Skip item specific requirements for not wand magic damage
- return;
- }
-
- // Magic damage modifiers implemented in Unit::SpellDamageBonus
- // This information for client side use only
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- {
- if(m_amount > 0)
- {
- for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
+ case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
{
- if((GetMiscValue() & (1<<i)) != 0)
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_POS+i,m_amount,apply);
+ Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetUnitOwner(), GetUnitOwner(), radius); // No GetCharmer in searcher
+ Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(GetUnitOwner(), targets, u_check);
+ GetUnitOwner()->VisitNearbyObject(radius, searcher);
+ break;
}
- }
- else
- {
- for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; i++)
+ case SPELL_EFFECT_APPLY_AREA_AURA_PET:
+ targets.push_back(GetUnitOwner());
+ case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
{
- if((GetMiscValue() & (1<<i)) != 0)
- m_target->ApplyModUInt32Value(PLAYER_FIELD_MOD_DAMAGE_DONE_NEG+i,m_amount,apply);
+ if(Unit *owner = GetUnitOwner()->GetCharmerOrOwner())
+ if (GetUnitOwner()->IsWithinDistInMap(owner, radius))
+ targets.push_back(owner);
+ break;
}
}
- if(Guardian* pet = ((Player*)m_target)->GetGuardianPet())
- pet->UpdateAttackPowerAndDamage();
}
-}
-void AuraEffect::HandleModDamagePercentDone(bool apply, bool Real, bool changeAmount)
-{
- sLog.outDebug("AURA MOD DAMAGE type:%u negative:%u", GetMiscValue(), m_amount > 0);
-
- // apply item specific bonuses for already equipped weapon
- if((Real || changeAmount) && m_target->GetTypeId() == TYPEID_PLAYER)
+ // mark all auras as ready to remove
+ for (ApplicationMap::iterator appIter = m_applications.begin(); appIter != m_applications.end(); appIter++)
+ if (appIter->second->HasEffect(effIndex))
+ appIter->second->_SetCanBeRemoved(true);
+
+ for (UnitList::iterator appIter = targets.begin(); appIter != targets.end(); appIter++)
{
- for (int i = 0; i < MAX_ATTACK; ++i)
- if(Item* pItem = ((Player*)m_target)->GetWeaponForAttack(WeaponAttackType(i)))
- ((Player*)m_target)->_ApplyWeaponDependentAuraDamageMod(pItem,WeaponAttackType(i),this,apply);
- }
+ // add an aura to units new in list
+ ApplicationMap::iterator itr = m_applications.find((*appIter)->GetGUID());
- // GetMiscValue() is bitmask of spell schools
- // 1 ( 0-bit ) - normal school damage (SPELL_SCHOOL_MASK_NORMAL)
- // 126 - full bitmask all magic damages (SPELL_SCHOOL_MASK_MAGIC) including wand
- // 127 - full bitmask any damages
- //
- // mods must be applied base at equipped weapon class and subclass comparison
- // with spell->EquippedItemClass and EquippedItemSubClassMask and EquippedItemInventoryTypeMask
- // GetMiscValue() comparison with item generated damage types
-
- if((GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL) != 0)
- {
- // apply generic physical damage bonuses including wand case
- if (GetSpellProto()->EquippedItemClass == -1 || m_target->GetTypeId() != TYPEID_PLAYER)
+ if (itr == m_applications.end())
{
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_MAINHAND, TOTAL_PCT, float(m_amount), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_amount), apply);
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_RANGED, TOTAL_PCT, float(m_amount), apply);
- }
- else
- {
- // done in Player::_ApplyWeaponDependentAuraMods
- }
- // For show in client
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT,m_amount/100.0f,apply);
- }
-
- // Skip non magic case for speedup
- if((GetMiscValue() & SPELL_SCHOOL_MASK_MAGIC) == 0)
- return;
-
- if( GetSpellProto()->EquippedItemClass != -1 || GetSpellProto()->EquippedItemInventoryTypeMask != 0 )
- {
- // wand magic case (skip generic to all item spell bonuses)
- // done in Player::_ApplyWeaponDependentAuraMods
-
- // Skip item specific requirements for not wand magic damage
- return;
- }
-
- // Magic damage percent modifiers implemented in Unit::SpellDamageBonus
- // Send info to client
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- for (int i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i)
- m_target->ApplyModSignedFloatValue(PLAYER_FIELD_MOD_DAMAGE_DONE_PCT+i,m_amount/100.0f,apply);
-}
-
-void AuraEffect::HandleModOffhandDamagePercent(bool apply, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- sLog.outDebug("AURA MOD OFFHAND DAMAGE");
-
- m_target->HandleStatModifier(UNIT_MOD_DAMAGE_OFFHAND, TOTAL_PCT, float(m_amount), apply);
-}
-
-/********************************/
-/*** POWER COST ***/
-/********************************/
-
-void AuraEffect::HandleModPowerCostPCT(bool apply, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- float amount = m_amount /100.0f;
- for (int i = 0; i < MAX_SPELL_SCHOOL; ++i)
- if(GetMiscValue() & (1<<i))
- m_target->ApplyModSignedFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,amount,apply);
-}
-
-void AuraEffect::HandleModPowerCost(bool apply, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- for (int i = 0; i < MAX_SPELL_SCHOOL; ++i)
- if(GetMiscValue() & (1<<i))
- m_target->ApplyModInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,m_amount,apply);
-}
-
-void AuraEffect::HandleNoReagentUseAura(bool Apply, bool Real, bool /*changeAmount*/)
-{
- // spells required only Real aura add/remove
- if(!Real)
- return;
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- flag96 mask;
- Unit::AuraEffectList const& noReagent = m_target->GetAurasByType(SPELL_AURA_NO_REAGENT_USE);
- for (Unit::AuraEffectList::const_iterator i = noReagent.begin(); i != noReagent.end(); ++i)
- mask |= (*i)->m_spellProto->EffectSpellClassMask[(*i)->m_effIndex];
-
- m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1 , mask[0]);
- m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+1, mask[1]);
- m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+2, mask[2]);
-}
-
-/*********************************************************/
-/*** OTHERS ***/
-/*********************************************************/
-
-void AuraEffect::HandleAuraAllowOnlyAbility(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(!Real)
- return;
-
- if(!apply && m_target->HasAuraType(SPELL_AURA_ALLOW_ONLY_ABILITY))
- return;
-
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- {
- if (apply)
- m_target->SetFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY);
- else
- m_target->RemoveFlag(PLAYER_FLAGS, PLAYER_ALLOW_ONLY_ABILITY);
- }
-}
-
-void AuraEffect::HandleAuraEmpathy(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(!Real || m_target->GetTypeId() != TYPEID_UNIT)
- return;
-
- CreatureInfo const * ci = objmgr.GetCreatureTemplate(m_target->GetEntry());
- if(ci && ci->type == CREATURE_TYPE_BEAST)
- m_target->ApplyModUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_SPECIALINFO, apply);
-}
-
-void AuraEffect::HandleAuraUntrackable(bool apply, bool Real, bool /*changeAmount*/)
-{
- if (!Real)
- return;
- if(apply)
- m_target->SetByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_UNTRACKABLE);
- else
- m_target->RemoveByteFlag(UNIT_FIELD_BYTES_1, 3, UNIT_BYTE1_FLAG_UNTRACKABLE);
-}
-
-void AuraEffect::HandleAuraModPacify(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(!Real)
- return;
-
- if(apply)
- m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
- else
- m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED);
-}
-
-void AuraEffect::HandleAuraModPacifyAndSilence(bool apply, bool Real, bool changeAmount)
-{
- // Vengeance of the Blue Flight
- if(m_spellProto->Id == 45839)
- {
- if(apply)
- m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- else
- m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
- }
- HandleAuraModPacify(apply,Real, changeAmount);
- HandleAuraModSilence(apply,Real, changeAmount);
-}
-
-void AuraEffect::HandleAuraGhost(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(!Real || m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- if(apply)
- m_target->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST);
- else
- m_target->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST);
-}
-
-void AuraEffect::HandleAuraAllowFlight(bool apply, bool Real, bool /*changeAmount*/)
-{
- // all applied/removed only at real aura add/remove
- if(!Real)
- return;
-
- if(m_target->GetTypeId() == TYPEID_UNIT)
- m_target->SetFlying(apply);
-
- if(Player *plr = m_target->m_movedPlayer)
- {
- // allow fly
- WorldPacket data;
- if(apply)
- data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);
- else
- data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12);
- data.append(m_target->GetPackGUID());
- data << uint32(0); // unk
- plr->SendDirectMessage(&data);
- }
-
- //m_target->SendMessageToSet(&data, true);
-}
-
-void AuraEffect::HandleModRating(bool apply, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
- if (GetMiscValue() & (1 << rating))
- ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), m_amount, apply);
-}
-
-void AuraEffect::HandleModRatingFromStat(bool apply, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- // Just recalculate ratings
- for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating)
- if (GetMiscValue() & (1 << rating))
- ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), 0, apply);
-}
-
-void AuraEffect::HandleForceMoveForward(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(!Real || m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- if(apply)
- m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE);
- else
- m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_FORCE_MOVE);
-}
-
-void AuraEffect::HandleAuraModExpertise(bool /*apply*/, bool Real, bool changeAmount)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- ((Player*)m_target)->UpdateExpertise(BASE_ATTACK);
- ((Player*)m_target)->UpdateExpertise(OFF_ATTACK);
-}
-
-void AuraEffect::HandleModTargetResistance(bool apply, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
- // applied to damage as HandleNoImmediateEffect in Unit::CalcAbsorbResist and Unit::CalcArmorReducedDamage
-
- // show armor penetration
- if (m_target->GetTypeId() == TYPEID_PLAYER && (GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
- m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE,m_amount, apply);
-
- // show as spell penetration only full spell penetration bonuses (all resistances except armor and holy
- if (m_target->GetTypeId() == TYPEID_PLAYER && (GetMiscValue() & SPELL_SCHOOL_MASK_SPELL)==SPELL_SCHOOL_MASK_SPELL)
- m_target->ApplyModInt32Value(PLAYER_FIELD_MOD_TARGET_RESISTANCE,m_amount, apply);
-}
-
-void AuraEffect::HandleShieldBlockValue(bool apply, bool Real, bool /*changeAmount*/)
-{
- BaseModType modType = FLAT_MOD;
- if(m_auraName == SPELL_AURA_MOD_SHIELD_BLOCKVALUE_PCT)
- modType = PCT_MOD;
-
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->HandleBaseModValue(SHIELD_BLOCK_VALUE, modType, float(m_amount), apply);
-}
-
-void AuraEffect::HandleAuraRetainComboPoints(bool apply, bool Real, bool changeAmount)
-{
- // spells required only Real aura add/remove
- if(!Real && !changeAmount)
- return;
-
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- Player *target = (Player*)m_target;
-
- // combo points was added in SPELL_EFFECT_ADD_COMBO_POINTS handler
- // remove only if aura expire by time (in case combo points amount change aura removed without combo points lost)
- if( !apply && GetParentAura()->GetAuraDuration()==0 && target->GetComboTarget())
- if(Unit* unit = ObjectAccessor::GetUnit(*m_target,target->GetComboTarget()))
- target->AddComboPoints(unit, -m_amount);
-}
-
-void AuraEffect::HandleModUnattackable( bool Apply, bool Real , bool /*changeAmount*/)
-{
- if(!Real)
- return;
-
- if(Apply)
- {
- m_target->CombatStop();
- m_target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION);
- }
-
- m_target->ApplyModFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE, Apply);
-}
-
-void AuraEffect::HandleSpiritOfRedemption( bool apply, bool Real , bool /*changeAmount*/)
-{
- // spells required only Real aura add/remove
- if(!Real)
- return;
-
- // prepare spirit state
- if(apply)
- {
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- {
- // disable breath/etc timers
- ((Player*)m_target)->StopMirrorTimers();
-
- // set stand state (expected in this form)
- if(!m_target->IsStandState())
- m_target->SetStandState(UNIT_STAND_STATE_STAND);
- }
-
- m_target->SetHealth(1);
- }
- // die at aura end
- else
- m_target->setDeathState(JUST_DIED);
-}
-
-void AuraEffect::PeriodicTick()
-{
- if(!m_target->isAlive())
- return;
-
- switch(GetAuraName())
- {
- case SPELL_AURA_PERIODIC_DAMAGE:
- case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
- {
- Unit *pCaster = GetCaster();
- if(!pCaster)
- return;
-
- // Consecrate ticks can miss and will not show up in the combat log
- if (GetSpellProto()->Effect[GetEffIndex()] == SPELL_EFFECT_PERSISTENT_AREA_AURA &&
- pCaster->SpellHitResult(m_target,GetSpellProto(),false) != SPELL_MISS_NONE)
- return;
-
- // Check for immune (not use charges)
- if (m_target->IsImmunedToDamage(GetSpellProto()))
- return;
+ // check target immunities
+ if ((*appIter)->IsImmunedToSpell(GetSpellProto())
+ || (*appIter)->hasUnitState(UNIT_STAT_ISOLATED))
+ continue;
- // some auras remove at specific health level or more
- if (m_auraName == SPELL_AURA_PERIODIC_DAMAGE)
+ // Allow to remove by stack when aura is going to be applied on owner
+ if (*appIter != GetOwner())
{
- switch (GetId())
+ bool addUnit = true;
+ // 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 = (*appIter)->GetAppliedAuras().begin(); iter != (*appIter)->GetAppliedAuras().end(); ++iter)
{
- case 43093: case 31956: case 38801: // Grievous Wound
- case 35321: case 38363: case 39215: // Gushing Wound
- if(m_target->GetHealth() == m_target->GetMaxHealth())
- {
- m_target->RemoveAurasDueToSpell(GetId());
- return;
- }
- break;
- case 38772: // Grievous Wound
+ Aura const * aura = iter->second->GetBase();
+ if(!spellmgr.CanAurasStack(GetSpellProto(), aura->GetSpellProto(), aura->GetCasterGUID() == GetCasterGUID()))
{
- uint32 percent =
- GetEffIndex() < 2 && GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_DUMMY ?
- pCaster->CalculateSpellDamage(GetSpellProto(),GetEffIndex()+1,GetSpellProto()->EffectBasePoints[GetEffIndex()+1],m_target) :
- 100;
- if(m_target->GetHealth()*100 >= m_target->GetMaxHealth()*percent)
- {
- m_target->RemoveAurasDueToSpell(GetId());
- return;
- }
- break;
- }
- case 41337: // Aura of Anger
- {
- if (AuraEffect * aurEff = GetParentAura()->GetPartAura(1))
- {
- aurEff->ApplyModifier(false, false, true);
- aurEff->SetAmount(aurEff->GetAmount()+5);
- aurEff->ApplyModifier(true, false, true);
- }
- m_amount = 100 * m_tickNumber;
- break;
- }
- // Brutallus Burn
- case 46394:
- {
- if (m_tickNumber % 11 == 0)
- m_amount *= 2;
+ addUnit = false;
break;
}
- case 31803:
- case 53742:
- {
- float ap = pCaster->GetTotalAttackPowerValue(BASE_ATTACK);
- int32 holy = pCaster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) +
- pCaster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellProto), m_target);
-
- m_amount = (0.013f * holy + 0.025f * ap) * 6 / 5 * m_tickNumber;
- break;
- }
- default:
- break;
- }
- }
-
- uint32 absorb=0;
- uint32 resist=0;
- CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL );
-
- // ignore non positive values (can be result apply spellmods to aura damage
- //uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
- uint32 pdamage = GetAmount() > 0 ? GetAmount() : 0;
-
- if(GetAuraName() == SPELL_AURA_PERIODIC_DAMAGE)
- {
- pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetParentAura()->GetStackAmount());
-
- // Calculate armor mitigation if it is a physical spell
- // But not for bleed mechanic spells
- if ( GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL &&
- GetEffectMechanic(GetSpellProto(), m_effIndex) != MECHANIC_BLEED)
- {
- uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage, GetSpellProto());
- cleanDamage.mitigated_damage += pdamage - pdamageReductedArmor;
- pdamage = pdamageReductedArmor;
- }
-
- // Curse of Agony damage-per-tick calculation
- if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags[0] & 0x400) && GetSpellProto()->SpellIconID==544)
- {
- uint32 totalTick = GetParentAura()->GetAuraMaxDuration() / m_amplitude;
- // 1..4 ticks, 1/2 from normal tick damage
- if(m_tickNumber <= totalTick / 3)
- pdamage = pdamage/2;
- // 9..12 ticks, 3/2 from normal tick damage
- else if(m_tickNumber > totalTick * 2 / 3)
- pdamage += (pdamage+1)/2; // +1 prevent 0.5 damage possible lost at 1..4 ticks
- // 5..8 ticks have normal tick damage
- }
- // There is a Chance to make a Soul Shard when Drain soul does damage
- if (GetSpellProto()->SpellFamilyName==SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags[0] & 0x00004000))
- {
- if(roll_chance_i(20))
- pCaster->CastSpell(pCaster, 24827, true, 0, this);
}
+ if (!addUnit)
+ continue;
}
- else
- pdamage = uint32(m_target->GetMaxHealth()*pdamage/100);
-
- bool crit = IsPeriodicTickCrit(pCaster);
- if (crit)
- pdamage = pCaster->SpellCriticalDamageBonus(m_spellProto, pdamage, m_target);
-
- // only from players
- if (IS_PLAYER_GUID(GetCasterGUID()))
- pdamage -= m_target->GetSpellDamageReduction(pdamage);
-
- pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist, m_spellProto);
-
- sLog.outDetail("PeriodicTick: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
- GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
-
- pCaster->DealDamageMods(m_target,pdamage,&absorb);
-
- Unit* target = m_target; // aura can be deleted in DealDamage
- SpellEntry const* spellProto = GetSpellProto();
-
- // Set trigger flag
- uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;
- uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;
- uint32 procEx = PROC_EX_NORMAL_HIT | PROC_EX_INTERNAL_DOT;
- pdamage = (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist);
- if (pdamage)
- procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE;
-
- int32 overkill = pdamage - m_target->GetHealth();
- if (overkill < 0)
- overkill = 0;
-
- SpellPeriodicAuraLogInfo pInfo(this, pdamage, overkill, absorb, resist, 0.0f, crit);
- m_target->SendPeriodicAuraLog(&pInfo);
-
- pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, procEx, pdamage, BASE_ATTACK, spellProto);
-
- pCaster->DealDamage(target, pdamage, &cleanDamage, DOT, GetSpellSchoolMask(spellProto), spellProto, true);
- break;
}
- case SPELL_AURA_PERIODIC_LEECH:
- {
- Unit *pCaster = GetCaster();
- if(!pCaster)
- return;
-
- if(!pCaster->isAlive())
- return;
-
- if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA &&
- pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE)
- return;
- // Check for immune
- if(m_target->IsImmunedToDamage(GetSpellProto()))
- return;
-
- uint32 absorb=0;
- uint32 resist=0;
- CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL );
-
- //uint32 pdamage = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
- uint32 pdamage = GetAmount() > 0 ? GetAmount() : 0;
- pdamage = pCaster->SpellDamageBonus(m_target, GetSpellProto(), pdamage, DOT, GetParentAura()->GetStackAmount());
-
- bool crit = IsPeriodicTickCrit(pCaster);
- if (crit)
- pdamage = pCaster->SpellCriticalDamageBonus(m_spellProto, pdamage, m_target);
-
- //Calculate armor mitigation if it is a physical spell
- if (GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL)
- {
- uint32 pdamageReductedArmor = pCaster->CalcArmorReducedDamage(m_target, pdamage, GetSpellProto());
- cleanDamage.mitigated_damage += pdamage - pdamageReductedArmor;
- pdamage = pdamageReductedArmor;
- }
-
- // Reduce dot damage from resilience for players.
- if (m_target->GetTypeId() == TYPEID_PLAYER)
- pdamage-=((Player*)m_target)->GetSpellDamageReduction(pdamage);
-
- pCaster->CalcAbsorbResist(m_target, GetSpellSchoolMask(GetSpellProto()), DOT, pdamage, &absorb, &resist, m_spellProto);
-
- if(m_target->GetHealth() < pdamage)
- pdamage = uint32(m_target->GetHealth());
-
- sLog.outDetail("PeriodicTick: %u (TypeId: %u) health leech of %u (TypeId: %u) for %u dmg inflicted by %u abs is %u",
- GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId(),absorb);
-
- pCaster->SendSpellNonMeleeDamageLog(m_target, GetId(), pdamage, GetSpellSchoolMask(GetSpellProto()), absorb, resist, false, 0, crit);
-
- Unit* target = m_target; // aura can be deleted in DealDamage
- SpellEntry const* spellProto = GetSpellProto();
- float multiplier = spellProto->EffectMultipleValue[GetEffIndex()] > 0 ? spellProto->EffectMultipleValue[GetEffIndex()] : 1;
- int32 stackAmount = GetParentAura()->GetStackAmount();
-
- // Set trigger flag
- uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;
- uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;
- uint32 procEx = PROC_EX_NORMAL_HIT | PROC_EX_INTERNAL_DOT;
- pdamage = (pdamage <= absorb+resist) ? 0 : (pdamage-absorb-resist);
- if (pdamage)
- procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE;
- pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, procEx, pdamage, BASE_ATTACK, spellProto);
- int32 new_damage = pCaster->DealDamage(target, pdamage, &cleanDamage, DOT, GetSpellSchoolMask(spellProto), spellProto, false);
-
- if (!target->isAlive() && pCaster->IsNonMeleeSpellCasted(false))
- for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; ++i)
- if (Spell* spell = pCaster->GetCurrentSpell(CurrentSpellTypes(i)))
- if (spell->m_spellInfo->Id == GetId())
- spell->cancel();
-
- if(Player *modOwner = pCaster->GetSpellModOwner())
- modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_MULTIPLE_VALUE, multiplier);
-
- uint32 heal = uint32(pCaster->SpellHealingBonus(pCaster, spellProto, uint32(new_damage * multiplier), DOT, stackAmount));
-
- int32 gain = pCaster->DealHeal(pCaster, heal, spellProto);
- pCaster->getHostilRefManager().threatAssist(pCaster, gain * 0.5f, spellProto);
- break;
- }
- case SPELL_AURA_PERIODIC_HEALTH_FUNNEL: // only three spells
+ if (itr == m_applications.end() || !itr->second->HasEffect(effIndex))
{
- Unit *donator = GetCaster();
- if(!donator || !donator->GetHealth())
- return;
-
- uint32 pdamage = GetAmount() * GetParentAura()->GetStackAmount();
- if(donator->GetHealth() < pdamage)
- pdamage = donator->GetHealth() - 1;
- if(!pdamage)
- return;
-
- Unit* target = m_target; // aura can be deleted in DealDamage
- SpellEntry const* spellProto = GetSpellProto();
- //donator->SendSpellNonMeleeDamageLog(donator, GetId(), pdamage, GetSpellSchoolMask(spellProto), 0, 0, false, 0);
- donator->ModifyHealth(-(int32)pdamage);
- sLog.outDetail("PeriodicTick: donator %u target %u damage %u.", donator->GetEntry(), target->GetEntry(), pdamage);
-
- if(spellProto->EffectMultipleValue[GetEffIndex()] > 0)
- pdamage *= spellProto->EffectMultipleValue[GetEffIndex()];
-
- donator->DealHeal(target, pdamage, spellProto);
- break;
- }
- case SPELL_AURA_PERIODIC_HEAL:
- case SPELL_AURA_OBS_MOD_HEALTH:
- {
- Unit *pCaster = GetCaster();
- if(!pCaster)
- return;
-
- // heal for caster damage (must be alive)
- if(m_target != pCaster && GetSpellProto()->AttributesEx2 & SPELL_ATTR_EX2_HEALTH_FUNNEL && !pCaster->isAlive())
- return;
-
- if(GetParentAura()->GetAuraDuration() ==-1 && m_target->GetHealth()==m_target->GetMaxHealth())
- return;
-
- // ignore non positive values (can be result apply spellmods to aura damage
- //uint32 amount = GetModifierValuePerStack() > 0 ? GetModifierValuePerStack() : 0;
- int32 pdamage = GetAmount() > 0 ? GetAmount() : 0;
-
- if(m_auraName==SPELL_AURA_OBS_MOD_HEALTH)
- pdamage = uint32(m_target->GetMaxHealth() * pdamage * GetParentAura()->GetStackAmount() / 100);
- else
- {
- // Wild Growth (1/7 - 6 + 2*ramainTicks) %
- if (m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellIconID == 2864)
- {
- int32 ticks = GetParentAura()->GetAuraMaxDuration()/m_amplitude;
- int32 remainingTicks = int32(float(GetParentAura()->GetAuraDuration()) / m_amplitude + 0.5);
- pdamage = int32(pdamage) + int32(pdamage)*ticks*(-6+2*remainingTicks)/100;
- }
-
- pdamage = pCaster->SpellHealingBonus(m_target, GetSpellProto(), pdamage, DOT, GetParentAura()->GetStackAmount());
- }
-
- bool crit = IsPeriodicTickCrit(pCaster);
- if (crit)
- pdamage = pCaster->SpellCriticalHealingBonus(m_spellProto, pdamage, m_target);
-
- sLog.outDetail("PeriodicTick: %u (TypeId: %u) heal of %u (TypeId: %u) for %u health inflicted by %u",
- GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
-
- int32 gain = m_target->ModifyHealth(pdamage);
-
- SpellPeriodicAuraLogInfo pInfo(this, pdamage, pdamage - gain, 0, 0, 0.0f, crit);
- m_target->SendPeriodicAuraLog(&pInfo);
-
- // add HoTs to amount healed in bgs
- if( pCaster->GetTypeId() == TYPEID_PLAYER )
- if( BattleGround *bg = ((Player*)pCaster)->GetBattleGround() )
- bg->UpdatePlayerScore(((Player*)pCaster), SCORE_HEALING_DONE, gain);
-
- m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
-
- Unit* target = m_target; // aura can be deleted in DealDamage
- SpellEntry const* spellProto = GetSpellProto();
- bool haveCastItem = GetParentAura()->GetCastItemGUID()!=0;
-
- // Health Funnel
- // heal for caster damage
- if(m_target!=pCaster && GetSpellProto()->AttributesEx2 & SPELL_ATTR_EX2_HEALTH_FUNNEL)
- {
- uint32 dmg = spellProto->manaPerSecond;
- if(pCaster->GetHealth() <= dmg && pCaster->GetTypeId() == TYPEID_PLAYER)
- {
- pCaster->RemoveAurasDueToSpell(GetId());
-
- // finish current generic/channeling spells, don't affect autorepeat
- pCaster->FinishSpell(CURRENT_GENERIC_SPELL);
- pCaster->FinishSpell(CURRENT_CHANNELED_SPELL);
- }
- else
- {
- uint32 damage = gain;
- uint32 absorb = 0;
- pCaster->DealDamageMods(pCaster,damage,&absorb);
- pCaster->SendSpellNonMeleeDamageLog(pCaster, GetId(), damage, GetSpellSchoolMask(GetSpellProto()), absorb, 0, false, 0, false);
-
- CleanDamage cleanDamage = CleanDamage(0, 0, BASE_ATTACK, MELEE_HIT_NORMAL );
- pCaster->DealDamage(pCaster, damage, &cleanDamage, NODAMAGE, GetSpellSchoolMask(GetSpellProto()), GetSpellProto(), true);
- }
- }
-
- uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;
- uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;
- uint32 procEx = PROC_EX_NORMAL_HIT | PROC_EX_INTERNAL_HOT;
- // ignore item heals
- if(!haveCastItem)
- pCaster->ProcDamageAndSpell(target, procAttacker, procVictim, procEx, pdamage, BASE_ATTACK, spellProto);
- break;
- }
- case SPELL_AURA_PERIODIC_MANA_LEECH:
- {
- if(GetMiscValue() < 0 || GetMiscValue() >= MAX_POWERS)
- return;
-
- Powers power = Powers(GetMiscValue());
-
- // power type might have changed between aura applying and tick (druid's shapeshift)
- if(m_target->getPowerType() != power)
- return;
-
- Unit *pCaster = GetCaster();
- if(!pCaster)
- return;
-
- if(!pCaster->isAlive())
- return;
-
- if( GetSpellProto()->Effect[GetEffIndex()]==SPELL_EFFECT_PERSISTENT_AREA_AURA &&
- pCaster->SpellHitResult(m_target,GetSpellProto(),false)!=SPELL_MISS_NONE)
- return;
-
- // Check for immune (not use charges)
- if(m_target->IsImmunedToDamage(GetSpellProto()))
- return;
-
- // ignore non positive values (can be result apply spellmods to aura damage
- uint32 pdamage = m_amount > 0 ? m_amount : 0;
-
- // Special case: draining x% of mana (up to a maximum of 2*x% of the caster's maximum mana)
- // It's mana percent cost spells, m_amount is percent drain from target
- if (m_spellProto->ManaCostPercentage)
- {
- // max value
- uint32 maxmana = pCaster->GetMaxPower(power) * pdamage * 2 / 100;
- pdamage = m_target->GetMaxPower(power) * pdamage / 100;
- if(pdamage > maxmana)
- pdamage = maxmana;
- }
-
- sLog.outDetail("PeriodicTick: %u (TypeId: %u) power leech of %u (TypeId: %u) for %u dmg inflicted by %u",
- GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), pdamage, GetId());
-
- int32 drain_amount = m_target->GetPower(power) > pdamage ? pdamage : m_target->GetPower(power);
-
- // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
- if (power == POWER_MANA)
- drain_amount -= m_target->GetSpellCritDamageReduction(drain_amount);
-
- m_target->ModifyPower(power, -drain_amount);
-
- float gain_multiplier = 0;
-
- if(pCaster->GetMaxPower(power) > 0)
- {
- gain_multiplier = GetSpellProto()->EffectMultipleValue[GetEffIndex()];
-
- if(Player *modOwner = pCaster->GetSpellModOwner())
- modOwner->ApplySpellMod(GetId(), SPELLMOD_MULTIPLE_VALUE, gain_multiplier);
- }
-
- SpellPeriodicAuraLogInfo pInfo(this, drain_amount, 0, 0, 0, gain_multiplier, false);
- m_target->SendPeriodicAuraLog(&pInfo);
-
- int32 gain_amount = int32(drain_amount*gain_multiplier);
-
- if(gain_amount)
- {
- int32 gain = pCaster->ModifyPower(power,gain_amount);
- m_target->AddThreat(pCaster, float(gain) * 0.5f, GetSpellSchoolMask(GetSpellProto()), GetSpellProto());
- }
-
- // Mark of Kaz'rogal
- if(GetId() == 31447 && m_target->GetPower(power) == 0)
- {
- m_target->CastSpell(m_target, 31463, true, 0, this);
- // Remove aura
- GetParentAura()->SetAuraDuration(0);
- }
-
- // Mark of Kazzak
- if(GetId() == 32960)
- {
- int32 modifier = (m_target->GetPower(power) * 0.05f);
- m_target->ModifyPower(power, -modifier);
-
- if(m_target->GetPower(power) == 0)
- {
- m_target->CastSpell(m_target, 32961, true, 0, this);
- // Remove aura
- GetParentAura()->SetAuraDuration(0);
- }
- }
- // Mana Feed - Drain Mana
- if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK
- && m_spellProto->SpellFamilyFlags[0] & 0x00000010)
- {
- int32 manaFeedVal = 0;
- if (AuraEffect const * aurEff = GetParentAura()->GetPartAura(1))
- manaFeedVal = aurEff->GetAmount();
-
- if(manaFeedVal > 0)
- {
- manaFeedVal = manaFeedVal * gain_amount / 100;
- pCaster->CastCustomSpell(pCaster, 32554, &manaFeedVal, NULL, NULL, true, NULL, this);
- }
- }
- break;
- }
- case SPELL_AURA_OBS_MOD_POWER:
- {
- if(GetMiscValue() < 0)
- return;
-
- Powers power;
- if (GetMiscValue() == POWER_ALL)
- power = m_target->getPowerType();
- else
- power = Powers(GetMiscValue());
-
- if(m_target->GetMaxPower(power) == 0)
- return;
-
- if(GetParentAura()->GetAuraDuration() ==-1 && m_target->GetPower(power)==m_target->GetMaxPower(power))
- return;
-
- uint32 amount = m_amount * m_target->GetMaxPower(power) /100;
- sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u",
- GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), amount, GetId());
-
- SpellPeriodicAuraLogInfo pInfo(this, amount, 0, 0, 0, 0.0f, false);
- m_target->SendPeriodicAuraLog(&pInfo);
-
- int32 gain = m_target->ModifyPower(power,amount);
-
- if(Unit* pCaster = GetCaster())
- m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
- break;
- }
- case SPELL_AURA_PERIODIC_ENERGIZE:
- {
- // ignore non positive values (can be result apply spellmods to aura damage
- if(m_amount < 0 || GetMiscValue() >= MAX_POWERS)
- return;
-
- Powers power = Powers(GetMiscValue());
-
- if(m_target->GetMaxPower(power) == 0)
- return;
-
- if(GetParentAura()->GetAuraDuration() ==-1 && m_target->GetPower(power)==m_target->GetMaxPower(power))
- return;
-
- uint32 amount = m_amount;
-
- SpellPeriodicAuraLogInfo pInfo(this, amount, 0, 0, 0, 0.0f, false);
- m_target->SendPeriodicAuraLog(&pInfo);
-
- sLog.outDetail("PeriodicTick: %u (TypeId: %u) energize %u (TypeId: %u) for %u dmg inflicted by %u",
- GUID_LOPART(GetCasterGUID()), GuidHigh2TypeId(GUID_HIPART(GetCasterGUID())), m_target->GetGUIDLow(), m_target->GetTypeId(), amount, GetId());
-
- int32 gain = m_target->ModifyPower(power,amount);
-
- if(Unit* pCaster = GetCaster())
- m_target->getHostilRefManager().threatAssist(pCaster, float(gain) * 0.5f, GetSpellProto());
- break;
- }
- case SPELL_AURA_POWER_BURN_MANA:
- {
- Unit *pCaster = GetCaster();
- if(!pCaster)
- return;
-
- // Check for immune (not use charges)
- if(m_target->IsImmunedToDamage(GetSpellProto()))
- return;
-
- int32 pdamage = m_amount > 0 ? m_amount : 0;
-
- Powers powerType = Powers(GetMiscValue());
-
- if(!m_target->isAlive() || m_target->getPowerType() != powerType)
- return;
-
- // resilience reduce mana draining effect at spell crit damage reduction (added in 2.4)
- if (powerType == POWER_MANA)
- pdamage -= m_target->GetSpellCritDamageReduction(pdamage);
-
- uint32 gain = uint32(-m_target->ModifyPower(powerType, -pdamage));
-
- gain = uint32(gain * GetSpellProto()->EffectMultipleValue[GetEffIndex()]);
-
- SpellEntry const* spellProto = GetSpellProto();
- //maybe has to be sent different to client, but not by SMSG_PERIODICAURALOG
- SpellNonMeleeDamage damageInfo(pCaster, m_target, spellProto->Id, spellProto->SchoolMask);
- //no SpellDamageBonus for burn mana
- pCaster->CalculateSpellDamageTaken(&damageInfo, gain, spellProto);
-
- pCaster->DealDamageMods(damageInfo.target,damageInfo.damage,&damageInfo.absorb);
-
- pCaster->SendSpellNonMeleeDamageLog(&damageInfo);
-
- // Set trigger flag
- uint32 procAttacker = PROC_FLAG_ON_DO_PERIODIC;
- uint32 procVictim = PROC_FLAG_ON_TAKE_PERIODIC;
- uint32 procEx = createProcExtendMask(&damageInfo, SPELL_MISS_NONE) | PROC_EX_INTERNAL_DOT;
- if (damageInfo.damage)
- procVictim|=PROC_FLAG_TAKEN_ANY_DAMAGE;
-
- pCaster->ProcDamageAndSpell(damageInfo.target, procAttacker, procVictim, procEx, damageInfo.damage, BASE_ATTACK, spellProto);
-
- pCaster->DealSpellDamage(&damageInfo, true);
- break;
- }
- case SPELL_AURA_MOD_REGEN:
- {
- int32 gain = m_target->ModifyHealth(m_amount);
- if (Unit *caster = GetCaster())
- m_target->getHostilRefManager().threatAssist(caster, float(gain) * 0.5f, GetSpellProto());
- break;
- }
- case SPELL_AURA_MOD_POWER_REGEN:
- {
- Powers pt = m_target->getPowerType();
- if(int32(pt) != GetMiscValue())
- return;
-
- if ( GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED )
- {
- // eating anim
- m_target->HandleEmoteCommand(EMOTE_ONESHOT_EAT);
- }
- // Butchery
- else if (m_spellProto->SpellFamilyName==SPELLFAMILY_DEATHKNIGHT
- && m_spellProto->SpellIconID==2664)
- {
- if (m_target->isInCombat())
- m_target->ModifyPower(pt,m_amount);
- }
+ if((*appIter)->IsImmunedToSpellEffect(GetSpellProto(), effIndex))
+ continue;
+ // add new unit to persistent area aura
+ (*appIter)->_ApplyAuraEffect(this, effIndex);
- // Anger Management
- // amount = 1+ 16 = 17 = 3,4*5 = 10,2*5/3
- // so 17 is rounded amount for 5 sec tick grow ~ 1 range grow in 3 sec
- if(pt == POWER_RAGE)
- m_target->ModifyPower(pt, m_amount*3/5);
- break;
- }
- case SPELL_AURA_DUMMY:
- {
- // Haunting Spirits
- if (GetId() == 7057)
- {
- m_target->CastSpell((Unit*)NULL , m_amount , true);
- m_amplitude = irand (0 , 60 ) + 30;
- m_amplitude *= IN_MILISECONDS;
- break;
- }
- break;
- }
- // Here tick dummy auras
- case SPELL_AURA_PERIODIC_DUMMY:
- {
- PeriodicDummyTick();
- break;
+ // start combat with targeted enemy
+ if(GetSpellProto()->Effect[effIndex] == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY)
+ GetUnitOwner()->CombatStart(*appIter);
}
- case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
- {
- Unit *pCaster = GetCaster();
- if (!pCaster)
- return;
-
- if (pCaster->GetTypeId() == TYPEID_UNIT && ((Creature*)pCaster)->isTotem() && ((Totem*)pCaster)->GetTotemType() != TOTEM_STATUE)
- {
- uint32 procAttacker = PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT;
- uint32 procVictim = PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT;
- SpellEntry const *spellProto = GetSpellProto();
- if (spellProto->SpellFamilyName == SPELLFAMILY_GENERIC) // SPELLFAMILY_GENERIC proc by triggered spell
- {
- uint32 trigger_spell_id = spellProto->EffectTriggerSpell[m_effIndex];
- SpellEntry const *triggeredSpellInfo = sSpellStore.LookupEntry(trigger_spell_id);
- ((Totem*)pCaster)->GetOwner()->ProcDamageAndSpell(pCaster, procAttacker, procVictim, PROC_EX_NORMAL_HIT, 0, BASE_ATTACK, triggeredSpellInfo);
- }
- else
- ((Totem*)pCaster)->GetOwner()->ProcDamageAndSpell(pCaster, procAttacker, procVictim, PROC_EX_NORMAL_HIT, 0, BASE_ATTACK, spellProto);
- }
-
- TriggerSpell();
- break;
- }
- case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
- {
- TriggerSpellWithValue();
- break;
- }
- default:
- break;
+ itr = m_applications.find((*appIter)->GetGUID());
+ if (itr != m_applications.end())
+ // mark aura of unit already in list to be not removed
+ itr->second->_SetCanBeRemoved(false);
}
-}
-void AuraEffect::PeriodicDummyTick()
-{
- Unit *caster = GetCaster();
- SpellEntry const* spell = GetSpellProto();
- switch (spell->SpellFamilyName)
+ // remove auras which are not in current area
+ for (ApplicationMap::iterator appIter = m_applications.begin(); appIter != m_applications.end();)
{
- case SPELLFAMILY_GENERIC:
- switch (spell->Id)
- {
- // Drink
- case 430:
- case 431:
- case 432:
- case 1133:
- case 1135:
- case 1137:
- case 10250:
- case 22734:
- case 27089:
- case 34291:
- case 43182:
- case 43183:
- case 46755:
- case 49472: // Drink Coffee
- case 57073:
- case 61830:
- {
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- // Get SPELL_AURA_MOD_POWER_REGEN aura from spell
- if (AuraEffect * aurEff = GetParentAura()->GetPartAura(0))
- {
- if (aurEff->GetAuraName() !=SPELL_AURA_MOD_POWER_REGEN)
- {
- m_isPeriodic = false;
- sLog.outError("Aura %d structure has been changed - first aura is no longer SPELL_AURA_MOD_POWER_REGEN", spell->Id);
- }
- else
- {
- // default case - not in arena
- if (!((Player*)m_target)->InArena())
- {
- aurEff->SetAmount(GetAmount());
- ((Player*)m_target)->UpdateManaRegen();
- m_isPeriodic = false;
- }
- else
- {
- //**********************************************
- // This feature uses only in arenas
- //**********************************************
- // Here need increase mana regen per tick (6 second rule)
- // on 0 tick - 0 (handled in 2 second)
- // on 1 tick - 166% (handled in 4 second)
- // on 2 tick - 133% (handled in 6 second)
-
- // Apply bonus for 1 - 4 tick
- switch (m_tickNumber)
- {
- case 1: // 0%
- aurEff->SetAmount(0);
- break;
- case 2: // 166%
- aurEff->SetAmount(GetAmount() * 5 / 3);
- break;
- case 3: // 133%
- aurEff->SetAmount(GetAmount() * 4 / 3);
- break;
- default: // 100% - normal regen
- aurEff->SetAmount(GetAmount());
- // No need to update after 4th tick
- m_isPeriodic = false;
- break;
- }
- ((Player*)m_target)->UpdateManaRegen();
- }
- }
- }
- return;
- }
- // Forsaken Skills
- case 7054:
- {
- // Possibly need cast one of them (but
- // 7038 Forsaken Skill: Swords
- // 7039 Forsaken Skill: Axes
- // 7040 Forsaken Skill: Daggers
- // 7041 Forsaken Skill: Maces
- // 7042 Forsaken Skill: Staves
- // 7043 Forsaken Skill: Bows
- // 7044 Forsaken Skill: Guns
- // 7045 Forsaken Skill: 2H Axes
- // 7046 Forsaken Skill: 2H Maces
- // 7047 Forsaken Skill: 2H Swords
- // 7048 Forsaken Skill: Defense
- // 7049 Forsaken Skill: Fire
- // 7050 Forsaken Skill: Frost
- // 7051 Forsaken Skill: Holy
- // 7053 Forsaken Skill: Shadow
- return;
- }
- case 45472: // Parachute
- if (m_target->GetTypeId() == TYPEID_PLAYER)
- {
- Player *plr = (Player*)m_target;
- if (plr->IsFalling())
- {
- plr->RemoveAurasDueToSpell(45472);
- plr->CastSpell(plr, 44795, true);
- }
- }
- break;
- case SPELL_RESTRICTED_FLIGHT_AREA_58730: // No Fly Zone - Wintergrasp
- case SPELL_RESTRICTED_FLIGHT_AREA_58600: // No fly Zone - Dalaran
- if (m_tickNumber == 10)
- {
- m_target->RemoveAurasByType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED);
- m_target->RemoveAurasByType(SPELL_AURA_FLY);
- }
- break;
- case 58549: // Tenacity
- case 59911: // Tenacity (vehicle)
- GetParentAura()->RefreshAura();
- break;
- case 62292: // Blaze (Pool of Tar)
- // should we use custom damage?
- m_target->CastSpell((Unit*)NULL, m_spellProto->EffectTriggerSpell[m_effIndex], true);
- break;
- default:
- break;
- }
- break;
- case SPELLFAMILY_MAGE:
- {
- // Mirror Image
- if (spell->Id == 55342)
- {
- // Set name of summons to name of caster
- m_target->CastSpell((Unit *)NULL, m_spellProto->EffectTriggerSpell[m_effIndex], true);
- m_isPeriodic = false;
- }
- break;
- }
- case SPELLFAMILY_WARLOCK:
- {
- switch (spell->Id)
- {
- // Demonic Circle
- case 48018:
- if(GameObject* obj = m_target->GetGameObject(spell->Id))
- {
- if (m_target->IsWithinDist(obj, GetSpellMaxRange(48020, true)))
- {
- if (!m_target->HasAura(62388))
- m_target->CastSpell(m_target, 62388, true);
- }
- else
- m_target->RemoveAura(62388);
- }
- return;
- }
- break;
- }
- case SPELLFAMILY_DRUID:
- {
- switch (spell->Id)
- {
- // Frenzied Regeneration
- case 22842:
- {
- // Converts up to 10 rage per second into health for $d. Each point of rage is converted into ${$m2/10}.1% of max health.
- // Should be manauser
- if (m_target->getPowerType()!=POWER_RAGE)
- return;
- uint32 rage = m_target->GetPower(POWER_RAGE);
- // Nothing todo
- if (rage == 0)
- return;
- int32 mod = (rage < 100) ? rage : 100;
- int32 points = m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target);
- int32 regen = m_target->GetMaxHealth() * (mod * points / 10) / 1000;
- m_target->CastCustomSpell(m_target, 22845, &regen, 0, 0, true, 0, this);
- m_target->SetPower(POWER_RAGE, rage-mod);
- return;
- }
- // Force of Nature
- case 33831:
- return;
- default:
- break;
- }
- break;
- }
- case SPELLFAMILY_ROGUE:
- {
- switch (spell->Id)
- {
- // Master of Subtlety
- case 31666:
- if (!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH))
- m_target->RemoveAurasDueToSpell(31665);
- break;
- // Killing Spree
- case 51690:
- {
- // TODO: this should use effect[1] of 51690
- std::list<Unit*> targets;
- {
- // eff_radius ==0
- float radius = GetSpellMaxRange(spell, false);
-
- CellPair p(Trinity::ComputeCellPair(caster->GetPositionX(),caster->GetPositionY()));
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
-
- Trinity::AnyUnfriendlyVisibleUnitInObjectRangeCheck u_check(caster, caster, radius);
- Trinity::UnitListSearcher<Trinity::AnyUnfriendlyVisibleUnitInObjectRangeCheck> checker(caster,targets, u_check);
-
- TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyUnfriendlyVisibleUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
- TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyUnfriendlyVisibleUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
-
- CellLock<GridReadGuard> cell_lock(cell, p);
-
- cell_lock->Visit(cell_lock, grid_object_checker, *caster->GetMap(), *caster, radius);
- cell_lock->Visit(cell_lock, world_object_checker, *caster->GetMap(), *caster, radius);
- }
-
- if(targets.empty())
- return;
-
- std::list<Unit*>::const_iterator itr = targets.begin();
- std::advance(itr, rand()%targets.size());
- Unit* target = *itr;
-
- caster->CastSpell(target, 57840, true);
- caster->CastSpell(target, 57841, true);
- return;
- }
- // Overkill
- case 58428:
- if (!m_target->HasAuraType(SPELL_AURA_MOD_STEALTH))
- m_target->RemoveAurasDueToSpell(58427);
- break;
-// default:
-// break;
- }
- break;
- }
- case SPELLFAMILY_HUNTER:
- {
- // Explosive Shot
- if (spell->SpellFamilyFlags[1] & 0x80000000)
- {
- if(caster)
- caster->CastCustomSpell(53352, SPELLVALUE_BASE_POINT0, m_amount, m_target, true, NULL, this);
- return;
- }
- switch (spell->Id)
- {
- // Feeding Frenzy Rank 1
- case 53511:
- if ( m_target->getVictim() && m_target->getVictim()->GetHealth() * 100 < m_target->getVictim()->GetMaxHealth() * 35 )
- m_target->CastSpell(m_target, 60096, true, 0, this);
- return;
- // Feeding Frenzy Rank 2
- case 53512:
- if ( m_target->getVictim() && m_target->getVictim()->GetHealth() * 100 < m_target->getVictim()->GetMaxHealth() * 35 )
- m_target->CastSpell(m_target, 60097, true, 0, this);
- return;
- default:
- break;
- }
- break;
- }
- case SPELLFAMILY_SHAMAN:
- {
- // Astral Shift
- if (spell->Id == 52179)
- {
- // Periodic need for remove visual on stun/fear/silence lost
- if (!(m_target->GetUInt32Value(UNIT_FIELD_FLAGS)&(UNIT_FLAG_STUNNED|UNIT_FLAG_FLEEING|UNIT_FLAG_SILENCED)))
- m_target->RemoveAurasDueToSpell(52179);
- return;
- }
- break;
- }
- case SPELLFAMILY_DEATHKNIGHT:
- {
- switch (spell->Id)
- {
- case 49016: //Hysteria
- uint32 damage = uint32(m_target->GetMaxHealth()*0.01f);
- m_target->DealDamage(m_target, damage, NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
- break;
- }
-
- // Death and Decay
- if (spell->SpellFamilyFlags[0] & 0x20)
- {
- if (caster)
- caster->CastCustomSpell(m_target, 52212, &m_amount, NULL, NULL, true, 0, this);
- return;
- }
- // Chains of Ice
- if (spell->SpellFamilyFlags[1] & 0x00004000)
- {
- // Get 0 effect aura
- if (AuraEffect *slow = GetParentAura()->GetPartAura(0))
- {
- slow->ApplyModifier(false, true);
- slow->SetAmount(slow->GetAmount() + GetAmount());
- if (slow->GetAmount() > 0) slow->SetAmount(0);
- slow->ApplyModifier(true, true);
- }
- return;
- }
- // Summon Gargoyle
- // Being pursuaded by Gargoyle - AI related?
- // if (spell->SpellFamilyFlags[1] & 0x00000080)
- // break;
- // Blood of the North
- // Reaping
- // Death Rune Mastery
- if (spell->SpellIconID == 3041 || spell->SpellIconID == 22 || spell->SpellIconID == 2622)
- {
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- // Aura not used - prevent removing death runes from other effects
- if (!GetAmount())
- return;
- if(((Player*)m_target)->getClass() != CLASS_DEATH_KNIGHT)
- return;
-
- // Remove death rune added on proc
- for (uint8 i = 0; i < MAX_RUNES && m_amount; ++i)
- {
- if (m_spellProto->SpellIconID == 2622)
- {
- if (((Player*)m_target)->GetCurrentRune(i) != RUNE_DEATH ||
- ((Player*)m_target)->GetBaseRune(i) == RUNE_BLOOD)
- continue;
- }
- else
- {
- if (((Player*)m_target)->GetCurrentRune(i) != RUNE_DEATH ||
- ((Player*)m_target)->GetBaseRune(i) != RUNE_BLOOD)
- continue;
- }
-
- if (!(m_amount & (1<<i)))
- continue;
-
- ((Player*)m_target)->ConvertRune(i,((Player*)m_target)->GetBaseRune(i));
- }
- m_amount = 0;
- return;
- }
- break;
- }
- default:
- break;
+ AuraApplication * aurApp = appIter->second;
+ ++appIter;
+ if (aurApp->_CanBeRemoved())
+ aurApp->GetTarget()->_UnapplyAuraEffect(aurApp, effIndex, AURA_REMOVE_BY_DEFAULT);
}
}
-void AuraEffect::HandlePreventFleeing(bool apply, bool Real, bool /*changeAmount*/)
+DynObjAura::DynObjAura(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID)
+ : Aura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID)
{
- if(!Real)
- return;
-
- Unit::AuraEffectList const& fearAuras = m_target->GetAurasByType(SPELL_AURA_MOD_FEAR);
- if( !fearAuras.empty() )
- {
- m_target->SetControlled(!apply, UNIT_STAT_FLEEING);
- /*if (apply)
- m_target->SetFeared(false, fearAuras.front()->GetCasterGUID());
- else
- m_target->SetFeared(true);*/
- }
+ GetDynobjOwner()->SetAura(this);
}
-void AuraEffect::HandleArenaPreparation(bool apply, bool Real, bool /*changeAmount*/)
+void DynObjAura::Remove(AuraRemoveMode removeMode)
{
- if(!Real)
+ if (IsRemoved())
return;
-
- if(apply)
- m_target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);
- else
- m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);
+ _Remove(removeMode);
}
-/**
- * Such auras are applied from a caster(=player) to a vehicle.
- * This has been verified using spell #49256
- */
-void AuraEffect::HandleAuraControlVehicle(bool apply, bool Real, bool /*changeAmount*/)
+void DynObjAura::UpdateTargetMapForEffect(Unit * caster, uint8 effIndex)
{
- if(!Real)
- return;
+ float radius = GetDynobjOwner()->GetRadius();
- if(!m_target->IsVehicle())
- return;
+ // fill up to date target list
+ UnitList targets;
- Unit *caster = GetParentAura()->GetUnitSource();
- if(!caster || caster == m_target)
- return;
+ Unit * dynObjOwnerCaster = GetDynobjOwner()->GetCaster();
- if (apply)
+ if(GetSpellProto()->EffectImplicitTargetB[effIndex] == TARGET_DEST_DYNOBJ_ALLY
+ || GetSpellProto()->EffectImplicitTargetB[effIndex] == TARGET_UNIT_AREA_ALLY_DST)
{
- //if(caster->GetTypeId() == TYPEID_PLAYER)
- // if(Pet *pet = ((Player*)caster)->GetPet())
- // pet->Remove(PET_SAVE_AS_CURRENT);
- caster->EnterVehicle(m_target->GetVehicleKit(), m_amount - 1);
+ Trinity::AnyFriendlyUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
+ Trinity::UnitListSearcher<Trinity::AnyFriendlyUnitInObjectRangeCheck> searcher(GetDynobjOwner(), targets, u_check);
+ GetDynobjOwner()->VisitNearbyObject(radius, searcher);
}
else
{
- if(GetId() == 53111) // Devour Humanoid
- {
- m_target->Kill(caster);
- if(caster->GetTypeId() == TYPEID_UNIT)
- ((Creature*)caster)->RemoveCorpse();
- }
-
- // some SPELL_AURA_CONTROL_VEHICLE auras have a dummy effect on the player - remove them
- caster->RemoveAurasDueToSpell(GetId());
- caster->ExitVehicle();
+ Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(GetDynobjOwner(), dynObjOwnerCaster, radius);
+ Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(GetDynobjOwner(), targets, u_check);
+ GetDynobjOwner()->VisitNearbyObject(radius, searcher);
}
-}
-void AuraEffect::HandleAuraConvertRune(bool apply, bool Real, bool changeAmount)
-{
- if(!Real && !changeAmount)
- return;
+ // mark all auras as ready to remove
+ for (ApplicationMap::iterator appIter = m_applications.begin(); appIter != m_applications.end(); appIter++)
+ if (appIter->second->HasEffect(effIndex))
+ appIter->second->_SetCanBeRemoved(true);
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- Player *plr = (Player*)m_target;
-
- if(plr->getClass() != CLASS_DEATH_KNIGHT)
- return;
-
- uint32 runes = 0;
- // convert number of runes specified in aura amount of rune type in miscvalue to runetype in miscvalueb
- for (uint32 i = 0; i < MAX_RUNES && m_amount; ++i)
+ for (UnitList::iterator appIter = targets.begin(); appIter != targets.end(); appIter++)
{
- if(apply)
+ // add an aura to units new in list
+ ApplicationMap::iterator itr = m_applications.find((*appIter)->GetGUID());
+
+ if (itr == m_applications.end())
{
- if (GetMiscValue() != plr->GetCurrentRune(i))
+ // persistent area aura does not hit flying targets
+ if ((*appIter)->isInFlight()
+ // check target immunities
+ || (*appIter)->IsImmunedToSpell(GetSpellProto())
+ || (*appIter)->hasUnitState(UNIT_STAT_ISOLATED))
continue;
- if(!plr->GetRuneCooldown(i))
- {
- plr->ConvertRune(i, RuneType(GetSpellProto()->EffectMiscValueB[m_effIndex]));
- runes |= 1<<i;
- --m_amount;
- }
}
- else
- {
- if(plr->GetCurrentRune(i) == RuneType(GetSpellProto()->EffectMiscValueB[m_effIndex]))
- {
- if (m_amount & (1<<i))
- plr->ConvertRune(i, plr->GetBaseRune(i));
- }
- }
- }
- if (apply)
- m_amount = runes;
-}
-
-// Control Auras
-void AuraEffect::HandleAuraModStun(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(!Real)
- return;
-
- m_target->SetControlled(apply, UNIT_STAT_STUNNED);
-}
-
-void AuraEffect::HandleAuraModRoot(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(!Real)
- return;
-
- m_target->SetControlled(apply, UNIT_STAT_ROOT);
-}
-
-// Charm Auras
-
-void AuraEffect::HandleModPossess(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(!Real)
- return;
-
- Unit* caster = GetCaster();
- if(caster && caster->GetTypeId() == TYPEID_UNIT)
- {
- HandleModCharm(apply, Real, false);
- return;
- }
-
- if(apply)
- m_target->SetCharmedBy(caster, CHARM_TYPE_POSSESS);
- else
- m_target->RemoveCharmedBy(caster);
-}
-
-// only one spell has this aura
-void AuraEffect::HandleModPossessPet(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(!Real)
- return;
-
- Unit* caster = GetCaster();
- if(!caster || caster->GetTypeId() != TYPEID_PLAYER)
- return;
-
- //seems it may happen that when removing it is no longer owner's pet
- //if(((Player*)caster)->GetPet() != m_target)
- // return;
-
- if(apply)
- {
- if(((Player*)caster)->GetPet() != m_target)
- return;
-
- m_target->SetCharmedBy(caster, CHARM_TYPE_POSSESS);
- }
- else
- {
- m_target->RemoveCharmedBy(caster);
-
- // Reinitialize the pet bar and make the pet come back to the owner
- ((Player*)caster)->PetSpellInitialize();
- if(!m_target->getVictim())
+ if (itr == m_applications.end() || !itr->second->HasEffect(effIndex))
{
- m_target->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, m_target->GetFollowAngle());
- //if(m_target->GetCharmInfo())
- // m_target->GetCharmInfo()->SetCommandState(COMMAND_FOLLOW);
- }
- }
-}
-
-void AuraEffect::HandleModCharm(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(!Real)
- return;
-
- Unit* caster = GetCaster();
-
- if(apply)
- m_target->SetCharmedBy(caster, CHARM_TYPE_CHARM);
- else
- m_target->RemoveCharmedBy(caster);
-}
-
-void AuraEffect::HandleCharmConvert(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(!Real)
- return;
-
- Unit* caster = GetCaster();
-
- if(apply)
- m_target->SetCharmedBy(caster, CHARM_TYPE_CONVERT);
- else
- m_target->RemoveCharmedBy(caster);
-}
-
-void AuraEffect::HandlePhase(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(!Real)
- return;
-
- // no-phase is also phase state so same code for apply and remove
-
- // phase auras normally not expected at BG but anyway better check
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- {
- // drop flag at invisible in bg
- if(((Player*)m_target)->InBattleGround())
- if(BattleGround *bg = ((Player*)m_target)->GetBattleGround())
- bg->EventPlayerDroppedFlag((Player*)m_target);
-
- // GM-mode have mask 0xFFFFFFFF
- if(!((Player*)m_target)->isGameMaster())
- m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL,false);
-
- ((Player*)m_target)->GetSession()->SendSetPhaseShift(apply ? GetMiscValue() : PHASEMASK_NORMAL);
- }
- else
- m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL,false);
-
- // need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)
- if(m_target->GetVisibility()!=VISIBILITY_OFF)
- m_target->SetVisibility(m_target->GetVisibility());
-}
+ if((*appIter)->IsImmunedToSpellEffect(GetSpellProto(), effIndex))
+ continue;
+ // add new unit to persistent area aura
+ (*appIter)->_ApplyAuraEffect(this, effIndex);
-void AuraEffect::HandleAuraInitializeImages( bool Apply, bool Real , bool /*changeAmount*/)
-{
- if (!Real)
- return;
- if (Apply)
- {
- Unit * caster = GetCaster();
- if (!caster)
- return;
- // Set item visual
- if (caster->GetTypeId()== TYPEID_PLAYER)
- {
- if (Item const * item = ((Player *)caster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
- m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, item->GetProto()->ItemId);
- if (Item const * item = ((Player *)caster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
- m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, item->GetProto()->ItemId);
- }
- else // TYPEID_UNIT
- {
- m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID));
- m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1));
- m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2));
+ // start combat with targeted enemy
+ if(GetSpellProto()->EffectImplicitTargetB[effIndex] != TARGET_DEST_DYNOBJ_ALLY
+ && GetSpellProto()->EffectImplicitTargetB[effIndex] != TARGET_UNIT_AREA_ALLY_DST)
+ dynObjOwnerCaster->CombatStart(*appIter);
}
- }
- else
- {
- // Remove equipment visual
- if (m_target->GetTypeId() == TYPEID_PLAYER)
- {
- for (uint8 i = 0; i < 3; ++i)
- m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, 0);
- }
- else // TYPEID_UNIT
- {
- ((Creature*)m_target)->LoadEquipment(((Creature*)m_target)->GetEquipmentId());
- }
- }
-}
-
-void AuraEffect::HandleAuraCloneCaster( bool Apply, bool Real , bool /*changeAmount*/)
-{
- if (!Real)
- return;
- if (Apply)
- {
- Unit * caster = GetCaster();
- if (!caster)
- return;
- // Set display id (probably for portrait?)
- m_target->SetDisplayId(caster->GetDisplayId());
- m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_MIRROR_IMAGE);
+ itr = m_applications.find((*appIter)->GetGUID());
+ if (itr != m_applications.end())
+ // mark aura of unit already in list to be not removed
+ itr->second->_SetCanBeRemoved(false);
}
- else
- {
- m_target->SetDisplayId(m_target->GetNativeDisplayId());
- m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_MIRROR_IMAGE);
- }
-}
-void AuraEffect::HandleAuraModCritPct(bool apply, bool Real, bool changeAmount)
-{
- /*
- if(m_target->GetTypeId() != TYPEID_PLAYER)
+ // remove auras which are not in current area
+ for (ApplicationMap::iterator appIter = m_applications.begin(); appIter != m_applications.end();)
{
- m_target->m_baseSpellCritChance += apply ? m_amount:-m_amount;
- return;
+ AuraApplication * aurApp = appIter->second;
+ ++appIter;
+ if (aurApp->_CanBeRemoved())
+ aurApp->GetTarget()->_UnapplyAuraEffect(aurApp, effIndex, AURA_REMOVE_BY_DEFAULT);
}
-
- if(Real || changeAmount)
- ((Player*)m_target)->UpdateAllSpellCritChances();
-
- ((Player*)m_target)->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (m_amount), apply);
- ((Player*)m_target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (m_amount), apply);
- ((Player*)m_target)->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (m_amount), apply);
- */
- // spells required only Real aura add/remove
- if(!Real)
- return;
-
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- ((Player*)m_target)->HandleBaseModValue(CRIT_PERCENTAGE, FLAT_MOD, float (m_amount), apply);
- ((Player*)m_target)->HandleBaseModValue(OFFHAND_CRIT_PERCENTAGE, FLAT_MOD, float (m_amount), apply);
- ((Player*)m_target)->HandleBaseModValue(RANGED_CRIT_PERCENTAGE, FLAT_MOD, float (m_amount), apply);
-
- // included in Player::UpdateSpellCritChance calculation
- ((Player*)m_target)->UpdateAllSpellCritChances();
-}
-
-void AuraEffect::HandleAuraLinked(bool apply, bool Real, bool /*changeAmount*/)
-{
- if (!Real)
- return;
-
- if (apply)
- {
- Unit * caster = GetCaster();
- if (!caster)
- return;
- // If amount avalible cast with basepoints (Crypt Fever for example)
- if (m_amount)
- caster->CastCustomSpell(m_target, m_spellProto->EffectTriggerSpell[m_effIndex], &m_amount, NULL, NULL, true, NULL, this);
- else
- caster->CastSpell(m_target, m_spellProto->EffectTriggerSpell[m_effIndex],true, NULL, this);
- }
- else
- m_target->RemoveAura(m_spellProto->EffectTriggerSpell[m_effIndex], GetCasterGUID(), AuraRemoveMode(GetParentAura()->GetRemoveMode()));
-}
-
-int32 AuraEffect::CalculateCrowdControlAuraAmount(Unit * caster)
-{
- // Damage cap for CC effects
- if (!m_spellProto->procFlags)
- return 0;
-
- if (m_auraName !=SPELL_AURA_MOD_CONFUSE &&
- m_auraName !=SPELL_AURA_MOD_FEAR &&
- m_auraName !=SPELL_AURA_MOD_STUN &&
- m_auraName !=SPELL_AURA_MOD_ROOT &&
- m_auraName !=SPELL_AURA_TRANSFORM)
- return 0;
-
- int32 damageCap = (int32)(m_target->GetMaxHealth()*0.10f);
-
- if (!caster)
- return damageCap;
-
- // Glyphs increasing damage cap
- Unit::AuraEffectList const& overrideClassScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
- for (Unit::AuraEffectList::const_iterator itr = overrideClassScripts.begin(); itr != overrideClassScripts.end(); ++itr)
- {
- if((*itr)->isAffectedOnSpell(m_spellProto))
- {
- // Glyph of Fear, Glyph of Frost nova and similar auras
- if ((*itr)->GetMiscValue() == 7801)
- {
- damageCap += (int32)(damageCap*(*itr)->GetAmount()/100.0f);
- break;
- }
- }
- }
- return damageCap;
-}
-
-bool AuraEffect::IsPeriodicTickCrit(Unit const * pCaster) const
-{
- Unit::AuraEffectList const& mPeriodicCritAuras= pCaster->GetAurasByType(SPELL_AURA_ABILITY_PERIODIC_CRIT);
- for (Unit::AuraEffectList::const_iterator itr = mPeriodicCritAuras.begin(); itr != mPeriodicCritAuras.end(); ++itr)
- {
- if ((*itr)->isAffectedOnSpell(m_spellProto) && pCaster->isSpellCrit(m_target, m_spellProto, GetSpellSchoolMask(m_spellProto)))
- return true;
- }
- return false;
-}
-
-void AuraEffect::HandleAuraModInebriation(bool apply, bool Real, bool /*changeAmount*/)
-{
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
-
- m_target->SetUInt32Value(PLAYER_FAKE_INEBRIATION, apply ? ((uint32)1)<<(GetMiscValue()-1) : 0 );
}
diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h
index 83576d6be34..0d855fd0647 100644
--- a/src/game/SpellAuras.h
+++ b/src/game/SpellAuras.h
@@ -17,419 +17,207 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
#ifndef TRINITY_SPELLAURAS_H
#define TRINITY_SPELLAURAS_H
#include "SpellAuraDefines.h"
-class Unit;
+class Unit;
struct SpellEntry;
struct SpellModifier;
struct ProcTriggerSpell;
// forward decl
-class Aura;
class AuraEffect;
+class Aura;
+class DynamicObject;
+
+class AuraApplication
+{
+ friend AuraApplication * Unit::__ApplyAura(Aura * aura);
+ friend void Unit::__UnapplyAura(AuraApplicationMap::iterator &i);
+ friend bool Unit::_ApplyAuraEffect(Aura * aura, uint8 effIndex);
+ private:
+ Unit * const m_target;
+ Aura * const m_base;
+ uint8 m_slot; // Aura slot on unit
+ uint8 m_flags; // Aura info flag
+ AuraRemoveMode m_removeMode:8; // Store info for know remove aura reason
+ bool m_needClientUpdate:1;
+ bool m_isNeedManyNegativeEffects:1;
+ bool m_canBeRemoved:1; // used only in aura list update of AuraBase
+
+ explicit AuraApplication(Unit * target, Unit * caster, Aura * base);
+ void _Remove();
+ private:
+ bool _CheckPositive(Unit * caster) const;
+ void _HandleEffect(uint8 effIndex, bool apply);
+ public:
+ bool _CanBeRemoved() const {return m_canBeRemoved;}
+ void _SetCanBeRemoved(bool val) {m_canBeRemoved = val;}
-typedef void(AuraEffect::*pAuraHandler)(bool Apply, bool Real, bool changeAmount);
-// Real == true at aura add/remove
-// Real == false at aura mod unapply/reapply; when adding/removing dependent aura/item/stat mods
-//
-// Code in aura handler can be guarded by if(Real) check if it should execution only at real add/remove of aura
-//
-// MAIN RULE: Code MUST NOT be guarded by if(Real) check if it modifies any stats
-// (percent auras, stats mods, etc)
-// Second rule: Code must be guarded by if(Real) check if it modifies object state (start/stop attack, send packets to client, etc)
-//
-// Other case choice: each code line moved under if(Real) check is Trinity speedup,
-// each setting object update field code line moved under if(Real) check is significant Trinity speedup, and less server->client data sends
-// each packet sending code moved under if(Real) check is _large_ Trinity speedup, and lot less server->client data sends
-//
-// changeAmount == true at changing existing aura amount - called wit real == false
-// if aura has amount dependant effect handler has to allow proceeding it
-// example: change speed aura, modifier aura
+ Unit * GetTarget() const { return m_target; }
+ Aura * GetBase() const { return m_base; }
+
+ uint8 GetSlot() const { return m_slot; }
+ uint8 GetFlags() const { return m_flags; }
+ uint8 GetEffectMask() const { return m_flags & (AFLAG_EFF_INDEX_0 | AFLAG_EFF_INDEX_1 | AFLAG_EFF_INDEX_2); }
+ bool HasEffect(uint8 effect) const { assert(effect < MAX_SPELL_EFFECTS); return m_flags & (1<<effect); }
+ bool IsPositive() const { return m_flags & AFLAG_POSITIVE; }
+
+ void SetRemoveMode(AuraRemoveMode mode) { m_removeMode = mode; }
+ AuraRemoveMode GetRemoveMode() const {return m_removeMode;}
+
+ void SetNeedClientUpdate() { m_needClientUpdate = true;}
+ bool IsNeedClientUpdate() const { return m_needClientUpdate;}
+ void ClientUpdate(bool remove = false);
+};
class TRINITY_DLL_SPEC Aura
{
- friend void Player::SendAurasForTarget(Unit *target);
public:
- virtual ~Aura();
- explicit Aura(SpellEntry const* spellproto, uint32 effMask, Unit *target, WorldObject *source, Unit *caster, int32 *currentBasePoints = NULL, Item *castItem = NULL);
+ typedef UNORDERED_MAP<uint64, AuraApplication *> ApplicationMap;
+
+ static Aura * TryCreate(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount = NULL, Item * castItem = NULL, uint64 casterGUID = 0);
+ static Aura * TryCreate(SpellEntry const* spellproto, WorldObject * owner, Unit * caster, int32 *baseAmount = NULL, Item * castItem = NULL, uint64 casterGUID = 0);
+ static Aura * Create(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount = NULL, Item * castItem = NULL, uint64 casterGUID = 0);
+ explicit Aura(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID);
+ ~Aura();
SpellEntry const* GetSpellProto() const { return m_spellProto; }
- uint32 GetId() const{ return m_spellProto->Id; }
- uint64 GetCastItemGUID() const { return m_castItemGuid; }
+ uint32 GetId() const{ return GetSpellProto()->Id; }
+ uint64 GetCastItemGUID() const { return m_castItemGuid; }
uint64 const& GetCasterGUID() const { return m_casterGuid; }
Unit* GetCaster() const;
- uint64 const& GetSourceGUID() const { return m_sourceGuid; }
- Unit *GetUnitSource() const;
- Unit* GetTarget() const { return m_target; }
- time_t GetAuraApplyTime() const { return m_applyTime; }
-
- int32 GetAuraMaxDuration() const { return m_maxduration; }
- void SetAuraMaxDuration(int32 duration) { m_maxduration = duration; }
- int32 GetAuraDuration() const { return m_duration; }
- void SetAuraDuration(int32 duration, bool withMods = false);
- void RefreshAura() { SetAuraDuration(m_maxduration);}
- bool IsExpired() const { return !GetAuraDuration() && !(IsPermanent() || IsPassive()); }
-
- void SendAuraUpdate();
- uint8 GetAuraSlot() const { return m_auraSlot; }
- void SetAuraSlot(uint8 slot) { m_auraSlot = slot; }
- uint8 GetAuraCharges() const { return m_procCharges; }
- void SetAuraCharges(uint8 charges);
- bool DropAuraCharge();
- void SetProcDamage(uint32 val) { m_procDamage = val; }
- uint32 GetProcDamage() const { return m_procDamage; }
+ WorldObject * GetOwner() const { return m_owner; }
+ Unit * GetUnitOwner() const { assert(GetType() == UNIT_AURA_TYPE); return (Unit*)m_owner; }
+ DynamicObject * GetDynobjOwner() const { assert(GetType() == DYNOBJ_AURA_TYPE); return (DynamicObject*)m_owner; }
- uint8 GetStackAmount() const { return m_stackAmount; }
- void SetStackAmount(uint8 num, bool applied = true);
- bool modStackAmount(int32 num); // return true if last charge dropped
+ AuraObjectType GetType() const;
- void SetRemoveMode(AuraRemoveMode mode) { m_removeMode = mode; }
- uint8 GetRemoveMode() const {return m_removeMode;}
+ virtual void _ApplyForTarget(Unit * target, Unit * caster, AuraApplication * auraApp);
+ virtual void _UnapplyForTarget(Unit * target, Unit * caster, AuraApplication * auraApp);
+ void _Remove(AuraRemoveMode removeMode);
+ virtual void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT) = 0;
- inline uint8 GetEffectMask() const {return m_auraFlags & 7;}
- AuraEffect * GetPartAura (uint8 effIndex) const {assert (effIndex < MAX_SPELL_EFFECTS); return m_partAuras[effIndex];}
- bool SetPartAura(AuraEffect* aurEff, uint8 effIndex);
+ virtual void UpdateTargetMapForEffect(Unit * caster, uint8 effIndex) = 0;
+ void UpdateTargetMap(Unit * caster);
- bool IsPositive() const { return m_positive; }
- void SetNegative() { m_positive = false; }
- void SetPositive() { m_positive = true; }
- bool IsPermanent() const { return m_permanent; }
- void SetPermanent(bool val) { m_permanent = val; }
+ void ApplyForTargets() {Unit * caster = GetCaster(); UpdateTargetMap(caster);}
+ void ApplyEffectForTargets(uint8 effIndex) {Unit * caster = GetCaster(); UpdateTargetMapForEffect(caster, effIndex);}
- bool IsPassive() const { return m_isPassive; }
- bool IsDeathPersistent() const { return m_isDeathPersist; }
- bool IsRemovedOnShapeLost() const { return m_isRemovedOnShapeLost; }
- bool CanBeSaved() const;
- bool IsRemoved() const { return m_isRemoved; }
+ void UpdateOwner(uint32 diff, WorldObject * owner);
+ void Update(uint32 diff, Unit * caster);
- bool IsPersistent() const;
- bool IsAreaAura() const;
- bool IsAuraType(AuraType type) const;
- void SetLoadedState(uint64 caster_guid,int32 maxduration,int32 duration,int32 charges, uint8 stackamount, int32 * amount);
- bool HasEffect(uint8 effIndex) const {return bool (m_partAuras[effIndex]);}
- inline void HandleEffects(bool apply)
- {
- for (uint8 i = 0; i<MAX_SPELL_EFFECTS; ++i)
- if (m_partAuras[i])
- m_target->HandleAuraEffect(m_partAuras[i], apply);
- }
- void ApplyAllModifiers(bool apply, bool Real=false);
- void HandleAuraSpecificMods(bool apply);
-
- void Update(uint32 diff);
-
- void _AddAura();
- void _RemoveAura();
+ time_t GetApplyTime() const { return m_applyTime; }
+ int32 GetMaxDuration() const { return m_maxDuration; }
+ void SetMaxDuration(int32 duration) { m_maxDuration = duration; }
+ int32 GetDuration() const { return m_duration; }
+ void SetDuration(int32 duration, bool withMods = false);
+ void RefreshDuration();
+ bool IsExpired() const { return !GetDuration();}
+ bool IsPermanent() const { return GetMaxDuration() == -1; }
- // Allow Apply Aura Handler to modify and access m_AuraDRGroup
- void setDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; }
- DiminishingGroup getDiminishGroup() const { return m_AuraDRGroup; }
+ uint8 GetCharges() const { return m_procCharges; }
+ void SetCharges(uint8 charges);
+ bool DropCharge();
- // Single cast aura helpers
- void UnregisterSingleCastAura();
- bool IsSingleTarget() const {return m_isSingleTargetAura;}
- void SetIsSingleTarget(bool val) { m_isSingleTargetAura = val;}
+ uint8 GetStackAmount() const { return m_stackAmount; }
+ void SetStackAmount(uint8 num, bool applied = true);
+ bool ModStackAmount(int32 num); // return true if last charge dropped
+
+ uint8 GetCasterLevel() const { return m_casterLevel; }
+ bool IsPassive() const;
+ bool IsDeathPersistent() const;
+ bool IsRemovedOnShapeLost(Unit * target) const { return (GetCasterGUID() == target->GetGUID() && m_spellProto->Stances && !(m_spellProto->AttributesEx2 & SPELL_ATTR_EX2_NOT_NEED_SHAPESHIFT) && !(m_spellProto->Attributes & SPELL_ATTR_NOT_SHAPESHIFT)); }
+ bool CanBeSaved() const;
+ bool IsRemoved() const { return m_isRemoved; }
+ bool IsVisible() const;
+ // Single cast aura helpers
+ bool IsSingleTarget() const {return m_isSingleTarget;}
+ void SetIsSingleTarget(bool val) { m_isSingleTarget = val;}
+
+ void SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint8 stackamount, uint8 recalculateMask, int32 * amount);
+
+ // helpers for aura effects
+ bool HasEffect(uint8 effIndex) const { return bool(GetEffect(effIndex)); }
+ bool HasEffectType(AuraType type) const;
+ AuraEffect * GetEffect (uint8 effIndex) const { assert (effIndex < MAX_SPELL_EFFECTS); return m_effects[effIndex]; }
+ uint8 GetEffectMask() const { uint8 effMask = 0; for(uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (m_effects[i]) effMask |= 1<<i; return effMask; }
+ void RecalculateAmountOfEffects();
+ void HandleAllEffects(AuraApplication const * aurApp, uint8 mode, bool apply);
+
+ // Helpers for targets
+ ApplicationMap const & GetApplicationMap() {return m_applications;}
+ const AuraApplication * GetApplicationOfTarget (uint64 const & guid) const { ApplicationMap::const_iterator itr = m_applications.find(guid); if (itr != m_applications.end()) return itr->second; return NULL; }
+ AuraApplication * GetApplicationOfTarget (uint64 const & guid) { ApplicationMap::iterator itr = m_applications.find(guid); if (itr != m_applications.end()) return itr->second; return NULL; }
+ bool IsAppliedOnTarget (uint64 const & guid) const { return m_applications.find(guid) != m_applications.end(); }
+
+ bool IsPositive(Unit * const target) const { return (GetApplicationOfTarget(target->GetGUID()))->IsPositive(); }
+ bool GetEffectMask(Unit * const target) const { return (GetApplicationOfTarget(target->GetGUID()))->GetEffectMask(); }
+ uint8 GetSlot(Unit * const target) const { return (GetApplicationOfTarget(target->GetGUID()))->GetSlot(); }
+ bool HasEffect(Unit * const target, uint8 eff) const { return (GetApplicationOfTarget(target->GetGUID()))->HasEffect(eff); }
+ void SetNeedClientUpdateForTargets() const;
+ void HandleAuraSpecificMods(AuraApplication const * aurApp, Unit * caster, bool apply);
private:
- const SpellEntry * const m_spellProto;
- Unit * const m_target;
- //WorldObject * const m_source;
- const uint64 m_sourceGuid;
- const uint64 m_casterGuid;
- const uint64 m_castItemGuid; // it is NOT safe to keep a pointer to the item because it may get deleted
- const time_t m_applyTime;
-
- int32 m_maxduration; // Max aura duration
+ void _DeleteRemovedApplications();
+ protected:
+ SpellEntry const * const m_spellProto;
+ uint64 const m_casterGuid;
+ uint64 const m_castItemGuid; // it is NOT safe to keep a pointer to the item because it may get deleted
+ time_t const m_applyTime;
+ WorldObject * const m_owner; //
+
+ int32 m_maxDuration; // Max aura duration
int32 m_duration; // Current time
int32 m_timeCla; // Timer for power per sec calcultion
- AuraRemoveMode m_removeMode:8; // Store info for know remove aura reason
- DiminishingGroup m_AuraDRGroup:8; // Diminishing
-
- uint8 m_auraSlot; // Aura slot on unit (for show in client)
- uint8 m_auraFlags; // Aura info flag (for send data to client)
- uint8 m_auraLevel; // Aura level (store caster level for correct show level dep amount)
+ uint8 const m_casterLevel; // Aura level (store caster level for correct show level dep amount)
uint8 m_procCharges; // Aura charges (0 for infinite)
uint8 m_stackAmount; // Aura stack amount
- AuraEffect * m_partAuras[3];
- uint32 m_procDamage; // used in aura proc code
+ AuraEffect * m_effects[3];
+ ApplicationMap m_applications;
- bool m_isDeathPersist:1;
- bool m_isRemovedOnShapeLost:1;
- bool m_isPassive:1;
- bool m_positive:1;
- bool m_permanent:1;
bool m_isRemoved:1;
- bool m_isSingleTargetAura:1; // true if it's a single target spell and registered at caster - can change at spell steal for example
+ bool m_isSingleTarget:1; // true if it's a single target spell and registered at caster - can change at spell steal for example
- bool IsVisible() const;
+ private:
+ Unit::AuraApplicationList m_removedApplications;
};
-class TRINITY_DLL_SPEC AuraEffect
+class TRINITY_DLL_SPEC UnitAura : public Aura
{
- public:
- friend AuraEffect* CreateAuraEffect(Aura * parentAura, uint32 effIndex, int32 *currentBasePoints);
- friend void Aura::SetStackAmount(uint8 stackAmount, bool applied);
- //aura handlers
- void HandleNULL(bool, bool, bool)
- {
- // NOT IMPLEMENTED
- }
- void HandleUnused(bool, bool, bool)
- {
- // NOT USED BY ANY SPELL OR USELESS
- }
- void HandleNoImmediateEffect(bool, bool, bool)
- {
- // aura not have immediate effect at add/remove and handled by ID in other code place
- }
- void HandleBindSight(bool Apply, bool Real, bool changeAmount);
- void HandleModPossess(bool Apply, bool Real, bool changeAmount);
- void HandlePeriodicDamage(bool Apply, bool Real, bool changeAmount);
- void HandleAuraDummy(bool Apply, bool Real, bool changeAmount);
- void HandleAuraPeriodicDummy(bool apply, bool Real, bool changeAmount);
- void HandleModConfuse(bool Apply, bool Real, bool changeAmount);
- void HandleModCharm(bool Apply, bool Real, bool changeAmount);
- void HandleModFear(bool Apply, bool Real, bool changeAmount);
- void HandlePeriodicHeal(bool Apply, bool Real, bool changeAmount);
- void HandleModAttackSpeed(bool Apply, bool Real, bool changeAmount);
- void HandleModMeleeRangedSpeedPct(bool apply, bool Real, bool changeAmount);
- void HandleModCombatSpeedPct(bool apply, bool Real, bool changeAmount);
- void HandleModThreat(bool Apply, bool Real, bool changeAmount);
- void HandleModTaunt(bool Apply, bool Real, bool changeAmount);
- void HandleFeignDeath(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModDisarm(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModStalked(bool Apply, bool Real, bool changeAmount);
- void HandleAuraWaterWalk(bool Apply, bool Real, bool changeAmount);
- void HandleAuraFeatherFall(bool Apply, bool Real, bool changeAmount);
- void HandleAuraHover(bool Apply, bool Real, bool changeAmount);
- void HandleAddModifier(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModStun(bool Apply, bool Real, bool changeAmount);
- void HandleModDamageDone(bool Apply, bool Real, bool changeAmount);
- void HandleAuraUntrackable(bool Apply, bool Real, bool changeAmount);
- void HandleAuraEmpathy(bool Apply, bool Real, bool changeAmount);
- void HandleModOffhandDamagePercent(bool apply, bool Real, bool changeAmount);
- void HandleAuraModRangedAttackPower(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModIncreaseEnergyPercent(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModIncreaseHealthPercent(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModRegenInterrupt(bool Apply, bool Real, bool changeAmount);
- void HandleHaste(bool Apply, bool Real, bool changeAmount);
- void HandlePeriodicTriggerSpell(bool Apply, bool Real, bool changeAmount);
- void HandlePeriodicTriggerSpellWithValue(bool apply, bool Real, bool changeAmount);
- void HandlePeriodicEnergize(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModResistanceExclusive(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModPetTalentsPoints(bool Apply, bool Real, bool changeAmount);
- void HandleModStealth(bool Apply, bool Real, bool changeAmount);
- void HandleInvisibility(bool Apply, bool Real, bool changeAmount);
- void HandleInvisibilityDetect(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModTotalHealthPercentRegen(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModTotalEnergyPercentRegen(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModResistance(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModRoot(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModSilence(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModStat(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModIncreaseSpeed(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModIncreaseMountedSpeed(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModIncreaseFlightSpeed(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModDecreaseSpeed(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModUseNormalSpeed(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModIncreaseHealth(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModIncreaseEnergy(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModShapeshift(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModEffectImmunity(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModStateImmunity(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModSchoolImmunity(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModDmgImmunity(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModDispelImmunity(bool Apply, bool Real, bool changeAmount);
- void HandleAuraProcTriggerSpell(bool Apply, bool Real, bool changeAmount);
- void HandleAuraTrackCreatures(bool Apply, bool Real, bool changeAmount);
- void HandleAuraTrackResources(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModParryPercent(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModDodgePercent(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModBlockPercent(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModWeaponCritPercent(bool Apply, bool Real, bool changeAmount);
- void HandlePeriodicLeech(bool Apply, bool Real, bool changeAmount);
- void HandleModHitChance(bool Apply, bool Real, bool changeAmount);
- void HandleModSpellHitChance(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModScale(bool Apply, bool Real, bool changeAmount);
- void HandlePeriodicManaLeech(bool Apply, bool Real, bool changeAmount);
- void HandlePeriodicHealthFunnel(bool apply, bool Real, bool changeAmount);
- void HandleModCastingSpeed(bool Apply, bool Real, bool changeAmount);
- void HandleAuraMounted(bool Apply, bool Real, bool changeAmount);
- void HandleWaterBreathing(bool Apply, bool Real, bool changeAmount);
- void HandleModBaseResistance(bool Apply, bool Real, bool changeAmount);
- void HandleModRegen(bool Apply, bool Real, bool changeAmount);
- void HandleModPowerRegen(bool Apply, bool Real, bool changeAmount);
- void HandleModPowerRegenPCT(bool Apply, bool Real, bool changeAmount);
- void HandleChannelDeathItem(bool Apply, bool Real, bool changeAmount);
- void HandlePeriodicDamagePCT(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModAttackPower(bool Apply, bool Real, bool changeAmount);
- void HandleAuraTransform(bool Apply, bool Real, bool changeAmount);
- void HandleModSpellCritChance(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModIncreaseSwimSpeed(bool Apply, bool Real, bool changeAmount);
- void HandleModPowerCostPCT(bool Apply, bool Real, bool changeAmount);
- void HandleModPowerCost(bool Apply, bool Real, bool changeAmount);
- void HandleFarSight(bool Apply, bool Real, bool changeAmount);
- void HandleModPossessPet(bool Apply, bool Real, bool changeAmount);
- void HandleModMechanicImmunity(bool Apply, bool Real, bool changeAmount);
- void HandleModStateImmunityMask(bool apply, bool Real, bool changeAmount);
- void HandleAuraModSkill(bool Apply, bool Real, bool changeAmount);
- void HandleModDamagePercentDone(bool Apply, bool Real, bool changeAmount);
- void HandleModPercentStat(bool Apply, bool Real, bool changeAmount);
- void HandleModResistancePercent(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModBaseResistancePCT(bool Apply, bool Real, bool changeAmount);
- void HandleModShieldBlockPCT(bool Apply, bool Real, bool changeAmount);
- void HandleAuraTrackStealthed(bool Apply, bool Real, bool changeAmount);
- void HandleModShieldBlock(bool Apply, bool Real, bool changeAmount);
- void HandleForceReaction(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModRangedHaste(bool Apply, bool Real, bool changeAmount);
- void HandleRangedAmmoHaste(bool Apply, bool Real, bool changeAmount);
- void HandleModHealingDone(bool Apply, bool Real, bool changeAmount);
- void HandleModTotalPercentStat(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModTotalThreat(bool Apply, bool Real, bool changeAmount);
- void HandleModUnattackable(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModPacify(bool Apply, bool Real, bool changeAmount);
- void HandleAuraGhost(bool Apply, bool Real, bool changeAmount);
- void HandleAuraAllowFlight(bool Apply, bool Real, bool changeAmount);
- void HandleModRating(bool apply, bool Real, bool changeAmount);
- void HandleModRatingFromStat(bool apply, bool Real, bool changeAmount);
- void HandleModTargetResistance(bool apply, bool Real, bool changeAmount);
- void HandleAuraModAttackPowerPercent(bool apply, bool Real, bool changeAmount);
- void HandleAuraModRangedAttackPowerPercent(bool apply, bool Real, bool changeAmount);
- void HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real, bool changeAmount);
- void HandleAuraModAttackPowerOfArmor(bool apply, bool Real, bool changeAmount);
- void HandleAuraModAttackPowerOfStatPercent(bool apply, bool Real, bool changeAmount);
- void HandleSpiritOfRedemption(bool apply, bool Real, bool changeAmount);
- void HandleModManaRegen(bool apply, bool Real, bool changeAmount);
- void HandleComprehendLanguage(bool apply, bool Real, bool changeAmount);
- void HandleShieldBlockValue(bool apply, bool Real, bool changeAmount);
- void HandleModSpellCritChanceShool(bool apply, bool Real, bool changeAmount);
- void HandleAuraRetainComboPoints(bool apply, bool Real, bool changeAmount);
- void HandleModSpellDamagePercentFromStat(bool apply, bool Real, bool changeAmount);
- void HandleModSpellHealingPercentFromStat(bool apply, bool Real, bool changeAmount);
- void HandleAuraControlVehicle(bool apply, bool Real, bool changeAmount);
- void HandleModSpellDamagePercentFromAttackPower(bool apply, bool Real, bool changeAmount);
- void HandleModSpellHealingPercentFromAttackPower(bool apply, bool Real, bool changeAmount);
- void HandleAuraModPacifyAndSilence(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModIncreaseMaxHealth(bool apply, bool Real, bool changeAmount);
- void HandleAuraModExpertise(bool apply, bool Real, bool changeAmount);
- void HandleForceMoveForward(bool apply, bool Real, bool changeAmount);
- void HandleAuraModResistenceOfStatPercent(bool apply, bool Real, bool changeAmount);
- void HandleAuraPowerBurn(bool apply, bool Real, bool changeAmount);
- void HandlePreventFleeing(bool apply, bool Real, bool changeAmount);
- void HandleArenaPreparation(bool apply, bool Real, bool changeAmount);
- void HandleAuraConvertRune(bool apply, bool Real, bool changeAmount);
- void HandleAuraIncreaseBaseHealthPercent(bool Apply, bool Real, bool changeAmount);
- void HandleNoReagentUseAura(bool Apply, bool Real, bool changeAmount);
- void HandlePhase(bool Apply, bool Real, bool changeAmount);
- void HandleAuraAllowOnlyAbility(bool apply, bool Real, bool changeAmount);
- void HandleCharmConvert(bool apply, bool Real, bool changeAmount);
- void HandleAuraInitializeImages(bool Apply, bool Real, bool changeAmount);
- void HandleAuraCloneCaster(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModCritPct(bool Apply, bool Real, bool changeAmount);
- void HandleAuraLinked(bool Apply, bool Real, bool changeAmount);
- void HandleAuraModInebriation(bool apply, bool Real, bool changeAmount);
-
- void HandleAuraEffectSpecificMods(bool apply, bool Real, bool changeAmount);
- int32 CalculateCrowdControlAuraAmount(Unit * caster);
-
- // add/remove SPELL_AURA_MOD_SHAPESHIFT (36) linked auras
- void HandleShapeshiftBoosts(bool apply);
-
- Unit * GetCaster() const { return m_parentAura->GetCaster(); }
- uint64 GetCasterGUID() const{ return m_parentAura->GetCasterGUID(); }
- Aura * GetParentAura() const { return m_parentAura; }
-
- SpellEntry const* GetSpellProto() const { return m_spellProto; }
- uint32 GetId() const { return m_spellProto->Id; }
- uint32 GetEffIndex() const { return m_effIndex; }
- int32 GetBasePoints() const { return m_currentBasePoints; }
- int32 GetAuraAmplitude(){return m_amplitude;}
- void ResetPeriodicTimer(){m_periodicTimer = m_amplitude;}
-
- virtual void Update(uint32 diff);
-
- uint32 GetTickNumber() const { return m_tickNumber; }
- int32 GetTotalTicks () const { return m_amplitude ? (GetParentAura()->GetAuraMaxDuration() / m_amplitude) : 1;}
- bool IsAreaAura() const { return m_isAreaAura; }
- bool IsPeriodic() const { return m_isPeriodic; }
- bool IsPersistent() const { return m_isPersistent; }
- bool IsApplied() const { return m_isApplied; }
- void SetApplied (bool val) {m_isApplied = val; }
- bool isAffectedOnSpell(SpellEntry const *spell) const;
-
- void ApplyModifier(bool apply, bool Real = false, bool changeAmount=false);
- void RecalculateAmount(bool applied = true);
- void HandleAuraEffect(bool apply);
- void ApplyAllModifiers(bool apply, bool Real);
-
- Unit* GetTriggerTarget() const;
- void TriggerSpell();
- void TriggerSpellWithValue();
- void PeriodicTick();
- void PeriodicDummyTick();
-
- int32 GetMiscBValue() const {return m_spellProto->EffectMiscValueB[m_effIndex];}
- int32 GetMiscValue() const {return m_spellProto->EffectMiscValue[m_effIndex];}
- uint32 GetAuraName() const {return m_auraName;}
- int32 GetAmount() const {return m_amount;}
- void SetAmount(int32 amount) { m_amount = amount; }
- void CleanupTriggeredSpells();
-
+ friend Aura * Aura::Create(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID);
protected:
- explicit AuraEffect(Aura * parentAura, uint8 effIndex, int32 *currentBasePoints = NULL);
- Aura * const m_parentAura;
- Unit * const m_target;
-
- uint32 m_tickNumber;
+ explicit UnitAura(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID);
+ public:
+ void _ApplyForTarget(Unit * target, Unit * caster, AuraApplication * aurApp);
+ void _UnapplyForTarget(Unit * target, Unit * caster, AuraApplication * aurApp);
- const SpellEntry * const m_spellProto;
- const uint8 m_effIndex;
- const AuraType m_auraName;
- int32 m_currentBasePoints;
- int32 m_amount;
+ void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
- SpellModifier *m_spellmod;
+ void UpdateTargetMapForEffect(Unit * caster, uint8 effIndex);
- int32 m_periodicTimer; // Timer for periodic auras
- int32 m_amplitude;
+ // Allow Apply Aura Handler to modify and access m_AuraDRGroup
+ void SetDiminishGroup(DiminishingGroup group) { m_AuraDRGroup = group; }
+ DiminishingGroup GetDiminishGroup() const { return m_AuraDRGroup; }
- bool m_isPeriodic:1;
- bool m_isAreaAura:1;
- bool m_isPersistent:1;
- bool m_isApplied:1;
private:
- bool IsPeriodicTickCrit(Unit const * pCaster) const;
+ DiminishingGroup m_AuraDRGroup:8; // Diminishing
};
-class TRINITY_DLL_SPEC AreaAuraEffect : public AuraEffect
+class TRINITY_DLL_SPEC DynObjAura : public Aura
{
- public:
- friend AuraEffect* CreateAuraEffect(Aura * parentAura, uint32 effIndex, int32 *currentBasePoints);
- void Update(uint32 diff);
- Unit *GetSource() const { return GetParentAura()->GetUnitSource(); }
+ friend Aura * Aura::Create(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID);
protected:
- explicit AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 *currentBasePoints = NULL);
- float m_radius;
- int32 m_removeTime;
- AreaAuraType m_areaAuraType;
-};
-
-class TRINITY_DLL_SPEC PersistentAreaAuraEffect : public AuraEffect
-{
+ explicit DynObjAura(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID);
public:
- friend AuraEffect* CreateAuraEffect(Aura * parentAura, uint32 effIndex, int32 *currentBasePoints);
- void Update(uint32 diff);
- DynamicObject *GetSource() const;
- protected:
- explicit PersistentAreaAuraEffect(Aura * parentAura, uint32 eff, int32 *currentBasePoints = NULL);
-};
-
-AuraEffect* CreateAuraEffect(Aura * parentAura, uint32 effIndex, int32 *currentBasePoints = NULL);
+ void Remove(AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
+ void UpdateTargetMapForEffect(Unit * caster, uint8 effIndex);
+};
#endif
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index a39c7adbc77..8e3af99e89c 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -34,6 +34,7 @@
#include "SpellId.h"
#include "DynamicObject.h"
#include "SpellAuras.h"
+#include "SpellAuraEffects.h"
#include "Group.h"
#include "UpdateData.h"
#include "MapManager.h"
@@ -196,7 +197,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
&Spell::EffectApplyAreaAura, //128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
&Spell::EffectApplyAreaAura, //129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
&Spell::EffectRedirectThreat, //130 SPELL_EFFECT_REDIRECT_THREAT
- &Spell::EffectUnused, //131 SPELL_EFFECT_131 used in some test spells
+ &Spell::EffectPlayerNotification, //131 SPELL_EFFECT_PLAYER_NOTIFICATION
&Spell::EffectPlayMusic, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value (SoundEntries.dbc)
&Spell::EffectUnlearnSpecialization, //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION unlearn profession specialization
&Spell::EffectKillCredit, //134 SPELL_EFFECT_KILL_CREDIT misc value is creature entry
@@ -362,14 +363,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
case SPELL_POSITIVE_CHARGE_39090: spellId = SPELL_POSITIVE_CHARGE_39089; break;
case SPELL_NEGATIVE_CHARGE_39093: spellId = SPELL_NEGATIVE_CHARGE_39092; break;
}
- Aura *aur = m_caster->GetAura(spellId);
- if (!aur)
- {
- m_caster->CastSpell(m_caster, spellId, true);
- aur = m_caster->GetAura(spellId);
- }
- if (aur)
- aur->SetStackAmount(count);
+ m_caster->SetAuraStack(spellId, m_caster, count);
}
}
@@ -464,7 +458,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
// Check aura state for speed but aura state set not only for Immolate spell
if(unitTarget->HasAuraState(AURA_STATE_CONFLAGRATE))
{
- if (unitTarget->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x4))
+ if (unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x4, 0, 0))
damage += damage/4;
}
}
@@ -473,7 +467,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
{
AuraEffect const* aura = NULL; // found req. aura for damage calculation
- Unit::AuraEffectList const &mPeriodic = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
+ Unit::AuraEffectList const &mPeriodic = unitTarget->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE);
for (Unit::AuraEffectList::const_iterator i = mPeriodic.begin(); i != mPeriodic.end(); ++i)
{
// for caster applied auras only
@@ -497,7 +491,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
if (aura)
{
uint32 pdamage = aura->GetAmount() > 0 ? aura->GetAmount() : 0;
- pdamage = m_caster->SpellDamageBonus(unitTarget, aura->GetSpellProto(), pdamage, DOT, aura->GetParentAura()->GetStackAmount());
+ pdamage = m_caster->SpellDamageBonus(unitTarget, aura->GetSpellProto(), pdamage, DOT, aura->GetBase()->GetStackAmount());
damage += pdamage * 4; // 4 ticks of 3 seconds = 12 secs
apply_direct_bonus = false;
// Glyph of Conflagrate
@@ -525,7 +519,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
{
int32 back_damage = m_caster->SpellDamageBonus(unitTarget, m_spellInfo, (uint32)damage, SPELL_DIRECT_DAMAGE);
// Pain and Suffering reduces damage
- if (AuraEffect * aurEff = m_caster->GetDummyAura(SPELLFAMILY_PRIEST, 2874, 0))
+ if (AuraEffect * aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 2874, 0))
back_damage -= aurEff->GetAmount() * back_damage / 100;
if(back_damage < unitTarget->GetHealth())
@@ -537,7 +531,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
// We are in Shadow Form
if (m_caster->m_form == FORM_SHADOW)
// We have Improved Mind Blast
- if (AuraEffect * aurEff = m_caster->GetDummyAura(SPELLFAMILY_PRIEST,95,0))
+ if (AuraEffect * aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST,95,0))
// Chance has been successfully rolled
if (roll_chance_i(aurEff->GetAmount()))
m_caster->CastSpell(unitTarget, SPELL_MIND_TRAUMA_48301, true);
@@ -547,13 +541,13 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
{
// Glyph of Smite
if (AuraEffect * aurEff = m_caster->GetAuraEffect(55692, 0))
- if (unitTarget->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x100000, 0, 0, m_caster->GetGUID()))
+ if (unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x100000, 0, 0, m_caster->GetGUID()))
damage += damage * aurEff->GetAmount() / 100;
}
// Improved Mind Blast (Mind Blast in shadow form bonus)
else if (m_caster->m_form == FORM_SHADOW && (m_spellInfo->SpellFamilyFlags[0] & 0x00002000))
{
- Unit::AuraEffectList const& ImprMindBlast = m_caster->GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER);
+ Unit::AuraEffectList const& ImprMindBlast = m_caster->GetAuraEffectsByType(SPELL_AURA_ADD_FLAT_MODIFIER);
for(Unit::AuraEffectList::const_iterator i = ImprMindBlast.begin(); i != ImprMindBlast.end(); ++i)
{
if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST &&
@@ -585,8 +579,8 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
else if (m_spellInfo->SpellFamilyFlags[0] & 0x00000001)
{
// Improved Insect Swarm
- if (AuraEffect const * aurEff = m_caster->GetDummyAura(SPELLFAMILY_DRUID, 1771, 0))
- if (unitTarget->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00200000))
+ if (AuraEffect const * aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
+ if (unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00200000, 0, 0))
damage = int32(damage*(100.0f+aurEff->GetAmount())/100.0f);
}
break;
@@ -600,16 +594,16 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
if (uint32 combo = ((Player*)m_caster)->GetComboPoints())
{
// Lookup for Deadly poison (only attacker applied)
- if (AuraEffect const * aurEff = unitTarget->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x10000, 0, 0, m_caster->GetGUID()))
+ if (AuraEffect const * aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_ROGUE, 0x10000, 0, 0, m_caster->GetGUID()))
{
// count consumed deadly poison doses at target
bool needConsume = true;
uint32 spellId = aurEff->GetId();
- uint32 doses = aurEff->GetParentAura()->GetStackAmount();
+ uint32 doses = aurEff->GetBase()->GetStackAmount();
if (doses > combo)
doses = combo;
// Master Poisoner
- Unit::AuraEffectList const& auraList = ((Player*)m_caster)->GetAurasByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
+ Unit::AuraEffectList const& auraList = ((Player*)m_caster)->GetAuraEffectsByType(SPELL_AURA_MOD_AURA_DURATION_BY_DISPEL_NOT_STACK);
for (Unit::AuraEffectList::const_iterator iter = auraList.begin(); iter != auraList.end(); ++iter)
{
if ((*iter)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellProto()->SpellIconID == 1960)
@@ -662,7 +656,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
{
bool found = false;
// check dazed affect
- Unit::AuraEffectList const& decSpeedList = unitTarget->GetAurasByType(SPELL_AURA_MOD_DECREASE_SPEED);
+ Unit::AuraEffectList const& decSpeedList = unitTarget->GetAuraEffectsByType(SPELL_AURA_MOD_DECREASE_SPEED);
for (Unit::AuraEffectList::const_iterator iter = decSpeedList.begin(); iter != decSpeedList.end(); ++iter)
{
if ((*iter)->GetSpellProto()->SpellIconID == 15 && (*iter)->GetSpellProto()->Dispel == 0)
@@ -729,7 +723,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)
case SPELLFAMILY_DEATHKNIGHT:
{
// Blood Boil - bonus for diseased targets
- if (m_spellInfo->SpellFamilyFlags[0] & 0x00040000 && unitTarget->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0, 0, 0x00000002, m_caster->GetGUID()))
+ if (m_spellInfo->SpellFamilyFlags[0] & 0x00040000 && unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0, 0, 0x00000002, m_caster->GetGUID()))
{
damage += m_damage / 2;
damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)* 0.035f);
@@ -853,7 +847,7 @@ void Spell::EffectDummy(uint32 i)
AuraEffect* deepWound = unitTarget->GetAuraEffect(SPELL_DEEP_WOUNDS_12721, 0);
if (deepWound)
{
- int32 remainingTicks = deepWound->GetParentAura()->GetAuraDuration() / deepWound->GetAuraAmplitude();
+ int32 remainingTicks = deepWound->GetBase()->GetDuration() / deepWound->GetAmplitude();
damage += remainingTicks * deepWound->GetAmount();
}
@@ -1637,7 +1631,7 @@ void Spell::EffectDummy(uint32 i)
int32 mana = damage;
// Improved Life Tap mod
- if (AuraEffect const * aurEff = m_caster->GetDummyAura(SPELLFAMILY_WARLOCK, 208, 0))
+ if (AuraEffect const * aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_WARLOCK, 208, 0))
mana = (aurEff->GetAmount() + 100)* mana / 100;
m_caster->CastCustomSpell(unitTarget, 31818, &mana, NULL, NULL, true);
@@ -1994,7 +1988,7 @@ void Spell::EffectDummy(uint32 i)
if (Item *item = ((Player*)m_caster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
{
// Damage is increased by 25% if your off-hand weapon is enchanted with Flametongue.
- if (m_caster->GetAura(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0x200000))
+ if (m_caster->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0x200000, 0, 0))
m_damage += m_damage * damage / 100;
}
return;
@@ -2339,15 +2333,15 @@ void Spell::EffectTriggerSpell(uint32 effIndex)
case 35729:
{
uint32 dispelMask = GetDispellMask(DISPEL_ALL);
- Unit::AuraMap& Auras = unitTarget->GetAuras();
- for (Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end();)
+ Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::iterator iter = Auras.begin(); iter != Auras.end();)
{
// remove all harmful spells on you...
- SpellEntry const* spell = iter->second->GetSpellProto();
+ SpellEntry const* spell = iter->second->GetBase()->GetSpellProto();
if((spell->DmgClass == SPELL_DAMAGE_CLASS_MAGIC // only affect magic spells
|| ((1<<spell->Dispel) & dispelMask))
// ignore positive and passive auras
- && !iter->second->IsPositive() && !iter->second->IsPassive())
+ && !iter->second->IsPositive() && !iter->second->GetBase()->IsPassive())
{
m_caster->RemoveAura(iter);
}
@@ -2596,16 +2590,20 @@ void Spell::EffectTeleportUnits(uint32 i)
void Spell::EffectApplyAura(uint32 i)
{
- if (m_spellAura)
- if (AuraEffect * AurEff = m_spellAura->GetPartAura(i))
- unitTarget->HandleAuraEffect(AurEff, true);
+ if (!m_spellAura)
+ return;
+ assert (unitTarget == m_spellAura->GetOwner());
+ if (!m_spellAura->IsRemoved())
+ m_spellAura->ApplyEffectForTargets(i);
}
void Spell::EffectApplyAreaAura(uint32 i)
{
- if (m_spellAura)
- if (AuraEffect * AurEff = m_spellAura->GetPartAura(i))
- unitTarget->HandleAuraEffect(AurEff, true);
+ if (!m_spellAura)
+ return;
+ assert (unitTarget == m_spellAura->GetOwner());
+ if (!m_spellAura->IsRemoved())
+ m_spellAura->ApplyEffectForTargets(i);
}
void Spell::EffectUnlearnSpecialization( uint32 i )
@@ -2764,7 +2762,7 @@ void Spell::SpellDamageHeal(uint32 /*i*/)
// Swiftmend - consumes Regrowth or Rejuvenation
else if (m_spellInfo->TargetAuraState == AURA_STATE_SWIFTMEND && unitTarget->HasAuraState(AURA_STATE_SWIFTMEND, m_spellInfo, m_caster))
{
- Unit::AuraEffectList const& RejorRegr = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);
+ Unit::AuraEffectList const& RejorRegr = unitTarget->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL);
// find most short by duration
AuraEffect *targetAura = NULL;
for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
@@ -2772,7 +2770,7 @@ void Spell::SpellDamageHeal(uint32 /*i*/)
if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
&& (*i)->GetSpellProto()->SpellFamilyFlags[0] & 0x50)
{
- if(!targetAura || (*i)->GetParentAura()->GetAuraDuration() < targetAura->GetParentAura()->GetAuraDuration())
+ if(!targetAura || (*i)->GetBase()->GetDuration() < targetAura->GetBase()->GetDuration())
targetAura = *i;
}
}
@@ -2813,11 +2811,11 @@ void Spell::SpellDamageHeal(uint32 /*i*/)
if (AuraEffect const* aurEff = m_caster->GetAuraEffect(62971, 0))
{
- Unit::AuraEffectList const& Periodic = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);
+ Unit::AuraEffectList const& Periodic = unitTarget->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL);
for (Unit::AuraEffectList::const_iterator i = Periodic.begin(); i != Periodic.end(); ++i)
{
if (m_caster->GetGUID() == (*i)->GetCasterGUID())
- addhealth += addhealth * (*i)->GetParentAura()->GetStackAmount() * aurEff->GetAmount() / 100;
+ addhealth += addhealth * aurEff->GetAmount() / 100;
}
}
}
@@ -2825,11 +2823,11 @@ void Spell::SpellDamageHeal(uint32 /*i*/)
else if (m_spellInfo->SpellFamilyName==SPELLFAMILY_SHAMAN && m_spellInfo->SpellFamilyFlags[0] & 0x100)
{
addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL);
- if (AuraEffect * aurEff = unitTarget->GetAura(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_SHAMAN, 0, 0, 0x10, m_originalCasterGUID))
+ if (AuraEffect * aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_SHAMAN, 0, 0, 0x10, m_originalCasterGUID))
{
addhealth *= 1.25f;
// consume aura
- unitTarget->RemoveAura(aurEff->GetParentAura());
+ unitTarget->RemoveAura(aurEff->GetBase());
}
}
// Death Pact - return pct of max health to caster
@@ -3099,29 +3097,34 @@ void Spell::EffectCreateRandomItem(uint32 i)
void Spell::EffectPersistentAA(uint32 i)
{
- if(m_spellDynObj)
+ if (!m_spellAura)
{
- assert(ObjectAccessor::GetObjectInWorld(m_spellDynObj->GetGUID(), (DynamicObject*)NULL) == m_spellDynObj);
- m_spellDynObj->AddEffect(i);
- return;
- }
+ float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
+ if(Player* modOwner = m_originalCaster->GetSpellModOwner())
+ modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius);
- float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
- if(Player* modOwner = m_originalCaster->GetSpellModOwner())
- modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius);
+ Unit *caster = m_caster->GetEntry() == WORLD_TRIGGER ? m_originalCaster : m_caster;
+ DynamicObject* dynObj = new DynamicObject;
+ if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, m_targets.m_dstPos, radius, false))
+ {
+ delete dynObj;
+ return;
+ }
+ dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x01eeeeee);
+ caster->AddDynObject(dynObj);
+ dynObj->GetMap()->Add(dynObj);
- Unit *caster = m_caster->GetEntry() == WORLD_TRIGGER ? m_originalCaster : m_caster;
- int32 duration = GetSpellDuration(m_spellInfo);
- DynamicObject* dynObj = new DynamicObject;
- if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, 1<<i, m_targets.m_dstPos, duration, radius, false))
- {
- delete dynObj;
- return;
+ if (Aura * aura = Aura::TryCreate(m_spellInfo, dynObj, caster, &m_currentBasePoints[0]))
+ m_spellAura = aura;
+ else
+ {
+ assert(false);
+ return;
+ }
}
- dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x01eeeeee);
- caster->AddDynObject(dynObj);
- dynObj->GetMap()->Add(dynObj);
- m_spellDynObj = dynObj;
+ assert(m_spellAura->GetDynobjOwner());
+ if (!m_spellAura->IsRemoved())
+ m_spellAura->ApplyEffectForTargets(i);
}
void Spell::EffectEnergize(uint32 i)
@@ -3181,10 +3184,10 @@ void Spell::EffectEnergize(uint32 i)
{
// find elixirs on target
uint32 elixir_mask = 0;
- Unit::AuraMap& Auras = unitTarget->GetAuras();
- for (Unit::AuraMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
+ Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::iterator itr = Auras.begin(); itr != Auras.end(); ++itr)
{
- uint32 spell_id = itr->second->GetId();
+ uint32 spell_id = itr->second->GetBase()->GetId();
if(uint32 mask = spellmgr.GetSpellElixirMask(spell_id))
elixir_mask |= mask;
}
@@ -3724,7 +3727,7 @@ void Spell::EffectLearnSpell(uint32 i)
sLog.outDebug("Spell: Player %u has learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow());
}
-typedef std::list< std::pair<uint32, uint64> > DispelList;
+typedef std::list< uint32 > DispelList;
void Spell::EffectDispel(uint32 i)
{
if(!unitTarget)
@@ -3735,15 +3738,15 @@ void Spell::EffectDispel(uint32 i)
// Create dispel mask by dispel type
uint32 dispel_type = m_spellInfo->EffectMiscValue[i];
uint32 dispelMask = GetDispellMask( DispelType(dispel_type));
- Unit::AuraMap const& auras = unitTarget->GetAuras();
+ Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
{
- Aura *aur = itr->second;
- if ((1<<aur->GetSpellProto()->Dispel) & dispelMask)
+ Aura * aura = itr->second;
+ if ((1<<aura->GetSpellProto()->Dispel) & dispelMask)
{
- if(aur->GetSpellProto()->Dispel == DISPEL_MAGIC)
+ if(aura->GetSpellProto()->Dispel == DISPEL_MAGIC)
{
- bool positive = aur->IsPositive() ? (!(aur->GetSpellProto()->AttributesEx & SPELL_ATTR_EX_NEGATIVE)) : false;
+ bool positive = aura->IsPositive(unitTarget) ? (!(aura->GetSpellProto()->AttributesEx & SPELL_ATTR_EX_NEGATIVE)) : false;
// do not remove positive auras if friendly target
// negative auras if non-friendly target
@@ -3751,10 +3754,10 @@ void Spell::EffectDispel(uint32 i)
continue;
}
- bool dispel_charges = aur->GetSpellProto()->AttributesEx7 & SPELL_ATTR_EX7_DISPEL_CHARGES;
+ bool dispel_charges = aura->GetSpellProto()->AttributesEx7 & SPELL_ATTR_EX7_DISPEL_CHARGES;
- for (uint8 i = dispel_charges ? aur->GetAuraCharges() : aur->GetStackAmount(); i; --i)
- dispel_list.push_back(aur);
+ for (uint8 i = dispel_charges ? aura->GetCharges() : aura->GetStackAmount(); i; --i)
+ dispel_list.push_back(aura);
}
}
@@ -3774,7 +3777,8 @@ void Spell::EffectDispel(uint32 i)
if (GetDispelChance((*itr)->GetCaster(), (*itr)->GetId()))
{
- success_list.push_back(std::make_pair((*itr)->GetId(), (*itr)->GetCasterGUID()));
+ unitTarget->RemoveAurasDueToSpellByDispel(*itr, m_caster);
+ success_list.push_back((*itr)->GetId());
dispel_list.erase(itr);
}
else
@@ -3807,9 +3811,8 @@ void Spell::EffectDispel(uint32 i)
for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
{
// Send dispelled spell info
- dataSuccess << uint32(itr->first); // Spell Id
+ dataSuccess << uint32(*itr); // Spell Id
dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
- unitTarget->RemoveAurasDueToSpellByDispel(itr->first, itr->second, m_caster);
}
m_caster->SendMessageToSet(&dataSuccess, true);
@@ -3899,11 +3902,12 @@ void Spell::EffectAddFarsight(uint32 i)
float radius = GetSpellRadiusForFriend(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[i]));
int32 duration = GetSpellDuration(m_spellInfo);
DynamicObject* dynObj = new DynamicObject;
- if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, 0, m_targets.m_dstPos, duration, radius, true))
+ if(!dynObj->Create(objmgr.GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, m_targets.m_dstPos, radius, true))
{
delete dynObj;
return;
}
+ dynObj->SetDuration(duration);
dynObj->SetUInt32Value(DYNAMICOBJECT_BYTES, 0x80000002);
m_caster->AddDynObject(dynObj);
@@ -4138,6 +4142,7 @@ void Spell::EffectEnchantItemTmp(uint32 i)
{
sLog.outError("Spell::EffectEnchantItemTmp: unknown spell id %i", spell_id);
return;
+
}
for(int j = BASE_ATTACK; j <= OFF_ATTACK; ++j)
@@ -4461,11 +4466,11 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
if (needCast)
m_caster->CastSpell(unitTarget, 58567, true);
- if (Aura* aur = unitTarget->GetAura(58567, m_caster->GetGUID()))
+ if (Aura * aur = unitTarget->GetAura(58567, m_caster->GetGUID()))
{
// 58388 - Glyph of Devastate dummy aura.
if (int32 num = (needCast ? 0 : 1) + (m_caster->HasAura(58388) ? 1 : 0))
- aur->modStackAmount(num);
+ aur->ModStackAmount(num);
fixed_bonus += (aur->GetStackAmount() - 1) * CalculateDamage(2, unitTarget);
}
}
@@ -4498,10 +4503,10 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
// full aura scan
else
{
- Unit::AuraMap const& auras = unitTarget->GetAuras();
- for (Unit::AuraMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
+ Unit::AuraApplicationMap const& auras = unitTarget->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
{
- if (itr->second->GetSpellProto()->Dispel == DISPEL_POISON)
+ if (itr->second->GetBase()->GetSpellProto()->Dispel == DISPEL_POISON)
{
found = true;
break;
@@ -4558,7 +4563,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
// Shred, Maul - Rend and Tear
else if (m_spellInfo->SpellFamilyFlags[0] & 0x00008800 && unitTarget->HasAuraState(AURA_STATE_BLEEDING, m_spellInfo, m_caster))
{
- if (AuraEffect const* rendAndTear = m_caster->GetDummyAura(SPELLFAMILY_DRUID, 2859, 0))
+ if (AuraEffect const* rendAndTear = m_caster->GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 0))
{
totalDamagePercentMod *= float((rendAndTear->GetAmount() + 100.0f) / 100.0f);
}
@@ -4616,7 +4621,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)
{
bool consumeDiseases = true;
// Annihilation
- if (AuraEffect * aurEff = m_caster->GetDummyAura(SPELLFAMILY_DEATHKNIGHT, 2710, 0))
+ if (AuraEffect * aurEff = m_caster->GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 2710, 0))
{
// Do not consume diseases if roll sucesses
if (roll_chance_i(aurEff->GetAmount()))
@@ -4897,17 +4902,17 @@ void Spell::EffectScriptEffect(uint32 effIndex)
// Glyph of Starfire
case 54846:
{
- if (AuraEffect const * aurEff = unitTarget->GetAura(SPELL_AURA_PERIODIC_DAMAGE,SPELLFAMILY_DRUID,0x00000002,0,0,m_caster->GetGUID()))
+ if (AuraEffect const * aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE,SPELLFAMILY_DRUID,0x00000002,0,0,m_caster->GetGUID()))
{
- uint32 countMin = aurEff->GetParentAura()->GetAuraMaxDuration();
+ uint32 countMin = aurEff->GetBase()->GetMaxDuration();
uint32 countMax = 18000;
countMax += m_caster->HasAura(38414) ? 3000 : 0;
countMax += m_caster->HasAura(57865) ? 3000 : 0;
if (countMin < countMax)
{
- aurEff->GetParentAura()->SetAuraDuration(uint32(aurEff->GetParentAura()->GetAuraDuration()+3000));
- aurEff->GetParentAura()->SetAuraMaxDuration(countMin+3000);
+ aurEff->GetBase()->SetDuration(uint32(aurEff->GetBase()->GetDuration()+3000));
+ aurEff->GetBase()->SetMaxDuration(countMin+3000);
}
}
return;
@@ -4915,17 +4920,17 @@ void Spell::EffectScriptEffect(uint32 effIndex)
// Glyph of Shred
case 63974:
{
- if (AuraEffect const * aurEff = unitTarget->GetAura(SPELL_AURA_PERIODIC_DAMAGE,SPELLFAMILY_DRUID,0x00800000,0,0,m_caster->GetGUID()))
+ if (AuraEffect const * aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE,SPELLFAMILY_DRUID,0x00800000,0,0,m_caster->GetGUID()))
{
- uint32 countMin = aurEff->GetParentAura()->GetAuraMaxDuration();
+ uint32 countMin = aurEff->GetBase()->GetMaxDuration();
uint32 countMax = 20000;
countMax += m_caster->HasAura(54818) ? 4000 : 0;
countMax += m_caster->HasAura(60141) ? 4000 : 0;
if (countMin < countMax)
{
- aurEff->GetParentAura()->SetAuraDuration(uint32(aurEff->GetParentAura()->GetAuraDuration()+3000));
- aurEff->GetParentAura()->SetAuraMaxDuration(countMin+2000);
+ aurEff->GetBase()->SetDuration(uint32(aurEff->GetBase()->GetDuration()+3000));
+ aurEff->GetBase()->SetMaxDuration(countMin+2000);
}
}
@@ -4934,16 +4939,16 @@ void Spell::EffectScriptEffect(uint32 effIndex)
// Glyph of Backstab
case 63975:
{
- if (AuraEffect const * aurEff = unitTarget->GetAura(SPELL_AURA_PERIODIC_DAMAGE,SPELLFAMILY_ROGUE,0x00100000,0,0,m_caster->GetGUID()))
+ if (AuraEffect const * aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE,SPELLFAMILY_ROGUE,0x00100000,0,0,m_caster->GetGUID()))
{
- uint32 countMin = aurEff->GetParentAura()->GetAuraMaxDuration();
+ uint32 countMin = aurEff->GetBase()->GetMaxDuration();
uint32 countMax = 12000;
countMax += m_caster->HasAura(56801) ? 4000 : 0;
if (countMin < countMax)
{
- aurEff->GetParentAura()->SetAuraDuration(uint32(aurEff->GetParentAura()->GetAuraDuration()+3000));
- aurEff->GetParentAura()->SetAuraMaxDuration(countMin+2000);
+ aurEff->GetBase()->SetDuration(uint32(aurEff->GetBase()->GetDuration()+3000));
+ aurEff->GetBase()->SetMaxDuration(countMin+2000);
}
}
@@ -5602,9 +5607,9 @@ void Spell::EffectScriptEffect(uint32 effIndex)
}
Aura * chargesaura = m_caster->GetAura(59907);
- if(chargesaura && chargesaura->GetAuraCharges() > 1)
+ if(chargesaura && chargesaura->GetCharges() > 1)
{
- chargesaura->SetAuraCharges(chargesaura->GetAuraCharges() - 1);
+ chargesaura->SetCharges(chargesaura->GetCharges() - 1);
m_caster->CastSpell(unitTarget, spell_heal, true, NULL, NULL, ((TempSummon*)m_caster)->GetSummonerGUID());
}
else
@@ -5678,7 +5683,7 @@ void Spell::EffectScriptEffect(uint32 effIndex)
uint32 rank = 0;
// Improved Healthstone
- if (AuraEffect const * aurEff = unitTarget->GetDummyAura(SPELLFAMILY_WARLOCK, 284, 0))
+ if (AuraEffect const * aurEff = unitTarget->GetDummyAuraEffect(SPELLFAMILY_WARLOCK, 284, 0))
{
if(aurEff->GetId() == 18692)
rank = 1;
@@ -5726,8 +5731,8 @@ void Spell::EffectScriptEffect(uint32 effIndex)
// Everlasting Affliction
case 47422:
// Refresh corruption on target
- if (AuraEffect * aur = unitTarget->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x2, 0, 0, m_caster->GetGUID()))
- aur->GetParentAura()->RefreshAura();
+ if (AuraEffect * aur = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_WARLOCK, 0x2, 0, 0, m_caster->GetGUID()))
+ aur->GetBase()->RefreshDuration();
return;
// Demonic Empowerment
case 47193:
@@ -5764,8 +5769,8 @@ void Spell::EffectScriptEffect(uint32 effIndex)
case 63521:
{
// Divine Plea
- if(Aura *AuraDivinePlea = m_caster->GetAura(54428))
- AuraDivinePlea->RefreshAura();
+ if(Aura * aura = m_caster->GetAura(54428))
+ aura->RefreshDuration();
return;
}
}
@@ -5781,8 +5786,8 @@ void Spell::EffectScriptEffect(uint32 effIndex)
if (!unitTarget)
return;
// Refresh Shadow Word: Pain on target
- if (AuraEffect * aur = unitTarget->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0, 0, m_caster->GetGUID()))
- aur->GetParentAura()->RefreshAura();
+ if (AuraEffect * aur = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0, 0, m_caster->GetGUID()))
+ aur->GetBase()->RefreshDuration();
return;
}
default:
@@ -5797,7 +5802,7 @@ void Spell::EffectScriptEffect(uint32 effIndex)
// Invigoration
case 53412:
{
- if (AuraEffect * aurEff = unitTarget->GetDummyAura(SPELLFAMILY_HUNTER, 3487, 0))
+ if (AuraEffect * aurEff = unitTarget->GetDummyAuraEffect(SPELLFAMILY_HUNTER, 3487, 0))
{
if (roll_chance_i(aurEff->GetAmount()))
unitTarget->CastSpell(unitTarget, 53398, true);
@@ -5818,51 +5823,51 @@ void Spell::EffectScriptEffect(uint32 effIndex)
{
uint32 spellId = 0;
int32 basePoint = 0;
- Unit::AuraMap& Auras = unitTarget->GetAuras();
- for (Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
+ Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::iterator i = Auras.begin(); i != Auras.end(); ++i)
{
- Aura *aura = (*i).second;
+ Aura * aura = (*i).second->GetBase();
if (aura->GetCasterGUID() != m_caster->GetGUID())
continue;
// Search only Serpent Sting, Viper Sting, Scorpid Sting auras
flag96 familyFlag = aura->GetSpellProto()->SpellFamilyFlags;
if (!(familyFlag[1] & 0x00000080 || familyFlag[0] & 0x0000C000))
continue;
- if (!aura->GetPartAura(0))
- continue;
-
- // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting.
- if (familyFlag[0] & 0x4000)
- {
- int32 TickCount = aura->GetPartAura(0)->GetTotalTicks();
- spellId = 53353; // 53353 Chimera Shot - Serpent
- basePoint = aura->GetPartAura(0)->GetAmount() * TickCount * 40 / 100;
- }
- // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting.
- else if (familyFlag[1] & 0x00000080)
+ if (AuraEffect const * aurEff = aura->GetEffect(0))
{
- int32 TickCount = aura->GetPartAura(0)->GetTotalTicks();
- spellId = 53358; // 53358 Chimera Shot - Viper
-
- // Amount of one aura tick
- basePoint = aura->GetPartAura(0)->GetAmount() * aura->GetTarget()->GetMaxPower(POWER_MANA) / 100 ;
- int32 casterBasePoint = aura->GetPartAura(0)->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 50 ;
- if (basePoint > casterBasePoint)
- basePoint = casterBasePoint;
- basePoint = basePoint * TickCount * 60 / 100;
+ // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting.
+ if (familyFlag[0] & 0x4000)
+ {
+ int32 TickCount = aurEff->GetTotalTicks();
+ spellId = 53353; // 53353 Chimera Shot - Serpent
+ basePoint = aurEff->GetAmount() * TickCount * 40 / 100;
+ }
+ // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting.
+ else if (familyFlag[1] & 0x00000080)
+ {
+ int32 TickCount = aura->GetEffect(0)->GetTotalTicks();
+ spellId = 53358; // 53358 Chimera Shot - Viper
+
+ // Amount of one aura tick
+ basePoint = aurEff->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 100 ;
+ int32 casterBasePoint = aurEff->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 50 ;
+ if (basePoint > casterBasePoint)
+ basePoint = casterBasePoint;
+ basePoint = basePoint * TickCount * 60 / 100;
+ }
+ // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute.
+ else if (familyFlag[0] & 0x00008000)
+ spellId = 53359; // 53359 Chimera Shot - Scorpid
+ // ?? nothing say in spell desc (possibly need addition check)
+ //if (familyFlag & 0x0000010000000000LL || // dot
+ // familyFlag & 0x0000100000000000LL) // stun
+ //{
+ // spellId = 53366; // 53366 Chimera Shot - Wyvern
+ //}
+
+ // Refresh aura duration
+ aura->RefreshDuration();
}
- // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute.
- else if (familyFlag[0] & 0x00008000)
- spellId = 53359; // 53359 Chimera Shot - Scorpid
- // ?? nothing say in spell desc (possibly need addition check)
- //if (familyFlag & 0x0000010000000000LL || // dot
- // familyFlag & 0x0000100000000000LL) // stun
- //{
- // spellId = 53366; // 53366 Chimera Shot - Wyvern
- //}
-
- // Refresh aura duration
- aura->RefreshAura();
break;
}
if (spellId)
@@ -5907,10 +5912,10 @@ void Spell::EffectScriptEffect(uint32 effIndex)
return;
}
// all seals have aura dummy in 2 effect
- Unit::AuraMap & sealAuras = m_caster->GetAuras();
- for (Unit::AuraMap::iterator iter = sealAuras.begin(); iter != sealAuras.end();)
+ Unit::AuraApplicationMap & sealAuras = m_caster->GetAppliedAuras();
+ for (Unit::AuraApplicationMap::iterator iter = sealAuras.begin(); iter != sealAuras.end();)
{
- switch (iter->second->GetId())
+ switch (iter->first)
{
// Heart of the Crusader
case 20335: // Rank 1
@@ -5923,11 +5928,11 @@ void Spell::EffectScriptEffect(uint32 effIndex)
spellId3 = 54499;
break;
}
-
- if (IsSealSpell(iter->second->GetSpellProto()))
+ Aura * aura = iter->second->GetBase();
+ if (IsSealSpell(aura->GetSpellProto()))
{
- if (AuraEffect * aureff = iter->second->GetPartAura(2))
- if (aureff->GetAuraName() == SPELL_AURA_DUMMY)
+ if (AuraEffect * aureff = aura->GetEffect(2))
+ if (aureff->GetAuraType() == SPELL_AURA_DUMMY)
{
if (sSpellStore.LookupEntry(aureff->GetAmount()))
spellId2 = aureff->GetAmount();
@@ -6807,18 +6812,19 @@ void Spell::EffectDispelMechanic(uint32 i)
std::queue < std::pair < uint32, uint64 > > dispel_list;
- Unit::AuraMap& Auras = unitTarget->GetAuras();
+ Unit::AuraMap& Auras = unitTarget->GetOwnedAuras();
for (Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end(); iter++)
{
- if((GetAllSpellMechanicMask(iter->second->GetSpellProto()) & (1<<(mechanic))) && GetDispelChance(iter->second->GetCaster(), iter->second->GetId()))
- {
- dispel_list.push(std::make_pair(iter->second->GetId(), iter->second->GetCasterGUID() ) );
- }
+ Aura * aura = iter->second;
+ if((GetAllSpellMechanicMask(aura->GetSpellProto()) & (1<<(mechanic))) && GetDispelChance(aura->GetCaster(), aura->GetId()))
+ {
+ dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID() ) );
+ }
}
for (; dispel_list.size(); dispel_list.pop())
{
- unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, AURA_REMOVE_BY_ENEMY_SPELL);
+ unitTarget->RemoveAura(dispel_list.front().first, dispel_list.front().second, 0, AURA_REMOVE_BY_ENEMY_SPELL);
}
}
@@ -7163,15 +7169,15 @@ void Spell::EffectStealBeneficialBuff(uint32 i)
std::list <Aura *> steal_list;
// Create dispel mask by dispel type
uint32 dispelMask = GetDispellMask( DispelType(m_spellInfo->EffectMiscValue[i]) );
- Unit::AuraMap const& auras = unitTarget->GetAuras();
+ Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
{
- Aura *aur = (*itr).second;
- if (aur && (1<<aur->GetSpellProto()->Dispel) & dispelMask)
+ Aura * aura = itr->second;
+ if ((1<<aura->GetSpellProto()->Dispel) & dispelMask)
{
// Need check for passive? this
- if (aur->IsPositive() && !aur->IsPassive() && !(aur->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_NOT_STEALABLE))
- steal_list.push_back(aur);
+ if (aura->IsPositive(unitTarget) && !aura->IsPassive() && !(aura->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_NOT_STEALABLE))
+ steal_list.push_back(aura);
}
}
// Ok if exist some buffs for dispel try dispel it
@@ -7187,6 +7193,7 @@ void Spell::EffectStealBeneficialBuff(uint32 i)
for (uint32 i=urand(0, list_size-1); i>0; --i)
itr++;
success_list.push_back(*itr);
+ unitTarget->RemoveAurasDueToSpellBySteal(*itr, m_caster);
steal_list.erase(itr);
}
if (success_list.size())
@@ -7197,11 +7204,10 @@ void Spell::EffectStealBeneficialBuff(uint32 i)
data << uint32(m_spellInfo->Id); // dispel spell id
data << uint8(0); // not used
data << uint32(success_list.size()); // count
- for (std::list < Aura * > ::iterator itr = success_list.begin(); itr!=success_list.end(); ++itr)
+ for (std::list < Aura * >::iterator itr = success_list.begin(); itr!=success_list.end(); ++itr)
{
- data << uint32((*itr)->GetId()); // Spell Id
+ data << uint32((*itr)->GetId()); // Spell Id
data << uint8(0); // 0 - steals !=0 transfers
- unitTarget->RemoveAurasDueToSpellBySteal((*itr)->GetId(), (*itr)->GetCasterGUID(), m_caster);
}
m_caster->SendMessageToSet(&data, true);
}
@@ -7443,6 +7449,20 @@ void Spell::EffectActivateSpec(uint32 /*eff_idx*/)
((Player*)unitTarget)->ActivateSpec(damage-1); // damage is 1 or 2, spec is 0 or 1
}
+void Spell::EffectPlayerNotification(uint32 /*eff_idx*/)
+{
+ if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ switch(m_spellInfo->Id)
+ {
+ case 58730: // Restricted Flight Area
+ case 58600: // Restricted Flight Area
+ ((Player *)unitTarget)->GetSession()->SendNotification(LANG_ZONE_NOFLYZONE);
+ break;
+ }
+}
+
void Spell::EffectCastButtons(uint32 i)
{
if (!unitTarget || m_caster->GetTypeId() != TYPEID_PLAYER)
diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp
index 6a03d13bf6d..c3e72c94561 100644
--- a/src/game/SpellHandler.cpp
+++ b/src/game/SpellHandler.cpp
@@ -420,7 +420,7 @@ void WorldSession::HandleCancelAuraOpcode( WorldPacket& recvPacket)
// non channeled case
// maybe should only remove one buff when there are multiple?
- _player->RemoveAurasDueToSpell(spellId, 0, AURA_REMOVE_BY_CANCEL);
+ _player->RemoveOwnedAura(spellId, 0, 0, AURA_REMOVE_BY_CANCEL);
}
void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
@@ -458,7 +458,7 @@ void WorldSession::HandlePetCancelAuraOpcode( WorldPacket& recvPacket)
return;
}
- pet->RemoveAurasDueToSpell(spellId);
+ pet->RemoveOwnedAura(spellId, 0, 0, AURA_REMOVE_BY_CANCEL);
pet->AddCreatureSpellCooldown(spellId);
}
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 0a20cb1eefe..3534a9da14e 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -319,6 +319,11 @@ bool IsPassiveSpell(uint32 spellId)
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
if (!spellInfo)
return false;
+ return IsPassiveSpell(spellInfo);
+}
+
+bool IsPassiveSpell(SpellEntry const * spellInfo)
+{
if(spellInfo->Attributes & SPELL_ATTR_PASSIVE)
return true;
return false;
@@ -463,7 +468,7 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
if(!spellInfo)
- return SPELL_NORMAL;
+ return SPELL_SPECIFIC_NORMAL;
switch(spellInfo->SpellFamilyName)
{
@@ -494,16 +499,16 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
}
if(food && drink)
- return SPELL_FOOD_AND_DRINK;
+ return SPELL_SPECIFIC_FOOD_AND_DRINK;
else if(food)
- return SPELL_FOOD;
+ return SPELL_SPECIFIC_FOOD;
else if(drink)
- return SPELL_DRINK;
+ return SPELL_SPECIFIC_DRINK;
}
// Well Fed buffs (must be exclusive with Food / Drink replenishment effects, or else Well Fed will cause them to be removed)
// SpellIcon 2560 is Spell 46687, does not have this flag
else if ((spellInfo->AttributesEx2 & SPELL_ATTR_EX2_FOOD_BUFF) || spellInfo->SpellIconID == 2560)
- return SPELL_WELL_FED;
+ return SPELL_SPECIFIC_WELL_FED;
// this may be a hack
//else if((spellInfo->AttributesEx2 & SPELL_ATTR_EX2_FOOD_BUFF)
// && !spellInfo->Category)
@@ -520,10 +525,10 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
case 8096: // Intellect
case 8115: // Agility
case 8091: // Armor
- return SPELL_SCROLL;
+ return SPELL_SPECIFIC_SCROLL;
case 12880: // Enrage (Enrage)
case 57518: // Enrage (Wrecking Crew)
- return SPELL_WARRIOR_ENRAGE;
+ return SPELL_SPECIFIC_WARRIOR_ENRAGE;
}
}
break;
@@ -532,23 +537,23 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
{
// family flags 18(Molten), 25(Frost/Ice), 28(Mage)
if (spellInfo->SpellFamilyFlags[0] & 0x12040000)
- return SPELL_MAGE_ARMOR;
+ return SPELL_SPECIFIC_MAGE_ARMOR;
// Arcane brillance and Arcane intelect (normal check fails because of flags difference)
if (spellInfo->SpellFamilyFlags[0] & 0x400)
- return SPELL_MAGE_ARCANE_BRILLANCE;
+ return SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE;
if ((spellInfo->SpellFamilyFlags[0] & 0x1000000) && spellInfo->EffectApplyAuraName[0]==SPELL_AURA_MOD_CONFUSE)
- return SPELL_MAGE_POLYMORPH;
+ return SPELL_SPECIFIC_MAGE_POLYMORPH;
break;
}
case SPELLFAMILY_WARRIOR:
{
if (spellInfo->SpellFamilyFlags[1] & 0x000080 || spellInfo->SpellFamilyFlags[0] & 0x10000)
- return SPELL_POSITIVE_SHOUT;
+ return SPELL_SPECIFIC_POSITIVE_SHOUT;
if (spellInfo->Id == 12292) // Death Wish
- return SPELL_WARRIOR_ENRAGE;
+ return SPELL_SPECIFIC_WARRIOR_ENRAGE;
break;
}
@@ -556,15 +561,15 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
{
// only warlock curses have this
if (spellInfo->Dispel == DISPEL_CURSE)
- return SPELL_CURSE;
+ return SPELL_SPECIFIC_CURSE;
// Warlock (Demon Armor | Demon Skin | Fel Armor)
if (spellInfo->SpellFamilyFlags[1] & 0x20000020 || spellInfo->SpellFamilyFlags[2] & 0x00000010)
- return SPELL_WARLOCK_ARMOR;
+ return SPELL_SPECIFIC_WARLOCK_ARMOR;
//seed of corruption and corruption
if (spellInfo->SpellFamilyFlags[1] & 0x10 || spellInfo->SpellFamilyFlags[0] & 0x2)
- return SPELL_WARLOCK_CORRUPTION;
+ return SPELL_SPECIFIC_WARLOCK_CORRUPTION;
break;
}
case SPELLFAMILY_PRIEST:
@@ -573,11 +578,11 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
if ((spellInfo->Attributes & SPELL_ATTR_CASTABLE_WHILE_SITTING) &&
(spellInfo->InterruptFlags & SPELL_INTERRUPT_FLAG_AUTOATTACK) &&
(spellInfo->SpellIconID == 52 || spellInfo->SpellIconID == 79))
- return SPELL_WELL_FED;
+ return SPELL_SPECIFIC_WELL_FED;
// Divine Spirit and Prayer of Spirit
if (spellInfo->SpellFamilyFlags[0] & 0x20)
- return SPELL_PRIEST_DIVINE_SPIRIT;
+ return SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT;
break;
}
@@ -585,39 +590,39 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
{
// only hunter stings have this
if (spellInfo->Dispel == DISPEL_POISON)
- return SPELL_STING;
+ return SPELL_SPECIFIC_STING;
// only hunter aspects have this (but not all aspects in hunter family)
if( spellInfo->SpellFamilyFlags.HasFlag(0x00380000, 0x00440000, 0x00001010))
- return SPELL_ASPECT;
+ return SPELL_SPECIFIC_ASPECT;
break;
}
case SPELLFAMILY_PALADIN:
{
if (IsSealSpell(spellInfo))
- return SPELL_SEAL;
+ return SPELL_SPECIFIC_SEAL;
if (spellInfo->SpellFamilyFlags[0] & 0x11010002)
- return SPELL_BLESSING;
+ return SPELL_SPECIFIC_BLESSING;
if (spellInfo->SpellFamilyFlags[0] & 0x00002190)
- return SPELL_HAND;
+ return SPELL_SPECIFIC_HAND;
// Judgement of Wisdom, Judgement of Light, Judgement of Justice
if (spellInfo->Id == 20184 || spellInfo->Id == 20185 || spellInfo->Id == 20186)
- return SPELL_JUDGEMENT;
+ return SPELL_SPECIFIC_JUDGEMENT;
// only paladin auras have this (for palaldin class family)
if( spellInfo->SpellFamilyFlags[2] & 0x00000020 )
- return SPELL_AURA;
+ return SPELL_SPECIFIC_AURA;
break;
}
case SPELLFAMILY_SHAMAN:
{
if (IsElementalShield(spellInfo))
- return SPELL_ELEMENTAL_SHIELD;
+ return SPELL_SPECIFIC_ELEMENTAL_SHIELD;
break;
}
@@ -628,7 +633,7 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
case SPELLFAMILY_DEATHKNIGHT:
if (spellInfo->Id == SPELL_ID_BLOOD_PRESENCE || spellInfo->Id == SPELL_ID_FROST_PRESENCE || spellInfo->Id == SPELL_ID_UNHOLY_PRESENCE)
//if (spellInfo->Category == 47)
- return SPELL_PRESENCE;
+ return SPELL_SPECIFIC_PRESENCE;
break;
}
@@ -642,13 +647,13 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
case SPELL_AURA_MOD_POSSESS_PET:
case SPELL_AURA_MOD_POSSESS:
case SPELL_AURA_AOE_CHARM:
- return SPELL_CHARM;
+ return SPELL_SPECIFIC_CHARM;
case SPELL_AURA_TRACK_CREATURES:
case SPELL_AURA_TRACK_RESOURCES:
case SPELL_AURA_TRACK_STEALTHED:
- return SPELL_TRACKER;
+ return SPELL_SPECIFIC_TRACKER;
case SPELL_AURA_PHASE:
- return SPELL_PHASE;
+ return SPELL_SPECIFIC_PHASE;
}
}
}
@@ -656,7 +661,7 @@ SpellSpecific GetSpellSpecific(uint32 spellId)
if(SpellSpecific sp = spellmgr.GetSpellElixirSpecific(spellInfo->Id))
return sp;
- return SPELL_NORMAL;
+ return SPELL_SPECIFIC_NORMAL;
}
// target not allow have more one spell specific from same caster
@@ -664,16 +669,16 @@ bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1,SpellSpecific s
{
switch(spellSpec1)
{
- case SPELL_SEAL:
- case SPELL_BLESSING:
- case SPELL_HAND:
- case SPELL_AURA:
- case SPELL_STING:
- case SPELL_CURSE:
- case SPELL_ASPECT:
- case SPELL_POSITIVE_SHOUT:
- case SPELL_JUDGEMENT:
- case SPELL_WARLOCK_CORRUPTION:
+ case SPELL_SPECIFIC_SEAL:
+ case SPELL_SPECIFIC_BLESSING:
+ case SPELL_SPECIFIC_HAND:
+ case SPELL_SPECIFIC_AURA:
+ case SPELL_SPECIFIC_STING:
+ case SPELL_SPECIFIC_CURSE:
+ case SPELL_SPECIFIC_ASPECT:
+ case SPELL_SPECIFIC_POSITIVE_SHOUT:
+ case SPELL_SPECIFIC_JUDGEMENT:
+ case SPELL_SPECIFIC_WARLOCK_CORRUPTION:
return spellSpec1==spellSpec2;
default:
return false;
@@ -684,40 +689,40 @@ bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1, SpellSpecific
{
switch(spellSpec1)
{
- case SPELL_PHASE:
- case SPELL_TRACKER:
- case SPELL_WARLOCK_ARMOR:
- case SPELL_MAGE_ARMOR:
- case SPELL_ELEMENTAL_SHIELD:
- case SPELL_MAGE_POLYMORPH:
- case SPELL_PRESENCE:
- case SPELL_WELL_FED:
- case SPELL_CHARM:
- case SPELL_SCROLL:
- case SPELL_WARRIOR_ENRAGE:
- case SPELL_MAGE_ARCANE_BRILLANCE:
- case SPELL_PRIEST_DIVINE_SPIRIT:
+ case SPELL_SPECIFIC_PHASE:
+ case SPELL_SPECIFIC_TRACKER:
+ case SPELL_SPECIFIC_WARLOCK_ARMOR:
+ case SPELL_SPECIFIC_MAGE_ARMOR:
+ case SPELL_SPECIFIC_ELEMENTAL_SHIELD:
+ case SPELL_SPECIFIC_MAGE_POLYMORPH:
+ case SPELL_SPECIFIC_PRESENCE:
+ case SPELL_SPECIFIC_WELL_FED:
+ case SPELL_SPECIFIC_CHARM:
+ case SPELL_SPECIFIC_SCROLL:
+ case SPELL_SPECIFIC_WARRIOR_ENRAGE:
+ case SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE:
+ case SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT:
return spellSpec1==spellSpec2;
- case SPELL_FOOD:
- return spellSpec2==SPELL_FOOD
- || spellSpec2==SPELL_FOOD_AND_DRINK;
- case SPELL_DRINK:
- return spellSpec2==SPELL_DRINK
- || spellSpec2==SPELL_FOOD_AND_DRINK;
- case SPELL_FOOD_AND_DRINK:
- return spellSpec2==SPELL_FOOD
- || spellSpec2==SPELL_DRINK
- || spellSpec2==SPELL_FOOD_AND_DRINK;
- case SPELL_BATTLE_ELIXIR:
- return spellSpec2==SPELL_BATTLE_ELIXIR
- || spellSpec2==SPELL_FLASK_ELIXIR;
- case SPELL_GUARDIAN_ELIXIR:
- return spellSpec2==SPELL_GUARDIAN_ELIXIR
- || spellSpec2==SPELL_FLASK_ELIXIR;
- case SPELL_FLASK_ELIXIR:
- return spellSpec2==SPELL_BATTLE_ELIXIR
- || spellSpec2==SPELL_GUARDIAN_ELIXIR
- || spellSpec2==SPELL_FLASK_ELIXIR;
+ case SPELL_SPECIFIC_FOOD:
+ return spellSpec2==SPELL_SPECIFIC_FOOD
+ || spellSpec2==SPELL_SPECIFIC_FOOD_AND_DRINK;
+ case SPELL_SPECIFIC_DRINK:
+ return spellSpec2==SPELL_SPECIFIC_DRINK
+ || spellSpec2==SPELL_SPECIFIC_FOOD_AND_DRINK;
+ case SPELL_SPECIFIC_FOOD_AND_DRINK:
+ return spellSpec2==SPELL_SPECIFIC_FOOD
+ || spellSpec2==SPELL_SPECIFIC_DRINK
+ || spellSpec2==SPELL_SPECIFIC_FOOD_AND_DRINK;
+ case SPELL_SPECIFIC_BATTLE_ELIXIR:
+ return spellSpec2==SPELL_SPECIFIC_BATTLE_ELIXIR
+ || spellSpec2==SPELL_SPECIFIC_FLASK_ELIXIR;
+ case SPELL_SPECIFIC_GUARDIAN_ELIXIR:
+ return spellSpec2==SPELL_SPECIFIC_GUARDIAN_ELIXIR
+ || spellSpec2==SPELL_SPECIFIC_FLASK_ELIXIR;
+ case SPELL_SPECIFIC_FLASK_ELIXIR:
+ return spellSpec2==SPELL_SPECIFIC_BATTLE_ELIXIR
+ || spellSpec2==SPELL_SPECIFIC_GUARDIAN_ELIXIR
+ || spellSpec2==SPELL_SPECIFIC_FLASK_ELIXIR;
default:
return false;
}
@@ -1036,10 +1041,9 @@ bool IsSingleTargetSpell(SpellEntry const *spellInfo)
if ( spellInfo->AttributesEx5 & SPELL_ATTR_EX5_SINGLE_TARGET_SPELL )
return true;
- // TODO - need found Judgements rule
switch(GetSpellSpecific(spellInfo->Id))
{
- case SPELL_JUDGEMENT:
+ case SPELL_SPECIFIC_JUDGEMENT:
return true;
default:
break;
@@ -1061,8 +1065,8 @@ bool IsSingleTargetSpells(SpellEntry const *spellInfo1, SpellEntry const *spellI
// spell with single target specific types
switch(spec1)
{
- case SPELL_JUDGEMENT:
- case SPELL_MAGE_POLYMORPH:
+ case SPELL_SPECIFIC_JUDGEMENT:
+ case SPELL_SPECIFIC_MAGE_POLYMORPH:
if(GetSpellSpecific(spellInfo2->Id) == spec1)
return true;
break;
@@ -1499,7 +1503,7 @@ bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const* spellPr
if (procEvent_procEx & PROC_EX_EX_TRIGGER_ALWAYS)
return true;
// PROC_EX_NOT_ACTIVE_SPELL and PROC_EX_ONLY_ACTIVE_SPELL flags handle: if passed checks before
- if ((procExtra & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) && ((procEvent_procEx & (AURA_SPELL_PROC_EX_MASK | AURA_REMOVE_PROC_EX_MASK)) == 0))
+ if ((procExtra & (PROC_EX_NORMAL_HIT|PROC_EX_CRITICAL_HIT)) && ((procEvent_procEx & (AURA_SPELL_PROC_EX_MASK)) == 0))
return true;
}
// Check Extra Requirement like (hit/crit/miss/resist/parry/dodge/block/immune/reflect/absorb and other)
@@ -2525,17 +2529,6 @@ void SpellMgr::LoadSpellAreas()
continue;
}
- switch (spellInfo->EffectApplyAuraName[0])
- {
- case SPELL_AURA_DUMMY:
- case SPELL_AURA_PHASE:
- case SPELL_AURA_GHOST:
- break;
- default:
- sLog.outErrorDb("Spell %u listed in `spell_area` have aura spell requirement (%u) without dummy/phase/ghost aura in effect 0", spell,abs(spellArea.auraSpell));
- continue;
- }
-
if (abs(spellArea.auraSpell) == spellArea.spellId)
{
sLog.outErrorDb("Spell %u listed in `spell_area` have aura spell (%u) requirement for itself", spell,abs(spellArea.auraSpell));
@@ -3577,21 +3570,6 @@ void SpellMgr::LoadSpellCustomAttr()
for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j)
{
- switch (spellInfo->EffectApplyAuraName[j])
- {
- case SPELL_AURA_MOD_ROOT:
- mSpellCustomAttr[i] |= SPELL_ATTR_CU_AURA_CC;
- mSpellCustomAttr[i] |= SPELL_ATTR_CU_MOVEMENT_IMPAIR;
- count++;
- break;
- case SPELL_AURA_MOD_DECREASE_SPEED:
- mSpellCustomAttr[i] |= SPELL_ATTR_CU_MOVEMENT_IMPAIR;
- count++;
- break;
- default:
- break;
- }
-
switch (spellInfo->Effect[j])
{
case SPELL_EFFECT_SCHOOL_DAMAGE:
@@ -3645,7 +3623,6 @@ void SpellMgr::LoadSpellCustomAttr()
case SPELL_AURA_MOD_FEAR:
case SPELL_AURA_MOD_STUN:
mSpellCustomAttr[i] |= SPELL_ATTR_CU_AURA_CC;
- mSpellCustomAttr[i] &= ~SPELL_ATTR_CU_MOVEMENT_IMPAIR;
count++;
break;
}
diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h
index 54bb649e218..a31c4c5434c 100644
--- a/src/game/SpellMgr.h
+++ b/src/game/SpellMgr.h
@@ -143,36 +143,36 @@ enum SpellFamilyFlag
// Spell clasification
enum SpellSpecific
{
- SPELL_NORMAL = 0,
- SPELL_SEAL = 1,
- SPELL_BLESSING = 2,
- SPELL_AURA = 3,
- SPELL_STING = 4,
- SPELL_CURSE = 5,
- SPELL_ASPECT = 6,
- SPELL_TRACKER = 7,
- SPELL_WARLOCK_ARMOR = 8,
- SPELL_MAGE_ARMOR = 9,
- SPELL_ELEMENTAL_SHIELD = 10,
- SPELL_MAGE_POLYMORPH = 11,
- SPELL_POSITIVE_SHOUT = 12,
- SPELL_JUDGEMENT = 13,
- SPELL_BATTLE_ELIXIR = 14,
- SPELL_GUARDIAN_ELIXIR = 15,
- SPELL_FLASK_ELIXIR = 16,
- SPELL_WARLOCK_CORRUPTION= 17,
- SPELL_WELL_FED = 18,
- SPELL_FOOD = 19,
- SPELL_DRINK = 20,
- SPELL_FOOD_AND_DRINK = 21,
- SPELL_PRESENCE = 22,
- SPELL_CHARM = 23,
- SPELL_SCROLL = 24,
- SPELL_MAGE_ARCANE_BRILLANCE = 25,
- SPELL_WARRIOR_ENRAGE = 26,
- SPELL_PRIEST_DIVINE_SPIRIT = 27,
- SPELL_HAND = 28,
- SPELL_PHASE = 29,
+ SPELL_SPECIFIC_NORMAL = 0,
+ SPELL_SPECIFIC_SEAL = 1,
+ SPELL_SPECIFIC_BLESSING = 2,
+ SPELL_SPECIFIC_AURA = 3,
+ SPELL_SPECIFIC_STING = 4,
+ SPELL_SPECIFIC_CURSE = 5,
+ SPELL_SPECIFIC_ASPECT = 6,
+ SPELL_SPECIFIC_TRACKER = 7,
+ SPELL_SPECIFIC_WARLOCK_ARMOR = 8,
+ SPELL_SPECIFIC_MAGE_ARMOR = 9,
+ SPELL_SPECIFIC_ELEMENTAL_SHIELD = 10,
+ SPELL_SPECIFIC_MAGE_POLYMORPH = 11,
+ SPELL_SPECIFIC_POSITIVE_SHOUT = 12,
+ SPELL_SPECIFIC_JUDGEMENT = 13,
+ SPELL_SPECIFIC_BATTLE_ELIXIR = 14,
+ SPELL_SPECIFIC_GUARDIAN_ELIXIR = 15,
+ SPELL_SPECIFIC_FLASK_ELIXIR = 16,
+ SPELL_SPECIFIC_WARLOCK_CORRUPTION= 17,
+ SPELL_SPECIFIC_WELL_FED = 18,
+ SPELL_SPECIFIC_FOOD = 19,
+ SPELL_SPECIFIC_DRINK = 20,
+ SPELL_SPECIFIC_FOOD_AND_DRINK = 21,
+ SPELL_SPECIFIC_PRESENCE = 22,
+ SPELL_SPECIFIC_CHARM = 23,
+ SPELL_SPECIFIC_SCROLL = 24,
+ SPELL_SPECIFIC_MAGE_ARCANE_BRILLANCE = 25,
+ SPELL_SPECIFIC_WARRIOR_ENRAGE = 26,
+ SPELL_SPECIFIC_PRIEST_DIVINE_SPIRIT = 27,
+ SPELL_SPECIFIC_HAND = 28,
+ SPELL_SPECIFIC_PHASE = 29,
};
#define SPELL_LINKED_MAX_SPELLS 200000
@@ -301,6 +301,7 @@ bool IsHigherHankOfSpell(uint32 spellId_1,uint32 spellId_2);
bool IsSingleFromSpellSpecificPerCaster(SpellSpecific spellSpec1, SpellSpecific spellSpec2);
bool IsSingleFromSpellSpecificPerTarget(SpellSpecific spellSpec1, SpellSpecific spellSpec2);
bool IsPassiveSpell(uint32 spellId);
+bool IsPassiveSpell(SpellEntry const * spellInfo);
bool IsAutocastableSpell(uint32 spellId);
uint32 CalculatePowerCost(SpellEntry const * spellInfo, Unit const * caster, SpellSchoolMask schoolMask);
@@ -404,6 +405,12 @@ inline bool IsAreaAuraEffect(uint32 effect)
return true;
return false;
}
+
+inline bool IsUnitOwnedAuraEffect(uint32 effect)
+{
+ return (IsAreaAuraEffect(effect) || effect == SPELL_EFFECT_APPLY_AURA);
+}
+
inline bool IsDispel(SpellEntry const *spellInfo)
{
//spellsteal is also dispel
@@ -573,8 +580,6 @@ enum ProcFlagsEx
PROC_EX_ABSORB = 0x0000400,
PROC_EX_REFLECT = 0x0000800,
PROC_EX_INTERRUPT = 0x0001000, // Melee hit result can be Interrupt (not used)
- PROC_EX_AURA_REMOVE_DESTROY = 0x0002000, // Aura absorb destroy or dispel
- PROC_EX_AURA_REMOVE_EXPIRE = 0x0004000, // Aura remove by default and by cancel
PROC_EX_NOT_ACTIVE_SPELL = 0x0008000, // Spell mustn't do damage/heal to proc
PROC_EX_EX_TRIGGER_ALWAYS = 0x0010000, // If set trigger always no matter of hit result
PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000, // If set trigger always but only one time (not implemented yet)
@@ -587,8 +592,6 @@ enum ProcFlagsEx
PROC_EX_INTERNAL_TRIGGERED = 0x4000000,
PROC_EX_INTERNAL_REQ_FAMILY = 0x8000000
};
-#define AURA_REMOVE_PROC_EX_MASK \
- (PROC_EX_AURA_REMOVE_DESTROY | PROC_EX_AURA_REMOVE_EXPIRE)
#define AURA_SPELL_PROC_EX_MASK \
(PROC_EX_NORMAL_HIT | PROC_EX_CRITICAL_HIT | PROC_EX_MISS | \
@@ -822,7 +825,6 @@ inline bool IsProfessionSkill(uint32 skill)
#define SPELL_ATTR_CU_LINK_HIT 0x00000800
#define SPELL_ATTR_CU_LINK_AURA 0x00001000
#define SPELL_ATTR_CU_LINK_REMOVE 0x00002000
-#define SPELL_ATTR_CU_MOVEMENT_IMPAIR 0x00004000
#define SPELL_ATTR_CU_EXCLUDE_SELF 0x00008000
#define SPELL_ATTR_CU_NEGATIVE_EFF0 0x00010000
#define SPELL_ATTR_CU_NEGATIVE_EFF1 0x00020000
@@ -866,15 +868,15 @@ class SpellMgr
{
uint32 mask = GetSpellElixirMask(spellid);
if((mask & ELIXIR_FLASK_MASK)==ELIXIR_FLASK_MASK)
- return SPELL_FLASK_ELIXIR;
+ return SPELL_SPECIFIC_FLASK_ELIXIR;
else if(mask & ELIXIR_BATTLE_MASK)
- return SPELL_BATTLE_ELIXIR;
+ return SPELL_SPECIFIC_BATTLE_ELIXIR;
else if(mask & ELIXIR_GUARDIAN_MASK)
- return SPELL_GUARDIAN_ELIXIR;
+ return SPELL_SPECIFIC_GUARDIAN_ELIXIR;
else if(mask & ELIXIR_WELL_FED)
- return SPELL_WELL_FED;
+ return SPELL_SPECIFIC_WELL_FED;
else
- return SPELL_NORMAL;
+ return SPELL_SPECIFIC_NORMAL;
}
uint16 GetSpellThreat(uint32 spellid) const
diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp
index 05e47ee1db3..f5d8bf636f2 100644
--- a/src/game/StatSystem.cpp
+++ b/src/game/StatSystem.cpp
@@ -24,6 +24,7 @@
#include "Creature.h"
#include "SharedDefines.h"
#include "SpellAuras.h"
+#include "SpellAuraEffects.h"
/*#######################################
######## ########
@@ -97,9 +98,9 @@ bool Player::UpdateStats(Stats stat)
// Update ratings in exist SPELL_AURA_MOD_RATING_FROM_STAT and only depends from stat
uint32 mask = 0;
- AuraEffectList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT);
+ AuraEffectList const& modRatingFromStat = GetAuraEffectsByType(SPELL_AURA_MOD_RATING_FROM_STAT);
for (AuraEffectList::const_iterator i = modRatingFromStat.begin(); i != modRatingFromStat.end(); ++i)
- if (Stats((*i)->GetMiscBValue()) == stat)
+ if (Stats((*i)->GetMiscValueB()) == stat)
mask |= (*i)->GetMiscValue();
if (mask)
{
@@ -188,11 +189,11 @@ void Player::UpdateArmor()
value += GetModifierValue(unitMod, TOTAL_VALUE);
//add dynamic flat mods
- AuraEffectList const& mResbyIntellect = GetAurasByType(SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT);
+ AuraEffectList const& mResbyIntellect = GetAuraEffectsByType(SPELL_AURA_MOD_RESISTANCE_OF_STAT_PERCENT);
for (AuraEffectList::const_iterator i = mResbyIntellect.begin(); i != mResbyIntellect.end(); ++i)
{
if((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
- value += int32(GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetAmount() / 100.0f);
+ value += int32(GetStat(Stats((*i)->GetMiscValueB())) * (*i)->GetAmount() / 100.0f);
}
value *= GetModifierValue(unitMod, TOTAL_PCT);
@@ -315,7 +316,7 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
case FORM_DIREBEAR:
case FORM_MOONKIN:
{
- Unit::AuraEffectList const& mDummy = GetAurasByType(SPELL_AURA_DUMMY);
+ Unit::AuraEffectList const& mDummy = GetAuraEffectsByType(SPELL_AURA_DUMMY);
for (Unit::AuraEffectList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr)
{
// Predatory Strikes (effect 0)
@@ -360,18 +361,18 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
{
if ((getClassMask() & CLASSMASK_WAND_USERS)==0)
{
- AuraEffectList const& mRAPbyStat = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT);
+ AuraEffectList const& mRAPbyStat = GetAuraEffectsByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT);
for (AuraEffectList::const_iterator i = mRAPbyStat.begin(); i != mRAPbyStat.end(); ++i)
attPowerMod += int32(GetStat(Stats((*i)->GetMiscValue())) * (*i)->GetAmount() / 100.0f);
}
}
else
{
- AuraEffectList const& mAPbyStat = GetAurasByType(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT);
+ AuraEffectList const& mAPbyStat = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT);
for (AuraEffectList::const_iterator i = mAPbyStat.begin(); i != mAPbyStat.end(); ++i)
attPowerMod += int32(GetStat(Stats((*i)->GetMiscValue())) * (*i)->GetAmount() / 100.0f);
- AuraEffectList const& mAPbyArmor = GetAurasByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR);
+ AuraEffectList const& mAPbyArmor = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACK_POWER_OF_ARMOR);
for (AuraEffectList::const_iterator iter = mAPbyArmor.begin(); iter != mAPbyArmor.end(); ++iter)
// always: ((*i)->GetModifier()->m_miscvalue == 1 == SPELL_SCHOOL_MASK_NORMAL)
attPowerMod += int32(GetArmor() / (*iter)->GetAmount());
@@ -666,7 +667,7 @@ void Player::UpdateExpertise(WeaponAttackType attack)
Item *weapon = GetWeaponForAttack(attack);
- AuraEffectList const& expAuras = GetAurasByType(SPELL_AURA_MOD_EXPERTISE);
+ AuraEffectList const& expAuras = GetAuraEffectsByType(SPELL_AURA_MOD_EXPERTISE);
for (AuraEffectList::const_iterator itr = expAuras.begin(); itr != expAuras.end(); ++itr)
{
// item neutral spell
@@ -711,7 +712,7 @@ void Player::UpdateManaRegen()
float power_regen_mp5 = (GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) + m_baseManaRegen) / 5.0f;
// Get bonus from SPELL_AURA_MOD_MANA_REGEN_FROM_STAT aura
- AuraEffectList const& regenAura = GetAurasByType(SPELL_AURA_MOD_MANA_REGEN_FROM_STAT);
+ AuraEffectList const& regenAura = GetAuraEffectsByType(SPELL_AURA_MOD_MANA_REGEN_FROM_STAT);
for (AuraEffectList::const_iterator i = regenAura.begin(); i != regenAura.end(); ++i)
{
power_regen_mp5 += GetStat(Stats((*i)->GetMiscValue())) * (*i)->GetAmount() / 500.0f;
@@ -730,7 +731,7 @@ void Player::_ApplyAllStatBonuses()
{
SetCanModifyStats(false);
- _ApplyAllAuraMods();
+ _ApplyAllAuraStatMods();
_ApplyAllItemMods();
SetCanModifyStats(true);
@@ -743,7 +744,7 @@ void Player::_RemoveAllStatBonuses()
SetCanModifyStats(false);
_RemoveAllItemMods();
- _RemoveAllAuraMods();
+ _RemoveAllAuraStatMods();
SetCanModifyStats(true);
@@ -1239,7 +1240,7 @@ void Guardian::UpdateDamagePhysical(WeaponAttackType attType)
}
}
- Unit::AuraEffectList const& mDummy = GetAurasByType(SPELL_AURA_MOD_ATTACKSPEED);
+ Unit::AuraEffectList const& mDummy = GetAuraEffectsByType(SPELL_AURA_MOD_ATTACKSPEED);
for(Unit::AuraEffectList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr)
{
switch ((*itr)->GetSpellProto()->Id)
diff --git a/src/game/ThreatManager.cpp b/src/game/ThreatManager.cpp
index 5788d954882..438a6cb0381 100644
--- a/src/game/ThreatManager.cpp
+++ b/src/game/ThreatManager.cpp
@@ -285,7 +285,7 @@ HostilReference* ThreatContainer::selectNextVictim(Creature* pAttacker, HostilRe
assert(target); // if the ref has status online the target must be there !
// some units are prefered in comparison to others
- if(!noPriorityTargetFound && (target->IsImmunedToDamage(pAttacker->GetMeleeDamageSchoolMask()) || target->hasNegativeAuraWithInterruptFlag(AURA_INTERRUPT_FLAG_TAKE_DAMAGE)) )
+ if(!noPriorityTargetFound && (target->IsImmunedToDamage(pAttacker->GetMeleeDamageSchoolMask()) || target->HasNegativeAuraWithInterruptFlag(AURA_INTERRUPT_FLAG_TAKE_DAMAGE)) )
{
if(iter != lastRef)
{
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 89342551cdb..b31a406e185 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -33,6 +33,7 @@
#include "Spell.h"
#include "Group.h"
#include "SpellAuras.h"
+#include "SpellAuraEffects.h"
#include "MapManager.h"
#include "ObjectAccessor.h"
#include "CreatureAI.h"
@@ -125,12 +126,8 @@ Unit::Unit()
m_SummonSlot[i] = 0;
m_ObjectSlot[0] = m_ObjectSlot[1] = m_ObjectSlot[2] = m_ObjectSlot[3] = 0;
- //m_Aura = NULL;
- //m_AurasCheck = 2000;
- //m_removeAuraTimer = 4;
- //tmpAura = NULL;
- m_AurasUpdateIterator = m_Auras.end();
+ m_auraUpdateIterator = m_ownedAuras.end();
m_Visibility = VISIBILITY_ON;
m_interruptMask = 0;
@@ -200,7 +197,7 @@ Unit::~Unit()
RemoveAllGameObjects();
RemoveAllDynObjects();
- _DeleteAuras();
+ _DeleteRemovedAuras();
if (m_charmInfo)
delete m_charmInfo;
@@ -211,6 +208,9 @@ Unit::~Unit()
assert(m_attackers.empty());
assert(m_sharedVision.empty());
assert(m_Controlled.empty());
+ assert(m_appliedAuras.empty());
+ assert(m_ownedAuras.empty());
+ assert(m_removedAuras.empty());
}
void Unit::Update(uint32 p_time)
@@ -514,87 +514,11 @@ void Unit::GetRandomContactPoint(const Unit* obj, float &x, float &y, float &z,
, GetAngle(obj) + (attacker_number ? (M_PI/2 - M_PI * rand_norm()) * float(attacker_number) / combat_reach * 0.3 : 0));
}
-void Unit::RemoveMovementImpairingAuras()
-{
- RemoveAurasWithMechanic((1<<MECHANIC_SNARE)|(1<<MECHANIC_ROOT));
- return;
-
- for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
- {
- if (spellmgr.GetSpellCustomAttr(iter->second->GetId()) & SPELL_ATTR_CU_MOVEMENT_IMPAIR)
- RemoveAura(iter);
- else
- ++iter;
- }
-}
-
-void Unit::RemoveAurasWithInterruptFlags(uint32 flag, uint32 except)
-{
- if (!(m_interruptMask & flag))
- return;
-
- // interrupt auras
- for (AuraList::iterator iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end();)
- {
- Aura * aur = *iter;
- ++iter;
- if ((aur->GetSpellProto()->AuraInterruptFlags & flag) && (!except || aur->GetId() != except))
- {
- uint32 removedAuras = m_removedAurasCount;
- RemoveAura(aur, AURA_REMOVE_BY_ENEMY_SPELL);
- if (m_removedAurasCount > removedAuras + 1)
- iter = m_interruptableAuras.begin();
- }
- }
-
- // interrupt channeled spell
- if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
- if (spell->getState() == SPELL_STATE_CASTING
- && (spell->m_spellInfo->ChannelInterruptFlags & flag)
- && spell->m_spellInfo->Id != except)
- InterruptNonMeleeSpells(false);
-
- UpdateInterruptMask();
-}
-
-void Unit::RemoveAurasWithFamily(uint32 family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID)
-{
- for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
- {
- if (!casterGUID || iter->second->GetCasterGUID() == casterGUID)
- {
- SpellEntry const *spell = iter->second->GetSpellProto();
- if (spell->SpellFamilyName == family && spell->SpellFamilyFlags.HasFlag(familyFlag1, familyFlag2, familyFlag3))
- {
- RemoveAura(iter);
- continue;
- }
- }
- ++iter;
- }
-}
-
-void Unit::RemoveAurasWithMechanic(uint32 mechanic_mask, AuraRemoveMode removemode, uint32 except)
-{
- for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
- {
- if (!except || iter->second->GetId() != except)
- {
- if (GetAllSpellMechanicMask(iter->second->GetSpellProto()) & mechanic_mask)
- {
- RemoveAura(iter, removemode);
- continue;
- }
- }
- ++iter;
- }
-}
-
void Unit::UpdateInterruptMask()
{
m_interruptMask = 0;
- for (AuraList::const_iterator i = m_interruptableAuras.begin(); i != m_interruptableAuras.end(); ++i)
- m_interruptMask |= (*i)->GetSpellProto()->AuraInterruptFlags;
+ for (AuraApplicationList::const_iterator i = m_interruptableAuras.begin(); i != m_interruptableAuras.end(); ++i)
+ m_interruptMask |= (*i)->GetBase()->GetSpellProto()->AuraInterruptFlags;
if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
if (spell->getState() == SPELL_STATE_CASTING)
@@ -605,7 +529,7 @@ bool Unit::HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, uint
{
if (!HasAuraType(auraType))
return false;
- AuraEffectList const &auras = GetAurasByType(auraType);
+ AuraEffectList const &auras = GetAuraEffectsByType(auraType);
for (AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
if (SpellEntry const *iterSpellProto = (*itr)->GetSpellProto())
if (iterSpellProto->SpellFamilyName == familyName && iterSpellProto->SpellFamilyFlags[0] & familyFlags)
@@ -925,7 +849,7 @@ void Unit::CastStop(uint32 except_spellid)
InterruptSpell(CurrentSpellTypes(i),false);
}
-void Unit::CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
+void Unit::CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem, AuraEffect const * triggeredByAura, uint64 originalCaster)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
@@ -938,7 +862,7 @@ void Unit::CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castIte
CastSpell(Victim,spellInfo,triggered,castItem,triggeredByAura, originalCaster);
}
-void Unit::CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
+void Unit::CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, Item *castItem, AuraEffect const * triggeredByAura, uint64 originalCaster)
{
if (!spellInfo)
{
@@ -996,7 +920,7 @@ void Unit::CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, I
spell->prepare(&targets, triggeredByAura);
}
-void Unit::CastCustomSpell(Unit* target, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
+void Unit::CastCustomSpell(Unit* target, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem, AuraEffect const * triggeredByAura, uint64 originalCaster)
{
CustomSpellValues values;
if (bp0)
@@ -1008,14 +932,14 @@ void Unit::CastCustomSpell(Unit* target, uint32 spellId, int32 const* bp0, int32
CastCustomSpell(spellId, values, target, triggered, castItem, triggeredByAura, originalCaster);
}
-void Unit::CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* target, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
+void Unit::CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* target, bool triggered, Item *castItem, AuraEffect const * triggeredByAura, uint64 originalCaster)
{
CustomSpellValues values;
values.AddSpellMod(mod, value);
CastCustomSpell(spellId, values, target, triggered, castItem, triggeredByAura, originalCaster);
}
-void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* Victim, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster)
+void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* Victim, bool triggered, Item *castItem, AuraEffect const * triggeredByAura, uint64 originalCaster)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
if (!spellInfo)
@@ -1072,7 +996,7 @@ void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit*
}
// used for scripting
-void Unit::CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster, Unit* OriginalVictim)
+void Unit::CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem, AuraEffect const * triggeredByAura, uint64 originalCaster, Unit* OriginalVictim)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
@@ -1621,7 +1545,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
// victim's damage shield
std::set<AuraEffect*> alreadyDone;
uint32 removedAuras = pVictim->m_removedAurasCount;
- AuraEffectList const& vDamageShields = pVictim->GetAurasByType(SPELL_AURA_DAMAGE_SHIELD);
+ AuraEffectList const& vDamageShields = pVictim->GetAuraEffectsByType(SPELL_AURA_DAMAGE_SHIELD);
for (AuraEffectList::const_iterator i = vDamageShields.begin(), next = vDamageShields.begin(); i != vDamageShields.end(); i = next)
{
++next;
@@ -1679,15 +1603,15 @@ uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEnt
if (Player *modOwner = GetSpellModOwner())
modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_IGNORE_ARMOR, armor);
- AuraEffectList const& ResIgnoreAurasAb = GetAurasByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
+ AuraEffectList const& ResIgnoreAurasAb = GetAuraEffectsByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
for (AuraEffectList::const_iterator j = ResIgnoreAurasAb.begin(); j != ResIgnoreAurasAb.end(); ++j)
{
if ((*j)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL
- && (*j)->isAffectedOnSpell(spellInfo))
+ && (*j)->IsAffectedOnSpell(spellInfo))
armor= int32(float(armor) * (float(100-(*j)->GetAmount())/100.0f));
}
- AuraEffectList const& ResIgnoreAuras = GetAurasByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ AuraEffectList const& ResIgnoreAuras = GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
for (AuraEffectList::const_iterator j = ResIgnoreAuras.begin(); j != ResIgnoreAuras.end(); ++j)
{
if ((*j)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL)
@@ -1696,7 +1620,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEnt
if (GetTypeId() == TYPEID_PLAYER)
{
- AuraEffectList const& ResIgnoreAuras = GetAurasByType(SPELL_AURA_MOD_ARMOR_PENETRATION_PCT);
+ AuraEffectList const& ResIgnoreAuras = GetAuraEffectsByType(SPELL_AURA_MOD_ARMOR_PENETRATION_PCT);
for (AuraEffectList::const_iterator itr = ResIgnoreAuras.begin(); itr != ResIgnoreAuras.end(); ++itr)
{
// item neutral spell
@@ -1814,15 +1738,15 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
*resist += damageResisted;
- AuraEffectList const &ResIgnoreAurasAb = GetAurasByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
+ AuraEffectList const &ResIgnoreAurasAb = GetAuraEffectsByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST);
for (AuraEffectList::const_iterator j = ResIgnoreAurasAb.begin(); j != ResIgnoreAurasAb.end(); ++j)
{
if ((*j)->GetMiscValue() & schoolMask
- && (*j)->isAffectedOnSpell(spellInfo))
+ && (*j)->IsAffectedOnSpell(spellInfo))
*resist= int32(float(*resist) * (float(100-(*j)->GetAmount())/100.0f));
}
- AuraEffectList const &ResIgnoreAuras = GetAurasByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
+ AuraEffectList const &ResIgnoreAuras = GetAuraEffectsByType(SPELL_AURA_MOD_IGNORE_TARGET_RESIST);
for (AuraEffectList::const_iterator j = ResIgnoreAuras.begin(); j != ResIgnoreAuras.end(); ++j)
{
if ((*j)->GetMiscValue() & schoolMask)
@@ -1843,7 +1767,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
bool existExpired = false;
TriggeredSpellInfoVct triggeredSpells;
// absorb without mana cost
- AuraEffectList const& vSchoolAbsorb = pVictim->GetAurasByType(SPELL_AURA_SCHOOL_ABSORB);
+ AuraEffectList const& vSchoolAbsorb = pVictim->GetAuraEffectsByType(SPELL_AURA_SCHOOL_ABSORB);
for (AuraEffectList::const_iterator i = vSchoolAbsorb.begin(); i != vSchoolAbsorb.end() && RemainingDamage > 0; ++i)
{
if (!((*i)->GetMiscValue() & schoolMask))
@@ -1961,14 +1885,14 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
if (!caster)
break;
// Glyph of Power Word: Shield
- if (Aura *glyph = pVictim->GetAura(55672,0))
+ if (AuraEffect *glyph = pVictim->GetAuraEffect(55672, 0))
{
- int32 heal = int32(glyph->GetPartAura(0)->GetAmount() *
+ int32 heal = int32(glyph->GetAmount() *
(RemainingDamage >= currentAbsorb ? currentAbsorb : RemainingDamage) / 100);
pVictim->CastCustomSpell(pVictim, 56160, &heal, NULL, NULL, true, 0, *i);
}
// Reflective Shield
- if (AuraEffect const * aurEff = caster->GetDummyAura(SPELLFAMILY_PRIEST, 566, 0))
+ if (AuraEffect const * aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 566, 0))
{
switch(aurEff->GetMiscValue())
{
@@ -2114,13 +2038,12 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
{
for (AuraEffectList::const_iterator i = vSchoolAbsorb.begin(); i != vSchoolAbsorb.end();)
{
- Aura *aura=(*i)->GetParentAura();
- AuraEffect *auraeff =(*i);
+ AuraEffect * auraEff =(*i);
++i;
- if (auraeff->GetAmount()<=0)
+ if (auraEff->GetAmount()<=0)
{
uint32 removedAuras = pVictim->m_removedAurasCount;
- pVictim->RemoveAura(aura, AURA_REMOVE_BY_ENEMY_SPELL);
+ auraEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
if (removedAuras+1<pVictim->m_removedAurasCount)
i=vSchoolAbsorb.begin();
}
@@ -2128,7 +2051,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
}
// absorb by mana cost
- AuraEffectList const& vManaShield = pVictim->GetAurasByType(SPELL_AURA_MANA_SHIELD);
+ AuraEffectList const& vManaShield = pVictim->GetAuraEffectsByType(SPELL_AURA_MANA_SHIELD);
for (AuraEffectList::const_iterator i = vManaShield.begin(), next; i != vManaShield.end() && RemainingDamage > 0; i = next)
{
next = i; ++next;
@@ -2159,7 +2082,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
(*i)->SetAmount((*i)->GetAmount()-currentAbsorb);
if ((*i)->GetAmount() <= 0)
{
- pVictim->RemoveAura((*i)->GetParentAura(), AURA_REMOVE_BY_ENEMY_SPELL);
+ (*i)->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL);
next = vManaShield.begin();
}
@@ -2169,7 +2092,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
// only split damage if not damaging yourself
if (pVictim != this)
{
- AuraEffectList const& vSplitDamageFlat = pVictim->GetAurasByType(SPELL_AURA_SPLIT_DAMAGE_FLAT);
+ AuraEffectList const& vSplitDamageFlat = pVictim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_FLAT);
for (AuraEffectList::const_iterator i = vSplitDamageFlat.begin(), next; i != vSplitDamageFlat.end() && RemainingDamage >= 0; i = next)
{
next = i; ++next;
@@ -2201,7 +2124,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
DealDamage(caster, splitted, &cleanDamage, DIRECT_DAMAGE, schoolMask, (*i)->GetSpellProto(), false);
}
- AuraEffectList const& vSplitDamagePct = pVictim->GetAurasByType(SPELL_AURA_SPLIT_DAMAGE_PCT);
+ AuraEffectList const& vSplitDamagePct = pVictim->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_PCT);
for (AuraEffectList::const_iterator i = vSplitDamagePct.begin(), next; i != vSplitDamagePct.end() && RemainingDamage >= 0; i = next)
{
next = i; ++next;
@@ -2232,11 +2155,11 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
TotalAbsorb = (TotalAbsorb - RemainingDamage > 0) ? TotalAbsorb - RemainingDamage : 0;
// TODO: School should be checked for absorbing auras or for attacks?
int32 auraAbsorbMod = GetMaxPositiveAuraModifier(SPELL_AURA_MOD_TARGET_ABSORB_SCHOOL);
- AuraEffectList const& AbsIgnoreAurasAb = GetAurasByType(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL);
+ AuraEffectList const& AbsIgnoreAurasAb = GetAuraEffectsByType(SPELL_AURA_MOD_TARGET_ABILITY_ABSORB_SCHOOL);
for (AuraEffectList::const_iterator i = AbsIgnoreAurasAb.begin(); i != AbsIgnoreAurasAb.end(); ++i)
{
if ((*i)->GetAmount() > auraAbsorbMod
- && (*i)->isAffectedOnSpell(spellInfo))
+ && (*i)->IsAffectedOnSpell(spellInfo))
auraAbsorbMod = (*i)->GetAmount();
}
@@ -2282,13 +2205,13 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff
{
// Incanter's Absorption
// TODO: move this code to procflag
- if (AuraEffect const * aurEff = pVictim->GetDummyAura(SPELLFAMILY_GENERIC, 2941, 0))
+ if (AuraEffect const * aurEff = pVictim->GetDummyAuraEffect(SPELLFAMILY_GENERIC, 2941, 0))
{
// Get total damage bonus from auras
int32 current_dmg = 0;
- std::pair<AuraMap::const_iterator, AuraMap::const_iterator> range = pVictim->GetAuras().equal_range(44413);
+ std::pair<AuraMap::const_iterator, AuraMap::const_iterator> range = pVictim->GetOwnedAuras().equal_range(44413);
for (AuraMap::const_iterator iter = range.first; iter != range.second; ++iter)
- if (AuraEffect const * bonusEff = iter->second->GetPartAura(0))
+ if (AuraEffect const * bonusEff = iter->second->GetEffect(0))
current_dmg += bonusEff->GetAmount();
int32 new_dmg = (int32)*absorb * aurEff->GetAmount() / 100;
@@ -2629,10 +2552,10 @@ bool Unit::isSpellBlocked(Unit *pVictim, SpellEntry const * /*spellProto*/, Weap
{
/* Currently not exist spells with ignore block
// Ignore combat result aura (parry/dodge check on prepare)
- AuraList const& ignore = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
+ AuraList const& ignore = GetAuraEffectsByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
for (AuraList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
{
- if (!(*i)->isAffectedOnSpell(spellProto))
+ if (!(*i)->IsAffectedOnSpell(spellProto))
continue;
if ((*i)->GetMiscValue() == )
return false;
@@ -2820,10 +2743,10 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell)
canBlock = false;
}
// Ignore combat result aura
- AuraEffectList const &ignore = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
+ AuraEffectList const &ignore = GetAuraEffectsByType(SPELL_AURA_IGNORE_COMBAT_RESULT);
for (AuraEffectList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)
{
- if (!(*i)->isAffectedOnSpell(spell))
+ if (!(*i)->IsAffectedOnSpell(spell))
continue;
switch ((*i)->GetMiscValue())
{
@@ -2996,7 +2919,7 @@ SpellMissInfo Unit::SpellHitResult(Unit *pVictim, SpellEntry const *spell, bool
if (CanReflect)
{
int32 reflectchance = pVictim->GetTotalAuraModifier(SPELL_AURA_REFLECT_SPELLS);
- Unit::AuraEffectList const& mReflectSpellsSchool = pVictim->GetAurasByType(SPELL_AURA_REFLECT_SPELLS_SCHOOL);
+ Unit::AuraEffectList const& mReflectSpellsSchool = pVictim->GetAuraEffectsByType(SPELL_AURA_REFLECT_SPELLS_SCHOOL);
for (Unit::AuraEffectList::const_iterator i = mReflectSpellsSchool.begin(); i != mReflectSpellsSchool.end(); ++i)
if((*i)->GetMiscValue() & GetSpellSchoolMask(spell))
reflectchance += (*i)->GetAmount();
@@ -3277,13 +3200,12 @@ uint32 Unit::GetWeaponSkillValue (WeaponAttackType attType, Unit const* target)
return value;
}
-void Unit::_DeleteAuras()
+void Unit::_DeleteRemovedAuras()
{
while(!m_removedAuras.empty())
{
delete m_removedAuras.front();
m_removedAuras.pop_front();
-// sLog.outDebug("Aura %d is deleted from unit %d", Aur->GetId(), GetGUIDLow());
}
}
@@ -3302,25 +3224,29 @@ void Unit::_UpdateSpells( uint32 time )
}
}
- // update auras
- // m_AurasUpdateIterator can be updated in inderect called code at aura remove to skip next planned to update but removed auras
- for (m_AurasUpdateIterator = m_Auras.begin(); m_AurasUpdateIterator != m_Auras.end();)
+ // update auraBases
+ // m_auraBaseUpdateIterator can be updated in indirect called code at aura remove to skip next planned to update but removed auras
+ for (m_auraUpdateIterator = m_ownedAuras.begin(); m_auraUpdateIterator != m_ownedAuras.end();)
{
- Aura* i_aura = m_AurasUpdateIterator->second;
- ++m_AurasUpdateIterator; // need shift to next for allow update if need into aura update
- i_aura->Update(time);
+ Aura * i_aura = m_auraUpdateIterator->second;
+ ++m_auraUpdateIterator; // need shift to next for allow update if need into aura update
+ i_aura->UpdateOwner(time, this);
}
- // remove expired auras
- for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end();)
+ // remove expired auras - do that after updates(used in scripts?)
+ for (AuraMap::iterator i = m_ownedAuras.begin(); i != m_ownedAuras.end();)
{
if(i->second->IsExpired())
- RemoveAura(i, AURA_REMOVE_BY_EXPIRE);
+ RemoveOwnedAura(i, AURA_REMOVE_BY_EXPIRE);
else
++i;
}
- _DeleteAuras();
+ for (VisibleAuraMap::iterator itr = m_visibleAuras.begin(); itr != m_visibleAuras.end(); ++itr)
+ if (itr->second->IsNeedClientUpdate())
+ itr->second->ClientUpdate();
+
+ _DeleteRemovedAuras();
if(!m_gameObj.empty())
{
@@ -3591,332 +3517,269 @@ void Unit::DeMorph()
SetDisplayId(GetNativeDisplayId());
}
-int32 Unit::GetTotalAuraModifier(AuraType auratype) const
-{
- int32 modifier = 0;
-
- AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
- for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
- modifier += (*i)->GetAmount();
-
- return modifier;
-}
-
-float Unit::GetTotalAuraMultiplier(AuraType auratype) const
+void Unit::_AddAura(Aura * aura)
{
- float multiplier = 1.0f;
-
- AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
- for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
- multiplier *= (100.0f + (*i)->GetAmount())/100.0f;
-
- return multiplier;
+ m_ownedAuras.insert(AuraMap::value_type(aura->GetId(), aura));
}
-int32 Unit::GetMaxPositiveAuraModifier(AuraType auratype)
+AuraApplication * Unit::__ApplyAura(Aura * aura)
{
- int32 modifier = 0;
+ // auraBase musn't be removed
+ assert(!aura->IsRemoved());
- AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
- for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
- {
- if ((*i)->GetAmount() > modifier)
- modifier = (*i)->GetAmount();
- }
+ SpellEntry const* aurSpellInfo = aura->GetSpellProto();
+ uint32 aurId = aurSpellInfo->Id;
- return modifier;
-}
+ // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
+ if( !isAlive() && !IsDeathPersistentSpell(aurSpellInfo) &&
+ (GetTypeId() != TYPEID_PLAYER || !((Player*)this)->GetSession()->PlayerLoading()) )
+ return NULL;
-int32 Unit::GetMaxNegativeAuraModifier(AuraType auratype) const
-{
- int32 modifier = 0;
+ Unit * caster = aura->GetCaster();
- AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
- for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
- if ((*i)->GetAmount() < modifier)
- modifier = (*i)->GetAmount();
+ // Add all pointers to lists here to prevent possible pointer invalidation on spellcast/auraapply/auraremove
- return modifier;
-}
+ AuraApplication * aurApp = new AuraApplication(this, caster, aura);
+ m_appliedAuras.insert(AuraApplicationMap::value_type(aurId, aurApp));
-int32 Unit::GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const
-{
- int32 modifier = 0;
+ // Register single cast aura
+ if (caster && aura->IsSingleTarget())
+ caster->GetSingleCastAuras().push_back(aurApp);
- AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
- for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ if(aurSpellInfo->AuraInterruptFlags)
{
- if ((*i)->GetMiscValue()& misc_mask)
- modifier += (*i)->GetAmount();
+ m_interruptableAuras.push_back(aurApp);
+ AddInterruptMask(aurSpellInfo->AuraInterruptFlags);
}
- return modifier;
-}
-float Unit::GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask) const
-{
- float multiplier = 1.0f;
+ AuraState aState = GetSpellAuraState(aura->GetSpellProto());
+ if(aState)
+ m_auraStateAuras.insert(AuraStateAurasMap::value_type(aState, aurApp));
- AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
- for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
- {
- if ((*i)->GetMiscValue()& misc_mask)
- multiplier *= (100.0f + (*i)->GetAmount())/100.0f;
- }
- return multiplier;
-}
-
-int32 Unit::GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const
-{
- int32 modifier = 0;
+ aura->_ApplyForTarget(this, caster, aurApp);
- AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
- for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ // passive and Incanter's Absorption and auras with different type can stack with themselves any number of times
+ // auras with type other than TARGET_AURA have CanAuraStack check in their target selection code, so shouldn't go here
+ if (!aura->IsPassive() && aura->GetType() == UNIT_AURA_TYPE && aurId != 44413)
{
- if ((*i)->GetMiscValue()& misc_mask && (*i)->GetAmount() > modifier)
- modifier = (*i)->GetAmount();
- }
-
- return modifier;
-}
-
-int32 Unit::GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const
-{
- int32 modifier = 0;
+ // find current aura from spell and change it's stackamount
+ if (AuraApplication * foundAura = GetAuraApplication(aurId, aura->GetCasterGUID(), 0, aurApp))
+ {
+ if(aurSpellInfo->StackAmount)
+ aura->ModStackAmount(foundAura->GetBase()->GetStackAmount());
- AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
- for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
- {
- if ((*i)->GetMiscValue()& misc_mask && (*i)->GetAmount() < modifier)
- modifier = (*i)->GetAmount();
+ // Use the new one to replace the old one
+ // This is the only place where AURA_REMOVE_BY_STACK should be used
+ RemoveAura(foundAura, AURA_REMOVE_BY_STACK);
+ }
}
- return modifier;
-}
-
-int32 Unit::GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
-{
- int32 modifier = 0;
-
- AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
- for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ // update single target auras list - after aura stack check to allow single target auras to stack
+ if (aura->IsSingleTarget())
{
- if ((*i)->GetMiscValue()== misc_value)
- modifier += (*i)->GetAmount();
+ for (;;)
+ {
+ bool restart = false;
+ AuraApplicationList& scAuras = caster->GetSingleCastAuras();
+ for (AuraApplicationList::iterator itr = scAuras.begin(); itr != scAuras.end(); ++itr)
+ {
+ if( (*itr)->GetBase() != aura &&
+ IsSingleTargetSpells((*itr)->GetBase()->GetSpellProto(), aura->GetSpellProto()))
+ {
+ (*itr)->GetBase()->Remove(AURA_REMOVE_BY_DEFAULT);
+ restart = true;
+ break;
+ }
+ }
+
+ if(!restart)
+ break;
+ }
}
- return modifier;
-}
-float Unit::GetTotalAuraMultiplierByMiscValue(AuraType auratype, int32 misc_value) const
-{
- float multiplier = 1.0f;
+ _RemoveNoStackAurasDueToAura(aura);
- AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
- for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
- {
- if ((*i)->GetMiscValue()== misc_value)
- multiplier *= (100.0f + (*i)->GetAmount())/100.0f;
- }
- return multiplier;
-}
+ // Update target aura state flag
+ if(aState)
+ ModifyAuraState(aState, true);
-int32 Unit::GetMaxPositiveAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
-{
- int32 modifier = 0;
+ // Sitdown on apply aura req seated
+ if (aurSpellInfo->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED && !IsSitState())
+ SetStandState(UNIT_STAND_STATE_SIT);
- AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
- for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
- {
- if ((*i)->GetMiscValue()== misc_value && (*i)->GetAmount() > modifier)
- modifier = (*i)->GetAmount();
- }
+ aura->HandleAuraSpecificMods(aurApp, caster, true);
- return modifier;
+ if (aurApp->GetRemoveMode())
+ return NULL;
+
+ return aurApp;
}
-int32 Unit::GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
+void Unit::__UnapplyAura(AuraApplicationMap::iterator &i)
{
- int32 modifier = 0;
+ AuraApplication * aurApp = i->second;
+ assert(aurApp->GetTarget() == this);
+ Aura * aura = aurApp->GetBase();
- AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
- for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
- {
- if ((*i)->GetMiscValue()== misc_value && (*i)->GetAmount() < modifier)
- modifier = (*i)->GetAmount();
- }
+ // dead loop is killing the server probably
+ assert(m_removedAurasCount < 0xFFFFFFFF);
- return modifier;
-}
+ ++m_removedAurasCount;
-bool Unit::AddAura(Aura *Aur, bool handleEffects)
-{
- // aura doesn't apply effects-return
- if (!Aur->GetEffectMask() || Aur->IsExpired())
- {
- delete Aur;
- return false;
- }
+ Unit * caster = aura->GetCaster();
- SpellEntry const* aurSpellInfo = Aur->GetSpellProto();
+ // Remove all pointers from lists here to prevent possible pointer invalidation on spellcast/auraapply/auraremove
+ m_appliedAuras.erase(i);
- // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load)
- if( !isAlive() && !IsDeathPersistentSpell(aurSpellInfo) &&
- //Aur->GetId() != 2584 && // Waiting to Resurrect (not have death persistence flag)
- (GetTypeId() != TYPEID_PLAYER || !((Player*)this)->GetSession()->PlayerLoading()) )
- {
- delete Aur;
- return false;
- }
+ // Unregister single cast aura
+ if (caster && aura->IsSingleTarget())
+ caster->GetSingleCastAuras().remove(aurApp);
- if(Aur->GetTarget() != this)
+ if (aura->GetSpellProto()->AuraInterruptFlags)
{
- sLog.outError("Aura (spell %u) add to aura list of %s (lowguid: %u) but Aura target is %s (lowguid: %u)",
- Aur->GetId(),(GetTypeId() == TYPEID_PLAYER?"player":"creature"),GetGUIDLow(),
- (Aur->GetTarget()->GetTypeId() == TYPEID_PLAYER?"player":"creature"),Aur->GetTarget()->GetGUIDLow());
- delete Aur;
- return false;
+ m_interruptableAuras.remove(aurApp);
+ UpdateInterruptMask();
}
- uint32 aurId = aurSpellInfo->Id;
-
- // passive and persistent and Incanter's Absorption auras can stack with themselves any number of times
- if (!Aur->IsPassive() && !Aur->IsPersistent() && aurId != 44413)
+ bool auraStateFound = false;
+ AuraState auraState;
+ if (auraState = GetSpellAuraState(aura->GetSpellProto()))
{
- // find current aura from spell and change it's stackamount
- if (Aura * foundAura = GetAura(aurId, Aur->GetCasterGUID()))
+ bool canBreak = false;
+ // Get mask of all aurastates from remaining auras
+ for (AuraStateAurasMap::iterator itr = m_auraStateAuras.lower_bound(auraState); itr != m_auraStateAuras.upper_bound(auraState) && !(auraStateFound && canBreak);)
{
- if(aurSpellInfo->StackAmount)
+ if (itr->second == aurApp)
{
- uint8 stackAmount = foundAura->GetStackAmount() + 1;
- if (stackAmount > aurSpellInfo->StackAmount)
- stackAmount = aurSpellInfo->StackAmount;
- Aur->SetStackAmount(stackAmount, false);
-
- // spell is triggered with only stackamount change but no amount change
- switch(aurId)
- {
- case 28832: // Mark of Korth'azz
- case 28833: // Mark of Blaumeux
- case 28834: // Mark of Rivendare
- case 28835: // Mark of Zeliek
- if(Unit *caster = Aur->GetCaster()) // actually we can also use cast(this, originalcasterguid)
- {
- int32 damage;
- switch(stackAmount)
- {
- case 1: damage = 0; break;
- case 2: damage = 500; break;
- case 3: damage = 1000; break;
- case 4: damage = 1500; break;
- case 5: damage = 4000; break;
- case 6: damage = 12000; break;
- default:damage = 20000 + 1000 * (stackAmount - 7); break;
- }
- if(damage)
- caster->CastCustomSpell(28836, SPELLVALUE_BASE_POINT0, damage, this);
- }
- break;
- case 64821: // Fuse Armor (Razorscale)
- if(stackAmount == aurSpellInfo->StackAmount)
- CastSpell(this, 64774, true, NULL, NULL, Aur->GetCasterGUID());
- break;
- }
+ m_auraStateAuras.erase(itr);
+ itr = m_auraStateAuras.lower_bound(auraState);
+ canBreak = true;
+ continue;
}
-
- // Use the new one to replace the old one
- // This is the only place where AURA_REMOVE_BY_STACK should be used
- RemoveAura(foundAura, AURA_REMOVE_BY_STACK);
+ auraStateFound = true;
+ ++itr;
}
}
- // passive auras not stacable with other ranks
- if (!RemoveNoStackAurasDueToAura(Aur))
+ aurApp->_Remove();
+ aura->_UnapplyForTarget(this, caster, aurApp);
+
+ // remove effects of the spell - needs to be done after removing aura from lists
+ for (uint8 itr = 0 ; itr < MAX_SPELL_EFFECTS; ++itr)
{
- delete Aur;
- return false; // couldn't remove conflicting aura with higher rank
+ if (aurApp->HasEffect(itr))
+ aurApp->_HandleEffect(itr, false);
}
- // update single target auras list (before aura add to aura list, to prevent unexpected remove recently added aura)
- if (Aur->IsSingleTarget())
+ // all effect mustn't be applied
+ assert(!aurApp->GetEffectMask());
+
+ // Remove totem at next update if totem looses its aura
+ if (aurApp->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE && GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isTotem()&& ((TempSummon*)this)->GetSummonerGUID() == aura->GetCasterGUID())
{
- // caster pointer can be deleted in time aura remove, find it by guid at each iteration
- for (;;)
- {
- Unit* caster = Aur->GetCaster();
- assert(caster);
+ if (((Totem*)this)->GetSpell() == aura->GetId() && ((Totem*)this)->GetTotemType() == TOTEM_PASSIVE)
+ ((Totem*)this)->setDeathState(JUST_DIED);
+ }
- bool restart = false;
- AuraList& scAuras = caster->GetSingleCastAuras();
- for (AuraList::iterator itr = scAuras.begin(); itr != scAuras.end(); ++itr)
- {
- if( (*itr)->GetTarget() != Aur->GetTarget() &&
- IsSingleTargetSpells((*itr)->GetSpellProto(),aurSpellInfo) )
- {
- (*itr)->GetTarget()->RemoveAurasDueToSpell((*itr)->GetId(), caster->GetGUID(), AURA_REMOVE_BY_DEFAULT);
- restart = true;
- break;
- }
- }
+ // Remove aurastates only if were not found
+ if (!auraStateFound)
+ ModifyAuraState(auraState, false);
- if(!restart)
- {
- // done
- scAuras.push_back(Aur);
- break;
- }
- }
- }
+ aura->HandleAuraSpecificMods(aurApp, caster, false);
- // add aura, register in lists and arrays
- Aur->_AddAura();
+ // only way correctly remove all auras from list
+ //if(removedAuras != m_removedAurasCount) new aura may be added
+ i = m_appliedAuras.begin();
+}
- //*****************************************************
- // Update target aura state flag
- //*****************************************************
- if(AuraState aState = GetSpellAuraState(Aur->GetSpellProto()))
+bool Unit::_ApplyAuraEffect(Aura * aura, uint8 effIndex)
+{
+ // check if aura has requested effect - should always do
+ assert(aura);
+ assert(aura->HasEffect(effIndex));
+ AuraApplication * aurApp = aura->GetApplicationOfTarget(GetGUID());
+ if (!aurApp)
{
- m_auraStateAuras.insert(AuraStateAurasMap::value_type(aState, Aur));
- ModifyAuraState(aState, true);
+ // real aura apply
+ aurApp = __ApplyAura(aura);
+ if (!aurApp)
+ return false;
}
+ // add effect to unit
+ aurApp->_HandleEffect(effIndex, true);
+ return true;
+}
- m_Auras.insert(AuraMap::value_type(aurId, Aur));
+// Not implemented - afaik there should be no way to remove effects separately
+void Unit::_UnapplyAuraEffect(AuraApplication * aurApp, uint8 effIndex, AuraRemoveMode removeMode)
+{
+ assert(aurApp);
+ assert(aurApp->HasEffect(effIndex));
+ _UnapplyAura(aurApp, removeMode);
+}
- if(aurSpellInfo->AuraInterruptFlags)
+void Unit::_UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode)
+{
+ AuraApplication * aurApp = i->second;
+ assert(aurApp);
+ assert(!aurApp->GetRemoveMode());
+ aurApp->SetRemoveMode(removeMode);
+ sLog.outDebug("Aura %u now is remove mode %d", aurApp->GetBase()->GetId(), removeMode);
+ __UnapplyAura(i);
+}
+
+void Unit::_UnapplyAura(AuraApplication * aurApp, AuraRemoveMode removeMode)
+{
+ // aura can be removed from unit only if it's applied on it, shouldn't happen
+ assert(aurApp->GetBase()->GetApplicationOfTarget(GetGUID()) == aurApp);
+ uint32 spellId = aurApp->GetBase()->GetId();
+ for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
{
- m_interruptableAuras.push_back(Aur);
- AddInterruptMask(aurSpellInfo->AuraInterruptFlags);
+ if (iter->second == aurApp)
+ {
+ _UnapplyAura(iter, removeMode);
+ return;
+ }
+ else
+ ++iter;
}
-
- if (handleEffects)
- Aur->HandleEffects(true);
-
- sLog.outDebug("Aura %u now is in use", aurId);
- return true;
}
-bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
+void Unit::_RemoveNoStackAurasDueToAura(Aura * aura)
{
- SpellEntry const* spellProto = Aur->GetSpellProto();
+ if (aura->GetType() == DYNOBJ_AURA_TYPE)
+ return;
+
+ SpellEntry const* spellProto = aura->GetSpellProto();
- uint32 spellId = Aur->GetId();
+ uint32 spellId = aura->GetId();
// passive spell special case (only non stackable with ranks)
if(IsPassiveSpell(spellId) && IsPassiveSpellStackableWithRanks(spellProto))
- return true;
+ return;
//bool linked = spellmgr.GetSpellCustomAttr(spellId) & SPELL_ATTR_CU_LINK_AURA? true : false;
bool remove = false;
- for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i)
+ for (AuraApplicationMap::iterator i = m_appliedAuras.begin(); i != m_appliedAuras.end(); ++i)
{
if(remove)
{
remove = false;
- i = m_Auras.begin();
+ i = m_appliedAuras.begin();
}
- SpellEntry const* i_spellProto = i->second->GetSpellProto();
+ // Do not check already applied aura
+ if (i->second->GetBase() == aura)
+ continue;
+
+ // Do not check already applied aura
+ if (i->second->GetBase()->GetType() != aura->GetType())
+ continue;
+
+ SpellEntry const* i_spellProto = i->second->GetBase()->GetSpellProto();
uint32 i_spellId = i_spellProto->Id;
- bool sameCaster = Aur->GetCasterGUID() == (*i).second->GetCasterGUID();
+ bool sameCaster = aura->GetCasterGUID() == (*i).second->GetBase()->GetCasterGUID();
if(IsPassiveSpell(i_spellId))
{
@@ -3942,49 +3805,102 @@ bool Unit::RemoveNoStackAurasDueToAura(Aura *Aur)
}
}
- // check if they can stack
-
- /*// Dont remove by stack with linked auras
- // Not needed for now
- if(sameCaster && linked)
- {
- if(const std::vector<int32> *spell_triggered = spellmgr.GetSpellLinked(spellId + SPELL_LINK_AURA))
- for (std::vector<int32>::const_iterator itr = spell_triggered->begin(); itr != spell_triggered->end(); ++itr)
- if(*itr>0 && *itr==i_spellId)
- {
- is_triggered_by_spell=true;
- break;
- }
- }*/
-
if (is_triggered_by_spell)
continue;
if(spellmgr.CanAurasStack(spellProto, i_spellProto, sameCaster))
continue;
- //some spells should be not removed by lower rank of them (totem, paladin aura)
- if (!sameCaster
- &&(Aur->IsAreaAura())
- &&(spellProto->DurationIndex==21)
- &&(spellmgr.IsRankSpellDueToSpell(spellProto, i_spellId))
- &&(IsHigherHankOfSpell(spellId,i_spellId)))
- return false;
-
// Remove all auras by aura caster
RemoveAura(i, AURA_REMOVE_BY_DEFAULT);
- if(i == m_Auras.end())
+ if(i == m_appliedAuras.end())
break;
remove = true;
}
- return true;
}
-void Unit::RemoveAura(uint32 spellId, uint64 caster, AuraRemoveMode removeMode)
+void Unit::_HandleAuraEffect(AuraEffect * aurEff, bool apply)
{
- for (AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);)
+ if (apply)
+ m_modAuras[aurEff->GetAuraType()].push_back(aurEff);
+ else
+ m_modAuras[aurEff->GetAuraType()].remove(aurEff);
+}
+
+// All aura base removes should go threw this function!
+void Unit::RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode)
+{
+ Aura * aura = i->second;
+ assert(!aura->IsRemoved());
+
+ // if unit currently update aura list then make safe update iterator shift to next
+ if (m_auraUpdateIterator == i)
+ ++m_auraUpdateIterator;
+
+ m_ownedAuras.erase(i);
+
+ aura->_Remove(removeMode);
+
+ i = m_ownedAuras.begin();
+}
+
+void Unit::RemoveOwnedAura(uint32 spellId, uint64 caster, uint8 reqEffMask, AuraRemoveMode removeMode)
+{
+ for (AuraMap::iterator itr = m_ownedAuras.lower_bound(spellId); itr != m_ownedAuras.upper_bound(spellId);)
+ if(((itr->second->GetEffectMask() & reqEffMask) == reqEffMask) && (!caster || itr->second->GetCasterGUID() == caster))
+ {
+ RemoveOwnedAura(itr, removeMode);
+ itr = m_ownedAuras.lower_bound(spellId);
+ }
+ else
+ ++itr;
+}
+
+void Unit::RemoveOwnedAura(Aura * aura, AuraRemoveMode removeMode)
+{
+ if (aura->IsRemoved())
+ return;
+
+ assert(aura->GetOwner() == this);
+
+ uint32 spellId = aura->GetId();
+ for (AuraMap::iterator itr = m_ownedAuras.lower_bound(spellId); itr != m_ownedAuras.upper_bound(spellId); ++itr)
+ if (itr->second == aura)
+ {
+ RemoveOwnedAura(itr, removeMode);
+ return;
+ }
+ assert(false);
+}
+
+Aura * Unit::GetOwnedAura(uint32 spellId, uint64 caster, uint8 reqEffMask) const
+{
+ for (AuraMap::const_iterator itr = m_ownedAuras.lower_bound(spellId); itr != m_ownedAuras.upper_bound(spellId); ++itr)
+ if(((itr->second->GetEffectMask() & reqEffMask) == reqEffMask) && (!caster || itr->second->GetCasterGUID() == caster))
+ return itr->second;
+ return NULL;
+}
+
+void Unit::RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode)
+{
+ AuraApplication * aurApp = i->second;
+ // Do not remove aura which is already being removed
+ if (aurApp->GetRemoveMode())
+ return;
+ Aura * aura = aurApp->GetBase();
+ _UnapplyAura(i, mode);
+ // Remove aura - for Area and Target auras
+ if (aura->GetOwner() == this)
+ aura->Remove(mode);
+}
+
+void Unit::RemoveAura(uint32 spellId, uint64 caster, uint8 reqEffMask, AuraRemoveMode removeMode)
+{
+ for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
{
- if (!caster || iter->second->GetCasterGUID() == caster)
+ Aura const * aura = iter->second->GetBase();
+ if (((aura->GetEffectMask() & reqEffMask) == reqEffMask)
+ && (!caster || aura->GetCasterGUID() == caster))
{
RemoveAura(iter, removeMode);
return;
@@ -3994,14 +3910,16 @@ void Unit::RemoveAura(uint32 spellId, uint64 caster, AuraRemoveMode removeMode)
}
}
-void Unit::RemoveAura(Aura * aur ,AuraRemoveMode mode)
+void Unit::RemoveAura(AuraApplication * aurApp, AuraRemoveMode mode)
{
+ assert(aurApp->GetBase()->GetApplicationOfTarget(GetGUID()) == aurApp);
// no need to remove
- if (!aur || aur->IsRemoved())
+ if (aurApp->GetRemoveMode() || aurApp->GetBase()->IsRemoved())
return;
- for (AuraMap::iterator iter = m_Auras.lower_bound(aur->GetId()); iter != m_Auras.upper_bound(aur->GetId());)
+ uint32 spellId = aurApp->GetBase()->GetId();
+ for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
{
- if (aur == iter->second)
+ if (aurApp == iter->second)
{
RemoveAura(iter, mode);
return;
@@ -4011,14 +3929,26 @@ void Unit::RemoveAura(Aura * aur ,AuraRemoveMode mode)
}
}
-void Unit::RemoveAurasDueToSpell(uint32 spellId, uint64 caster, AuraRemoveMode removeMode)
+void Unit::RemoveAura(Aura * aura, AuraRemoveMode mode)
{
- for (AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);)
+ if (aura->IsRemoved())
+ return;
+ if (AuraApplication * aurApp = aura->GetApplicationOfTarget(GetGUID()))
+ RemoveAura(aurApp, mode);
+ else
+ assert(false);
+}
+
+void Unit::RemoveAurasDueToSpell(uint32 spellId, uint64 caster, uint8 reqEffMask, AuraRemoveMode removeMode)
+{
+ for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
{
- if (!caster || iter->second->GetCasterGUID()==caster)
+ Aura const * aura = iter->second->GetBase();
+ if (((aura->GetEffectMask() & reqEffMask) == reqEffMask)
+ && (!caster || aura->GetCasterGUID() == caster))
{
RemoveAura(iter, removeMode);
- iter = m_Auras.lower_bound(spellId);
+ iter = m_appliedAuras.lower_bound(spellId);
}
else
++iter;
@@ -4027,9 +3957,11 @@ void Unit::RemoveAurasDueToSpell(uint32 spellId, uint64 caster, AuraRemoveMode r
void Unit::RemoveAuraFromStack(uint32 spellId, uint64 caster, AuraRemoveMode removeMode)
{
- for (AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);)
+ for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);)
{
- if (!caster || iter->second->GetCasterGUID()==caster)
+ Aura const * aura = iter->second;
+ if ((aura->GetType() == UNIT_AURA_TYPE)
+ && (!caster || aura->GetCasterGUID() == caster))
{
RemoveAuraFromStack(iter, removeMode);
return;
@@ -4039,49 +3971,65 @@ void Unit::RemoveAuraFromStack(uint32 spellId, uint64 caster, AuraRemoveMode rem
}
}
-inline void Unit::RemoveAuraFromStack(AuraMap::iterator &iter,AuraRemoveMode removeMode)
+inline void Unit::RemoveAuraFromStack(AuraMap::iterator &iter, AuraRemoveMode removeMode)
{
- if (iter->second->modStackAmount(-1))
- RemoveAura(iter, removeMode);
+ if (iter->second->ModStackAmount(-1))
+ RemoveOwnedAura(iter, removeMode);
}
-void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeller)
+void Unit::RemoveAurasDueToSpellByDispel(Aura * aura, Unit *dispeller)
{
- for (AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);)
+ if (aura->IsRemoved())
+ return;
+
+ uint32 spellId = aura->GetId();
+
+ for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);)
{
- Aura *aur = iter->second;
- if (casterGUID == aur->GetCasterGUID())
+ if (aura == iter->second)
{
- if (aur->GetSpellProto()->AttributesEx7 & SPELL_ATTR_EX7_DISPEL_CHARGES)
- iter = aur->DropAuraCharge() ? m_Auras.begin() : iter;
+ if (aura->GetSpellProto()->AttributesEx7 & SPELL_ATTR_EX7_DISPEL_CHARGES)
+ aura->DropCharge();
else
RemoveAuraFromStack(iter, AURA_REMOVE_BY_ENEMY_SPELL);
// Unstable Affliction (crash if before removeaura?)
- if (aur->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (aur->GetSpellProto()->SpellFamilyFlags[1] & 0x0100))
+ if (aura->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (aura->GetSpellProto()->SpellFamilyFlags[1] & 0x0100))
{
- if (AuraEffect const * aurEff = aur->GetPartAura(0))
+ if (AuraEffect const * aurEff = aura->GetEffect(0))
{
int32 damage = aurEff->GetAmount()*9;
// backfire damage and silence
dispeller->CastCustomSpell(dispeller, 31117, &damage, NULL, NULL, true, NULL, NULL, GetGUID());
}
}
- if (aur->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (aur->GetSpellProto()->SpellFamilyFlags[0] & 0x10000000))
+ // Flame Shock
+ if (aura->GetSpellProto()->SpellFamilyName == SPELLFAMILY_SHAMAN && (aura->GetSpellProto()->SpellFamilyFlags[0] & 0x10000000))
{
- Unit *caster = GetUnit(*this, casterGUID);
- uint32 triggered_spell_id = 0;
+ Unit * caster = aura->GetCaster();
if (caster)
{
+ uint32 triggeredSpellId = 0;
// Lava Flows
- if (caster->HasAura(51482)) // Rank 3
- triggered_spell_id = 65264;
- else if (caster->HasAura(51481)) // Rank 2
- triggered_spell_id = 65263;
- else if (caster->HasAura(51480)) // Rank 1
- triggered_spell_id = 64694;
- if (triggered_spell_id)
- caster->CastSpell(caster, triggered_spell_id, true);
+ if (AuraEffect const * aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_SHAMAN, 3087, 0))
+ {
+ switch(aurEff->GetId())
+ {
+ case 51482: // Rank 3
+ triggeredSpellId = 65264;
+ break;
+ case 51481: // Rank 2
+ triggeredSpellId = 65263;
+ break;
+ case 51480: // Rank 1
+ triggeredSpellId = 64694;
+ break;
+ default:
+ sLog.outError("Aura::HandleAuraSpecificMods: Unknown rank of Lava Flows (%d) found", aurEff->GetId());
+ }
+ }
+ if (triggeredSpellId)
+ caster->CastSpell(caster, triggeredSpellId, true);
}
}
return;
@@ -4091,55 +4039,67 @@ void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit
}
}
-void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer)
+void Unit::RemoveAurasDueToSpellBySteal(Aura * aura, Unit *stealer)
{
- if (casterGUID == stealer->GetGUID())
+ if (aura->IsRemoved())
return;
- for (AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);)
+ uint32 spellId = aura->GetId();
+
+ for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);)
{
- Aura * aur = iter->second;
- if (casterGUID == aur->GetCasterGUID())
+ if (aura == iter->second)
{
int32 damage[MAX_SPELL_EFFECTS];
- for (uint8 i=0; i<MAX_SPELL_EFFECTS; ++i)
+ int32 baseDamage[MAX_SPELL_EFFECTS];
+ uint8 effMask = 0;
+ uint8 recalculateMask = 0;
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (aur->GetPartAura(i))
- damage[i]=aur->GetPartAura(i)->GetAmount();
+ if (aura->GetEffect(i))
+ {
+ baseDamage[i] = aura->GetEffect(i)->GetBaseAmount();
+ damage[i] = aura->GetEffect(i)->GetAmount();
+ effMask |= (1<<i);
+ if (aura->GetEffect(i)->CanBeRecalculated())
+ recalculateMask |= (1<<i);
+ }
else
- damage[i]=NULL;
+ {
+ baseDamage[i] = NULL;
+ damage[i] = NULL;
+ }
}
- bool steal_charge = aur->GetSpellProto()->AttributesEx7 & SPELL_ATTR_EX7_DISPEL_CHARGES;
+ bool stealCharge = aura->GetSpellProto()->AttributesEx7 & SPELL_ATTR_EX7_DISPEL_CHARGES;
- if (Aura * new_aur = steal_charge ? stealer->GetAura(aur->GetId(), aur->GetCasterGUID()) : NULL)
+ if (stealCharge)
+ aura->DropCharge();
+ else
+ RemoveAuraFromStack(iter, AURA_REMOVE_BY_ENEMY_SPELL);
+
+
+ if (Aura * newAura = stealCharge ? stealer->GetAura(aura->GetId(), aura->GetCasterGUID()) : NULL)
{
- uint8 new_charges = new_aur->GetAuraCharges() + 1;
- uint8 max_charges = new_aur->GetSpellProto()->procCharges;
+ uint8 newCharges = newAura->GetCharges() + 1;
+ uint8 maxCharges = newAura->GetSpellProto()->procCharges;
// We must be able to steal as much charges as original caster can have
- if (Player* modOwner = aur->GetCaster()->GetSpellModOwner())
- modOwner->ApplySpellMod(aur->GetId(), SPELLMOD_CHARGES, max_charges);
- // TODO: Do we need to refresh an aura?
- new_aur->SetAuraCharges(max_charges < new_charges ? max_charges : new_charges);
+ if (Unit * caster = newAura->GetCaster())
+ if (Player* modOwner = caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(aura->GetId(), SPELLMOD_CHARGES, maxCharges);
+ newAura->SetCharges(maxCharges < newCharges ? maxCharges : newCharges);
}
else
{
- int32 dur = 2*MINUTE*IN_MILISECONDS < aur->GetAuraDuration() ? 2*MINUTE*IN_MILISECONDS : aur->GetAuraDuration();
+ int32 dur = 2*MINUTE*IN_MILISECONDS < aura->GetDuration() ? 2*MINUTE*IN_MILISECONDS : aura->GetDuration();
- new_aur = new Aura(aur->GetSpellProto(),aur->GetEffectMask(), stealer, stealer, stealer);
- new_aur->SetLoadedState(aur->GetCasterGUID(), dur, dur, steal_charge ? 1 : aur->GetAuraCharges(), aur->GetStackAmount(), &damage[0]);
-
- // Unregister _before_ adding to stealer
- aur->UnregisterSingleCastAura();
+ newAura = Aura::TryCreate(aura->GetSpellProto(), effMask, stealer, NULL, &baseDamage[0], NULL, aura->GetCasterGUID());
+ assert(newAura);
+ newAura->SetLoadedState(dur, dur, stealCharge ? 1 : aura->GetCharges(), aura->GetStackAmount(), recalculateMask, &damage[0]);
// strange but intended behaviour: Stolen single target auras won't be treated as single targeted
- new_aur->SetIsSingleTarget(false);
- stealer->AddAura(new_aur);
+ newAura->SetIsSingleTarget(false);
+ newAura->ApplyForTargets();
}
-
- if (steal_charge)
- iter = aur->DropAuraCharge() ? m_Auras.begin() : iter;
- else
- RemoveAuraFromStack(iter, AURA_REMOVE_BY_ENEMY_SPELL);
return;
}
else
@@ -4149,12 +4109,12 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit
void Unit::RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId)
{
- for (AuraMap::iterator iter = m_Auras.lower_bound(spellId); iter != m_Auras.upper_bound(spellId);)
+ for (AuraApplicationMap::iterator iter = m_appliedAuras.lower_bound(spellId); iter != m_appliedAuras.upper_bound(spellId);)
{
- if (!castItem || iter->second->GetCastItemGUID()==castItem->GetGUID())
+ if (!castItem || iter->second->GetBase()->GetCastItemGUID() == castItem->GetGUID())
{
RemoveAura(iter);
- iter = m_Auras.upper_bound(spellId); // overwrite by more appropriate
+ iter = m_appliedAuras.upper_bound(spellId); // overwrite by more appropriate
}
else
++iter;
@@ -4163,15 +4123,17 @@ void Unit::RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId)
void Unit::RemoveAurasByType(AuraType auraType, uint64 casterGUID, Aura * except, bool negative, bool positive)
{
- for (AuraEffectList::const_iterator iter = m_modAuras[auraType].begin(); iter != m_modAuras[auraType].end();)
+ for (AuraEffectList::iterator iter = m_modAuras[auraType].begin(); iter != m_modAuras[auraType].end();)
{
- Aura * aur = (*iter)->GetParentAura();
+ Aura * aura = (*iter)->GetBase();
+ AuraApplication * aurApp = aura ->GetApplicationOfTarget(GetGUID());
+
++iter;
- if (aur != except && (!casterGUID || aur->GetCasterGUID()==casterGUID)
- && ((negative && !aur->IsPositive()) || (positive && aur->IsPositive())))
+ if (aura != except && (!casterGUID || aura->GetCasterGUID() == casterGUID)
+ && ((negative && !aurApp->IsPositive()) || (positive && aurApp->IsPositive())))
{
uint32 removedAuras = m_removedAurasCount;
- RemoveAura(aur);
+ RemoveAura(aurApp);
if (m_removedAurasCount > removedAuras + 1)
iter = m_modAuras[auraType].begin();
}
@@ -4181,17 +4143,18 @@ void Unit::RemoveAurasByType(AuraType auraType, uint64 casterGUID, Aura * except
void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase)
{
// single target auras from other casters
- for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
+ for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
{
- if (iter->second->GetCasterGUID()!=GetGUID() && IsSingleTargetSpell(iter->second->GetSpellProto()))
+ Aura const * aura = iter->second;
+ if (aura->GetCasterGUID() !=GetGUID() && IsSingleTargetSpell(aura->GetSpellProto()))
{
if (!newPhase)
- RemoveAura(iter);
+ RemoveOwnedAura(iter);
else
{
- Unit* caster = iter->second->GetCaster();
+ Unit* caster = aura->GetCaster();
if (!caster || !caster->InSamePhase(newPhase))
- RemoveAura(iter);
+ RemoveOwnedAura(iter);
else
++iter;
}
@@ -4201,121 +4164,145 @@ void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase)
}
// single target auras at other targets
- AuraList& scAuras = GetSingleCastAuras();
- for (AuraList::iterator iter = scAuras.begin(); iter != scAuras.end();)
+ AuraApplicationList& scAuras = GetSingleCastAuras();
+ for (AuraApplicationList::iterator iter = scAuras.begin(); iter != scAuras.end();)
{
- Aura * aura=*iter;
+ AuraApplication * aurApp= *iter;
++iter;
- if (aura->GetTarget() != this && !aura->GetTarget()->InSamePhase(newPhase))
+ if (aurApp->GetTarget() != this && !aurApp->GetTarget()->InSamePhase(newPhase))
{
uint32 removedAuras = m_removedAurasCount;
- aura->GetTarget()->RemoveAura(aura);
+ aurApp->GetBase()->Remove();
if (m_removedAurasCount > removedAuras + 1)
iter = scAuras.begin();
}
}
}
-void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
-{
- Aura* Aur = i->second;
-
- // if unit currently update aura list then make safe update iterator shift to next
- if (m_AurasUpdateIterator == i)
- ++m_AurasUpdateIterator;
-
- // some ShapeshiftBoosts at remove trigger removing other auras including parent Shapeshift aura
- // remove aura from list before to prevent deleting it before
- m_Auras.erase(i);
-
- ++m_removedAurasCount;
-
- if(Aur->IsPersistent())
- if(DynamicObject *dynObj = ObjectAccessor::GetObjectInWorld(Aur->GetSourceGUID(), (DynamicObject*)NULL))
- dynObj->RemoveAffected(this);
- Aur->UnregisterSingleCastAura();
+void Unit::RemoveAurasWithInterruptFlags(uint32 flag, uint32 except)
+{
+ if (!(m_interruptMask & flag))
+ return;
- if(Aur->GetSpellProto()->AuraInterruptFlags)
+ // interrupt auras
+ for (AuraApplicationList::iterator iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end();)
{
- m_interruptableAuras.remove(Aur);
- UpdateInterruptMask();
+ Aura * aura = (*iter)->GetBase();
+ ++iter;
+ if ((aura->GetSpellProto()->AuraInterruptFlags & flag) && (!except || aura->GetId() != except))
+ {
+ uint32 removedAuras = m_removedAurasCount;
+ RemoveAura(aura);
+ if (m_removedAurasCount > removedAuras + 1)
+ iter = m_interruptableAuras.begin();
+ }
}
- Aur->SetRemoveMode(mode);
-
- sLog.outDebug("Aura %u now is remove mode %d", Aur->GetId(), mode);
- Aur->HandleEffects(false);
-
- // set aura to be removed during unit::_updatespells
- m_removedAuras.push_back(Aur);
+ // interrupt channeled spell
+ if (Spell* spell = m_currentSpells[CURRENT_CHANNELED_SPELL])
+ if (spell->getState() == SPELL_STATE_CASTING
+ && (spell->m_spellInfo->ChannelInterruptFlags & flag)
+ && spell->m_spellInfo->Id != except)
+ InterruptNonMeleeSpells(false);
- Aur->_RemoveAura();
+ UpdateInterruptMask();
+}
- bool auraStateFound = false;
- if (AuraState auraState = GetSpellAuraState(Aur->GetSpellProto()))
+void Unit::RemoveAurasWithFamily(SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID)
+{
+ for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
{
- bool canBreak = false;
- // Get mask of all aurastates from remaining auras
- for (AuraStateAurasMap::iterator itr = m_auraStateAuras.lower_bound(auraState); itr != m_auraStateAuras.upper_bound(auraState) && !(auraStateFound && canBreak);)
+ Aura const * aura = iter->second->GetBase();
+ if (!casterGUID || aura->GetCasterGUID() == casterGUID)
{
- if (itr->second == Aur)
+ SpellEntry const *spell = aura->GetSpellProto();
+ if (spell->SpellFamilyName == family && spell->SpellFamilyFlags.HasFlag(familyFlag1, familyFlag2, familyFlag3))
{
- m_auraStateAuras.erase(itr);
- itr = m_auraStateAuras.lower_bound(auraState);
- canBreak = true;
+ RemoveAura(iter);
continue;
}
- auraStateFound = true;
- ++itr;
}
- // Remove only aurastates which were not found
- if (!auraStateFound)
- ModifyAuraState(auraState, false);
- }
-
- // Remove totem at next update if totem looses its aura
- if (Aur->GetRemoveMode() == AURA_REMOVE_BY_EXPIRE && GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isTotem()&& ((TempSummon*)this)->GetSummonerGUID()==Aur->GetCasterGUID())
- {
- if (((Totem*)this)->GetSpell()==Aur->GetId() && ((Totem*)this)->GetTotemType()==TOTEM_PASSIVE)
- ((Totem*)this)->setDeathState(JUST_DIED);
+ ++iter;
}
+}
- // only way correctly remove all auras from list
- //if(removedAuras != m_removedAurasCount) new aura may be casted
- i = m_Auras.begin();
+void Unit::RemoveMovementImpairingAuras()
+{
+ RemoveAurasWithMechanic((1<<MECHANIC_SNARE)|(1<<MECHANIC_ROOT));
}
-void Unit::RemoveAllAuras()
+void Unit::RemoveAurasWithMechanic(uint32 mechanic_mask, AuraRemoveMode removemode, uint32 except)
{
- AuraMap::iterator iter = m_Auras.begin();
- while (!m_Auras.empty())
- RemoveAura(iter);
+ for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
+ {
+ Aura const * aura = iter->second->GetBase();
+ if (!except || aura->GetId() != except)
+ {
+ if (GetAllSpellMechanicMask(aura->GetSpellProto()) & mechanic_mask)
+ {
+ RemoveAura(iter, removemode);
+ continue;
+ }
+ }
+ ++iter;
+ }
}
-void Unit::RemoveAllAuras(uint64 casterGUID, Aura * except /*=NULL*/, bool negative /*=true*/, bool positive /*=true*/)
+void Unit::RemoveAreaAurasDueToLeaveWorld()
{
- for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
+ // make sure that all area auras not applied on self are removed - prevent access to deleted pointer later
+ for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
{
- if (iter->second != except && (!casterGUID || iter->second->GetCasterGUID()==casterGUID)
- && ((negative && !iter->second->IsPositive()) || (positive && iter->second->IsPositive())))
+ Aura * aura = iter->second;
+ ++iter;
+ Aura::ApplicationMap const & appMap = aura->GetApplicationMap();
+ for(Aura::ApplicationMap::const_iterator itr = appMap.begin(); itr!= appMap.end();)
+ {
+ AuraApplication * aurApp = itr->second;
+ ++itr;
+ Unit * target = aurApp->GetTarget();
+ if (target == this)
+ continue;
+ target->RemoveAura(aurApp);
+ // things linked on aura remove may apply new area aura - so start from the beginning
+ iter = m_ownedAuras.begin();
+ }
+ }
+
+ // remove area auras owned by others
+ for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
+ {
+ if (iter->second->GetBase()->GetOwner()!=this)
RemoveAura(iter);
else
++iter;
}
}
+void Unit::RemoveAllAuras()
+{
+ AuraApplicationMap::iterator aurAppIter = m_appliedAuras.begin();
+ while (!m_appliedAuras.empty())
+ _UnapplyAura(aurAppIter, AURA_REMOVE_BY_DEFAULT);
+
+ AuraMap::iterator aurIter = m_ownedAuras.begin();
+ while (!m_ownedAuras.empty())
+ RemoveOwnedAura(aurIter);
+}
+
void Unit::RemoveArenaAuras(bool onleave)
{
// in join, remove positive buffs, on end, remove negative
// used to remove positive visible auras in arenas
- for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
- {
- if ( !(iter->second->GetSpellProto()->AttributesEx4 & (1<<21)) // don't remove stances, shadowform, pally/hunter auras
- && !iter->second->IsPassive() // don't remove passive auras
- && (!(iter->second->GetSpellProto()->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) || !(iter->second->GetSpellProto()->Attributes & SPELL_ATTR_UNK8)) // not unaffected by invulnerability auras or not having that unknown flag (that seemed the most probable)
- && (iter->second->IsPositive() ^ onleave)) // remove positive buffs on enter, negative buffs on leave
- RemoveAura(iter);
+ for (AuraMap::iterator iter = m_ownedAuras.begin(); iter != m_ownedAuras.end();)
+ {
+ Aura const * aura = iter->second;
+ if ( !(aura->GetSpellProto()->AttributesEx4 & (1<<21)) // don't remove stances, shadowform, pally/hunter auras
+ && !aura->IsPassive() // don't remove passive auras
+ && (!(aura->GetSpellProto()->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY) || !(aura->GetSpellProto()->Attributes & SPELL_ATTR_UNK8)) // not unaffected by invulnerability auras or not having that unknown flag (that seemed the most probable)
+ && (aura->IsPositive(this) ^ onleave)) // remove positive buffs on enter, negative buffs on leave
+ RemoveOwnedAura(iter);
else
++iter;
}
@@ -4325,144 +4312,199 @@ void Unit::RemoveAllAurasOnDeath()
{
// used just after dieing to remove all visible auras
// and disable the mods for the passive ones
- for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end();)
+ for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();)
{
- if (!iter->second->IsPassive() && !iter->second->IsDeathPersistent())
+ Aura const * aura = iter->second->GetBase();
+ if (!aura->IsPassive() && !aura->IsDeathPersistent())
RemoveAura(iter, AURA_REMOVE_BY_DEATH);
else
++iter;
}
}
-void Unit::DelayAura(uint32 spellId, uint64 caster, int32 delaytime)
+void Unit::DelayOwnedAuras(uint32 spellId, uint64 caster, int32 delaytime)
{
- if (Aura * aur = GetAura(spellId, caster))
+ for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);++iter)
{
- if (aur->GetAuraDuration() < delaytime)
- aur->SetAuraDuration(0);
- else
- aur->SetAuraDuration(aur->GetAuraDuration() - delaytime);
- // update for out of range group members (on 1 slot use)
- UpdateAuraForGroup(aur->GetAuraSlot());
- sLog.outDebug("Aura %u partially interrupted on unit %u, new duration: %u ms",aur->GetId(), GetGUIDLow(), aur->GetAuraDuration());
+ Aura * aura = iter->second;
+ if (!caster || aura->GetCasterGUID() == caster)
+ {
+ if (aura->GetDuration() < delaytime)
+ aura->SetDuration(0);
+ else
+ aura->SetDuration(aura->GetDuration() - delaytime);
+
+ // update for out of range group members (on 1 slot use)
+ aura->SetNeedClientUpdateForTargets();
+ sLog.outDebug("Aura %u partially interrupted on unit %u, new duration: %u ms",aura->GetId() , GetGUIDLow(), aura->GetDuration());
+ }
}
}
-void Unit::_RemoveAllAuraMods()
+void Unit::_RemoveAllAuraStatMods()
{
- for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i)
- (*i).second->ApplyAllModifiers(false);
+ for (AuraApplicationMap::iterator i = m_appliedAuras.begin(); i != m_appliedAuras.end(); ++i)
+ (*i).second->GetBase()->HandleAllEffects(i->second, AURA_EFFECT_HANDLE_STAT, false);
}
-void Unit::_ApplyAllAuraMods()
+void Unit::_ApplyAllAuraStatMods()
{
- for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i)
- (*i).second->ApplyAllModifiers(true);
+ for (AuraApplicationMap::iterator i = m_appliedAuras.begin(); i != m_appliedAuras.end(); ++i)
+ (*i).second->GetBase()->HandleAllEffects(i->second, AURA_EFFECT_HANDLE_STAT, true);
}
-bool Unit::HasAuraTypeWithMiscvalue(AuraType auratype, uint32 miscvalue) const
+AuraEffect * Unit::GetAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster) const
{
- AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
- for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
- if (miscvalue == (*i)->GetMiscValue())
- return true;
- return false;
+ for (AuraApplicationMap::const_iterator itr = m_appliedAuras.lower_bound(spellId); itr != m_appliedAuras.upper_bound(spellId); ++itr)
+ if(itr->second->HasEffect(effIndex) && (!caster || itr->second->GetBase()->GetCasterGUID() == caster))
+ return itr->second->GetBase()->GetEffect(effIndex);
+ return NULL;
}
-bool Unit::HasAuraTypeWithValue(AuraType auratype, uint32 value) const
+AuraEffect * Unit::GetAuraEffectOfRankedSpell(uint32 spellId, uint8 effIndex, uint64 caster) const
{
- AuraEffectList const& mTotalAuraList = GetAurasByType(auratype);
- for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
- if (value == (*i)->GetAmount())
- return true;
- return false;
+ uint32 rankSpell = spellmgr.GetFirstSpellInChain(spellId);
+ while(true)
+ {
+ if (AuraEffect * aurEff = GetAuraEffect(spellId, effIndex, caster))
+ return aurEff;
+ SpellChainNode const * chainNode = spellmgr.GetSpellChainNode(rankSpell);
+ if (!chainNode)
+ break;
+ else
+ rankSpell = chainNode->next;
+ }
+ return NULL;
}
-bool Unit::HasAuraType(AuraType auraType) const
+AuraEffect* Unit::GetAuraEffect(AuraType type, SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
{
- return (!m_modAuras[auraType].empty());
+ AuraEffectList const& auras = GetAuraEffectsByType(type);
+ for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
+ {
+ if (effIndex != (*itr)->GetEffIndex())
+ continue;
+ SpellEntry const * spell = (*itr)->GetSpellProto();
+ if (spell->SpellIconID == iconId && spell->SpellFamilyName == name && !spell->SpellFamilyFlags)
+ return *itr;
+ }
+ return NULL;
}
-bool Unit::HasAura(uint32 spellId, uint64 caster) const
+AuraEffect* Unit::GetAuraEffect(AuraType type, SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID)
{
- //Special case for non existing spell
- if (spellId==61988)
- return HasAura(61987, caster) || HasAura(25771, caster);
+ AuraEffectList const& auras = GetAuraEffectsByType(type);
+ for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
+ {
+ SpellEntry const *spell = (*i)->GetSpellProto();
+ if (spell->SpellFamilyName == family && spell->SpellFamilyFlags.HasFlag(familyFlag1, familyFlag2, familyFlag3))
+ {
+ if (casterGUID && (*i)->GetCasterGUID()!=casterGUID)
+ continue;
+ return (*i);
+ }
+ }
+ return NULL;
+}
- if (Aura * aur = GetAura(spellId, caster))
- return true;
- return false;
+AuraApplication * Unit::GetAuraApplication(uint32 spellId, uint64 casterGUID, uint8 reqEffMask, AuraApplication * except) const
+{
+ for (AuraApplicationMap::const_iterator itr = m_appliedAuras.lower_bound(spellId); itr != m_appliedAuras.upper_bound(spellId); ++itr)
+ {
+ Aura const * aura = itr->second->GetBase();
+ if(((aura->GetEffectMask() & reqEffMask) == reqEffMask) && (!casterGUID || aura->GetCasterGUID() == casterGUID) && (!except || except!=itr->second))
+ return itr->second;
+ }
+ return NULL;
}
-bool Unit::HasAura(Aura * aur) const
+Aura * Unit::GetAura(uint32 spellId, uint64 casterGUID, uint8 reqEffMask) const
{
- // no need to find aura
- if (!aur || aur->IsRemoved())
- return false;
- for (AuraMap::const_iterator iter = m_Auras.lower_bound(aur->GetId()); iter != m_Auras.upper_bound(aur->GetId());)
+ AuraApplication * aurApp = GetAuraApplication(spellId, casterGUID, reqEffMask);
+ return aurApp ? aurApp->GetBase():NULL;
+}
+
+AuraApplication * Unit::GetAuraApplicationOfRankedSpel(uint32 spellId, uint64 casterGUID, uint8 reqEffMask, AuraApplication * except) const
+{
+ uint32 rankSpell = spellmgr.GetFirstSpellInChain(spellId);
+ while(true)
{
- if (aur == iter->second)
- return true;
+ if (AuraApplication * aurApp = GetAuraApplication(rankSpell, casterGUID, reqEffMask, except))
+ return aurApp;
+ SpellChainNode const * chainNode = spellmgr.GetSpellChainNode(rankSpell);
+ if (!chainNode)
+ break;
else
- ++iter;
+ rankSpell = chainNode->next;
}
- return false;
+ return NULL;
+}
+
+Aura * Unit::GetAuraOfRankedSpell(uint32 spellId, uint64 casterGUID, uint8 reqEffMask) const
+{
+ AuraApplication * aurApp = GetAuraApplicationOfRankedSpel(spellId, casterGUID, reqEffMask);
+ return aurApp ? aurApp->GetBase() : NULL;
}
bool Unit::HasAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster) const
{
- if (Aura * aur = GetAura(spellId, caster))
- return aur->HasEffect(effIndex);
+ for (AuraApplicationMap::const_iterator itr = m_appliedAuras.lower_bound(spellId); itr != m_appliedAuras.upper_bound(spellId); ++itr)
+ if(itr->second->HasEffect(effIndex) && (!caster || itr->second->GetBase()->GetCasterGUID() == caster))
+ return true;
return false;
}
-Aura * Unit::GetAura(uint32 spellId, uint64 caster) const
+bool Unit::HasAura(uint32 spellId, uint64 caster, uint8 reqEffMask) const
{
- if (!caster)
- {
- AuraMap::const_iterator itr = m_Auras.find(spellId);
- return itr != m_Auras.end() ? itr->second : NULL;
- }
- else
- {
- AuraMap const& auras = GetAuras();
- for (AuraMap::const_iterator itr = auras.lower_bound(spellId); itr != auras.upper_bound(spellId); ++itr)
- if(itr->second->GetCasterGUID()==caster)
- return itr->second;
- return NULL;
- }
+ //Special case for non existing spell
+ if (spellId==61988)
+ return HasAura(61987, caster, reqEffMask) || HasAura(25771, caster, reqEffMask);
+
+ if (GetAuraApplication(spellId, caster, reqEffMask))
+ return true;
+ return false;
}
-AuraEffect * Unit::GetAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster) const
+bool Unit::HasAuraType(AuraType auraType) const
+{
+ return (!m_modAuras[auraType].empty());
+}
+
+bool Unit::HasAuraTypeWithMiscvalue(AuraType auratype, uint32 miscvalue) const
{
- if (Aura * aur = GetAura(spellId, caster))
- return aur->GetPartAura(effIndex);
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ if (miscvalue == (*i)->GetMiscValue())
+ return true;
return false;
}
-AuraEffect* Unit::GetAura(AuraType type, uint32 family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID)
+bool Unit::HasAuraTypeWithValue(AuraType auratype, uint32 value) const
{
- AuraEffectList const& auras = GetAurasByType(type);
- for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ if (value == (*i)->GetAmount())
+ return true;
+ return false;
+}
+
+bool Unit::HasNegativeAuraWithInterruptFlag(uint32 flag)
+{
+ for (AuraApplicationList::iterator iter = m_interruptableAuras.begin(); iter != m_interruptableAuras.end(); ++iter)
{
- SpellEntry const *spell = (*i)->GetSpellProto();
- if (spell->SpellFamilyName == family && spell->SpellFamilyFlags.HasFlag(familyFlag1, familyFlag2, familyFlag3))
- {
- if (casterGUID && (*i)->GetCasterGUID()!=casterGUID)
- continue;
- return (*i);
- }
+ if (!(*iter)->IsPositive() && (*iter)->GetBase()->GetSpellProto()->AuraInterruptFlags & flag)
+ return true;
}
- return NULL;
+ return false;
}
AuraEffect * Unit::IsScriptOverriden(SpellEntry const * spell, int32 script) const
{
- AuraEffectList const& auras = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ AuraEffectList const& auras = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
{
if ((*i)->GetMiscValue() == script)
- if ((*i)->isAffectedOnSpell(spell))
+ if ((*i)->IsAffectedOnSpell(spell))
return (*i);
}
return NULL;
@@ -4513,7 +4555,7 @@ uint32 Unit::GetDoTsByCaster(uint64 casterGUID) const
uint32 dots=0;
for (AuraType const* itr = &diseaseAuraTypes[0]; itr && itr[0] != SPELL_AURA_NONE; ++itr)
{
- Unit::AuraEffectList const& auras = GetAurasByType(*itr);
+ Unit::AuraEffectList const& auras = GetAuraEffectsByType(*itr);
for (AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
{
// Get auras by caster
@@ -4524,6 +4566,162 @@ uint32 Unit::GetDoTsByCaster(uint64 casterGUID) const
return dots;
}
+int32 Unit::GetTotalAuraModifier(AuraType auratype) const
+{
+ int32 modifier = 0;
+
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ modifier += (*i)->GetAmount();
+
+ return modifier;
+}
+
+float Unit::GetTotalAuraMultiplier(AuraType auratype) const
+{
+ float multiplier = 1.0f;
+
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ multiplier *= (100.0f + (*i)->GetAmount())/100.0f;
+
+ return multiplier;
+}
+
+int32 Unit::GetMaxPositiveAuraModifier(AuraType auratype)
+{
+ int32 modifier = 0;
+
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ {
+ if ((*i)->GetAmount() > modifier)
+ modifier = (*i)->GetAmount();
+ }
+
+ return modifier;
+}
+
+int32 Unit::GetMaxNegativeAuraModifier(AuraType auratype) const
+{
+ int32 modifier = 0;
+
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ if ((*i)->GetAmount() < modifier)
+ modifier = (*i)->GetAmount();
+
+ return modifier;
+}
+
+int32 Unit::GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const
+{
+ int32 modifier = 0;
+
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ {
+ if ((*i)->GetMiscValue()& misc_mask)
+ modifier += (*i)->GetAmount();
+ }
+ return modifier;
+}
+
+float Unit::GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask) const
+{
+ float multiplier = 1.0f;
+
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ {
+ if ((*i)->GetMiscValue()& misc_mask)
+ multiplier *= (100.0f + (*i)->GetAmount())/100.0f;
+ }
+ return multiplier;
+}
+
+int32 Unit::GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const
+{
+ int32 modifier = 0;
+
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ {
+ if ((*i)->GetMiscValue()& misc_mask && (*i)->GetAmount() > modifier)
+ modifier = (*i)->GetAmount();
+ }
+
+ return modifier;
+}
+
+int32 Unit::GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const
+{
+ int32 modifier = 0;
+
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ {
+ if ((*i)->GetMiscValue()& misc_mask && (*i)->GetAmount() < modifier)
+ modifier = (*i)->GetAmount();
+ }
+
+ return modifier;
+}
+
+int32 Unit::GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
+{
+ int32 modifier = 0;
+
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ {
+ if ((*i)->GetMiscValue()== misc_value)
+ modifier += (*i)->GetAmount();
+ }
+ return modifier;
+}
+
+float Unit::GetTotalAuraMultiplierByMiscValue(AuraType auratype, int32 misc_value) const
+{
+ float multiplier = 1.0f;
+
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ {
+ if ((*i)->GetMiscValue()== misc_value)
+ multiplier *= (100.0f + (*i)->GetAmount())/100.0f;
+ }
+ return multiplier;
+}
+
+int32 Unit::GetMaxPositiveAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
+{
+ int32 modifier = 0;
+
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ {
+ if ((*i)->GetMiscValue()== misc_value && (*i)->GetAmount() > modifier)
+ modifier = (*i)->GetAmount();
+ }
+
+ return modifier;
+}
+
+int32 Unit::GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const
+{
+ int32 modifier = 0;
+
+ AuraEffectList const& mTotalAuraList = GetAuraEffectsByType(auratype);
+ for (AuraEffectList::const_iterator i = mTotalAuraList.begin(); i != mTotalAuraList.end(); ++i)
+ {
+ if ((*i)->GetMiscValue()== misc_value && (*i)->GetAmount() < modifier)
+ modifier = (*i)->GetAmount();
+ }
+
+ return modifier;
+}
+
void Unit::AddDynObject(DynamicObject* dynObj)
{
m_dynObjGUIDs.push_back(dynObj->GetGUID());
@@ -4727,15 +4925,15 @@ void Unit::ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVic
void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo *pInfo)
{
- AuraEffect *aura = pInfo->auraEff;
+ AuraEffect const * aura = pInfo->auraEff;
WorldPacket data(SMSG_PERIODICAURALOG, 30);
data.append(GetPackGUID());
data.appendPackGUID(aura->GetCasterGUID());
data << uint32(aura->GetId()); // spellId
data << uint32(1); // count
- data << uint32(aura->GetAuraName()); // auraId
- switch(aura->GetAuraName())
+ data << uint32(aura->GetAuraType()); // auraId
+ switch(aura->GetAuraType())
{
case SPELL_AURA_PERIODIC_DAMAGE:
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
@@ -4763,7 +4961,7 @@ void Unit::SendPeriodicAuraLog(SpellPeriodicAuraLogInfo *pInfo)
data << float(pInfo->multiplier); // gain multiplier
break;
default:
- sLog.outError("Unit::SendPeriodicAuraLog: unknown aura %u", uint32(aura->GetAuraName()));
+ sLog.outError("Unit::SendPeriodicAuraLog: unknown aura %u", uint32(aura->GetAuraType()));
return;
}
@@ -4868,8 +5066,8 @@ bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
{
SpellEntry const *hasteSpell = triggeredByAura->GetSpellProto();
- Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
- ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL;
+ Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
+ ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : NULL;
uint32 triggered_spell_id = 0;
Unit* target = pVictim;
@@ -4931,8 +5129,8 @@ bool Unit::HandleSpellCritChanceAuraProc(Unit *pVictim, uint32 /*damage*/, AuraE
{
SpellEntry const *triggeredByAuraSpell = triggeredByAura->GetSpellProto();
- Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
- ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL;
+ Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
+ ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : NULL;
uint32 triggered_spell_id = 0;
Unit* target = pVictim;
@@ -4995,25 +5193,14 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
uint32 effIndex = triggeredByAura->GetEffIndex();
int32 triggerAmount = triggeredByAura->GetAmount();
- Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
- ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL;
+ Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
+ ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : NULL;
uint32 triggered_spell_id = 0;
Unit* target = pVictim;
int32 basepoints0 = 0;
uint64 originalCaster = 0;
- // Master of subtlety (checked here because ranks have different spellfamilynames)
- if (dummySpell->Id == 31223 || dummySpell->Id == 31221 || dummySpell->Id == 31222)
- {
- if (procEx & AURA_REMOVE_PROC_EX_MASK)
- triggered_spell_id = 31666;
- else
- {
- triggered_spell_id = 31665;
- basepoints0 = triggerAmount;
- }
- }
switch(dummySpell->SpellFamilyName)
{
case SPELLFAMILY_GENERIC:
@@ -5036,30 +5223,15 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
case 33174:
case 33182:
{
- // Tricky thing here, we find current aura from spell by caster and change its modifier value
int32 spelldmg = CalculateSpellDamage(procSpell, 0, procSpell->EffectBasePoints[0],pVictim);
if (AuraEffect * Aur = pVictim->GetAuraEffect(procSpell->Id, effIndex+1, triggeredByAura->GetCasterGUID()))
{
// Remove aura mods
- Aur->ApplyModifier(false, false, true);
- Aur->SetAmount(Aur->GetAmount() + spelldmg/* * triggerAmount / 100*/);
- // Apply extended aura mods
- Aur->ApplyModifier(true, false, true);
+ Aur->ChangeAmount(Aur->GetAmount() + spelldmg);
return true;
}
return false;
}
- // Overkill
- case 58426:
- {
- if (procEx & AURA_REMOVE_PROC_EX_MASK)
- triggered_spell_id = 58428;
- else
- {
- triggered_spell_id = 58427;
- }
- break;
- }
// Eye for an Eye
case 9799:
case 25988:
@@ -5106,7 +5278,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
return false;
// find Mage Armor
- if (!GetAura(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT, SPELLFAMILY_MAGE, 0x10000000))
+ if (!GetAuraEffect(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT, SPELLFAMILY_MAGE, 0x10000000, 0, 0))
return false;
switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell)))
@@ -5175,7 +5347,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
case 33493:
{
// Cast finish spell at last charge
- if (triggeredByAura->GetParentAura()->GetAuraCharges() > 1)
+ if (triggeredByAura->GetBase()->GetCharges() > 1)
return false;
target = this;
@@ -5453,16 +5625,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
triggered_spell_id = 29077;
break;
}
- // Shattered Barrier
- if (dummySpell->SpellIconID == 2945)
- {
- // only on dispel/remove aura by destroy
- target = NULL;
- triggered_spell_id = 55080;
- CastSpell(target, triggered_spell_id, true, 0, triggeredByAura);
- return true;
- }
-
// Arcane Potency
if (dummySpell->SpellIconID == 2120)
{
@@ -5486,7 +5648,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
{
if (effIndex!=0)
return false;
- AuraEffect *counter = triggeredByAura->GetParentAura()->GetPartAura(1);
+ AuraEffect *counter = triggeredByAura->GetBase()->GetEffect(1);
if (!counter)
return true;
@@ -5568,7 +5730,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
return false;
}
- AuraEffectList const& DoTAuras = target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
+ AuraEffectList const& DoTAuras = target->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE);
for (Unit::AuraEffectList::const_iterator i = DoTAuras.begin(); i != DoTAuras.end(); ++i)
{
if ((*i)->GetCasterGUID() != GetGUID() || (*i)->GetId() != 12654 || (*i)->GetEffIndex() != 0)
@@ -5588,7 +5750,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
return false;
//last charge and crit
- if (triggeredByAura->GetParentAura()->GetAuraCharges() <= 1 && (procEx & PROC_EX_CRITICAL_HIT) )
+ if (triggeredByAura->GetBase()->GetCharges() <= 1 && (procEx & PROC_EX_CRITICAL_HIT) )
{
RemoveAurasDueToSpell(28682); //-> remove Combustion auras
return true; // charge counting (will removed)
@@ -5802,7 +5964,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
case 30296:
{
// Improved Soul Leech
- AuraEffectList const& SoulLeechAuras = GetAurasByType(SPELL_AURA_DUMMY);
+ AuraEffectList const& SoulLeechAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY);
for (Unit::AuraEffectList::const_iterator i = SoulLeechAuras.begin(); i != SoulLeechAuras.end(); ++i)
{
if ((*i)->GetId()==54117 || (*i)->GetId()==54118)
@@ -5818,7 +5980,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
// regen mana for caster
CastCustomSpell(this,59117,&basepoints0,NULL,NULL,true,castItem,triggeredByAura);
// Get second aura of spell for replenishment effect on party
- if (AuraEffect const * aurEff = (*i)->GetParentAura()->GetPartAura(1))
+ if (AuraEffect const * aurEff = (*i)->GetBase()->GetEffect(1))
{
// Replenishment - roll chance
if (roll_chance_i(aurEff->GetAmount()))
@@ -5835,22 +5997,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
triggered_spell_id = 30294;
break;
}
- // Improved Fear
- case 53754:
- {
- if(!pVictim || !pVictim->isAlive())
- return false;
- pVictim->CastSpell(pVictim, 60946,true, castItem, triggeredByAura);
- return true;
- }
- // Improved Fear (Rank 2)
- case 53759:
- {
- if(!pVictim || !pVictim->isAlive())
- return false;
- pVictim->CastSpell(pVictim, 60947,true, castItem, triggeredByAura);
- return true;
- }
// Shadowflame (Voidheart Raiment set bonus)
case 37377:
{
@@ -5940,18 +6086,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
pVictim->CastCustomSpell(pVictim,15290,&team,&self,NULL,true,castItem,triggeredByAura);
return true; // no hidden cooldown
}
- // Shadow Affinity (Ranks 1-3)
- case 15318:
- case 15272:
- case 15320:
- {
- if (!target)
- return false;
-
- basepoints0 = triggerAmount * target->GetCreateMana() / 100;
- triggered_spell_id = 64103;
- break;
- }
// Priest Tier 6 Trinket (Ashtongue Talisman of Acumen)
case 40438:
{
@@ -6002,43 +6136,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
RemoveMovementImpairingAuras();
break;
}
- // Rapture
- case 47535: // Rank 1 1.5% of max mana
- case 47536: // Rank 2 2% of max mana
- case 47537: // Rank 3 2.5% of max mana
- {
- // Effect 0 - proc on self
- if (effIndex == 0)
- {
- float multiplier = triggerAmount;
- if (dummySpell->Id == 47535)
- multiplier -= 0.5f;
- else if (dummySpell->Id == 47537)
- multiplier += 0.5f;
-
- basepoints0 = (multiplier * GetMaxPower(POWER_MANA) / 100);
- triggered_spell_id = 47755;
- target = this;
- }
- else
- {
- if (!roll_chance_i(triggerAmount))
- return false;
-
- switch(pVictim->getPowerType())
- {
- target = pVictim;
- case POWER_MANA:
- triggered_spell_id = 63654;
- basepoints0 = 2 * (pVictim->GetMaxPower(POWER_MANA) / 100);
- break;
- case POWER_RAGE: triggered_spell_id = 63653; break;
- case POWER_ENERGY: triggered_spell_id = 63655; break;
- case POWER_RUNIC_POWER: triggered_spell_id = 63652; break;
- }
- }
- break;
- }
// Glyph of Dispel Magic
case 55677:
{
@@ -6306,9 +6403,9 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
{
// "refresh your Slice and Dice duration to its 5 combo point maximum"
// lookup Slice and Dice
- if (AuraEffect const* aur = GetAura(SPELL_AURA_MOD_HASTE, SPELLFAMILY_ROGUE,0x40000, 0, 0))
+ if (AuraEffect const* aur = GetAuraEffect(SPELL_AURA_MOD_HASTE, SPELLFAMILY_ROGUE,0x40000, 0, 0))
{
- aur->GetParentAura()->SetAuraDuration(GetSpellMaxDuration(aur->GetSpellProto()), true);
+ aur->GetBase()->SetDuration(GetSpellMaxDuration(aur->GetSpellProto()), true);
return true;
}
return false;
@@ -6419,20 +6516,20 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
break;
}
// Light's Beacon - Beacon of Light
- if ( dummySpell->Id == 53651 )
+ if (dummySpell->Id == 53651)
{
- if (Unit *source = triggeredByAura->GetParentAura()->GetUnitSource())
+ // Get target of beacon of light
+ if (Unit * beaconTarget = triggeredByAura->GetBase()->GetCaster())
{
// do not proc when target of beacon of light is healed
- if (source == this)
+ if (beaconTarget == this)
return false;
- if (Unit * caster = triggeredByAura->GetCaster())
+ // check if it was heal by paladin which casted this beacon of light
+ if (Aura const * aura = beaconTarget->GetAura(53563, pVictim->GetGUID()))
{
- if (caster != pVictim)
- return false;
basepoints0 = damage;
triggered_spell_id = 53654;
- target = source;
+ target = beaconTarget;
break;
}
}
@@ -6441,10 +6538,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
// Judgements of the Wise
if (dummySpell->SpellIconID == 3017)
{
- //Mangos code, do not know if we need it
- // triggered only at casted Judgement spells, not at additional Judgement effects
- //if(!procSpell || procSpell->Category != 1210)
- // return;
target = this;
triggered_spell_id = 31930;
// replenishment
@@ -6611,7 +6704,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
chance = 15.0f;
}
// Judgement (any)
- else if (GetSpellSpecific(procSpell->Id)==SPELL_JUDGEMENT)
+ else if (GetSpellSpecific(procSpell->Id) == SPELL_SPECIFIC_JUDGEMENT)
{
triggered_spell_id = 40472;
chance = 50.0f;
@@ -6721,7 +6814,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
if( cooldown && ((Player*)this)->HasSpellCooldown(dummySpell->Id))
return false;
- if(triggeredByAura->GetParentAura() && castItem->GetGUID() != triggeredByAura->GetParentAura()->GetCastItemGUID())
+ if (triggeredByAura->GetBase() && castItem->GetGUID() != triggeredByAura->GetBase()->GetCastItemGUID())
return false;
WeaponAttackType attType = WeaponAttackType(((Player*)this)->GetAttackBySlot(castItem->GetSlot()));
@@ -6956,7 +7049,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
return false;
// Water Shield
- if (AuraEffect const * aurEff = GetAura(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0, 0x00000020))
+ if (AuraEffect const * aurEff = GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0, 0x00000020))
{
uint32 spell = aurEff->GetSpellProto()->EffectTriggerSpell[aurEff->GetEffIndex()];
CastSpell(this, spell, true, castItem, triggeredByAura);
@@ -7034,11 +7127,11 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger
if(dummySpell->SpellIconID == 3059)
{
// Lightning Shield
- if (AuraEffect const * aurEff = GetAura(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0x400))
+ if (AuraEffect const * aurEff = GetAuraEffect(SPELL_AURA_PROC_TRIGGER_SPELL, SPELLFAMILY_SHAMAN, 0x400, 0, 0))
{
uint32 spell = spellmgr.GetSpellWithRank(26364, spellmgr.GetSpellRank(aurEff->GetId()));
CastSpell(target, spell, true, castItem, triggeredByAura);
- aurEff->GetParentAura()->DropAuraCharge();
+ aurEff->GetBase()->DropCharge();
return true;
}
return false;
@@ -7319,8 +7412,8 @@ bool Unit::HandleObsModEnergyAuraProc(Unit *pVictim, uint32 damage, AuraEffect*
uint32 effIndex = triggeredByAura->GetEffIndex();
int32 triggerAmount = triggeredByAura->GetAmount();
- Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
- ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL;
+ Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
+ ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : NULL;
uint32 triggered_spell_id = 0;
Unit* target = pVictim;
@@ -7376,8 +7469,8 @@ bool Unit::HandleModDamagePctTakenAuraProc(Unit *pVictim, uint32 damage, AuraEff
uint32 effIndex = triggeredByAura->GetEffIndex();
int32 triggerAmount = triggeredByAura->GetAmount();
- Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
- ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL;
+ Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
+ ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : NULL;
uint32 triggered_spell_id = 0;
Unit* target = pVictim;
@@ -7432,7 +7525,7 @@ bool Unit::HandleModDamagePctTakenAuraProc(Unit *pVictim, uint32 damage, AuraEff
// Used in case when access to whole aura is needed
// All procs should be handled like this...
-bool Unit::HandleAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool * handled)
+bool Unit::HandleAuraProc(Unit *pVictim, uint32 damage, Aura * triggeredByAura, SpellEntry const * procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown, bool * handled)
{
SpellEntry const *dummySpell = triggeredByAura->GetSpellProto();
@@ -7455,11 +7548,11 @@ bool Unit::HandleAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, S
// can't proc from death rune use
if (rune == RUNE_DEATH)
return false;
- AuraEffect * aurEff = triggeredByAura->GetPartAura(0);
+ AuraEffect * aurEff = triggeredByAura->GetEffect(0);
if (!aurEff)
return false;
// Reset amplitude - set death rune remove timer to 30s
- aurEff->ResetPeriodicTimer();
+ aurEff->ResetPeriodic();
uint32 runesLeft;
if (dummySpell->SpellIconID == 2622)
@@ -7467,7 +7560,7 @@ bool Unit::HandleAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, S
else
runesLeft = 1;
- for (uint8 i=0; i<MAX_RUNES && runesLeft; ++i)
+ for (uint8 i=0; i < MAX_RUNES && runesLeft; ++i)
{
if (dummySpell->SpellIconID == 2622)
{
@@ -7486,8 +7579,7 @@ bool Unit::HandleAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, S
--runesLeft;
// Mark aura as used
- aurEff->SetAmount(aurEff->GetAmount() | (1<<i));
- ((Player*)this)->ConvertRune(i,RUNE_DEATH);
+ ((Player*)this)->AddRuneByAuraEffect(i, RUNE_DEATH, aurEff);
}
return true;
}
@@ -7524,11 +7616,11 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig
Unit* target = NULL;
int32 basepoints0 = 0;
- if(triggeredByAura->GetAuraName() == SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE)
+ if(triggeredByAura->GetAuraType() == SPELL_AURA_PROC_TRIGGER_SPELL_WITH_VALUE)
basepoints0 = triggerAmount;
- Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
- ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL;
+ Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
+ ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : NULL;
// Try handle unknown trigger spells
if (sSpellStore.LookupEntry(trigger_spell_id) == NULL)
@@ -7618,7 +7710,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig
if (auraSpellInfo->SpellFamilyFlags[0] & 0x4000)
{
// Improved Drain Soul
- Unit::AuraEffectList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_DUMMY);
+ Unit::AuraEffectList const& mAddFlatModifier = GetAuraEffectsByType(SPELL_AURA_DUMMY);
for (Unit::AuraEffectList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i)
{
if ((*i)->GetMiscValue() == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113)
@@ -8053,7 +8145,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig
// Honor Among Thieves
case 52916:
{
- target = triggeredByAura->GetParentAura()->GetCaster();
+ target = triggeredByAura->GetBase()->GetCaster();
if(!target)
return false;
@@ -8128,7 +8220,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig
if (isPet())
if (Unit * owner = GetOwner())
{
- if (AuraEffect * aurEff = owner->GetDummyAura(SPELLFAMILY_WARLOCK, 3220, 0))
+ if (AuraEffect * aurEff = owner->GetDummyAuraEffect(SPELLFAMILY_WARLOCK, 3220, 0))
{
basepoints0 = int32((aurEff->GetAmount() * owner->SpellBaseDamageBonus(SpellSchoolMask(SPELL_SCHOOL_MASK_MAGIC)) + 100.0f) / 100.0f);
CastCustomSpell(this,trigger_spell_id,&basepoints0,&basepoints0,NULL,true,castItem,triggeredByAura);
@@ -8247,8 +8339,8 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, uint32 damage, AuraE
if(!pVictim || !pVictim->isAlive())
return false;
- Item* castItem = triggeredByAura->GetParentAura()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
- ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetParentAura()->GetCastItemGUID()) : NULL;
+ Item* castItem = triggeredByAura->GetBase()->GetCastItemGUID() && GetTypeId() == TYPEID_PLAYER
+ ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetBase()->GetCastItemGUID()) : NULL;
uint32 triggered_spell_id = 0;
@@ -8869,10 +8961,10 @@ void Unit::ModifyAuraState(AuraState flag, bool apply)
if (flag != AURA_STATE_ENRAGE) // enrage aura state triggering continues auras
{
- Unit::AuraMap& tAuras = GetAuras();
- for (Unit::AuraMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
+ Unit::AuraApplicationMap& tAuras = GetAppliedAuras();
+ for (Unit::AuraApplicationMap::iterator itr = tAuras.begin(); itr != tAuras.end();)
{
- SpellEntry const* spellProto = (*itr).second->GetSpellProto();
+ SpellEntry const* spellProto = (*itr).second->GetBase()->GetSpellProto();
if (spellProto->CasterAuraState == flag)
RemoveAura(itr);
else
@@ -8888,7 +8980,7 @@ uint32 Unit::BuildAuraStateUpdateForTarget(Unit * target) const
uint32 auraStates = GetUInt32Value(UNIT_FIELD_AURASTATE) &~(PER_CASTER_AURA_STATE_MASK);
for (AuraStateAurasMap::const_iterator itr = m_auraStateAuras.begin(); itr != m_auraStateAuras.end(); ++itr)
if ((1<<(itr->first-1)) & PER_CASTER_AURA_STATE_MASK)
- if (itr->second->GetCasterGUID() == target->GetGUID())
+ if (itr->second->GetBase()->GetCasterGUID() == target->GetGUID())
auraStates |= (1<<(itr->first-1));
return auraStates;
@@ -8900,9 +8992,9 @@ bool Unit::HasAuraState(AuraState flag, SpellEntry const *spellProto, Unit const
{
if (spellProto)
{
- AuraEffectList const& stateAuras = Caster->GetAurasByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
+ AuraEffectList const& stateAuras = Caster->GetAuraEffectsByType(SPELL_AURA_ABILITY_IGNORE_AURASTATE);
for (AuraEffectList::const_iterator j = stateAuras.begin(); j != stateAuras.end(); ++j)
- if ((*j)->isAffectedOnSpell(spellProto))
+ if ((*j)->IsAffectedOnSpell(spellProto))
return true;
}
// Check per caster aura state
@@ -8910,7 +9002,7 @@ bool Unit::HasAuraState(AuraState flag, SpellEntry const *spellProto, Unit const
if ((1<<(flag-1)) & PER_CASTER_AURA_STATE_MASK)
{
for (AuraStateAurasMap::const_iterator itr = m_auraStateAuras.lower_bound(flag); itr != m_auraStateAuras.upper_bound(flag); ++itr)
- if (itr->second->GetCasterGUID() == Caster->GetGUID())
+ if (itr->second->GetBase()->GetCasterGUID() == Caster->GetGUID())
return true;
return false;
}
@@ -9279,25 +9371,25 @@ Unit* Unit::SelectMagnetTarget(Unit *victim, SpellEntry const *spellInfo)
if (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE)
return victim;
- Unit::AuraEffectList const& magnetAuras = victim->GetAurasByType(SPELL_AURA_SPELL_MAGNET);
+ Unit::AuraEffectList const& magnetAuras = victim->GetAuraEffectsByType(SPELL_AURA_SPELL_MAGNET);
for (Unit::AuraEffectList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr)
- if (Unit* magnet = (*itr)->GetParentAura()->GetUnitSource())
+ if (Unit* magnet = (*itr)->GetBase()->GetUnitOwner())
if (magnet->isAlive())
{
- (*itr)->GetParentAura()->DropAuraCharge();
+ (*itr)->GetBase()->DropCharge();
return magnet;
}
}
// Melee && ranged case
else
{
- AuraEffectList const& hitTriggerAuras = victim->GetAurasByType(SPELL_AURA_ADD_CASTER_HIT_TRIGGER);
+ AuraEffectList const& hitTriggerAuras = victim->GetAuraEffectsByType(SPELL_AURA_ADD_CASTER_HIT_TRIGGER);
for (AuraEffectList::const_iterator i = hitTriggerAuras.begin(); i != hitTriggerAuras.end(); ++i)
- if (Unit* magnet = (*i)->GetParentAura()->GetUnitSource())
+ if (Unit* magnet = (*i)->GetBase()->GetUnitOwner())
if (magnet->isAlive() && magnet->IsWithinLOSInMap(this))
if (roll_chance_i((*i)->GetAmount()))
{
- (*i)->GetParentAura()->DropAuraCharge();
+ (*i)->GetBase()->DropCharge();
return magnet;
}
}
@@ -9505,7 +9597,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
if (GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isPet())
DoneTotalMod *= ((Creature*)this)->GetSpellDamageMod(((Creature*)this)->GetCreatureInfo()->rank);
- AuraEffectList const &mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ AuraEffectList const &mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
if (((*i)->GetMiscValue() & GetSpellSchoolMask(spellProto)) &&
(*i)->GetSpellProto()->EquippedItemClass == -1 && // -1 == any item class (not wand)
@@ -9515,17 +9607,17 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
uint32 creatureTypeMask = pVictim->GetCreatureTypeMask();
// Add flat bonus from spell damage versus
DoneTotal += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_FLAT_SPELL_DAMAGE_VERSUS, creatureTypeMask);
- AuraEffectList const &mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);
+ AuraEffectList const &mDamageDoneVersus = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);
for (AuraEffectList::const_iterator i = mDamageDoneVersus.begin(); i != mDamageDoneVersus.end(); ++i)
if (creatureTypeMask & uint32((*i)->GetMiscValue()))
DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
// done scripted mod (take it from owner)
Unit *owner = GetOwner() ? GetOwner() : this;
- AuraEffectList const &mOverrideClassScript= owner->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ AuraEffectList const &mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
- if (!(*i)->isAffectedOnSpell(spellProto))
+ if (!(*i)->IsAffectedOnSpell(spellProto))
continue;
switch ((*i)->GetMiscValue())
{
@@ -9549,13 +9641,14 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
int32 stepPercent = CalculateSpellDamage((*i)->GetSpellProto(), 0, (*i)->GetSpellProto()->EffectBasePoints[0], this);
// count affliction effects and calc additional damage in percentage
int32 modPercent = 0;
- AuraMap const &victimAuras = pVictim->GetAuras();
- for (AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
+ AuraApplicationMap const &victimAuras = pVictim->GetAppliedAuras();
+ for (AuraApplicationMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
{
- SpellEntry const *m_spell = itr->second->GetSpellProto();
+ Aura const * aura = itr->second->GetBase();
+ SpellEntry const *m_spell = aura->GetSpellProto();
if (m_spell->SpellFamilyName != SPELLFAMILY_WARLOCK || !(m_spell->SpellFamilyFlags[1] & 0x0004071B || m_spell->SpellFamilyFlags[0] & 0x8044C402))
continue;
- modPercent += stepPercent * itr->second->GetStackAmount();
+ modPercent += stepPercent * aura->GetStackAmount();
if (modPercent >= maxPercent)
{
modPercent = maxPercent;
@@ -9573,7 +9666,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
break;
case 5481: // Starfire Bonus
{
- if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x200002, 0))
+ if (pVictim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x200002, 0, 0))
DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
break;
}
@@ -9611,7 +9704,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
// Rage of Rivendare
case 7293:
{
- if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0,0x02000000,0))
+ if (pVictim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0,0x02000000,0))
{
if (SpellChainNode const *chain = spellmgr.GetSpellChainNode((*i)->GetId()))
DoneTotalMod *= (chain->rank * 2.0f + 100.0f)/100.0f;
@@ -9621,7 +9714,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
// Twisted Faith
case 7377:
{
- if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0,0, GetGUID()))
+ if (pVictim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0,0, GetGUID()))
DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
break;
}
@@ -9632,7 +9725,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
case 7601:
case 7602:
{
- if (pVictim->GetAura(SPELL_AURA_MOD_STALKED, SPELLFAMILY_HUNTER, 0x400, 0))
+ if (pVictim->GetAuraEffect(SPELL_AURA_MOD_STALKED, SPELLFAMILY_HUNTER, 0x400, 0, 0))
DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
break;
}
@@ -9660,7 +9753,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
if (spellProto->SpellFamilyFlags[0]&0x20200021 || spellProto->SpellFamilyFlags[1]& 0x9000)
if (pVictim->HasAuraType(SPELL_AURA_MOD_DECREASE_SPEED))
{
- AuraEffectList const& mDumyAuras = GetAurasByType(SPELL_AURA_DUMMY);
+ AuraEffectList const& mDumyAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY);
for (AuraEffectList::const_iterator i = mDumyAuras.begin(); i != mDumyAuras.end(); ++i)
if ((*i)->GetSpellProto()->SpellIconID == 3263)
{
@@ -9676,7 +9769,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
// Increase Mind Flay damage
if (AuraEffect * aurEff = GetAuraEffect(55687, 0))
// if Shadow Word: Pain present
- if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0,0, GetGUID()))
+ if (pVictim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_PRIEST, 0x8000, 0,0, GetGUID()))
DoneTotalMod *= (aurEff->GetAmount() + 100.0f) / 100.f;
}
break;
@@ -9687,11 +9780,11 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
{
// Get stack of Holy Vengeance/Blood Corruption on the target added by caster
uint32 stacks = 0;
- Unit::AuraEffectList const& auras = pVictim->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
+ Unit::AuraEffectList const& auras = pVictim->GetAuraEffectsByType(SPELL_AURA_PERIODIC_DAMAGE);
for (Unit::AuraEffectList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
if (((*itr)->GetId() == 31803 || (*itr)->GetId() == 53742) && (*itr)->GetCasterGUID()==GetGUID())
{
- stacks = (*itr)->GetParentAura()->GetStackAmount();
+ stacks = (*itr)->GetBase()->GetStackAmount();
break;
}
// + 10% for each application of Holy Vengeance/Blood Corruption on the target
@@ -9704,7 +9797,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
if (spellProto->SpellFamilyFlags[1] & 0x00020040)
if (pVictim->HasAuraState(AURA_STATE_CONFLAGRATE))
{
- AuraEffectList const& mDumyAuras = GetAurasByType(SPELL_AURA_DUMMY);
+ AuraEffectList const& mDumyAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY);
for (AuraEffectList::const_iterator i = mDumyAuras.begin(); i != mDumyAuras.end(); ++i)
if ((*i)->GetSpellProto()->SpellIconID == 3173)
{
@@ -9716,29 +9809,29 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
case SPELLFAMILY_DEATHKNIGHT:
// Improved Icy Touch
if (spellProto->SpellFamilyFlags[0] & 0x2)
- if (AuraEffect * aurEff = GetDummyAura(SPELLFAMILY_DEATHKNIGHT, 2721, 0))
+ if (AuraEffect * aurEff = GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 2721, 0))
DoneTotalMod *= (100.0f + aurEff->GetAmount()) / 100.0f;
// Glacier Rot
if (spellProto->SpellFamilyFlags[0] & 0x2 || spellProto->SpellFamilyFlags[1] & 0x6)
- if (AuraEffect * aurEff = GetDummyAura(SPELLFAMILY_DEATHKNIGHT, 196, 0))
+ if (AuraEffect * aurEff = GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 196, 0))
if (pVictim->GetDiseasesByCaster(owner->GetGUID()) > 0)
DoneTotalMod *= (100.0f + aurEff->GetAmount()) / 100.0f;
// This is not a typo - Impurity has SPELLFAMILY_DRUID
- if (AuraEffect * aurEff = GetDummyAura(SPELLFAMILY_DRUID, 1986, 0))
+ if (AuraEffect * aurEff = GetDummyAuraEffect(SPELLFAMILY_DRUID, 1986, 0))
ApCoeffMod *= (100.0f + aurEff->GetAmount()) / 100.0f;
break;
}
// ..taken
- AuraEffectList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
+ AuraEffectList const& mModDamagePercentTaken = pVictim->GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
for (AuraEffectList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i)
if ((*i)->GetMiscValue() & GetSpellSchoolMask(spellProto) )
TakenTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
// .. taken pct: dummy auras
- AuraEffectList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
+ AuraEffectList const& mDummyAuras = pVictim->GetAuraEffectsByType(SPELL_AURA_DUMMY);
for (AuraEffectList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
{
switch((*i)->GetSpellProto()->SpellIconID)
@@ -9764,15 +9857,15 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
}
// From caster spells
- AuraEffectList const& mOwnerTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
+ AuraEffectList const& mOwnerTaken = pVictim->GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_FROM_CASTER);
for (AuraEffectList::const_iterator i = mOwnerTaken.begin(); i != mOwnerTaken.end(); ++i)
- if ((*i)->GetCasterGUID() == GetGUID() && (*i)->isAffectedOnSpell(spellProto))
+ if ((*i)->GetCasterGUID() == GetGUID() && (*i)->IsAffectedOnSpell(spellProto))
TakenTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
// Mod damage from spell mechanic
if (uint32 mechanicMask = GetAllSpellMechanicMask(spellProto))
{
- AuraEffectList const& mDamageDoneMechanic = pVictim->GetAurasByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
+ AuraEffectList const& mDamageDoneMechanic = pVictim->GetAuraEffectsByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
for (AuraEffectList::const_iterator i = mDamageDoneMechanic.begin(); i != mDamageDoneMechanic.end(); ++i)
if (mechanicMask & uint32(1<<((*i)->GetMiscValue())))
TakenTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
@@ -9892,7 +9985,7 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask)
int32 DoneAdvertisedBenefit = 0;
// ..done
- AuraEffectList const& mDamageDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE);
+ AuraEffectList const& mDamageDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE);
for (AuraEffectList::const_iterator i = mDamageDone.begin(); i != mDamageDone.end(); ++i)
if (((*i)->GetMiscValue() & schoolMask) != 0 &&
(*i)->GetSpellProto()->EquippedItemClass == -1 &&
@@ -9907,18 +10000,18 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask)
DoneAdvertisedBenefit +=((Player*)this)->GetBaseSpellPowerBonus();
// Damage bonus from stats
- AuraEffectList const& mDamageDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT);
+ AuraEffectList const& mDamageDoneOfStatPercent = GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT);
for (AuraEffectList::const_iterator i = mDamageDoneOfStatPercent.begin(); i != mDamageDoneOfStatPercent.end(); ++i)
{
if ((*i)->GetMiscValue() & schoolMask)
{
// stat used stored in miscValueB for this aura
- Stats usedStat = Stats((*i)->GetMiscBValue());
+ Stats usedStat = Stats((*i)->GetMiscValueB());
DoneAdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetAmount() / 100.0f);
}
}
// ... and attack power
- AuraEffectList const& mDamageDonebyAP = GetAurasByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER);
+ AuraEffectList const& mDamageDonebyAP = GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER);
for (AuraEffectList::const_iterator i =mDamageDonebyAP.begin(); i != mDamageDonebyAP.end(); ++i)
if ((*i)->GetMiscValue() & schoolMask)
DoneAdvertisedBenefit += int32(GetTotalAttackPowerValue(BASE_ATTACK) * (*i)->GetAmount() / 100.0f);
@@ -9933,13 +10026,13 @@ int32 Unit::SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVic
int32 TakenAdvertisedBenefit = 0;
// ..done (for creature type by mask) in taken
- AuraEffectList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
+ AuraEffectList const& mDamageDoneCreature = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
for (AuraEffectList::const_iterator i = mDamageDoneCreature.begin(); i != mDamageDoneCreature.end(); ++i)
if (creatureTypeMask & uint32((*i)->GetMiscValue()))
TakenAdvertisedBenefit += (*i)->GetAmount();
// ..taken
- AuraEffectList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
+ AuraEffectList const& mDamageTaken = pVictim->GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i)
if (((*i)->GetMiscValue() & schoolMask) != 0)
TakenAdvertisedBenefit += (*i)->GetAmount();
@@ -9984,10 +10077,10 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
crit_chance -= pVictim->GetSpellCritChanceReduction();
}
// scripted (increase crit chance ... against ... target by x%
- AuraEffectList const& mOverrideClassScript = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ AuraEffectList const& mOverrideClassScript = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
- if (!((*i)->isAffectedOnSpell(spellProto)))
+ if (!((*i)->IsAffectedOnSpell(spellProto)))
continue;
int32 modChance=0;
switch((*i)->GetMiscValue())
@@ -10027,8 +10120,8 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
if (spellProto->SpellFamilyFlags[0] & 0x4 && spellProto->SpellIconID == 1485)
{
// Improved Insect Swarm
- if (AuraEffect const * aurEff = GetDummyAura(SPELLFAMILY_DRUID, 1771, 0))
- if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00000002))
+ if (AuraEffect const * aurEff = GetDummyAuraEffect(SPELLFAMILY_DRUID, 1771, 0))
+ if (pVictim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00000002, 0, 0))
crit_chance+=aurEff->GetAmount();
break;
}
@@ -10055,7 +10148,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
// Lava Burst
if (spellProto->SpellFamilyFlags[1] & 0x00001000)
{
- if (AuraEffect const* flameShock = pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 0x10000000, 0,0, GetGUID()))
+ if (AuraEffect const* flameShock = pVictim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_SHAMAN, 0x10000000, 0,0, GetGUID()))
return true;
break;
}
@@ -10074,7 +10167,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM
// Rend and Tear - bonus crit chance for bleeding targets of Ferocious Bite
if (spellProto->SpellFamilyFlags[0] & 0x00800000 && pVictim->HasAuraState(AURA_STATE_BLEEDING, spellProto, this))
{
- if (AuraEffect const *rendAndTear = GetDummyAura(SPELLFAMILY_DRUID, 2859, 1))
+ if (AuraEffect const *rendAndTear = GetDummyAuraEffect(SPELLFAMILY_DRUID, 2859, 1))
crit_chance += rendAndTear->GetAmount();
break;
}
@@ -10187,16 +10280,16 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint
int32 TakenTotal = 0;
// Healing done percent
- AuraEffectList const& mHealingDonePct = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
+ AuraEffectList const& mHealingDonePct = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE_PERCENT);
for (AuraEffectList::const_iterator i = mHealingDonePct.begin(); i != mHealingDonePct.end(); ++i)
DoneTotalMod *= (100.0f + (*i)->GetAmount()) / 100.0f;
// done scripted mod (take it from owner)
Unit *owner = GetOwner() ? GetOwner() : this;
- AuraEffectList const &mOverrideClassScript= owner->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ AuraEffectList const &mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
- if (!(*i)->isAffectedOnSpell(spellProto))
+ if (!(*i)->IsAffectedOnSpell(spellProto))
continue;
switch((*i)->GetMiscValue())
{
@@ -10218,7 +10311,7 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint
break;
case 7798: // Glyph of Regrowth
{
- if (pVictim->GetAura(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x40, 0))
+ if (pVictim->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x40, 0, 0))
DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
break;
}
@@ -10226,23 +10319,24 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint
{
int32 stepPercent = (*i)->GetAmount();
int32 modPercent = 0;
- AuraMap const& victimAuras = pVictim->GetAuras();
- for (AuraMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
+ AuraApplicationMap const& victimAuras = pVictim->GetAppliedAuras();
+ for (AuraApplicationMap::const_iterator itr = victimAuras.begin(); itr != victimAuras.end(); ++itr)
{
- if (itr->second->GetCasterGUID()!=GetGUID())
+ Aura const * aura = itr->second->GetBase();
+ if (aura->GetCasterGUID()!=GetGUID())
continue;
- SpellEntry const* m_spell = itr->second->GetSpellProto();
+ SpellEntry const* m_spell = aura->GetSpellProto();
if ( m_spell->SpellFamilyName != SPELLFAMILY_DRUID ||
!(m_spell->SpellFamilyFlags[1] & 0x00000010 || m_spell->SpellFamilyFlags[0] & 0x50))
continue;
- modPercent += stepPercent * itr->second->GetStackAmount();
+ modPercent += stepPercent * aura->GetStackAmount();
}
DoneTotalMod *= (modPercent+100.0f)/100.0f;
break;
}
case 7871: // Glyph of Lesser Healing Wave
{
- if (pVictim->GetAura(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0 , 0x00000400, 0, GetGUID()))
+ if (pVictim->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_SHAMAN, 0 , 0x00000400, 0, GetGUID()))
DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
break;
}
@@ -10392,7 +10486,7 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint
if (spellProto->SpellFamilyName == SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags[1] & 0x2000000)
{
// Rejuvenation, Regrowth, Lifebloom, or Wild Growth
- if (pVictim->GetAura(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x50, 0x4000010, 0))
+ if (pVictim->GetAuraEffect(SPELL_AURA_PERIODIC_HEAL, SPELLFAMILY_DRUID, 0x50, 0x4000010, 0))
//increase healing by 20%
TakenTotalMod *= 1.2f;
}
@@ -10433,9 +10527,9 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint
TakenTotalMod *= (100.0f + maxval_hot) / 100.0f;
}
- AuraEffectList const& mHealingGet= pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING_RECEIVED);
+ AuraEffectList const& mHealingGet= pVictim->GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_RECEIVED);
for (AuraEffectList::const_iterator i = mHealingGet.begin(); i != mHealingGet.end(); ++i)
- if (GetGUID()==(*i)->GetCasterGUID() && (*i)->isAffectedOnSpell(spellProto) )
+ if (GetGUID()==(*i)->GetCasterGUID() && (*i)->IsAffectedOnSpell(spellProto) )
TakenTotalMod *= ((*i)->GetAmount() + 100.0f) / 100.0f;
heal = (int32(heal) + TakenTotal) * TakenTotalMod;
@@ -10447,7 +10541,7 @@ int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask)
{
int32 AdvertisedBenefit = 0;
- AuraEffectList const& mHealingDone = GetAurasByType(SPELL_AURA_MOD_HEALING_DONE);
+ AuraEffectList const& mHealingDone = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE);
for (AuraEffectList::const_iterator i = mHealingDone.begin(); i != mHealingDone.end(); ++i)
if (((*i)->GetMiscValue() & schoolMask) != 0)
AdvertisedBenefit += (*i)->GetAmount();
@@ -10459,7 +10553,7 @@ int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask)
AdvertisedBenefit +=((Player*)this)->GetBaseSpellPowerBonus();
// Healing bonus from stats
- AuraEffectList const& mHealingDoneOfStatPercent = GetAurasByType(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT);
+ AuraEffectList const& mHealingDoneOfStatPercent = GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT);
for (AuraEffectList::const_iterator i = mHealingDoneOfStatPercent.begin(); i != mHealingDoneOfStatPercent.end(); ++i)
{
// stat used dependent from misc value (stat index)
@@ -10468,7 +10562,7 @@ int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask)
}
// ... and attack power
- AuraEffectList const& mHealingDonebyAP = GetAurasByType(SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER);
+ AuraEffectList const& mHealingDonebyAP = GetAuraEffectsByType(SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER);
for (AuraEffectList::const_iterator i = mHealingDonebyAP.begin(); i != mHealingDonebyAP.end(); ++i)
if ((*i)->GetMiscValue() & schoolMask)
AdvertisedBenefit += int32(GetTotalAttackPowerValue(BASE_ATTACK) * (*i)->GetAmount() / 100.0f);
@@ -10479,7 +10573,7 @@ int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask)
int32 Unit::SpellBaseHealingBonusForVictim(SpellSchoolMask schoolMask, Unit *pVictim)
{
int32 AdvertisedBenefit = 0;
- AuraEffectList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_HEALING);
+ AuraEffectList const& mDamageTaken = pVictim->GetAuraEffectsByType(SPELL_AURA_MOD_HEALING);
for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i)
if (((*i)->GetMiscValue() & schoolMask) != 0)
AdvertisedBenefit += (*i)->GetAmount();
@@ -10590,7 +10684,7 @@ bool Unit::IsImmunedToSpellEffect(SpellEntry const* spellInfo, uint32 index) con
if (itr->type == aura)
return true;
// Check for immune to application of harmful magical effects
- AuraEffectList const& immuneAuraApply = GetAurasByType(SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL);
+ AuraEffectList const& immuneAuraApply = GetAuraEffectsByType(SPELL_AURA_MOD_IMMUNE_AURA_APPLY_SCHOOL);
for (AuraEffectList::const_iterator iter = immuneAuraApply.begin(); iter != immuneAuraApply.end(); ++iter)
if (spellInfo->Dispel == DISPEL_MAGIC && // Magic debuff
((*iter)->GetMiscValue() & GetSpellSchoolMask(spellInfo)) && // Check school
@@ -10640,7 +10734,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att
int32 TakenFlatBenefit = 0;
// ..done (for creature type by mask) in taken
- AuraEffectList const& mDamageDoneCreature = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
+ AuraEffectList const& mDamageDoneCreature = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE_CREATURE);
for (AuraEffectList::const_iterator i = mDamageDoneCreature.begin(); i != mDamageDoneCreature.end(); ++i)
if (creatureTypeMask & uint32((*i)->GetMiscValue()))
DoneFlatBenefit += (*i)->GetAmount();
@@ -10655,7 +10749,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att
APbonus += pVictim->GetTotalAuraModifier(SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS);
// ..done (base at attack power and creature type)
- AuraEffectList const& mCreatureAttackPower = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS);
+ AuraEffectList const& mCreatureAttackPower = GetAuraEffectsByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS);
for (AuraEffectList::const_iterator i = mCreatureAttackPower.begin(); i != mCreatureAttackPower.end(); ++i)
if (creatureTypeMask & uint32((*i)->GetMiscValue()))
APbonus += (*i)->GetAmount();
@@ -10665,7 +10759,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att
APbonus += pVictim->GetTotalAuraModifier(SPELL_AURA_MELEE_ATTACK_POWER_ATTACKER_BONUS);
// ..done (base at attack power and creature type)
- AuraEffectList const& mCreatureAttackPower = GetAurasByType(SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS);
+ AuraEffectList const& mCreatureAttackPower = GetAuraEffectsByType(SPELL_AURA_MOD_MELEE_ATTACK_POWER_VERSUS);
for (AuraEffectList::const_iterator i = mCreatureAttackPower.begin(); i != mCreatureAttackPower.end(); ++i)
if (creatureTypeMask & uint32((*i)->GetMiscValue()))
APbonus += (*i)->GetAmount();
@@ -10683,14 +10777,14 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att
}
// This is not a typo - Impurity has SPELLFAMILY_DRUID
- if (AuraEffect const * aurEff = GetDummyAura(SPELLFAMILY_DRUID, 1986, 0))
+ if (AuraEffect const * aurEff = GetDummyAuraEffect(SPELLFAMILY_DRUID, 1986, 0))
APbonus *= (100.0f + aurEff->GetAmount()) / 100.0f;
DoneFlatBenefit += int32(APbonus/14.0f * GetAPMultiplier(attType,normalized));
}
// ..taken
- AuraEffectList const& mDamageTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
+ AuraEffectList const& mDamageTaken = pVictim->GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_TAKEN);
for (AuraEffectList::const_iterator i = mDamageTaken.begin(); i != mDamageTaken.end(); ++i)
if ((*i)->GetMiscValue() & GetMeleeDamageSchoolMask())
TakenFlatBenefit += (*i)->GetAmount();
@@ -10712,23 +10806,23 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att
if (spellProto)
if (GetSpellSchoolMask(spellProto) != SPELL_SCHOOL_MASK_NORMAL)
{
- AuraEffectList const &mModDamagePercentDone = GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
+ AuraEffectList const &mModDamagePercentDone = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_DONE);
for (AuraEffectList::const_iterator i = mModDamagePercentDone.begin(); i != mModDamagePercentDone.end(); ++i)
if (((*i)->GetMiscValue() & GetSpellSchoolMask(spellProto)) && !((*i)->GetMiscValue() & SPELL_SCHOOL_MASK_NORMAL))
DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
}
- AuraEffectList const &mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);
+ AuraEffectList const &mDamageDoneVersus = GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_DONE_VERSUS);
for (AuraEffectList::const_iterator i = mDamageDoneVersus.begin(); i != mDamageDoneVersus.end(); ++i)
if (creatureTypeMask & uint32((*i)->GetMiscValue()))
DoneTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
// done scripted mod (take it from owner)
Unit *owner = GetOwner() ? GetOwner() : this;
- AuraEffectList const &mOverrideClassScript= owner->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ AuraEffectList const &mOverrideClassScript= owner->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffectList::const_iterator i = mOverrideClassScript.begin(); i != mOverrideClassScript.end(); ++i)
{
- if (!(*i)->isAffectedOnSpell(spellProto))
+ if (!(*i)->IsAffectedOnSpell(spellProto))
continue;
switch ((*i)->GetMiscValue())
{
@@ -10754,7 +10848,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att
// Rage of Rivendare
case 7293:
{
- if (pVictim->GetAura(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0,0x02000000,0))
+ if (pVictim->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DEATHKNIGHT, 0,0x02000000,0))
if (SpellChainNode const *chain = spellmgr.GetSpellChainNode((*i)->GetId()))
DoneTotalMod *= (chain->rank * 2.0f + 100.0f)/100.0f;
break;
@@ -10769,14 +10863,14 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att
case SPELLFAMILY_DEATHKNIGHT:
// Glacier Rot
if (spellProto->SpellFamilyFlags[0] & 0x2 || spellProto->SpellFamilyFlags[1] & 0x6)
- if (AuraEffect * aurEff = GetDummyAura(SPELLFAMILY_DEATHKNIGHT, 196, 0))
+ if (AuraEffect * aurEff = GetDummyAuraEffect(SPELLFAMILY_DEATHKNIGHT, 196, 0))
if (pVictim->GetDiseasesByCaster(owner->GetGUID()) > 0)
DoneTotalMod *= (100.0f + aurEff->GetAmount()) / 100.0f;
break;
}
// ..taken
- AuraEffectList const& mModDamagePercentTaken = pVictim->GetAurasByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
+ AuraEffectList const& mModDamagePercentTaken = pVictim->GetAuraEffectsByType(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN);
for (AuraEffectList::const_iterator i = mModDamagePercentTaken.begin(); i != mModDamagePercentTaken.end(); ++i)
if ((*i)->GetMiscValue() & GetMeleeDamageSchoolMask())
TakenTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
@@ -10793,7 +10887,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att
if (mechanicMask)
{
- AuraEffectList const& mDamageDoneMechanic = pVictim->GetAurasByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
+ AuraEffectList const& mDamageDoneMechanic = pVictim->GetAuraEffectsByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
for (AuraEffectList::const_iterator i = mDamageDoneMechanic.begin(); i != mDamageDoneMechanic.end(); ++i)
if (mechanicMask & uint32(1<<((*i)->GetMiscValue())))
TakenTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
@@ -10801,7 +10895,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att
}
// .. taken pct: dummy auras
- AuraEffectList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
+ AuraEffectList const& mDummyAuras = pVictim->GetAuraEffectsByType(SPELL_AURA_DUMMY);
for (AuraEffectList::const_iterator i = mDummyAuras.begin(); i != mDummyAuras.end(); ++i)
{
switch((*i)->GetSpellProto()->SpellIconID)
@@ -10839,7 +10933,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att
}
// .. taken pct: class scripts
- AuraEffectList const& mclassScritAuras = GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
+ AuraEffectList const& mclassScritAuras = GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
for (AuraEffectList::const_iterator i = mclassScritAuras.begin(); i != mclassScritAuras.end(); ++i)
{
switch((*i)->GetMiscValue())
@@ -10847,7 +10941,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att
case 6427: case 6428: // Dirty Deeds
if (pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this))
{
- AuraEffect* eff0 = (*i)->GetParentAura()->GetPartAura(0);
+ AuraEffect* eff0 = (*i)->GetBase()->GetEffect(0);
if (!eff0 || (*i)->GetEffIndex()!=1)
{
sLog.outError("Spell structure of DD (%u) changed.",(*i)->GetId());
@@ -10863,13 +10957,13 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att
if (attType != RANGED_ATTACK)
{
- AuraEffectList const& mModMeleeDamageTakenPercent = pVictim->GetAurasByType(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT);
+ AuraEffectList const& mModMeleeDamageTakenPercent = pVictim->GetAuraEffectsByType(SPELL_AURA_MOD_MELEE_DAMAGE_TAKEN_PCT);
for (AuraEffectList::const_iterator i = mModMeleeDamageTakenPercent.begin(); i != mModMeleeDamageTakenPercent.end(); ++i)
TakenTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
}
else
{
- AuraEffectList const& mModRangedDamageTakenPercent = pVictim->GetAurasByType(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT);
+ AuraEffectList const& mModRangedDamageTakenPercent = pVictim->GetAuraEffectsByType(SPELL_AURA_MOD_RANGED_DAMAGE_TAKEN_PCT);
for (AuraEffectList::const_iterator i = mModRangedDamageTakenPercent.begin(); i != mModRangedDamageTakenPercent.end(); ++i)
TakenTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
}
@@ -10928,10 +11022,10 @@ void Unit::ApplySpellDispelImmunity(const SpellEntry * spellProto, DispelType ty
// Create dispel mask by dispel type
uint32 dispelMask = GetDispellMask(type);
// Dispel all existing auras vs current dispel type
- AuraMap& auras = GetAuras();
- for (AuraMap::iterator itr = auras.begin(); itr != auras.end();)
+ AuraApplicationMap& auras = GetAppliedAuras();
+ for (AuraApplicationMap::iterator itr = auras.begin(); itr != auras.end();)
{
- SpellEntry const* spell = itr->second->GetSpellProto();
+ SpellEntry const* spell = itr->second->GetBase()->GetSpellProto();
if ((1<<spell->Dispel) & dispelMask )
{
// Dispel aura
@@ -11302,7 +11396,7 @@ bool Unit::canDetectInvisibilityOf(Unit const* u) const
{
if (m_invisibilityMask & u->m_invisibilityMask) // same group
return true;
- AuraEffectList const& auras = u->GetAurasByType(SPELL_AURA_MOD_STALKED); // Hunter mark
+ AuraEffectList const& auras = u->GetAuraEffectsByType(SPELL_AURA_MOD_STALKED); // Hunter mark
for (AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
if ((*iter)->GetCasterGUID()==GetGUID())
return true;
@@ -11316,7 +11410,7 @@ bool Unit::canDetectInvisibilityOf(Unit const* u) const
// find invisibility level
uint32 invLevel = 0;
- Unit::AuraEffectList const& iAuras = u->GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
+ Unit::AuraEffectList const& iAuras = u->GetAuraEffectsByType(SPELL_AURA_MOD_INVISIBILITY);
for (Unit::AuraEffectList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr)
if (((*itr)->GetMiscValue())==i && invLevel < (*itr)->GetAmount())
invLevel = (*itr)->GetAmount();
@@ -11329,7 +11423,7 @@ bool Unit::canDetectInvisibilityOf(Unit const* u) const
}
else
{
- Unit::AuraEffectList const& dAuras = GetAurasByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
+ Unit::AuraEffectList const& dAuras = GetAuraEffectsByType(SPELL_AURA_MOD_INVISIBILITY_DETECTION);
for (Unit::AuraEffectList::const_iterator itr = dAuras.begin(); itr != dAuras.end(); ++itr)
if (((*itr)->GetMiscValue())==i && detectLevel < (*itr)->GetAmount())
detectLevel = (*itr)->GetAmount();
@@ -11354,7 +11448,7 @@ bool Unit::canDetectStealthOf(Unit const* target, float distance) const
if (HasAuraType(SPELL_AURA_DETECT_STEALTH))
return true;
- AuraEffectList const &auras = target->GetAurasByType(SPELL_AURA_MOD_STALKED); // Hunter mark
+ AuraEffectList const &auras = target->GetAuraEffectsByType(SPELL_AURA_MOD_STALKED); // Hunter mark
for (AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
if ((*iter)->GetCasterGUID() == GetGUID())
return true;
@@ -11818,7 +11912,7 @@ Unit* Creature::SelectVictim()
Unit* target = NULL;
// First checking if we have some taunt on us
- const AuraEffectList& tauntAuras = GetAurasByType(SPELL_AURA_MOD_TAUNT);
+ const AuraEffectList& tauntAuras = GetAuraEffectsByType(SPELL_AURA_MOD_TAUNT);
if (!tauntAuras.empty())
{
Unit* caster;
@@ -11910,9 +12004,9 @@ Unit* Creature::SelectVictim()
if (m_invisibilityMask)
{
- Unit::AuraEffectList const& iAuras = GetAurasByType(SPELL_AURA_MOD_INVISIBILITY);
+ Unit::AuraEffectList const& iAuras = GetAuraEffectsByType(SPELL_AURA_MOD_INVISIBILITY);
for (Unit::AuraEffectList::const_iterator itr = iAuras.begin(); itr != iAuras.end(); ++itr)
- if ((*itr)->GetParentAura()->IsPermanent())
+ if ((*itr)->GetBase()->IsPermanent())
{
AI()->EnterEvadeMode();
break;
@@ -12711,6 +12805,8 @@ void Unit::RemoveFromWorld()
UnsummonAllTotems();
RemoveAllControlled();
+ RemoveAreaAurasDueToLeaveWorld();
+
if (m_NotifyListPos >= 0)
GetMap()->RemoveUnitFromNotify(this);
@@ -13222,13 +13318,12 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit * pTarget, uint32 procFlag,
ProcTriggeredList procTriggered;
// Fill procTriggered list
- for (AuraMap::const_iterator itr = GetAuras().begin(); itr!= GetAuras().end(); ++itr)
+ for (AuraApplicationMap::const_iterator itr = GetAppliedAuras().begin(); itr!= GetAppliedAuras().end(); ++itr)
{
// Do not allow auras to proc from effect triggered by itself
if (procAura && procAura->Id == itr->first)
continue;
- ProcTriggeredData triggerData(itr->second);
-
+ ProcTriggeredData triggerData(itr->second->GetBase());
// Defensive procs are active on absorbs (so absorption effects are not a hindrance)
bool active = (damage > 0) || ((procExtra & PROC_EX_ABSORB) && isVictim);
if (!IsTriggeredAtSpellProcEvent(pTarget, triggerData.aura, procSpell, procFlag, procExtra, attType, isVictim, active, triggerData.spellProcEvent))
@@ -13236,17 +13331,18 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit * pTarget, uint32 procFlag,
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (AuraEffect * aurEff = itr->second->GetPartAura(i))
+ if (itr->second->HasEffect(i))
{
+ AuraEffect * aurEff = itr->second->GetBase()->GetEffect(i);
// Skip this auras
- if (isNonTriggerAura[aurEff->GetAuraName()])
+ if (isNonTriggerAura[aurEff->GetAuraType()])
continue;
// If not trigger by default and spellProcEvent==NULL - skip
- if (!isTriggerAura[aurEff->GetAuraName()] && triggerData.spellProcEvent==NULL)
+ if (!isTriggerAura[aurEff->GetAuraType()] && triggerData.spellProcEvent==NULL)
continue;
uint32 triggered_spell_id = aurEff->GetSpellProto()->EffectTriggerSpell[i];
// check for positive auras that proc with charge drop
- bool positive = (!triggered_spell_id && IsPositiveSpell(aurEff->GetId()) && aurEff->GetParentAura()->GetAuraCharges()) ||
+ bool positive = (!triggered_spell_id && IsPositiveSpell(aurEff->GetId()) && aurEff->GetBase()->GetCharges()) ||
// check for positive auras that triggers unknown spells (Blessing Recovery, etc...)
(!sSpellStore.LookupEntry(triggered_spell_id) && IsPositiveSpell(aurEff->GetId())) ||
// final check for positive triggered spell
@@ -13271,10 +13367,10 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit * pTarget, uint32 procFlag,
for (ProcTriggeredList::const_iterator i = procTriggered.begin(); i != procTriggered.end(); ++i)
{
// look for aura in auras list, it may be removed while proc event processing
- if (!HasAura(i->aura))
+ if (i->aura->IsRemoved())
continue;
- bool useCharges= i->aura->GetAuraCharges()>0;
+ bool useCharges= i->aura->GetCharges()>0;
bool takeCharges = false;
SpellEntry const *spellInfo = i->aura->GetSpellProto();
uint32 Id = i->aura->GetId();
@@ -13301,10 +13397,10 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit * pTarget, uint32 procFlag,
if (!(i->effMask & (1<<effIndex)))
continue;
- AuraEffect *triggeredByAura = i->aura->GetPartAura(effIndex);
+ AuraEffect *triggeredByAura = i->aura->GetEffect(effIndex);
assert(triggeredByAura);
- switch(triggeredByAura->GetAuraName())
+ switch(triggeredByAura->GetAuraType())
{
case SPELL_AURA_PROC_TRIGGER_SPELL:
{
@@ -13433,12 +13529,12 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit * pTarget, uint32 procFlag,
{
// Damage is dealt after proc system - lets ignore auras which wasn't updated yet
// to make spell not remove its own aura
- if (i->aura->GetAuraDuration() == i->aura->GetAuraMaxDuration())
+ if (i->aura->GetDuration() == i->aura->GetMaxDuration())
break;
int32 damageLeft = triggeredByAura->GetAmount();
// No damage left
if (damageLeft < damage )
- RemoveAura(i->aura);
+ i->aura->Remove();
else
triggeredByAura->SetAmount(damageLeft-damage);
}
@@ -13455,7 +13551,7 @@ void Unit::ProcDamageAndSpellFor(bool isVictim, Unit * pTarget, uint32 procFlag,
}
// Remove charge (aura can be removed by triggers)
if (useCharges && takeCharges)
- i->aura->DropAuraCharge();
+ i->aura->DropCharge();
if (spellInfo->AttributesEx3 & SPELL_ATTR_EX3_DISABLE_PROC)
SetCantProc(false);
@@ -13598,7 +13694,7 @@ void Unit::SetStandState(uint8 state)
bool Unit::IsPolymorphed() const
{
- return GetSpellSpecific(getTransForm())==SPELL_MAGE_POLYMORPH;
+ return GetSpellSpecific(getTransForm())==SPELL_SPECIFIC_MAGE_POLYMORPH;
}
void Unit::SetDisplayId(uint32 modelId)
@@ -13718,16 +13814,6 @@ Unit* Unit::SelectNearbyTarget(float dist) const
return *tcIter;
}
-bool Unit::hasNegativeAuraWithInterruptFlag(uint32 flag)
-{
- for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); ++iter)
- {
- if (!iter->second->IsPositive() && iter->second->GetSpellProto()->AuraInterruptFlags & flag)
- return true;
- }
- return false;
-}
-
void Unit::ApplyAttackTimePercentMod( WeaponAttackType att,float val, bool apply )
{
float remainingTimePct = (float)m_attackTimer[att] / (GetAttackTime(att) * m_modAttackSpeedPct[att]);
@@ -13895,21 +13981,6 @@ float Unit::GetAPMultiplier(WeaponAttackType attType, bool normalized)
}
}
-AuraEffect* Unit::GetAuraEffect(AuraType type, SpellFamilyNames name, uint32 iconId, uint8 effIndex) const
-{
- Unit::AuraEffectList const& mDummy = GetAurasByType(type);
- for (Unit::AuraEffectList::const_iterator itr = mDummy.begin(); itr != mDummy.end(); ++itr)
- {
- if (effIndex != (*itr)->GetEffIndex())
- continue;
- SpellEntry const * spell = (*itr)->GetSpellProto();
- if (spell->SpellIconID == iconId && spell->SpellFamilyName == name
- && !spell->SpellFamilyFlags)
- return *itr;
- }
- return NULL;
-}
-
bool Unit::IsUnderLastManaUseEffect() const
{
return getMSTimeDiff(m_lastManaUse,getMSTime()) < 5000;
@@ -14101,14 +14172,21 @@ bool Unit::HandleAuraRaidProcFromChargeWithValue(AuraEffect *triggeredByAura)
int32 heal = triggeredByAura->GetAmount();
uint64 caster_guid = triggeredByAura->GetCasterGUID();
+ //Currently only Prayer of Mending
+ if (!(spellProto->SpellFamilyName == SPELLFAMILY_PRIEST && spellProto->SpellFamilyFlags[1] & 0x20))
+ {
+ sLog.outDebug("Unit::HandleAuraRaidProcFromChargeWithValue, received not handled spell: %u", spellProto->Id);
+ return false;
+ }
+
// jumps
- int32 jumps = triggeredByAura->GetParentAura()->GetAuraCharges()-1;
+ int32 jumps = triggeredByAura->GetBase()->GetCharges()-1;
// current aura expire
- triggeredByAura->GetParentAura()->SetAuraCharges(1); // will removed at next charges decrease
+ triggeredByAura->GetBase()->SetCharges(1); // will removed at next charges decrease
// next target selection
- if (jumps > 0 && IS_PLAYER_GUID(caster_guid))
+ if (jumps > 0)
{
float radius;
if (spellProto->EffectRadiusIndex[effIdx])
@@ -14116,15 +14194,16 @@ bool Unit::HandleAuraRaidProcFromChargeWithValue(AuraEffect *triggeredByAura)
else
radius = GetSpellMaxRangeForTarget(triggeredByAura->GetCaster(), sSpellRangeStore.LookupEntry(spellProto->rangeIndex));
- if (Player *caster = (Player*)triggeredByAura->GetCaster())
+ if (Unit * caster = triggeredByAura->GetCaster())
{
- caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius, NULL);
+ if (Player * modOwner = caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius, NULL);
if (Unit *target = GetNextRandomRaidMemberOrPet(radius))
{
- CastCustomSpell(target, spellProto->Id, &heal, NULL, NULL, true, NULL, triggeredByAura, caster->GetGUID());
- if (Aura *aur = target->GetAura(spellProto->Id, caster->GetGUID()))
- aur->SetAuraCharges(jumps);
+ CastCustomSpell(target, spellProto->Id, &heal, NULL, NULL, true, NULL, triggeredByAura, caster_guid);
+ if (Aura * aura = target->GetAura(spellProto->Id, caster->GetGUID()))
+ aura->SetCharges(jumps);
heal = caster->SpellHealingBonus(this, spellProto, heal, HEAL);
}
}
@@ -14158,24 +14237,17 @@ bool Unit::HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura)
return false;
}
- //Currently only Prayer of Mending
- if (!(spellProto->SpellFamilyName == SPELLFAMILY_PRIEST && spellProto->SpellFamilyFlags[1] & 0x20))
- {
- sLog.outDebug("Unit::HandleAuraRaidProcFromChargeWithValue, received not handled spell: %u", spellProto->Id);
- return false;
- }
-
uint64 caster_guid = triggeredByAura->GetCasterGUID();
uint32 effIdx = triggeredByAura->GetEffIndex();
// jumps
- int32 jumps = triggeredByAura->GetParentAura()->GetAuraCharges()-1;
+ int32 jumps = triggeredByAura->GetBase()->GetCharges()-1;
// current aura expire
- triggeredByAura->GetParentAura()->SetAuraCharges(1); // will removed at next charges decrease
+ triggeredByAura->GetBase()->SetCharges(1); // will removed at next charges decrease
// next target selection
- if (jumps > 0 && IS_PLAYER_GUID(caster_guid))
+ if (jumps > 0)
{
float radius;
if (spellProto->EffectRadiusIndex[effIdx])
@@ -14183,15 +14255,16 @@ bool Unit::HandleAuraRaidProcFromCharge(AuraEffect* triggeredByAura)
else
radius = GetSpellMaxRangeForTarget(triggeredByAura->GetCaster() ,sSpellRangeStore.LookupEntry(spellProto->rangeIndex));
- if (Player* caster = ((Player*)triggeredByAura->GetCaster()))
+ if (Unit * caster = triggeredByAura->GetCaster())
{
- caster->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius,NULL);
+ if (Player * modOwner = caster->GetSpellModOwner())
+ modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_RADIUS, radius, NULL);
if (Unit* target= GetNextRandomRaidMemberOrPet(radius))
{
CastSpell(target, spellProto, true,NULL,triggeredByAura,caster_guid);
- if (Aura * aur = target->GetAura(spellProto->Id, caster->GetGUID()))
- aur->SetAuraCharges(jumps);
+ if (Aura * aura = target->GetAura(spellProto->Id, caster->GetGUID()))
+ aura->SetCharges(jumps);
}
}
}
@@ -14267,7 +14340,7 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss)
bool SpiritOfRedemption = false;
if (pVictim->GetTypeId() == TYPEID_PLAYER && pVictim->getClass() == CLASS_PRIEST)
{
- AuraEffectList const& vDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);
+ AuraEffectList const& vDummyAuras = pVictim->GetAuraEffectsByType(SPELL_AURA_DUMMY);
for (AuraEffectList::const_iterator itr = vDummyAuras.begin(); itr != vDummyAuras.end(); ++itr)
{
if ((*itr)->GetSpellProto()->SpellIconID==1654)
@@ -14542,7 +14615,7 @@ void Unit::SetFeared(bool apply)
SetUInt64Value(UNIT_FIELD_TARGET, 0);
Unit *caster = NULL;
- Unit::AuraEffectList const& fearAuras = GetAurasByType(SPELL_AURA_MOD_FEAR);
+ Unit::AuraEffectList const& fearAuras = GetAuraEffectsByType(SPELL_AURA_MOD_FEAR);
if (!fearAuras.empty())
caster = ObjectAccessor::GetUnit(*this, fearAuras.front()->GetCasterGUID());
if (!caster)
@@ -15003,124 +15076,49 @@ void Unit::GetPartyMembers(std::list<Unit*> &TagUnitMap)
}
}
-void Unit::HandleAuraEffect(AuraEffect * aureff, bool apply)
+Aura * Unit::AddAura(uint32 spellId, Unit *target)
{
- if (aureff->GetParentAura()->IsRemoved())
- return;
-
- sLog.outDebug("HandleAuraEffect: %u, apply: %u: amount: %u", aureff->GetAuraName(), apply, aureff->GetAmount());
-
- if (apply)
- {
- if (aureff->IsApplied())
- return;
-
- aureff->SetApplied(true);
- m_modAuras[aureff->GetAuraName()].push_back(aureff);
- aureff->ApplyModifier(true, true);
- }
- else
- {
- if (!aureff->IsApplied())
- return;
+ if (!target || !target->isAlive())
+ return NULL;
- aureff->SetApplied(false);
- // remove from list before mods removing (prevent cyclic calls, mods added before including to aura list - use reverse order)
- m_modAuras[aureff->GetAuraName()].remove(aureff);
- aureff->ApplyModifier(false, true);
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
+ if (!spellInfo)
+ return NULL;
- // Remove all triggered by aura spells vs unlimited duration
- aureff->CleanupTriggeredSpells();
- }
+ return AddAura(spellInfo, MAX_EFFECT_MASK, target);
}
-void Unit::AddAura(uint32 spellId, Unit *target)
+Aura * Unit::AddAura(SpellEntry const *spellInfo, uint8 effMask, Unit *target)
{
- if (!target || !target->isAlive())
- return;
-
- SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
if (!spellInfo)
- return;
+ return NULL;
if (target->IsImmunedToSpell(spellInfo))
- return;
-
- uint8 eff_mask=0;
- Unit * source = this;
+ return NULL;
for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
- if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA || IsAreaAuraEffect(spellInfo->Effect[i]))
- {
- // Area auras applied as linked should have target as source (otherwise they'll be removed after first aura update)
- if (spellInfo->Effect[i] != SPELL_EFFECT_APPLY_AURA)
- source = target;
-
- if (target->IsImmunedToSpellEffect(spellInfo, i))
- continue;
- eff_mask|=1<<i;
- }
+ if (!(effMask & (1<<i)))
+ continue;
+ if (target->IsImmunedToSpellEffect(spellInfo, i))
+ effMask &= ~(1<<i);
}
- if (!eff_mask)
- return;
-
- // Because source is not give, use caster as source
- Aura *Aur = new Aura(spellInfo, eff_mask, target, source, this);
- target->AddAura(Aur);
-}
-
-void Unit::SetAuraStack(uint32 spellId, Unit *target, uint32 stack)
-{
- Aura *aur = target->GetAura(spellId, GetGUID());
- if (!aur)
+ if (Aura * aura = Aura::TryCreate(spellInfo, effMask, target, this))
{
- AddAura(spellId, target);
- aur = target->GetAura(spellId, GetGUID());
+ aura->ApplyForTargets();
+ return aura;
}
- if (aur && stack)
- aur->SetStackAmount(stack);
+ return NULL;
}
-// This function is only used for area aura and creature addon
-// it should be removed in the future
-Aura * Unit::AddAuraEffect(const SpellEntry * spellInfo, uint8 effIndex, WorldObject *source, Unit* caster, int32 * basePoints)
+void Unit::SetAuraStack(uint32 spellId, Unit *target, uint32 stack)
{
- // can't do that for passive auras - they stack from same caster so there is no way to get exact aura which should get effect
- //assert (!IsPassiveSpell(spellInfo));
-
- sLog.outDebug("AddAuraEffect: spell id: %u, effect index: %u", spellInfo->Id, (uint32)effIndex);
-
- Aura *aur = GetAura(spellInfo->Id, caster->GetGUID());
- // without this it may crash when shaman refresh totem? source is NULL
- if (aur && aur->GetSourceGUID() != source->GetGUID())
- {
- RemoveAura(aur);
- aur = NULL;
- }
-
- if (aur)
- {
- if (AuraEffect *aurEffect = CreateAuraEffect(aur, effIndex, basePoints))
- if (!aur->SetPartAura(aurEffect, effIndex))
- delete aurEffect;
- }
- else
- {
- if (basePoints)
- {
- int32 amount[MAX_SPELL_EFFECTS];
- amount[effIndex] = *basePoints;
- aur = new Aura(spellInfo, 1<<effIndex, this, source, caster, amount, NULL);
- }
- else
- aur = new Aura(spellInfo, 1<<effIndex, this, source, caster, NULL, NULL);
-
- if (!AddAura(aur))
- return NULL;
- }
- return aur;
+ Aura *aura = target->GetAura(spellId, GetGUID());
+ if (!aura)
+ aura = AddAura(spellId, target);
+ if (aura && stack)
+ aura->SetStackAmount(stack);
}
// Melee based spells can be miss, parry or dodge on this step
@@ -15580,13 +15578,13 @@ void Unit::ExitVehicle()
return;
Unit *vehicleBase = m_vehicle->GetBase();
- const AuraEffectList &modAuras = vehicleBase->GetAurasByType(SPELL_AURA_CONTROL_VEHICLE);
+ const AuraEffectList &modAuras = vehicleBase->GetAuraEffectsByType(SPELL_AURA_CONTROL_VEHICLE);
for (AuraEffectList::const_iterator itr = modAuras.begin(); itr != modAuras.end(); ++itr)
{
- if ((*itr)->GetParentAura()->GetSourceGUID() == GetGUID())
+ if ((*itr)->GetBase()->GetOwner() == this)
{
- vehicleBase->RemoveAura((*itr)->GetParentAura());
- break; // there should be no case that a vehicle has two auras for one source
+ vehicleBase->RemoveAura((*itr)->GetBase());
+ break; // there should be no case that a vehicle has two auras for one owner
}
}
@@ -15901,7 +15899,7 @@ void Unit::OutDebugInfo() const
sLog.outString();
sLog.outStringInLine("Aura List: ");
- for (AuraMap::const_iterator itr = m_Auras.begin(); itr != m_Auras.end(); ++itr)
+ for (AuraApplicationMap::const_iterator itr = m_appliedAuras.begin(); itr != m_appliedAuras.end(); ++itr)
sLog.outStringInLine("%u, ", itr->first);
sLog.outString();
diff --git a/src/game/Unit.h b/src/game/Unit.h
index d2a713349a1..5507335d848 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -85,6 +85,7 @@ enum SpellAuraInterruptFlags
AURA_INTERRUPT_FLAG_TELEPORTED = 0x00400000, // 22
AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT = 0x00800000, // 23 removed by entering pvp combat
AURA_INTERRUPT_FLAG_DIRECT_DAMAGE = 0x01000000, // 24 removed by any direct damage
+ AURA_INTERRUPT_FLAG_LANDING = 0x02000000, // 25 removed by hitting the ground
AURA_INTERRUPT_FLAG_NOT_VICTIM = (AURA_INTERRUPT_FLAG_HITBYSPELL | AURA_INTERRUPT_FLAG_TAKE_DAMAGE | AURA_INTERRUPT_FLAG_DIRECT_DAMAGE),
};
@@ -317,6 +318,7 @@ struct FactionTemplateEntry;
struct SpellEntry;
struct SpellValue;
+class AuraApplication;
class Aura;
class AuraEffect;
class Creature;
@@ -365,11 +367,12 @@ enum DamageTypeToSchool
enum AuraRemoveMode
{
- AURA_REMOVE_BY_DEFAULT=0, // scripted remove, remove by stack with aura with different ids and sc aura remove
- AURA_REMOVE_BY_STACK, // replace by aura with same id
+ AURA_REMOVE_NONE = 0,
+ AURA_REMOVE_BY_DEFAULT = 1, // scripted remove, remove by stack with aura with different ids and sc aura remove
+ AURA_REMOVE_BY_STACK, // replace by aura with same id
AURA_REMOVE_BY_CANCEL,
- AURA_REMOVE_BY_ENEMY_SPELL, // dispel and absorb aura destroy
- AURA_REMOVE_BY_EXPIRE, // dispel and absorb aura destroy
+ AURA_REMOVE_BY_ENEMY_SPELL, // dispel and absorb aura destroy
+ AURA_REMOVE_BY_EXPIRE, // aura duration has ended
AURA_REMOVE_BY_DEATH
};
@@ -854,10 +857,10 @@ struct SpellNonMeleeDamage{
struct SpellPeriodicAuraLogInfo
{
- SpellPeriodicAuraLogInfo(AuraEffect *_auraEff, uint32 _damage, uint32 _overDamage, uint32 _absorb, uint32 _resist, float _multiplier, bool _critical)
+ SpellPeriodicAuraLogInfo(AuraEffect const *_auraEff, uint32 _damage, uint32 _overDamage, uint32 _absorb, uint32 _resist, float _multiplier, bool _critical)
: auraEff(_auraEff), damage(_damage), overDamage(_overDamage), absorb(_absorb), resist(_resist), multiplier(_multiplier), critical(_critical){}
- AuraEffect *auraEff;
+ AuraEffect const * auraEff;
uint32 damage;
uint32 overDamage; // overkill/overheal
uint32 absorb;
@@ -1081,13 +1084,15 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
typedef std::set<Unit*> ControlList;
typedef std::pair<uint32, uint8> spellEffectPair;
typedef std::multimap<uint32, Aura*> AuraMap;
- typedef std::multimap<AuraState, Aura*> AuraStateAurasMap;
+ typedef std::multimap<uint32, AuraApplication*> AuraApplicationMap;
+ typedef std::multimap<AuraState, AuraApplication*> AuraStateAurasMap;
typedef std::list<AuraEffect *> AuraEffectList;
typedef std::list<Aura *> AuraList;
+ typedef std::list<AuraApplication *> AuraApplicationList;
typedef std::list<DiminishingReturn> Diminishing;
typedef std::set<uint32> ComboPointHolderSet;
- typedef std::map<uint8, Aura*> VisibleAuraMap;
+ typedef std::map<uint8, AuraApplication*> VisibleAuraMap;
virtual ~Unit ( );
@@ -1154,7 +1159,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void CombatStopWithPets(bool includingCast = false);
void StopAttackFaction(uint32 faction_id);
Unit* SelectNearbyTarget(float dist = NOMINAL_MELEE_RANGE) const;
- bool hasNegativeAuraWithInterruptFlag(uint32 flag);
void SendMeleeAttackStop(Unit* victim);
void SendMeleeAttackStart(Unit* pVictim);
@@ -1396,17 +1400,16 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage,Powers powertype);
void EnergizeBySpell(Unit *pVictim, uint32 SpellID, uint32 Damage, Powers powertype);
uint32 SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage);
- void CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastSpell(Unit* Victim, SpellEntry const *spellInfo, bool triggered, Item *castItem= NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0, Unit* originalVictim = 0);
- void CastCustomSpell(Unit* Victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem= NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* Victim = NULL, bool triggered = true, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* Victim = NULL, bool triggered = true, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastSpell(Unit* Victim, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect const * triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastSpell(Unit* Victim, SpellEntry const *spellInfo, bool triggered, Item *castItem= NULL, AuraEffect const * triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect const * triggeredByAura = NULL, uint64 originalCaster = 0, Unit* originalVictim = 0);
+ void CastCustomSpell(Unit* Victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem= NULL, AuraEffect const * triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* Victim = NULL, bool triggered = true, Item *castItem = NULL, AuraEffect const * triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* Victim = NULL, bool triggered = true, Item *castItem = NULL, AuraEffect const * triggeredByAura = NULL, uint64 originalCaster = 0);
void CastSpell(GameObject *go, uint32 spellId, bool triggered, Item *castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0);
- void AddAura(uint32 spellId, Unit *target);
+ Aura * AddAura(uint32 spellId, Unit *target);
+ Aura * AddAura(SpellEntry const *spellInfo, uint8 effMask, Unit *target);
void SetAuraStack(uint32 spellId, Unit *target, uint32 stack);
- void HandleAuraEffect(AuraEffect * aureff, bool apply);
- Aura *AddAuraEffect(const SpellEntry *spellInfo, uint8 effIndex, WorldObject *source, Unit *caster, int32 *basePoints = NULL);
bool IsDamageToThreatSpell(SpellEntry const * spellInfo) const;
@@ -1526,31 +1529,99 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
Pet* CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id = 0);
- bool AddAura(Aura *aur, bool handleEffects = true);
-
- void RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
- void RemoveAura(uint32 spellId, uint64 caster = 0 ,AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
+ // aura apply/remove helpers - you should better not use these
+ void _AddAura(Aura * aura);
+ AuraApplication * __ApplyAura(Aura * aura);
+ void __UnapplyAura(AuraApplicationMap::iterator &i);
+ bool _ApplyAuraEffect(Aura * aura, uint8 effIndex);
+ void _UnapplyAuraEffect(AuraApplication * aurApp, uint8 effIndex, AuraRemoveMode removeMode);
+ void _UnapplyAura(AuraApplicationMap::iterator &i, AuraRemoveMode removeMode);
+ void _UnapplyAura(AuraApplication * aurApp, AuraRemoveMode removeMode);
+ void _RemoveNoStackAurasDueToAura(Aura * aura);
+ void _HandleAuraEffect(AuraEffect * aurEff, bool apply);
+
+ // m_ownedAuras container management
+ AuraMap & GetOwnedAuras() { return m_ownedAuras; }
+ AuraMap const& GetOwnedAuras() const { return m_ownedAuras; }
+
+ void RemoveOwnedAura(AuraMap::iterator &i, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
+ void RemoveOwnedAura(uint32 spellId, uint64 caster, uint8 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
+ void RemoveOwnedAura(Aura * aura, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
+
+ Aura * GetOwnedAura(uint32 spellId, uint64 casterGUID = 0, uint8 reqEffMask = 0) const;
+
+ // m_appliedAuras container management
+ AuraApplicationMap & GetAppliedAuras() { return m_appliedAuras; }
+ AuraApplicationMap const& GetAppliedAuras() const { return m_appliedAuras; }
+
+ void RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
+ void RemoveAura(uint32 spellId, uint64 caster = 0, uint8 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
+ void RemoveAura(AuraApplication * aurApp, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
void RemoveAura(Aura * aur, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
- void RemoveAurasDueToSpell(uint32 spellId, uint64 caster = NULL ,AuraRemoveMode removeMode= AURA_REMOVE_BY_DEFAULT);
- void RemoveAuraFromStack(uint32 spellId, uint64 caster = NULL ,AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
+
+ void RemoveAurasDueToSpell(uint32 spellId, uint64 caster = NULL, uint8 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
+ void RemoveAuraFromStack(uint32 spellId, uint64 caster = NULL, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
inline void RemoveAuraFromStack(AuraMap::iterator &iter,AuraRemoveMode removeMode);
- void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeller);
- void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer);
+ void RemoveAurasDueToSpellByDispel(Aura * aura, Unit *dispeller);
+ void RemoveAurasDueToSpellBySteal(Aura * aura, Unit *stealer);
void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId);
void RemoveAurasByType(AuraType auraType, uint64 casterGUID = 0, Aura * except = NULL, bool negative = true, bool positive = true);
void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0);
-
- void RemoveRankAurasDueToSpell(uint32 spellId);
- bool RemoveNoStackAurasDueToAura(Aura *Aur);
void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except = NULL);
- void RemoveAurasWithFamily(uint32 family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID);
- void RemoveMovementImpairingAuras();
+ void RemoveAurasWithFamily(SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID);
void RemoveAurasWithMechanic(uint32 mechanic_mask, AuraRemoveMode removemode = AURA_REMOVE_BY_DEFAULT, uint32 except=0);
+ void RemoveMovementImpairingAuras();
+
+ void RemoveAreaAurasDueToLeaveWorld();
void RemoveAllAuras();
- void RemoveAllAuras(uint64 casterGUID, Aura * except = NULL, bool negative = true, bool positive = true);
void RemoveArenaAuras(bool onleave = false);
void RemoveAllAurasOnDeath();
- void DelayAura(uint32 spellId, uint64 caster, int32 delaytime);
+ void DelayOwnedAuras(uint32 spellId, uint64 caster, int32 delaytime);
+
+ void _RemoveAllAuraStatMods();
+ void _ApplyAllAuraStatMods();
+
+ AuraEffectList const& GetAuraEffectsByType(AuraType type) const { return m_modAuras[type]; }
+ AuraApplicationList & GetSingleCastAuras() { return m_scAuras; }
+ AuraApplicationList const& GetSingleCastAuras() const { return m_scAuras; }
+
+ AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, uint64 casterGUID = 0) const;
+ AuraEffect * GetAuraEffectOfRankedSpell(uint32 spellId, uint8 effIndex, uint64 casterGUID = 0) const;
+ AuraEffect * GetAuraEffect(AuraType type, SpellFamilyNames name, uint32 iconId, uint8 effIndex) const; // spell mustn't have familyflags
+ AuraEffect * GetAuraEffect(AuraType type, SpellFamilyNames family, uint32 familyFlag1 , uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID =0 );
+ inline AuraEffect* GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const { return GetAuraEffect(SPELL_AURA_DUMMY, name, iconId, effIndex);}
+
+ AuraApplication * GetAuraApplication(uint32 spellId, uint64 casterGUID = 0, uint8 reqEffMask = 0, AuraApplication * except = NULL) const;
+ Aura * GetAura(uint32 spellId, uint64 casterGUID = 0, uint8 reqEffMask = 0) const;
+
+ AuraApplication * GetAuraApplicationOfRankedSpel(uint32 spellId, uint64 casterGUID = 0, uint8 reqEffMask = 0, AuraApplication * except = NULL) const;
+ Aura * GetAuraOfRankedSpell(uint32 spellId, uint64 casterGUID = 0, uint8 reqEffMask = 0) const;
+
+ bool HasAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster = 0) const;
+ bool HasAura(uint32 spellId, uint64 caster = 0, uint8 reqEffMask = 0) const;
+ bool HasAuraType(AuraType auraType) const;
+ bool HasAuraTypeWithMiscvalue(AuraType auratype, uint32 miscvalue) const;
+ bool HasAuraTypeWithValue(AuraType auratype, uint32 value) const;
+ bool HasNegativeAuraWithInterruptFlag(uint32 flag);
+
+ AuraEffect * IsScriptOverriden(SpellEntry const * spell, int32 script) const;
+ uint32 GetDiseasesByCaster(uint64 casterGUID, bool remove = false);
+ uint32 GetDoTsByCaster(uint64 casterGUID) const;
+
+ int32 GetTotalAuraModifier(AuraType auratype) const;
+ float GetTotalAuraMultiplier(AuraType auratype) const;
+ int32 GetMaxPositiveAuraModifier(AuraType auratype);
+ int32 GetMaxNegativeAuraModifier(AuraType auratype) const;
+
+ int32 GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const;
+ float GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask) const;
+ int32 GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const;
+ int32 GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const;
+
+ int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const;
+ float GetTotalAuraMultiplierByMiscValue(AuraType auratype, int32 misc_value) const;
+ int32 GetMaxPositiveAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const;
+ int32 GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const;
float GetResistanceBuffMods(SpellSchools school, bool positive) const { return GetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school ); }
void SetResistanceBuffMods(SpellSchools school, bool positive, float val) { SetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school,val); }
@@ -1665,8 +1736,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
// function for low level grid visibility checks in player/creature cases
virtual bool IsVisibleInGridForPlayer(Player const* pl) const = 0;
- AuraList & GetSingleCastAuras() { return m_scAuras; }
- AuraList const& GetSingleCastAuras() const { return m_scAuras; }
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY];
// Threat related methods
@@ -1682,49 +1751,15 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
HostilRefManager& getHostilRefManager() { return m_HostilRefManager; }
VisibleAuraMap const *GetVisibleAuras() { return &m_visibleAuras; }
- Aura * GetVisibleAura(uint8 slot)
+ AuraApplication * GetVisibleAura(uint8 slot)
{
VisibleAuraMap::iterator itr = m_visibleAuras.find(slot);
if(itr != m_visibleAuras.end())
return itr->second;
return 0;
}
- void SetVisibleAura(uint8 slot, Aura * aur){ m_visibleAuras[slot]=aur; }
- void RemoveVisibleAura(uint8 slot){ m_visibleAuras.erase(slot); }
-
- AuraMap & GetAuras() { return m_Auras; }
- AuraMap const& GetAuras() const { return m_Auras; }
- AuraEffectList const& GetAurasByType(AuraType type) const { return m_modAuras[type]; }
-
- AuraEffect * GetAuraEffect(uint32 spellId, uint8 effIndex, uint64 casterGUID = 0) const;
- Aura * GetAura(uint32 spellId, uint64 casterGUID = 0) const;
- AuraEffect * GetAura(AuraType type, uint32 family, uint32 familyFlag1 , uint32 familyFlag2=0, uint32 familyFlag3=0, uint64 casterGUID=0);
- AuraEffect * IsScriptOverriden(SpellEntry const * spell, int32 script) const;
- bool HasAuraEffect(uint32 spellId, uint8 effIndex, uint64 caster = 0) const;
- bool HasAura(uint32 spellId, uint64 caster = 0) const;
- bool HasAura(Aura * aur) const;
- bool HasAuraType(AuraType auraType) const;
- bool HasAuraTypeWithMiscvalue(AuraType auratype, uint32 miscvalue) const;
- bool HasAuraTypeWithValue(AuraType auratype, uint32 value) const;
- inline AuraEffect* GetDummyAura(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const { return GetAuraEffect(SPELL_AURA_DUMMY, name, iconId, effIndex);}
- AuraEffect* GetAuraEffect(AuraType type, SpellFamilyNames name, uint32 iconId, uint8 effIndex) const;
- uint32 GetDiseasesByCaster(uint64 casterGUID, bool remove = false);
- uint32 GetDoTsByCaster(uint64 casterGUID) const;
-
- int32 GetTotalAuraModifier(AuraType auratype) const;
- float GetTotalAuraMultiplier(AuraType auratype) const;
- int32 GetMaxPositiveAuraModifier(AuraType auratype);
- int32 GetMaxNegativeAuraModifier(AuraType auratype) const;
-
- int32 GetTotalAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const;
- float GetTotalAuraMultiplierByMiscMask(AuraType auratype, uint32 misc_mask) const;
- int32 GetMaxPositiveAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const;
- int32 GetMaxNegativeAuraModifierByMiscMask(AuraType auratype, uint32 misc_mask) const;
-
- int32 GetTotalAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const;
- float GetTotalAuraMultiplierByMiscValue(AuraType auratype, int32 misc_value) const;
- int32 GetMaxPositiveAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const;
- int32 GetMaxNegativeAuraModifierByMiscValue(AuraType auratype, int32 misc_value) const;
+ void SetVisibleAura(uint8 slot, AuraApplication * aur){ m_visibleAuras[slot]=aur; UpdateAuraForGroup(slot);}
+ void RemoveVisibleAura(uint8 slot){ m_visibleAuras.erase(slot); UpdateAuraForGroup(slot);}
uint32 GetInterruptMask() const { return m_interruptMask; }
void AddInterruptMask(uint32 mask) { m_interruptMask |= mask; }
@@ -1797,9 +1832,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SetHover(bool on);
bool isHover() const { return HasAuraType(SPELL_AURA_HOVER); }
- void _RemoveAllAuraMods();
- void _ApplyAllAuraMods();
-
int32 CalculateSpellDamage(SpellEntry const* spellProto, uint8 effect_index, int32 basePoints, Unit const* target);
int32 CalcSpellDuration(SpellEntry const* spellProto);
int32 ModSpellDuration(SpellEntry const* spellProto, Unit const* target, int32 duration, bool positive);
@@ -1931,7 +1963,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
Transport * m_transport;
void _UpdateSpells(uint32 time);
- void _DeleteAuras();
+ void _DeleteRemovedAuras();
void _UpdateAutoRepeatSpell();
@@ -1946,9 +1978,6 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
DeathState m_deathState;
- AuraMap m_Auras;
- AuraMap::iterator m_AurasUpdateIterator;
- uint32 m_removedAurasCount;
int32 m_procDeep;
typedef std::list<uint64> DynObjectGUIDs;
@@ -1959,11 +1988,16 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
bool m_isSorted;
uint32 m_transform;
- AuraEffectList m_modAuras[TOTAL_AURAS];
- AuraList m_scAuras; // casted singlecast auras
- AuraList m_interruptableAuras;
+ AuraMap m_ownedAuras;
+ AuraApplicationMap m_appliedAuras;
AuraList m_removedAuras;
- AuraStateAurasMap m_auraStateAuras; // Used for improve performance of aura state checks on aura apply/remove
+ AuraMap::iterator m_auraUpdateIterator;
+ uint32 m_removedAurasCount;
+
+ AuraEffectList m_modAuras[TOTAL_AURAS];
+ AuraApplicationList m_scAuras; // casted singlecast auras
+ AuraApplicationList m_interruptableAuras; // auras which have interrupt mask applied on unit
+ AuraStateAurasMap m_auraStateAuras; // Used for improve performance of aura state checks on aura apply/remove
uint32 m_interruptMask;
float m_auraModifiersGroup[UNIT_MOD_END][MODIFIER_TYPE_END];
@@ -1992,7 +2026,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
uint32 m_unitTypeMask;
private:
- bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura* aura, SpellEntry const * procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const *& spellProcEvent );
+ bool IsTriggeredAtSpellProcEvent(Unit *pVictim, Aura * aura, SpellEntry const * procSpell, uint32 procFlag, uint32 procExtra, WeaponAttackType attType, bool isVictim, bool active, SpellProcEventEntry const *& spellProcEvent );
bool HandleDummyAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleHasteAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggeredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
bool HandleSpellCritChanceAuraProc( Unit *pVictim, uint32 damage, AuraEffect* triggredByAura, SpellEntry const *procSpell, uint32 procFlag, uint32 procEx, uint32 cooldown);
diff --git a/src/game/UnitAI.cpp b/src/game/UnitAI.cpp
index bafcb04a2f3..7365619030f 100644
--- a/src/game/UnitAI.cpp
+++ b/src/game/UnitAI.cpp
@@ -22,6 +22,7 @@
#include "Player.h"
#include "Creature.h"
#include "SpellAuras.h"
+#include "SpellAuraEffects.h"
#include "SpellMgr.h"
#include "CreatureAIImpl.h"
@@ -370,9 +371,9 @@ void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/)
//kill self if charm aura has infinite duration
if(charmer->IsInEvadeMode())
{
- Unit::AuraEffectList const& auras = me->GetAurasByType(SPELL_AURA_MOD_CHARM);
+ Unit::AuraEffectList const& auras = me->GetAuraEffectsByType(SPELL_AURA_MOD_CHARM);
for (Unit::AuraEffectList::const_iterator iter = auras.begin(); iter != auras.end(); ++iter)
- if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetParentAura()->IsPermanent())
+ if((*iter)->GetCasterGUID() == charmer->GetGUID() && (*iter)->GetBase()->IsPermanent())
{
charmer->Kill(me);
return;
diff --git a/src/shared/ByteBuffer.h b/src/shared/ByteBuffer.h
index d5001cfc1bf..6fd0c9b883d 100644
--- a/src/shared/ByteBuffer.h
+++ b/src/shared/ByteBuffer.h
@@ -386,21 +386,21 @@ class ByteBuffer
void appendPackGUID(uint64 guid)
{
- if (_storage.size() < _wpos + sizeof(guid) + 1)
- _storage.resize(_wpos + sizeof(guid) + 1);
-
- size_t mask_position = wpos();
- *this << uint8(0);
- for (uint8 i = 0; i < 8; ++i)
+ uint8 packGUID[8+1];
+ packGUID[0] = 0;
+ size_t size = 1;
+ for(uint8 i = 0;guid != 0;++i)
{
if(guid & 0xFF)
{
- _storage[mask_position] |= uint8(1 << i);
- *this << uint8(guid & 0xFF);
+ packGUID[0] |= uint8(1 << i);
+ packGUID[size] = uint8(guid & 0xFF);
+ ++size;
}
guid >>= 8;
}
+ append(packGUID, size);
}
void put(size_t pos, const uint8 *src, size_t cnt)