mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
[8497] Fixes in talent 53563 work and other area auras spells.
* Support mutiply beacon buffs at same target (as will be in 3.2.x) in triggering part. * Bonus heal caster expected original paladin, and used his heal bonuses, LoS not required for bonus heal. * Fixed bug with not apply not-caster affected area spell (hostile area spell or talent 53563) to another caster with same area aura active. Correctly remove only specific caster area aura at expire. * Not show area spell icon for telent 53563 at beacon for this aura. * Allow stacking dummy auras from diff casters, check formal aura types for effect at add aura stacking check. Last important for area auars that can have SPELL_AURA_NONE in modifier data instead formal effect auars at caster.
This commit is contained in:
parent
50d426e72c
commit
67d4335614
5 changed files with 116 additions and 22 deletions
|
|
@ -477,6 +477,9 @@ Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target,
|
||||||
m_areaAuraType = AREA_AURA_RAID;
|
m_areaAuraType = AREA_AURA_RAID;
|
||||||
if (target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem())
|
if (target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem())
|
||||||
m_modifier.m_auraname = SPELL_AURA_NONE;
|
m_modifier.m_auraname = SPELL_AURA_NONE;
|
||||||
|
// Light's Beacon not applied to caster itself (TODO: more generic check for another simialr spell if any?)
|
||||||
|
else if (target == caster_ptr && m_spellProto->Id == 53651)
|
||||||
|
m_modifier.m_auraname = SPELL_AURA_NONE;
|
||||||
break;
|
break;
|
||||||
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
|
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
|
||||||
m_areaAuraType = AREA_AURA_FRIEND;
|
m_areaAuraType = AREA_AURA_FRIEND;
|
||||||
|
|
@ -770,7 +773,40 @@ void AreaAura::Update(uint32 diff)
|
||||||
|
|
||||||
for(std::list<Unit *>::iterator tIter = targets.begin(); tIter != targets.end(); tIter++)
|
for(std::list<Unit *>::iterator tIter = targets.begin(); tIter != targets.end(); tIter++)
|
||||||
{
|
{
|
||||||
if((*tIter)->HasAura(GetId(), m_effIndex))
|
// flag for seelction is need apply aura to current iteration target
|
||||||
|
bool apply = true;
|
||||||
|
|
||||||
|
// we need ignore present caster self applied are auras sometime
|
||||||
|
// in cases if this only auras applied for spell effect
|
||||||
|
Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), m_effIndex);
|
||||||
|
for(Unit::AuraMap::const_iterator i = (*tIter)->GetAuras().lower_bound(spair); i != (*tIter)->GetAuras().upper_bound(spair); ++i)
|
||||||
|
{
|
||||||
|
if (i->second->IsDeleted())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
switch(m_areaAuraType)
|
||||||
|
{
|
||||||
|
case AREA_AURA_ENEMY:
|
||||||
|
// non caster self-casted auras (non stacked)
|
||||||
|
if(i->second->GetModifier()->m_auraname != SPELL_AURA_NONE)
|
||||||
|
apply = false;
|
||||||
|
break;
|
||||||
|
case AREA_AURA_RAID:
|
||||||
|
// non caster self-casted auras (stacked from diff. casters)
|
||||||
|
if(i->second->GetModifier()->m_auraname != SPELL_AURA_NONE || i->second->GetCasterGUID() == GetCasterGUID())
|
||||||
|
apply = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// in generic case not allow stacking area auras
|
||||||
|
apply = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!apply)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!apply)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel()))
|
if(SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(GetSpellProto(), (*tIter)->getLevel()))
|
||||||
|
|
@ -803,7 +839,7 @@ void AreaAura::Update(uint32 diff)
|
||||||
caster->IsFriendlyTo(m_target) != needFriendly
|
caster->IsFriendlyTo(m_target) != needFriendly
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
m_target->RemoveAura(GetId(), GetEffIndex());
|
m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(),GetCasterGUID());
|
||||||
}
|
}
|
||||||
else if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group
|
else if( m_areaAuraType == AREA_AURA_PARTY) // check if in same sub group
|
||||||
{
|
{
|
||||||
|
|
@ -835,16 +871,16 @@ void AreaAura::Update(uint32 diff)
|
||||||
{
|
{
|
||||||
Player* checkTarget = m_target->GetCharmerOrOwnerPlayerOrPlayerItself();
|
Player* checkTarget = m_target->GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||||
if(!checkTarget)
|
if(!checkTarget)
|
||||||
m_target->RemoveAura(GetId(), GetEffIndex());
|
m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_target->RemoveAura(GetId(), GetEffIndex());
|
m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
|
else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )
|
||||||
{
|
{
|
||||||
if( m_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
|
if( m_target->GetGUID() != caster->GetCharmerOrOwnerGUID() )
|
||||||
m_target->RemoveAura(GetId(), GetEffIndex());
|
m_target->RemoveAurasByCasterSpell(GetId(), GetEffIndex(), GetCasterGUID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -885,6 +921,32 @@ void Aura::ApplyModifier(bool apply, bool Real)
|
||||||
SetInUse(false);
|
SetInUse(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Aura::IsNeedVisibleSlot(Unit const* caster) const
|
||||||
|
{
|
||||||
|
bool totemAura = caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem();
|
||||||
|
|
||||||
|
// passive auras (except totem auras) do not get placed in the slots
|
||||||
|
if (m_isPassive && !totemAura)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// generic not caster case
|
||||||
|
if (m_target != caster)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// special area auras case at caster
|
||||||
|
switch(m_spellProto->Effect[GetEffIndex()])
|
||||||
|
{
|
||||||
|
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
|
||||||
|
return false;
|
||||||
|
case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
|
||||||
|
// not sure is totemAura need, just preserve old code results
|
||||||
|
return totemAura || m_modifier.m_auraname != SPELL_AURA_NONE;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void Aura::_AddAura()
|
void Aura::_AddAura()
|
||||||
{
|
{
|
||||||
if (!GetId())
|
if (!GetId())
|
||||||
|
|
@ -942,10 +1004,7 @@ void Aura::_AddAura()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// passive auras (except totem auras) do not get placed in the slots
|
if (IsNeedVisibleSlot(caster))
|
||||||
// area auras with SPELL_AURA_NONE are not shown on target
|
|
||||||
if((!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&
|
|
||||||
(m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster))
|
|
||||||
{
|
{
|
||||||
SetAuraSlot( slot );
|
SetAuraSlot( slot );
|
||||||
if(slot < MAX_AURAS) // slot found send data to client
|
if(slot < MAX_AURAS) // slot found send data to client
|
||||||
|
|
@ -2415,7 +2474,7 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
||||||
// original caster must be target (beacon)
|
// original caster must be target (beacon)
|
||||||
m_target->CastSpell(m_target,53651,true,NULL,this,m_target->GetGUID());
|
m_target->CastSpell(m_target,53651,true,NULL,this,m_target->GetGUID());
|
||||||
else
|
else
|
||||||
m_target->RemoveAurasDueToSpell(53651);
|
m_target->RemoveAurasByCasterSpell(53651,m_target->GetGUID());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -383,6 +383,7 @@ class MANGOS_DLL_SPEC Aura
|
||||||
uint32 m_in_use; // > 0 while in Aura::ApplyModifier call/Aura::Update/etc
|
uint32 m_in_use; // > 0 while in Aura::ApplyModifier call/Aura::Update/etc
|
||||||
private:
|
private:
|
||||||
void CleanupTriggeredSpells();
|
void CleanupTriggeredSpells();
|
||||||
|
bool IsNeedVisibleSlot(Unit const* caster) const; // helper for check req. visibility slot
|
||||||
};
|
};
|
||||||
|
|
||||||
class MANGOS_DLL_SPEC AreaAura : public Aura
|
class MANGOS_DLL_SPEC AreaAura : public Aura
|
||||||
|
|
|
||||||
|
|
@ -3417,6 +3417,7 @@ bool Unit::AddAura(Aura *Aur)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// m_auraname can be modified to SPELL_AURA_NONE for area auras, this expected for this value
|
||||||
AuraType aurName = Aur->GetModifier()->m_auraname;
|
AuraType aurName = Aur->GetModifier()->m_auraname;
|
||||||
|
|
||||||
spellEffectPair spair = spellEffectPair(Aur->GetId(), Aur->GetEffIndex());
|
spellEffectPair spair = spellEffectPair(Aur->GetId(), Aur->GetEffIndex());
|
||||||
|
|
@ -3445,10 +3446,15 @@ bool Unit::AddAura(Aura *Aur)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool stop = false;
|
bool stop = false;
|
||||||
switch(aurName)
|
|
||||||
|
// m_auraname can be modified to SPELL_AURA_NONE for area auras, use original
|
||||||
|
AuraType aurNameReal = AuraType(aurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()]);
|
||||||
|
|
||||||
|
switch(aurNameReal)
|
||||||
{
|
{
|
||||||
// DoT/HoT/etc
|
// DoT/HoT/etc
|
||||||
case SPELL_AURA_PERIODIC_DAMAGE: // allow stack
|
case SPELL_AURA_DUMMY: // allow stack
|
||||||
|
case SPELL_AURA_PERIODIC_DAMAGE:
|
||||||
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
|
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
|
||||||
case SPELL_AURA_PERIODIC_LEECH:
|
case SPELL_AURA_PERIODIC_LEECH:
|
||||||
case SPELL_AURA_PERIODIC_HEAL:
|
case SPELL_AURA_PERIODIC_HEAL:
|
||||||
|
|
@ -3752,6 +3758,22 @@ void Unit::RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Unit::RemoveAurasByCasterSpell(uint32 spellId, uint32 effindex, uint64 casterGUID)
|
||||||
|
{
|
||||||
|
spellEffectPair spair = spellEffectPair(spellId, effindex);
|
||||||
|
for(AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair);)
|
||||||
|
{
|
||||||
|
Aura *aur = iter->second;
|
||||||
|
if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID)
|
||||||
|
{
|
||||||
|
RemoveAura(iter);
|
||||||
|
iter = m_Auras.lower_bound(spair);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler)
|
void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler)
|
||||||
{
|
{
|
||||||
for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); )
|
for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); )
|
||||||
|
|
@ -5110,7 +5132,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
||||||
}
|
}
|
||||||
|
|
||||||
CastSpell(this, 28682, true, castItem, triggeredByAura);
|
CastSpell(this, 28682, true, castItem, triggeredByAura);
|
||||||
return (procEx & PROC_EX_CRITICAL_HIT);// charge update only at crit hits, no hidden cooldowns
|
return (procEx & PROC_EX_CRITICAL_HIT); // charge update only at crit hits, no hidden cooldowns
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -5807,22 +5829,33 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
||||||
if (GetGUID() == triggeredByAura->GetCasterGUID())
|
if (GetGUID() == triggeredByAura->GetCasterGUID())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// beacon
|
||||||
Unit* beacon = triggeredByAura->GetCaster();
|
Unit* beacon = triggeredByAura->GetCaster();
|
||||||
if (!beacon)
|
if (!beacon)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Aura* dummy = beacon->GetDummyAura(53563);
|
// find caster main aura at beacon
|
||||||
|
Aura* dummy = NULL;
|
||||||
|
Unit::AuraList const& baa = beacon->GetAurasByType(SPELL_AURA_DUMMY);
|
||||||
|
for(Unit::AuraList::const_iterator i = baa.begin(); i != baa.end(); ++i)
|
||||||
|
{
|
||||||
|
if ((*i)->GetId() == 53563 && (*i)->GetCasterGUID() == pVictim->GetGUID())
|
||||||
|
{
|
||||||
|
dummy = (*i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// original heal must be form beacon caster
|
||||||
if (!dummy)
|
if (!dummy)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// original heal must be form beacon caster
|
triggered_spell_id = 53652; // Beacon of Light
|
||||||
if (dummy->GetCasterGUID() != pVictim->GetGUID())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
triggered_spell_id = 53652; // Beacon of Light
|
|
||||||
basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100;
|
basepoints0 = triggeredByAura->GetModifier()->m_amount*damage/100;
|
||||||
target = beacon;
|
|
||||||
break;
|
// cast with original caster set but beacon to beacon for apply caster mods and avoid LoS check
|
||||||
|
beacon->CastCustomSpell(beacon,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura,pVictim->GetGUID());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
// Seal of the Martyr do damage trigger
|
// Seal of the Martyr do damage trigger
|
||||||
case 53720:
|
case 53720:
|
||||||
|
|
|
||||||
|
|
@ -1211,6 +1211,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
void RemoveAurasDueToSpell(uint32 spellId, Aura* except = NULL);
|
void RemoveAurasDueToSpell(uint32 spellId, Aura* except = NULL);
|
||||||
void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId);
|
void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId);
|
||||||
void RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID);
|
void RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID);
|
||||||
|
void RemoveAurasByCasterSpell(uint32 spellId, uint32 effindex, uint64 casterGUID);
|
||||||
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler);
|
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler);
|
||||||
void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer);
|
void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer);
|
||||||
void RemoveAurasDueToSpellByCancel(uint32 spellId);
|
void RemoveAurasDueToSpellByCancel(uint32 spellId);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "8496"
|
#define REVISION_NR "8497"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue