aboutsummaryrefslogtreecommitdiff
path: root/src/game/SpellAuras.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/SpellAuras.cpp')
-rw-r--r--src/game/SpellAuras.cpp238
1 files changed, 124 insertions, 114 deletions
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 5fedc013188..b9f440188d2 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -426,24 +426,22 @@ m_auraSlot(MAX_AURAS), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),m_aura
// 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 || caster==target)
- m_positive=IsPositiveSpell(m_spellProto->Id);
+ if (!caster || 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)
+ for (uint8 i=0;i<MAX_SPELL_EFFECTS;++i)
+ {
+ if (!(1<<i & GetEffectMask()))
+ continue;
+ if (m_positive == IsPositiveEffect(GetId(), i))
{
- if (!(1<<i & GetEffectMask()))
- continue;
- if (m_positive == IsPositiveEffect(GetId(), i))
- {
- swap = true;
- break;
- }
+ swap = true;
+ break;
}
- if (!swap)
- m_positive=!m_positive;
}
+ if (!swap)
+ m_positive=!m_positive;
}
Aura::~Aura()
@@ -607,36 +605,48 @@ void Aura::Update(uint32 diff)
m_duration -= diff;
if (m_duration < 0)
m_duration = 0;
- m_timeCla -= diff;
// all spells with manaPerSecond/manaPerSecondPerLevel have aura in effect 0
+ if(m_timeCla > 0)
+ m_timeCla -= diff;
if(m_timeCla <= 0)
{
if(Unit* caster = GetCaster())
{
- Powers powertype = Powers(m_spellProto->powerType);
- int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel();
- m_timeCla = 1000;
- if (manaPerSecond)
+ if(int32 manaPerSecond = m_spellProto->manaPerSecond + m_spellProto->manaPerSecondPerLevel * caster->getLevel())
{
- if(powertype==POWER_HEALTH)
+ m_timeCla = 1000;
+
+ Powers powertype = Powers(m_spellProto->powerType);
+ if(powertype == POWER_HEALTH)
{
- if (caster->GetHealth()>manaPerSecond)
+ 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);
+ {
+ if (caster->GetPower(powertype) >= manaPerSecond)
+ caster->ModifyPower(powertype, -manaPerSecond);
+ else
+ {
+ m_target->RemoveAura(this);
+ return;
+ }
+ }
}
}
}
}
- // Channeled aura required check distance from caster except in possessed cases
- if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID() && !m_target->isPossessed())
+ // Channeled aura required check distance from caster
+ if(IsChanneledSpell(m_spellProto) && m_caster_guid != m_target->GetGUID()
+ && !IsAreaAura() && !IsPersistent() // check for these is done in auraeffect
+ /* && !m_target->isPossessed()*/)
{
Unit* caster = GetCaster();
if(!caster)
@@ -647,16 +657,18 @@ void Aura::Update(uint32 diff)
// Get spell range
float radius=-1.0f;
SpellModOp mod;
+ // get part aura with lowest radius
for (uint8 i=0;i<3;++i)
{
if (HasEffect(i) && m_spellProto->EffectRadiusIndex[i])
{
- radius = caster->GetSpellRadiusForTarget(m_target, sSpellRadiusStore.LookupEntry(m_spellProto->EffectRadiusIndex[i]));
+ float new_radius = caster->GetSpellRadiusForTarget(m_target, sSpellRadiusStore.LookupEntry(m_spellProto->EffectRadiusIndex[i]));
+ if (radius < 0.0f || radius > new_radius)
+ radius = new_radius;
mod = SPELLMOD_RADIUS;
- break;
}
}
- if (radius<0)
+ if (radius < 0.0f)
{
radius = caster->GetSpellMaxRangeForTarget(m_target, sSpellRangeStore.LookupEntry(m_spellProto->rangeIndex)) ;
mod = SPELLMOD_RANGE;
@@ -672,16 +684,9 @@ void Aura::Update(uint32 diff)
}
}
- for (uint8 i = 0; i<MAX_SPELL_EFFECTS;++i)
+ for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
if (m_partAuras[i])
- {
- if (m_partAuras[i]->IsAreaAura())
- ((AreaAuraEffect *) m_partAuras[i])->Update(diff);
- else if(m_partAuras[i]->IsPersistent())
- ((PersistentAreaAuraEffect *) m_partAuras[i])->Update(diff);
- else
- m_partAuras[i]->Update(diff);
- }
+ m_partAuras[i]->Update(diff);
}
void AuraEffect::Update(uint32 diff)
@@ -764,28 +769,29 @@ void AreaAuraEffect::Update(uint32 diff)
}
else // aura at non-caster
{
- Unit * tmp_target = m_target;
- Unit* caster = GetCaster();
- uint32 tmp_spellId = GetId();
- uint32 tmp_effIndex = GetEffIndex();
- uint64 tmp_guid = GetCasterGUID();
-
// 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();
+
// 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( !caster || caster->hasUnitState(UNIT_STAT_ISOLATED) ||
- !caster->HasAuraEffect(tmp_spellId, tmp_effIndex) ||
- caster->IsFriendlyTo(tmp_target) != needFriendly
+ !caster->HasAuraEffect(GetId(), m_effIndex) ||
+ caster->IsFriendlyTo(m_target) != needFriendly
)
{
m_target->RemoveAura(GetParentAura());
}
- else if (!caster->IsWithinDistInMap(tmp_target, m_radius))
+ else if (!caster->IsWithinDistInMap(m_target, m_radius))
{
if (needFriendly)
{
@@ -802,17 +808,17 @@ void AreaAuraEffect::Update(uint32 diff)
m_removeTime = FRIENDLY_AA_REMOVE_TIME;
if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group
{
- if(!tmp_target->IsInPartyWith(caster))
+ if(!m_target->IsInPartyWith(caster))
m_target->RemoveAura(GetParentAura());
}
else if( m_areaAuraType == AREA_AURA_RAID)
{
- if(!tmp_target->IsInRaidWith(caster))
+ if(!m_target->IsInRaidWith(caster))
m_target->RemoveAura(GetParentAura());
}
else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
{
- if( tmp_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
+ if( m_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
m_target->RemoveAura(GetParentAura());
}
}
@@ -821,29 +827,21 @@ void AreaAuraEffect::Update(uint32 diff)
void PersistentAreaAuraEffect::Update(uint32 diff)
{
- bool remove = false;
-
- // 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
- Unit *caster = GetCaster();
- if (caster)
+ if(Unit *caster = GetCaster())
{
- DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex());
- if (dynObj)
+ if(DynamicObject *dynObj = caster->GetDynObject(GetId(), GetEffIndex()))
{
- if (!m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
- remove = true;
+ if(m_target->IsWithinDistInMap(dynObj, dynObj->GetRadius()))
+ {
+ AuraEffect::Update(diff);
+ return;
+ }
}
- else
- remove = true;
}
- else
- remove = true;
-
- if(remove)
- m_target->RemoveAura(GetParentAura());
- AuraEffect::Update(diff);
+ // 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)
@@ -1169,25 +1167,26 @@ void Aura::_RemoveAura()
// Proc on aura remove (only spell flags for now)
if (caster)
{
- uint32 ProcCaster, ProcVictim;
- if (IsPositiveSpell(GetId()))
- {
- ProcCaster = PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL;
- ProcVictim = PROC_FLAG_TAKEN_POSITIVE_SPELL;
- }
- else
- {
- ProcCaster = PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT;
- ProcVictim = PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT;
- }
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;
- else return;
-
- caster->ProcDamageAndSpell(m_target,ProcCaster, ProcVictim, procEx, m_procDamage, BASE_ATTACK, m_spellProto);
+ if (procEx)
+ {
+ uint32 ProcCaster, ProcVictim;
+ if (IsPositiveSpell(GetId()))
+ {
+ ProcCaster = PROC_FLAG_SUCCESSFUL_POSITIVE_SPELL;
+ ProcVictim = PROC_FLAG_TAKEN_POSITIVE_SPELL;
+ }
+ else
+ {
+ ProcCaster = PROC_FLAG_SUCCESSFUL_NEGATIVE_SPELL_HIT;
+ ProcVictim = PROC_FLAG_TAKEN_NEGATIVE_SPELL_HIT;
+ }
+ caster->ProcDamageAndSpell(m_target,ProcCaster, ProcVictim, procEx, m_procDamage, BASE_ATTACK, m_spellProto);
+ }
}
}
@@ -1208,11 +1207,10 @@ void Aura::SetStackAmount(uint8 stackAmount)
// Reapply if amount change
if (amount!=part->GetAmount())
{
- bool Real = bool (part->m_spellmod);
// Auras which are applying spellmod should have removed spellmods for real
- part->ApplyModifier(false,Real);
+ part->ApplyModifier(false,true);
part->SetAmount(amount);
- part->ApplyModifier(true, Real);
+ part->ApplyModifier(true,true);
}
}
}
@@ -2267,6 +2265,12 @@ void AuraEffect::HandleAuraDummy(bool apply, bool Real)
{
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())
@@ -2425,8 +2429,9 @@ void AuraEffect::HandleAuraDummy(bool apply, bool Real)
// Haunt
if(m_spellProto->SpellFamilyFlags[1] & 0x40000)
{
+ int32 bp0 = GetParentAura()->GetProcDamage() * m_amount / 100;
if(caster)
- caster->CastCustomSpell(caster, 48210, &m_currentBasePoints, 0, 0, true);
+ caster->CastCustomSpell(caster, 48210, &bp0, 0, 0, true, NULL, this);
return;
}
break;
@@ -3073,10 +3078,10 @@ void AuraEffect::HandleAuraTransform(bool apply, bool Real)
if(GetMiscValue()==0)
{
// player applied only
- if(m_target->GetTypeId()!=TYPEID_PLAYER)
+ if (m_target->GetTypeId()!=TYPEID_PLAYER)
return;
- switch(GetId())
+ switch (GetId())
{
// Orb of Deception
case 16739:
@@ -3152,16 +3157,19 @@ void AuraEffect::HandleAuraTransform(bool apply, bool Real)
if(GetId()==42016 && m_target->GetMountID() && !m_target->GetAurasByType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED).empty())
m_target->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID,16314);
}
- m_target->setTransForm(GetId());
}
+ // 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())
+ 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)->setRegenTimer(1000);
+ if (IS_PLAYER_GUID(GetCasterGUID()) )
+ ((Player*)m_target)->setRegenTimer(1*IN_MILISECONDS);
//dismount polymorphed target (after patch 2.4.2)
if (m_target->IsMounted())
@@ -3170,20 +3178,20 @@ void AuraEffect::HandleAuraTransform(bool apply, bool Real)
}
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())
- {
- m_target->SetDisplayId(m_target->GetNativeDisplayId());
- m_target->setTransForm(0);
- }
- else
+ 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))
+ if (!IsPositiveSpell((*i)->GetSpellProto()->Id))
{
handledAura = *i;
break;
@@ -3193,9 +3201,9 @@ void AuraEffect::HandleAuraTransform(bool apply, bool Real)
}
// Dragonmaw Illusion (restore mount model)
- if(GetId()==42016 && m_target->GetMountID()==16314)
+ if (GetId()==42016 && m_target->GetMountID()==16314)
{
- if(!m_target->GetAurasByType(SPELL_AURA_MOUNTED).empty())
+ 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))
@@ -3416,7 +3424,7 @@ void AuraEffect::HandleAuraModScale(bool apply, bool Real)
((Creature*)m_target)->AIM_Initialize();
if (((Creature*)m_target)->AI())
- ((Creature*)m_target)->AI()->AttackStart(caster);
+ ((Creature*)m_target)->AI()->AttackedBy(caster);
}
}
}
@@ -3572,7 +3580,7 @@ void AuraEffect::HandleAuraModPetTalentsPoints(bool Apply, bool Real)
{
((Creature*)m_target)->AIM_Initialize();
if (((Creature*)m_target)->AI())
- ((Creature*)m_target)->AI()->AttackStart(caster);
+ ((Creature*)m_target)->AI()->AttackedBy(caster);
}
}
}
@@ -3813,18 +3821,8 @@ void AuraEffect::HandleAuraModSilence(bool apply, bool Real)
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++)
- {
- Spell* currentSpell = m_target->m_currentSpells[i];
- if (currentSpell && currentSpell->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
- {
- uint32 state = currentSpell->getState();
- // Stop spells on prepare or casting state
- if ( state == SPELL_STATE_PREPARING || state == SPELL_STATE_CASTING )
- {
- currentSpell->cancel();
- }
- }
- }
+ if (m_target->m_currentSpells[i] && m_target->m_currentSpells[i]->m_spellInfo->PreventionType == SPELL_PREVENTION_TYPE_SILENCE)
+ m_target->InterruptSpell(i,false); // Stop spells on prepare or casting state
switch (GetId())
{
@@ -6172,6 +6170,18 @@ void AuraEffect::PeriodicTick()
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:
{