aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/SpellAuras.cpp144
-rw-r--r--src/game/Unit.cpp47
-rw-r--r--src/game/Unit.h4
3 files changed, 96 insertions, 99 deletions
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index c016d9ca98b..ad00013bbb7 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -797,7 +797,7 @@ void Aura::_AddAura()
// passive auras (except totem auras) do not get placed in the slots
// area auras with SPELL_AURA_NONE are not shown on target
// all further code applies only to active spells
- if(!((m_spellProto->Attributes & 0x80 || !m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&
+ if(!(((m_spellProto->Attributes & 0x80 && GetTalentSpellPos(GetId())) || !m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&
(m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster)))
return;
@@ -815,8 +815,6 @@ void Aura::_AddAura()
if(itr->second->GetCasterGUID()==GetCasterGUID())
{
slot = itr->second->GetAuraSlot();
- if(slot >= MAX_AURAS)
- return;
secondaura = true;
break;
}
@@ -825,46 +823,48 @@ void Aura::_AddAura()
break;
}
- // Lookup free slot
- if (!secondaura)
+ Unit::VisibleAuraMap const *visibleAuras = m_target->GetVisibleAuras();
+ if(visibleAuras->size() < MAX_AURAS || slot < MAX_AURAS) // got free slot
{
- Unit::VisibleAuraMap const *visibleAuras = m_target->GetVisibleAuras();
- if(visibleAuras->size() >= MAX_AURAS) // no free slot
- return;
-
- Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin();
- for(int freeSlot = 0; freeSlot < MAX_AURAS; ++itr, ++freeSlot)
+ // Lookup free slot
+ if (!secondaura)
{
- if(itr == visibleAuras->end() || itr->first != freeSlot)
+ Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin();
+ for(int freeSlot = 0; freeSlot < MAX_AURAS; ++itr, ++freeSlot)
{
- slot = freeSlot;
- break;
+ if(itr == visibleAuras->end() || itr->first != freeSlot)
+ {
+ slot = freeSlot;
+ break;
+ }
}
- }
- assert(slot < MAX_AURAS); // assert that we find a slot and it is valid
-
- AuraSlotEntry t_entry;
- t_entry.m_Flags=(IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE) | AFLAG_NOT_CASTER | ((GetAuraMaxDuration() > 0) ? AFLAG_DURATION : AFLAG_NONE);
- t_entry.m_Level=(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
+ assert(slot < MAX_AURAS); // assert that we find a slot and it is valid
- //init pointers-prevent unexpected behaviour
- for(uint8 i = 0; i < 3; i++)
- t_entry.m_slotAuras[i]=NULL;
+ AuraSlotEntry t_entry;
+ t_entry.m_Flags=(IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE) | AFLAG_NOT_CASTER | ((GetAuraMaxDuration() > 0) ? AFLAG_DURATION : AFLAG_NONE);
+ t_entry.m_Level=(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
+ t_entry.m_spellId = GetId();
+ //init pointers-prevent unexpected behaviour
+ for(uint8 i = 0; i < 3; i++)
+ t_entry.m_slotAuras[i]=NULL;
- m_target->SetVisibleAura(slot, t_entry);
- }
-
- AuraSlotEntry *entry = m_target->GetVisibleAura(slot);
- if(!entry)
- return;
+ m_target->SetVisibleAura(slot, t_entry);
+ }
- entry->m_Flags |= (1 << GetEffIndex());
- entry->m_slotAuras[GetEffIndex()]=this;
+ if(AuraSlotEntry *entry = m_target->GetVisibleAura(slot))
+ {
+ entry->m_Flags |= (1 << GetEffIndex());
+ entry->m_slotAuras[GetEffIndex()]=this;
- SetAuraSlot( slot );
+ SetAuraSlot( slot );
- // update for out of range group members (on 1 slot use)
- m_target->UpdateAuraForGroup(slot);
+ // update for out of range group members (on 1 slot use)
+ m_target->UpdateAuraForGroup(slot);
+ sLog.outDebug("Aura: %u Effect: %d put to unit visible auras slot: %u",GetId(), GetEffIndex(), slot);
+ }
+ }
+ else
+ sLog.outDebug("Aura: %u Effect: %d could not find empty unit visible slot",GetId(), GetEffIndex());
//*****************************************************
// Update target aura state flag
@@ -880,6 +880,18 @@ void Aura::_AddAura()
// 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, m_target);
+ else if(Unit* caster = GetCaster())
+ m_target->AddAura(*itr, m_target);
+ }
}
// Update Seals information
@@ -930,39 +942,44 @@ void Aura::_RemoveAura()
// return;
uint8 slot = GetAuraSlot();
- if(slot >= MAX_AURAS) // slot not set
- return;
+ if(slot < MAX_AURAS) // slot not set
+ {
+ if (AuraSlotEntry *entry = m_target->GetVisibleAura(slot))
+ {
+ // we have more auras, do not clear slot
+ if (entry->m_slotAuras[GetEffIndex()]==this)
+ {
+ entry->m_slotAuras[GetEffIndex()]=NULL; //unregister aura
+ }
+ }
+ }
bool lastaura=true;
-
- AuraSlotEntry *entry = m_target->GetVisibleAura(slot);
- if (entry)
+ for(uint8 i = 0; i < 3; i++)
{
- // we have more auras, do not clear slot
- if (entry->m_slotAuras[GetEffIndex()]==this)
+ Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i);
+ for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
{
- entry->m_slotAuras[GetEffIndex()]=NULL; //unregister aura
- for(uint8 i = 0; i < 3; ++i) //check slot for more auras of the spell
+ if(itr->second->GetCasterGUID()==GetCasterGUID())
{
- if(entry->m_slotAuras[i])
- {
- lastaura = false;
- break;
- }
+ lastaura = false;
+ break;
}
}
+ if(!lastaura)
+ break;
}
- // only remove icon when the last aura of the spell is removed (current aura already removed from list)
- if(lastaura)
+ if (lastaura)
{
+ // update for out of range group members
+ if (slot < MAX_AURAS)
+ m_target->UpdateAuraForGroup(slot);
+
// unregister aura diminishing (and store last time)
if (getDiminishGroup() != DIMINISHING_NONE )
m_target->ApplyDiminishingAura(getDiminishGroup(),false);
- // update for out of range group members
- m_target->UpdateAuraForGroup(slot);
-
// Check needed only if aura applies aurastate
if(GetAuraStateMask())
{
@@ -986,6 +1003,27 @@ void Aura::_RemoveAura()
// note: item based cooldowns and cooldown spell mods with charges ignored (unknown existed cases)
((Player*)caster)->SendCooldownEvent(GetSpellProto());
}
+
+ // Remove Linked Auras (on last aura remove)
+ uint32 id = GetId();
+ if(spellmgr.GetSpellCustomAttr(id) & 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(Unit* caster = GetCaster())
+ m_target->CastSpell(m_target, *itr, true, 0, 0, caster->GetGUID());
+ }
+ 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, false);
+ else
+ m_target->RemoveAurasDueToSpell(*itr);
+ }
}
}
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 52b7b4f5114..26b3d7ce7a3 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -2013,10 +2013,9 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
healAmount = pVictim->GetMaxHealth()/2;
healCaster = pVictim;
healSpell = 48153;
- currentAbsorb = mod->m_amount;
+ mod->m_amount=0;
RemainingDamage=0;
}
- else
continue;
}
@@ -3895,17 +3894,6 @@ bool Unit::AddAura(Aura *Aur)
Aur->ApplyModifier(true,true);
- uint32 id = Aur->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)
- ApplySpellImmune(id, IMMUNITY_ID, *itr, true);
- else if(Unit* caster = Aur->GetCaster())
- caster->AddAura(*itr, this);
- }
-
sLog.outDebug("Aura %u now is in use", Aur->GetModifier()->m_auraname);
return true;
}
@@ -4360,40 +4348,10 @@ void Unit::RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode)
Aur->ApplyModifier(false,true);
Aur->_RemoveAura();
- bool stack = false;
- spellEffectPair spair = spellEffectPair(Aur->GetId(), Aur->GetEffIndex());
- for(AuraMap::const_iterator itr = GetAuras().lower_bound(spair); itr != GetAuras().upper_bound(spair); ++itr)
- {
- if (itr->second->GetCasterGUID()==GetGUID())
- {
- stack = true;
- }
- }
- if (!stack)
+ //if (mode!=AURA_REMOVE_BY_REPLACE)
{
// Remove all triggered by aura spells vs unlimited duration
Aur->CleanupTriggeredSpells();
-
- // Remove Linked Auras
- uint32 id = Aur->GetId();
- if(spellmgr.GetSpellCustomAttr(id) & 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)
- RemoveAurasDueToSpell(-(*itr));
- else if(Unit* caster = Aur->GetCaster())
- CastSpell(this, *itr, true, 0, 0, caster->GetGUID());
- }
- 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)
- ApplySpellImmune(id, IMMUNITY_ID, *itr, false);
- else
- RemoveAurasDueToSpell(*itr);
- }
}
delete Aur;
@@ -13379,6 +13337,7 @@ void Unit::SendAuraUpdate(uint8 slot)
if(!ptr)
{
+ sLog.outDebug("Aura %u removed slot %u",entry->m_spellId, slot);
RemoveVisibleAura(slot);
SendMessageToSet(&data, true);
return;
diff --git a/src/game/Unit.h b/src/game/Unit.h
index 19e188922e6..1f199445f12 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -325,8 +325,8 @@ enum DamageTypeToSchool
enum AuraRemoveMode
{
AURA_REMOVE_BY_DEFAULT,
- AURA_REMOVE_BY_STACK, // at replace by semillar aura
- AURA_REMOVE_BY_CANCEL,
+ AURA_REMOVE_BY_STACK, // at replace by semillar aura
+ AURA_REMOVE_BY_CANCEL, // single target aura remove is considered as cancel
AURA_REMOVE_BY_DISPEL,
AURA_REMOVE_BY_DEATH
};