mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 07:37:01 +00:00
[7049] Work vs Auras
Allow stack some auras from some caster in one Move apply/remove aura state on apply/remove aura (on 1 add / on last remove) Correctly fill aura flag and send duration update to client Not use m_procCharges for store satack amount, used m_stackAmount Fixes in HandlePeriodicDamage (use m_stackAmount, fix formulas to 303, optimisation) Fixes in Spell::EffectSchoolDMG (use m_stackAmount, fix formulas to 303) Remove unused uint32 m_PeriodicEventId from aura struct Add Unit::RemoveSingleSpellAurasFromStack for remove one Spell auras from stack Add Aura::RefreshAura() for refresh aura duration Signed-off-by: DiSlord <dislord@nomail.com>
This commit is contained in:
parent
32a7c35a95
commit
c2741b50e7
6 changed files with 352 additions and 346 deletions
|
|
@ -337,14 +337,16 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=
|
||||||
};
|
};
|
||||||
|
|
||||||
Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) :
|
Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) :
|
||||||
m_procCharges(0), m_spellmod(NULL), m_effIndex(eff), m_caster_guid(0), m_target(target),
|
m_spellmod(NULL), m_caster_guid(0), m_castItemGuid(castItem?castItem->GetGUID():0), m_target(target),
|
||||||
m_timeCla(1000), m_castItemGuid(castItem?castItem->GetGUID():0), m_auraSlot(MAX_AURAS),
|
m_timeCla(1000), m_periodicTimer(0), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_AuraDRGroup(DIMINISHING_NONE),
|
||||||
m_positive(false), m_permanent(false), m_isPeriodic(false), m_isTrigger(false), m_isAreaAura(false),
|
m_effIndex(eff), m_auraSlot(MAX_AURAS), m_auraFlags(AFLAG_NONE), m_auraLevel(1), m_procCharges(0), m_stackAmount(1),
|
||||||
m_isPersistent(false), m_updated(false), m_removeMode(AURA_REMOVE_BY_DEFAULT), m_isRemovedOnShapeLost(true), m_in_use(false),
|
m_positive(false), m_permanent(false), m_isPeriodic(false), m_isTrigger(false), m_isAreaAura(false), m_isPersistent(false),
|
||||||
m_periodicTimer(0), m_PeriodicEventId(0), m_AuraDRGroup(DIMINISHING_NONE)
|
m_updated(false), m_isRemovedOnShapeLost(true), m_in_use(false)
|
||||||
{
|
{
|
||||||
assert(target);
|
assert(target);
|
||||||
|
|
||||||
|
int32 size = sizeof(Aura);
|
||||||
|
|
||||||
assert(spellproto && spellproto == sSpellStore.LookupEntry( spellproto->Id ) && "`info` must be pointer to sSpellStore element");
|
assert(spellproto && spellproto == sSpellStore.LookupEntry( spellproto->Id ) && "`info` must be pointer to sSpellStore element");
|
||||||
|
|
||||||
m_spellProto = spellproto;
|
m_spellProto = spellproto;
|
||||||
|
|
@ -889,12 +891,12 @@ void Aura::_AddAura()
|
||||||
if(!m_target)
|
if(!m_target)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// we can found aura in NULL_AURA_SLOT and then need store state instead check slot != NULL_AURA_SLOT
|
// Second aura if some spell
|
||||||
bool samespell = false;
|
|
||||||
bool secondaura = false;
|
bool secondaura = false;
|
||||||
|
// Try find slot for aura
|
||||||
uint8 slot = NULL_AURA_SLOT;
|
uint8 slot = NULL_AURA_SLOT;
|
||||||
|
// Lookup for some spell auras (and get slot from it)
|
||||||
for(uint8 i = 0; i < 3; i++)
|
for(uint8 i = 0; i < m_effIndex; i++)
|
||||||
{
|
{
|
||||||
Unit::spellEffectPair spair = Unit::spellEffectPair(GetId(), i);
|
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)
|
for(Unit::AuraMap::const_iterator itr = m_target->GetAuras().lower_bound(spair); itr != m_target->GetAuras().upper_bound(spair); ++itr)
|
||||||
|
|
@ -902,18 +904,30 @@ void Aura::_AddAura()
|
||||||
// allow use single slot only by auras from same caster
|
// allow use single slot only by auras from same caster
|
||||||
if(itr->second->GetCasterGUID()==GetCasterGUID())
|
if(itr->second->GetCasterGUID()==GetCasterGUID())
|
||||||
{
|
{
|
||||||
samespell = true;
|
|
||||||
if (m_effIndex > itr->second->GetEffIndex())
|
|
||||||
secondaura = true;
|
|
||||||
slot = itr->second->GetAuraSlot();
|
slot = itr->second->GetAuraSlot();
|
||||||
|
secondaura = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (secondaura)
|
||||||
if(samespell)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Lookup free slot
|
||||||
|
if (!secondaura && m_target->GetVisibleAurasCount() < MAX_AURAS)
|
||||||
|
{
|
||||||
|
Unit::VisibleAuraMap const *visibleAuras = m_target->GetVisibleAuras();
|
||||||
|
for(uint8 i = 0; i < MAX_AURAS; ++i)
|
||||||
|
{
|
||||||
|
Unit::VisibleAuraMap::const_iterator itr = visibleAuras->find(i);
|
||||||
|
if(itr == visibleAuras->end())
|
||||||
|
{
|
||||||
|
slot = i;
|
||||||
|
// update for out of range group members (on 1 slot use)
|
||||||
|
m_target->UpdateAuraForGroup(slot);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// not call total regen auras at adding
|
// not call total regen auras at adding
|
||||||
switch (m_modifier.m_auraname)
|
switch (m_modifier.m_auraname)
|
||||||
{
|
{
|
||||||
|
|
@ -939,59 +953,44 @@ void Aura::_AddAura()
|
||||||
if((!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&
|
if((!m_isPassive || (caster && caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->isTotem())) &&
|
||||||
(m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster))
|
(m_spellProto->Effect[GetEffIndex()] != SPELL_EFFECT_APPLY_AREA_AURA_ENEMY || m_target != caster))
|
||||||
{
|
{
|
||||||
if(!samespell) // new slot need
|
SetAuraSlot( slot );
|
||||||
|
if(slot < MAX_AURAS) // slot found send data to client
|
||||||
{
|
{
|
||||||
if(m_target->GetVisibleAurasCount() < MAX_AURAS)
|
SetAura(false);
|
||||||
{
|
SetAuraFlags((1 << GetEffIndex()) | AFLAG_NOT_CASTER | ((GetAuraMaxDuration() > 0) ? AFLAG_DURATION : AFLAG_NONE) | (IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE));
|
||||||
Unit::VisibleAuraMap const *visibleAuras = m_target->GetVisibleAuras();
|
SetAuraLevel(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
|
||||||
for(uint8 i = 0; i < MAX_AURAS; ++i)
|
SendAuraUpdate(false);
|
||||||
{
|
|
||||||
Unit::VisibleAuraMap::const_iterator itr = visibleAuras->find(i);
|
|
||||||
if(itr == visibleAuras->end())
|
|
||||||
{
|
|
||||||
slot = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetAuraSlot( slot );
|
|
||||||
|
|
||||||
// Not update fields for not first spell's aura, all data already in fields
|
|
||||||
if(!secondaura)
|
|
||||||
{
|
|
||||||
if(slot < MAX_AURAS) // slot found
|
|
||||||
{
|
|
||||||
SetAura(false);
|
|
||||||
SetAuraFlags((1 << GetEffIndex()) | AFLAG_NOT_CASTER | ((GetAuraMaxDuration() > 0) ? AFLAG_DURATION : AFLAG_NONE) | (IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE));
|
|
||||||
SetAuraLevel(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));
|
|
||||||
SendAuraUpdate(false);
|
|
||||||
|
|
||||||
// update for out of range group members
|
|
||||||
m_target->UpdateAuraForGroup(slot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // use found slot
|
|
||||||
{
|
|
||||||
SetAuraSlot( slot );
|
|
||||||
// Not recalculate stack count for second aura of the same spell
|
|
||||||
if (!secondaura)
|
|
||||||
UpdateSlotCounterAndDuration(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update Seals information
|
//*****************************************************
|
||||||
if( IsSealSpell(GetSpellProto()) )
|
// Update target aura state flag (at 1 aura apply)
|
||||||
m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true);
|
// TODO: Make it easer
|
||||||
|
//*****************************************************
|
||||||
// Conflagrate aura state
|
if (!secondaura)
|
||||||
if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
|
|
||||||
m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true);
|
|
||||||
|
|
||||||
if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
|
|
||||||
&& (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
|
|
||||||
{
|
{
|
||||||
m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true);
|
// Update Seals information
|
||||||
|
if( IsSealSpell(GetSpellProto()) )
|
||||||
|
m_target->ModifyAuraState(AURA_STATE_JUDGEMENT, true);
|
||||||
|
|
||||||
|
// Conflagrate aura state on Immolate
|
||||||
|
if (m_spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellProto->SpellFamilyFlags & 4)
|
||||||
|
m_target->ModifyAuraState(AURA_STATE_IMMOLATE, true);
|
||||||
|
|
||||||
|
// Faerie Fire (druid versions)
|
||||||
|
if( m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x0000000000000400LL)
|
||||||
|
m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE, true);
|
||||||
|
|
||||||
|
// Victorious
|
||||||
|
if( m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags & 0x0004000000000000LL)
|
||||||
|
m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, true);
|
||||||
|
|
||||||
|
// Swiftmend state on Regrowth & Rejuvenation
|
||||||
|
if(m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x50 )
|
||||||
|
m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, true);
|
||||||
|
|
||||||
|
// Deadly poison aura state
|
||||||
|
if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto->SpellFamilyFlags & 0x10000)
|
||||||
|
m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1029,8 +1028,7 @@ void Aura::_RemoveAura()
|
||||||
if(m_target->GetVisibleAura(slot) == 0)
|
if(m_target->GetVisibleAura(slot) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool samespell = false;
|
bool lastaura = true;
|
||||||
bool sameaura = false;
|
|
||||||
|
|
||||||
// find other aura in same slot (current already removed from list)
|
// find other aura in same slot (current already removed from list)
|
||||||
for(uint8 i = 0; i < 3; i++)
|
for(uint8 i = 0; i < 3; i++)
|
||||||
|
|
@ -1040,30 +1038,30 @@ void Aura::_RemoveAura()
|
||||||
{
|
{
|
||||||
if(itr->second->GetAuraSlot()==slot)
|
if(itr->second->GetAuraSlot()==slot)
|
||||||
{
|
{
|
||||||
samespell = true;
|
lastaura = false;
|
||||||
|
|
||||||
if(GetEffIndex()==i)
|
|
||||||
sameaura = true;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(samespell)
|
if(!lastaura)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// only remove icon when the last aura of the spell is removed (current aura already removed from list)
|
// only remove icon when the last aura of the spell is removed (current aura already removed from list)
|
||||||
if (!samespell)
|
if (lastaura)
|
||||||
{
|
{
|
||||||
SetAura(true);
|
SetAura(true);
|
||||||
SetAuraFlags(AFLAG_NONE);
|
SetAuraFlags(AFLAG_NONE);
|
||||||
SetAuraLevel(0);
|
SetAuraLevel(0);
|
||||||
SetAuraCharges(0);
|
|
||||||
SendAuraUpdate(true);
|
SendAuraUpdate(true);
|
||||||
|
|
||||||
// update for out of range group members
|
// update for out of range group members
|
||||||
m_target->UpdateAuraForGroup(slot);
|
m_target->UpdateAuraForGroup(slot);
|
||||||
|
|
||||||
|
//*****************************************************
|
||||||
|
// Update target aura state flag (at last aura remove)
|
||||||
|
// TODO: Make it easer
|
||||||
|
//*****************************************************
|
||||||
|
// Update Seals information
|
||||||
if( IsSealSpell(GetSpellProto()) )
|
if( IsSealSpell(GetSpellProto()) )
|
||||||
m_target->ModifyAuraState(AURA_STATE_JUDGEMENT,false);
|
m_target->ModifyAuraState(AURA_STATE_JUDGEMENT,false);
|
||||||
|
|
||||||
|
|
@ -1071,16 +1069,22 @@ void Aura::_RemoveAura()
|
||||||
if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
|
if (GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (GetSpellProto()->SpellFamilyFlags & 4))
|
||||||
m_target->ModifyAuraState(AURA_STATE_IMMOLATE, false);
|
m_target->ModifyAuraState(AURA_STATE_IMMOLATE, false);
|
||||||
|
|
||||||
|
// Faerie Fire (druid versions)
|
||||||
|
if( m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID && m_spellProto->SpellFamilyFlags & 0x0000000000000400LL)
|
||||||
|
m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE, false);
|
||||||
|
|
||||||
|
// Victorious
|
||||||
|
if( m_spellProto->SpellFamilyName == SPELLFAMILY_WARRIOR && m_spellProto->SpellFamilyFlags & 0x0004000000000000LL)
|
||||||
|
m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, false);
|
||||||
|
|
||||||
// Swiftmend aura state
|
// Swiftmend aura state
|
||||||
if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
|
if(GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && GetSpellProto()->SpellFamilyFlags & 0x50)
|
||||||
&& (GetSpellProto()->SpellFamilyFlags == 0x40 || GetSpellProto()->SpellFamilyFlags == 0x10))
|
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
Unit::AuraList const& RejorRegr = m_target->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);
|
Unit::AuraList const& RejorRegr = m_target->GetAurasByType(SPELL_AURA_PERIODIC_HEAL);
|
||||||
for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
|
for(Unit::AuraList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i)
|
||||||
{
|
{
|
||||||
if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID
|
if((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_DRUID && (*i)->GetSpellProto()->SpellFamilyFlags & 0x50 )
|
||||||
&& ((*i)->GetSpellProto()->SpellFamilyFlags == 0x40 || (*i)->GetSpellProto()->SpellFamilyFlags == 0x10) )
|
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1090,6 +1094,26 @@ void Aura::_RemoveAura()
|
||||||
m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, false);
|
m_target->ModifyAuraState(AURA_STATE_SWIFTMEND, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deadly poison aura state
|
||||||
|
if(m_spellProto->SpellFamilyName == SPELLFAMILY_ROGUE && m_spellProto->SpellFamilyFlags & 0x10000)
|
||||||
|
{
|
||||||
|
// current aura already removed, search present of another
|
||||||
|
bool found = false;
|
||||||
|
Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||||
|
for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
|
||||||
|
{
|
||||||
|
SpellEntry const* itr_spell = (*itr)->GetSpellProto();
|
||||||
|
if(itr_spell && itr_spell->SpellFamilyName==SPELLFAMILY_ROGUE && itr_spell->SpellFamilyFlags & 0x10000)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// this has been last deadly poison aura
|
||||||
|
if(!found)
|
||||||
|
m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,false);
|
||||||
|
}
|
||||||
|
|
||||||
// reset cooldown state for spells
|
// reset cooldown state for spells
|
||||||
if(caster && caster->GetTypeId() == TYPEID_PLAYER)
|
if(caster && caster->GetTypeId() == TYPEID_PLAYER)
|
||||||
{
|
{
|
||||||
|
|
@ -1097,8 +1121,6 @@ void Aura::_RemoveAura()
|
||||||
((Player*)caster)->SendCooldownEvent(GetSpellProto());
|
((Player*)caster)->SendCooldownEvent(GetSpellProto());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(sameaura) // decrease count for spell, only for same aura effect, or this spell auras in remove process.
|
|
||||||
UpdateSlotCounterAndDuration(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aura::SendAuraUpdate(bool remove)
|
void Aura::SendAuraUpdate(bool remove)
|
||||||
|
|
@ -1117,7 +1139,7 @@ void Aura::SendAuraUpdate(bool remove)
|
||||||
uint8 auraFlags = GetAuraFlags();
|
uint8 auraFlags = GetAuraFlags();
|
||||||
data << uint8(auraFlags);
|
data << uint8(auraFlags);
|
||||||
data << uint8(GetAuraLevel());
|
data << uint8(GetAuraLevel());
|
||||||
data << uint8(GetAuraCharges());
|
data << uint8(m_procCharges ? m_procCharges : m_stackAmount);
|
||||||
|
|
||||||
if(!(auraFlags & AFLAG_NOT_CASTER))
|
if(!(auraFlags & AFLAG_NOT_CASTER))
|
||||||
{
|
{
|
||||||
|
|
@ -1133,35 +1155,51 @@ void Aura::SendAuraUpdate(bool remove)
|
||||||
m_target->SendMessageToSet(&data, true);
|
m_target->SendMessageToSet(&data, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aura::UpdateSlotCounterAndDuration(bool add)
|
void Aura::SetStackAmount(uint8 stackAmount)
|
||||||
{
|
{
|
||||||
uint8 slot = GetAuraSlot();
|
if (stackAmount != m_stackAmount)
|
||||||
if(slot >= MAX_AURAS)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// calculate amount of similar auras by same effect index (similar different spells)
|
|
||||||
int8 count = 0;
|
|
||||||
|
|
||||||
// calculate auras and update durations in case aura adding
|
|
||||||
Unit::AuraList const& aura_list = m_target->GetAurasByType(GetModifier()->m_auraname);
|
|
||||||
for(Unit::AuraList::const_iterator i = aura_list.begin();i != aura_list.end(); ++i)
|
|
||||||
{
|
{
|
||||||
if( (*i)->GetId()==GetId() && (*i)->GetEffIndex()==m_effIndex &&
|
Unit *target = GetTarget();
|
||||||
(*i)->GetCasterGUID()==GetCasterGUID() )
|
Unit *caster = GetCaster();
|
||||||
|
if (!target || !caster)
|
||||||
|
return;
|
||||||
|
m_stackAmount = stackAmount;
|
||||||
|
int32 amount = m_stackAmount * caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, target);
|
||||||
|
// Reapply if amount change
|
||||||
|
if (amount!=m_modifier.m_amount)
|
||||||
{
|
{
|
||||||
++count;
|
ApplyModifier(false, true);
|
||||||
|
m_modifier.m_amount = amount;
|
||||||
if(add)
|
ApplyModifier(true, true);
|
||||||
(*i)->SetAuraDuration(GetAuraDuration());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
RefreshAura();
|
||||||
|
}
|
||||||
|
|
||||||
// at aura add aura not added yet, at aura remove aura already removed
|
bool Aura::modStackAmount(int32 num)
|
||||||
// in field stored (count-1)
|
{
|
||||||
if(!add)
|
// Can`t mod
|
||||||
--count;
|
if (!m_spellProto->StackAmount)
|
||||||
|
return true;
|
||||||
|
|
||||||
SetAuraCharges(count);
|
// Modify stack but limit it
|
||||||
|
int32 stackAmount = m_stackAmount + num;
|
||||||
|
if (stackAmount > m_spellProto->StackAmount)
|
||||||
|
stackAmount = m_spellProto->StackAmount;
|
||||||
|
else if (stackAmount <=0) // Last aura from stack removed
|
||||||
|
{
|
||||||
|
m_stackAmount = 0;
|
||||||
|
return true; // need remove aura
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update stack amount
|
||||||
|
SetStackAmount(stackAmount);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Aura::RefreshAura()
|
||||||
|
{
|
||||||
|
m_duration = m_maxduration;
|
||||||
SendAuraUpdate(false);
|
SendAuraUpdate(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2148,12 +2186,6 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
||||||
m_target->RemoveAurasDueToSpell(spellId);
|
m_target->RemoveAurasDueToSpell(spellId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Victorious
|
|
||||||
if(GetId()==32216 && m_target->getClass()==CLASS_WARRIOR)
|
|
||||||
{
|
|
||||||
m_target->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, apply);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
//Summon Fire Elemental
|
//Summon Fire Elemental
|
||||||
if (GetId() == 40133 && caster)
|
if (GetId() == 40133 && caster)
|
||||||
{
|
{
|
||||||
|
|
@ -2213,8 +2245,11 @@ void Aura::HandleAuraDummy(bool apply, bool Real)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// final heal
|
// final heal
|
||||||
if(m_target->IsInWorld())
|
if(m_target->IsInWorld() && m_stackAmount > 0)
|
||||||
m_target->CastCustomSpell(m_target,33778,&m_modifier.m_amount,NULL,NULL,true,NULL,this,GetCasterGUID());
|
{
|
||||||
|
int32 amount = m_modifier.m_amount / m_stackAmount;
|
||||||
|
m_target->CastCustomSpell(m_target,33778,&amount,NULL,NULL,true,NULL,this,GetCasterGUID());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -3593,15 +3628,11 @@ void Aura::HandleAuraModSilence(bool apply, bool Real)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Search Mana Tap auras on caster
|
// Search Mana Tap auras on caster
|
||||||
int32 energy = 0;
|
Aura * dummy = caster->GetDummyAura(28734);
|
||||||
Unit::AuraList const& m_dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
|
if (dummy)
|
||||||
for(Unit::AuraList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i)
|
|
||||||
if ((*i)->GetId() == 28734)
|
|
||||||
++energy;
|
|
||||||
if (energy)
|
|
||||||
{
|
{
|
||||||
energy *= 10;
|
int32 bp = dummy->GetStackAmount() * 10;
|
||||||
caster->CastCustomSpell(caster, 25048, &energy, NULL, NULL, true);
|
caster->CastCustomSpell(caster, 25048, &bp, NULL, NULL, true);
|
||||||
caster->RemoveAurasDueToSpell(28734);
|
caster->RemoveAurasDueToSpell(28734);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4089,6 +4120,10 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
|
||||||
|
|
||||||
Unit *caster = GetCaster();
|
Unit *caster = GetCaster();
|
||||||
|
|
||||||
|
// Custom damage calculation after
|
||||||
|
if (!apply || loading || !caster)
|
||||||
|
return;
|
||||||
|
|
||||||
switch (m_spellProto->SpellFamilyName)
|
switch (m_spellProto->SpellFamilyName)
|
||||||
{
|
{
|
||||||
case SPELLFAMILY_GENERIC:
|
case SPELLFAMILY_GENERIC:
|
||||||
|
|
@ -4097,8 +4132,7 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
|
||||||
if ( m_spellProto->SpellIconID == 147 && m_spellProto->SpellVisual[0] == 0 )
|
if ( m_spellProto->SpellIconID == 147 && m_spellProto->SpellVisual[0] == 0 )
|
||||||
{
|
{
|
||||||
// $AP*0.18/6 bonus per tick
|
// $AP*0.18/6 bonus per tick
|
||||||
if (apply && !loading && caster)
|
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
|
||||||
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -4108,16 +4142,12 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
|
||||||
// Rend
|
// Rend
|
||||||
if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
|
if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
|
||||||
{
|
{
|
||||||
// 0.00743*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
|
// $0.2*(($MWB+$mwb)/2+$AP/14*$MWS) bonus per tick
|
||||||
if (apply && !loading && caster)
|
float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||||
{
|
int32 mws = caster->GetAttackTime(BASE_ATTACK);
|
||||||
float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE);
|
||||||
int32 mws = caster->GetAttackTime(BASE_ATTACK);
|
float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE);
|
||||||
float mwb_min = caster->GetWeaponDamageRange(BASE_ATTACK,MINDAMAGE);
|
m_modifier.m_amount+=int32(((mwb_min+mwb_max)/2+ap*mws/14000)*0.2f);
|
||||||
float mwb_max = caster->GetWeaponDamageRange(BASE_ATTACK,MAXDAMAGE);
|
|
||||||
// WARNING! in 3.0 multiplier 0.00743f change to 0.6
|
|
||||||
m_modifier.m_amount+=int32(((mwb_min+mwb_max)/2+ap*mws/14000)*0.00743f);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -4127,90 +4157,77 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
|
||||||
// Rake
|
// Rake
|
||||||
if (m_spellProto->SpellFamilyFlags & 0x0000000000001000LL)
|
if (m_spellProto->SpellFamilyFlags & 0x0000000000001000LL)
|
||||||
{
|
{
|
||||||
// $AP*0.06/3 bonus per tick
|
// $AP*0.06 bonus per tick
|
||||||
if (apply && !loading && caster)
|
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 6 / 100);
|
||||||
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 2 / 100);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Lacerate
|
// Lacerate
|
||||||
if (m_spellProto->SpellFamilyFlags & 0x000000010000000000LL)
|
if (m_spellProto->SpellFamilyFlags & 0x000000010000000000LL)
|
||||||
{
|
{
|
||||||
// $AP*0.05/5 bonus per tick
|
// $AP*0.05/5 bonus per tick
|
||||||
if (apply && !loading && caster)
|
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
|
||||||
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Rip
|
// Rip
|
||||||
if (m_spellProto->SpellFamilyFlags & 0x000000000000800000LL)
|
if (m_spellProto->SpellFamilyFlags & 0x000000000000800000LL)
|
||||||
{
|
{
|
||||||
// $AP * min(0.06*$cp, 0.24)/6 [Yes, there is no difference, whether 4 or 5 CPs are being used]
|
// 0.01*$AP*cp
|
||||||
if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
|
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
|
||||||
|
Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
|
||||||
|
for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
|
||||||
{
|
{
|
||||||
uint8 cp = ((Player*)caster)->GetComboPoints();
|
if((*itr)->GetId()==34241)
|
||||||
|
|
||||||
// Idol of Feral Shadows. Cant be handled as SpellMod in SpellAura:Dummy due its dependency from CPs
|
|
||||||
Unit::AuraList const& dummyAuras = caster->GetAurasByType(SPELL_AURA_DUMMY);
|
|
||||||
for(Unit::AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)
|
|
||||||
{
|
{
|
||||||
if((*itr)->GetId()==34241)
|
m_modifier.m_amount += cp * (*itr)->GetModifier()->m_amount;
|
||||||
{
|
break;
|
||||||
m_modifier.m_amount += cp * (*itr)->GetModifier()->m_amount;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cp > 4) cp = 4;
|
|
||||||
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
|
|
||||||
}
|
}
|
||||||
|
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Lock Jaw
|
||||||
|
if (m_spellProto->SpellFamilyFlags & 0x1000000000000000LL)
|
||||||
|
{
|
||||||
|
// 0.15*$AP
|
||||||
|
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 15 / 100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SPELLFAMILY_ROGUE:
|
case SPELLFAMILY_ROGUE:
|
||||||
{
|
{
|
||||||
// Deadly poison aura state
|
|
||||||
if((m_spellProto->SpellFamilyFlags & 0x10000) && m_spellProto->SpellVisual[0]==5100)
|
|
||||||
{
|
|
||||||
if(apply)
|
|
||||||
m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,true);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// current aura already removed, search present of another
|
|
||||||
bool found = false;
|
|
||||||
Unit::AuraList const& auras = m_target->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
|
||||||
for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)
|
|
||||||
{
|
|
||||||
SpellEntry const* itr_spell = (*itr)->GetSpellProto();
|
|
||||||
if(itr_spell && itr_spell->SpellFamilyName==SPELLFAMILY_ROGUE && (itr_spell->SpellFamilyFlags & 0x10000) && itr_spell->SpellVisual[0]==5100)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// this has been last deadly poison aura
|
|
||||||
if(!found)
|
|
||||||
m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,false);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Rupture
|
// Rupture
|
||||||
if (m_spellProto->SpellFamilyFlags & 0x000000000000100000LL)
|
if (m_spellProto->SpellFamilyFlags & 0x000000000000100000LL)
|
||||||
{
|
{
|
||||||
// Dmg/tick = $AP*min(0.01*$cp, 0.03) [Like Rip: only the first three CP increase the contribution from AP]
|
if (caster->GetTypeId() != TYPEID_PLAYER)
|
||||||
if (apply && !loading && caster && caster->GetTypeId() == TYPEID_PLAYER)
|
return;
|
||||||
{
|
//1 point : ${($m1+$b1*1+0.015*$AP)*4} damage over 8 secs
|
||||||
uint8 cp = ((Player*)caster)->GetComboPoints();
|
//2 points: ${($m1+$b1*2+0.024*$AP)*5} damage over 10 secs
|
||||||
if (cp > 3) cp = 3;
|
//3 points: ${($m1+$b1*3+0.03*$AP)*6} damage over 12 secs
|
||||||
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * cp / 100);
|
//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[] = {0, 0.015f, 0.024, 0.03, 0.03428571, 0.0375};
|
||||||
|
uint8 cp = ((Player*)caster)->GetComboPoints();
|
||||||
|
if (cp > 5) cp = 5;
|
||||||
|
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * AP_per_combo[cp]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Garrote
|
// Garrote
|
||||||
if (m_spellProto->SpellFamilyFlags & 0x000000000000000100LL)
|
if (m_spellProto->SpellFamilyFlags & 0x000000000000000100LL)
|
||||||
{
|
{
|
||||||
// $AP*0.18/6 bonus per tick
|
// $AP*0.07 bonus per tick
|
||||||
if (apply && !loading && caster)
|
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 7 / 100);
|
||||||
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 3 / 100);
|
return;
|
||||||
|
}
|
||||||
|
if (m_spellProto->SpellFamilyFlags & 0x0000000000010000)
|
||||||
|
{
|
||||||
|
// 0.08*$AP / 4 * amount of stack
|
||||||
|
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(BASE_ATTACK) * 2 * GetStackAmount() * / 100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -4221,16 +4238,14 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
|
||||||
if (m_spellProto->SpellFamilyFlags & 0x0000000000004000LL)
|
if (m_spellProto->SpellFamilyFlags & 0x0000000000004000LL)
|
||||||
{
|
{
|
||||||
// $RAP*0.1/5 bonus per tick
|
// $RAP*0.1/5 bonus per tick
|
||||||
if (apply && !loading && caster)
|
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
|
||||||
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Immolation Trap
|
// Immolation Trap
|
||||||
if (m_spellProto->SpellFamilyFlags & 0x0000000000000004LL && m_spellProto->SpellIconID == 678)
|
if (m_spellProto->SpellFamilyFlags & 0x0000000000000004LL && m_spellProto->SpellIconID == 678)
|
||||||
{
|
{
|
||||||
// $RAP*0.1/5 bonus per tick
|
// $RAP*0.1/5 bonus per tick
|
||||||
if (apply && !loading && caster)
|
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
|
||||||
m_modifier.m_amount += int32(caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 10 / 500);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -4240,34 +4255,35 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)
|
||||||
// Consecration
|
// Consecration
|
||||||
if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
|
if (m_spellProto->SpellFamilyFlags & 0x0000000000000020LL)
|
||||||
{
|
{
|
||||||
if (apply && !loading && caster)
|
// ($m1+0.04*$SPH+0.04*$AP)
|
||||||
|
float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||||
|
int32 holy = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) +
|
||||||
|
caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellProto), m_target);
|
||||||
|
m_modifier.m_amount += int32(0.04f*holy + 0.04f*ap);
|
||||||
|
|
||||||
|
// Improved Consecration - Libram of the Eternal Rest
|
||||||
|
Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
|
||||||
|
for(Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
|
||||||
{
|
{
|
||||||
Unit::AuraList const& classScripts = caster->GetAurasByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS);
|
switch((*k)->GetModifier()->m_miscvalue)
|
||||||
for(Unit::AuraList::const_iterator k = classScripts.begin(); k != classScripts.end(); ++k)
|
|
||||||
{
|
{
|
||||||
int32 tickcount = GetSpellDuration(m_spellProto) / m_spellProto->EffectAmplitude[m_effIndex];
|
case 5147:
|
||||||
switch((*k)->GetModifier()->m_miscvalue)
|
|
||||||
{
|
{
|
||||||
case 5147: // Improved Consecration - Libram of the Eternal Rest
|
int32 tickcount = GetSpellDuration(m_spellProto) / m_spellProto->EffectAmplitude[m_effIndex];
|
||||||
{
|
m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
|
||||||
m_modifier.m_amount += (*k)->GetModifier()->m_amount / tickcount;
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Seal of Vengeance 0.013*$SPH+0.025*$AP per tick
|
// Seal of Vengeance 0.013*$SPH+0.025*$AP per tick (also can stack)
|
||||||
if(m_spellProto->SpellFamilyFlags & 0x0000080000000000LL)
|
if(m_spellProto->SpellFamilyFlags & 0x0000080000000000LL)
|
||||||
{
|
{
|
||||||
if (apply && !loading && caster)
|
float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||||
{
|
int32 holy = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) +
|
||||||
float ap = caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellProto), m_target);
|
||||||
int32 holy = caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) +
|
m_modifier.m_amount += int32((0.013f*holy + 0.025f*ap) * GetStackAmount());
|
||||||
caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellProto), m_target);
|
|
||||||
m_modifier.m_amount += int32(ap * 0.025f) + int32(holy * 13 / 1000);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -4333,14 +4349,6 @@ void Aura::HandleAuraModResistance(bool apply, bool Real)
|
||||||
m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,m_modifier.m_amount, apply);
|
m_target->ApplyResistanceBuffModsMod(SpellSchools(x),m_positive,m_modifier.m_amount, apply);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Faerie Fire (druid versions)
|
|
||||||
if( m_spellProto->SpellIconID == 109 &&
|
|
||||||
m_spellProto->SpellFamilyName == SPELLFAMILY_DRUID &&
|
|
||||||
m_spellProto->SpellFamilyFlags & 0x0000000000000400LL )
|
|
||||||
{
|
|
||||||
m_target->ModifyAuraState(AURA_STATE_FAERIE_FIRE,apply);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aura::HandleAuraModBaseResistancePCT(bool apply, bool Real)
|
void Aura::HandleAuraModBaseResistancePCT(bool apply, bool Real)
|
||||||
|
|
|
||||||
|
|
@ -275,6 +275,11 @@ class MANGOS_DLL_SPEC Aura
|
||||||
void SetAura(bool remove) { m_target->SetVisibleAura(m_auraSlot, remove ? 0 : GetId()); }
|
void SetAura(bool remove) { m_target->SetVisibleAura(m_auraSlot, remove ? 0 : GetId()); }
|
||||||
void SendAuraUpdate(bool remove);
|
void SendAuraUpdate(bool remove);
|
||||||
|
|
||||||
|
int8 GetStackAmount() {return m_stackAmount;}
|
||||||
|
void SetStackAmount(uint8 num);
|
||||||
|
bool modStackAmount(int32 num); // return true if last charge dropped
|
||||||
|
void RefreshAura();
|
||||||
|
|
||||||
bool IsPositive() { return m_positive; }
|
bool IsPositive() { return m_positive; }
|
||||||
void SetNegative() { m_positive = false; }
|
void SetNegative() { m_positive = false; }
|
||||||
void SetPositive() { m_positive = true; }
|
void SetPositive() { m_positive = true; }
|
||||||
|
|
@ -320,23 +325,28 @@ class MANGOS_DLL_SPEC Aura
|
||||||
|
|
||||||
Modifier m_modifier;
|
Modifier m_modifier;
|
||||||
SpellModifier *m_spellmod;
|
SpellModifier *m_spellmod;
|
||||||
uint32 m_effIndex;
|
|
||||||
SpellEntry const *m_spellProto;
|
SpellEntry const *m_spellProto;
|
||||||
int32 m_currentBasePoints; // cache SpellEntry::EffectBasePoints and use for set custom base points
|
|
||||||
uint64 m_caster_guid;
|
|
||||||
Unit* m_target;
|
Unit* m_target;
|
||||||
int32 m_maxduration;
|
uint64 m_caster_guid;
|
||||||
int32 m_duration;
|
|
||||||
int32 m_timeCla;
|
|
||||||
uint64 m_castItemGuid; // it is NOT safe to keep a pointer to the item because it may get deleted
|
uint64 m_castItemGuid; // it is NOT safe to keep a pointer to the item because it may get deleted
|
||||||
time_t m_applyTime;
|
time_t m_applyTime;
|
||||||
|
|
||||||
AuraRemoveMode m_removeMode;
|
int32 m_currentBasePoints; // cache SpellEntry::EffectBasePoints and use for set custom base points
|
||||||
|
int32 m_maxduration; // Max aura duration
|
||||||
|
int32 m_duration; // Current time
|
||||||
|
int32 m_timeCla; // Timer for power per sec calcultion
|
||||||
|
int32 m_periodicTimer; // Timer for periodic auras
|
||||||
|
|
||||||
uint8 m_auraSlot;
|
AuraRemoveMode m_removeMode:8; // Store info for know remove aura reason
|
||||||
uint8 m_auraFlags;
|
DiminishingGroup m_AuraDRGroup:8; // Diminishing
|
||||||
uint8 m_auraLevel;
|
|
||||||
int8 m_procCharges;
|
uint8 m_effIndex; // Aura effect index in spell
|
||||||
|
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 m_procCharges; // Aura charges (0 for infinite)
|
||||||
|
uint8 m_stackAmount; // Aura stack amount
|
||||||
|
|
||||||
bool m_positive:1;
|
bool m_positive:1;
|
||||||
bool m_permanent:1;
|
bool m_permanent:1;
|
||||||
|
|
@ -347,14 +357,10 @@ class MANGOS_DLL_SPEC Aura
|
||||||
bool m_isPersistent:1;
|
bool m_isPersistent:1;
|
||||||
bool m_isDeathPersist:1;
|
bool m_isDeathPersist:1;
|
||||||
bool m_isRemovedOnShapeLost:1;
|
bool m_isRemovedOnShapeLost:1;
|
||||||
bool m_updated:1;
|
bool m_updated:1; // Prevent remove aura by stack if set
|
||||||
bool m_in_use:1; // true while in Aura::ApplyModifier call
|
bool m_in_use:1; // true while in Aura::ApplyModifier call
|
||||||
|
|
||||||
int32 m_periodicTimer;
|
|
||||||
uint32 m_PeriodicEventId;
|
|
||||||
DiminishingGroup m_AuraDRGroup;
|
|
||||||
private:
|
private:
|
||||||
void UpdateSlotCounterAndDuration(bool add);
|
|
||||||
void CleanupTriggeredSpells();
|
void CleanupTriggeredSpells();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -480,31 +480,29 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
||||||
// consume from stack dozes not more that have combo-points
|
// consume from stack dozes not more that have combo-points
|
||||||
if(uint32 combo = ((Player*)m_caster)->GetComboPoints())
|
if(uint32 combo = ((Player*)m_caster)->GetComboPoints())
|
||||||
{
|
{
|
||||||
// count consumed deadly poison doses at target
|
Aura *poison = 0;
|
||||||
uint32 doses = 0;
|
// Lookup for Deadly poison (only attacker applied)
|
||||||
|
|
||||||
// remove consumed poison doses
|
|
||||||
Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||||
for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end() && combo;)
|
for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end() && combo;)
|
||||||
{
|
if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE &&
|
||||||
// Deadly poison (only attacker applied)
|
(*itr)->GetSpellProto()->SpellFamilyFlags & 0x10000 &&
|
||||||
if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && ((*itr)->GetSpellProto()->SpellFamilyFlags & 0x10000) &&
|
(*itr)->GetCasterGUID()==m_caster->GetGUID() )
|
||||||
(*itr)->GetSpellProto()->SpellVisual[0]==5100 && (*itr)->GetCasterGUID()==m_caster->GetGUID() )
|
|
||||||
{
|
{
|
||||||
--combo;
|
poison = *itr;
|
||||||
++doses;
|
break;
|
||||||
|
|
||||||
unitTarget->RemoveSingleAuraFromStack((*itr)->GetId(), (*itr)->GetEffIndex());
|
|
||||||
|
|
||||||
itr = auras.begin();
|
|
||||||
}
|
}
|
||||||
else
|
// count consumed deadly poison doses at target
|
||||||
++itr;
|
if (poison)
|
||||||
|
{
|
||||||
|
uint32 spellId = poison->GetId();
|
||||||
|
uint32 doses = poison->GetStackAmount();
|
||||||
|
if (doses > combo)
|
||||||
|
doses = combo;
|
||||||
|
for (int i=0; i< doses; i++)
|
||||||
|
unitTarget->RemoveSingleSpellAurasFromStack(spellId);
|
||||||
|
damage *= doses;
|
||||||
|
damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.03f * doses);
|
||||||
}
|
}
|
||||||
|
|
||||||
damage *= doses;
|
|
||||||
damage += int32(((Player*)m_caster)->GetTotalAttackPowerValue(BASE_ATTACK) * 0.03f * doses);
|
|
||||||
|
|
||||||
// Eviscerate and Envenom Bonus Damage (item set effect)
|
// Eviscerate and Envenom Bonus Damage (item set effect)
|
||||||
if(m_caster->GetDummyAura(37169))
|
if(m_caster->GetDummyAura(37169))
|
||||||
damage += ((Player*)m_caster)->GetComboPoints()*40;
|
damage += ((Player*)m_caster)->GetComboPoints()*40;
|
||||||
|
|
@ -572,19 +570,25 @@ void Spell::EffectSchoolDMG(uint32 effect_idx)
|
||||||
}
|
}
|
||||||
case SPELLFAMILY_PALADIN:
|
case SPELLFAMILY_PALADIN:
|
||||||
{
|
{
|
||||||
// Judgement of Vengeance
|
// Judgement of Vengeance ${1+0.22*$SPH+0.14*$AP} + 10% for each application of Holy Vengeance on the target
|
||||||
if((m_spellInfo->SpellFamilyFlags & 0x800000000LL) && m_spellInfo->SpellIconID==2292)
|
if((m_spellInfo->SpellFamilyFlags & 0x800000000LL) && m_spellInfo->SpellIconID==2292)
|
||||||
{
|
{
|
||||||
|
float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK);
|
||||||
|
int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) +
|
||||||
|
m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget);
|
||||||
|
damage+=int32(ap * 0.14f) + int32(holy * 22 / 100);
|
||||||
|
// Get stack of Holy Vengeance on the target added by caster
|
||||||
uint32 stacks = 0;
|
uint32 stacks = 0;
|
||||||
Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
Unit::AuraList const& auras = unitTarget->GetAurasByType(SPELL_AURA_PERIODIC_DAMAGE);
|
||||||
for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
|
for(Unit::AuraList::const_iterator itr = auras.begin(); itr!=auras.end(); ++itr)
|
||||||
if((*itr)->GetId() == 31803 && (*itr)->GetCasterGUID()==m_caster->GetGUID())
|
if((*itr)->GetId() == 31803 && (*itr)->GetCasterGUID()==m_caster->GetGUID())
|
||||||
++stacks;
|
{
|
||||||
if(!stacks)
|
stacks = (*itr)->GetStackAmount();
|
||||||
//No damage if the target isn't affected by this
|
break;
|
||||||
damage = -1;
|
}
|
||||||
else
|
// + 10% for each application of Holy Vengeance on the target
|
||||||
damage *= stacks;
|
if(stacks)
|
||||||
|
damage += damage * stacks * 10 /100;
|
||||||
}
|
}
|
||||||
// Avenger's Shield ($m1+0.07*$SPH+0.07*$AP)
|
// Avenger's Shield ($m1+0.07*$SPH+0.07*$AP)
|
||||||
else if(m_spellInfo->SpellFamilyFlags & 0x0000000000004000LL)
|
else if(m_spellInfo->SpellFamilyFlags & 0x0000000000004000LL)
|
||||||
|
|
@ -943,16 +947,12 @@ void Spell::EffectDummy(uint32 i)
|
||||||
}
|
}
|
||||||
case 28730: // Arcane Torrent (Mana)
|
case 28730: // Arcane Torrent (Mana)
|
||||||
{
|
{
|
||||||
int32 count = 0;
|
Aura * dummy = m_caster->GetDummyAura(28734);
|
||||||
Unit::AuraList const& m_dummyAuras = m_caster->GetAurasByType(SPELL_AURA_DUMMY);
|
if (dummy)
|
||||||
for(Unit::AuraList::const_iterator i = m_dummyAuras.begin(); i != m_dummyAuras.end(); ++i)
|
{
|
||||||
if ((*i)->GetId() == 28734)
|
int32 bp = damage * dummy->GetStackAmount();
|
||||||
++count;
|
|
||||||
if (count)
|
|
||||||
{
|
|
||||||
m_caster->RemoveAurasDueToSpell(28734);
|
|
||||||
int32 bp = damage * count;
|
|
||||||
m_caster->CastCustomSpell(m_caster, 28733, &bp, NULL, NULL, true);
|
m_caster->CastCustomSpell(m_caster, 28733, &bp, NULL, NULL, true);
|
||||||
|
m_caster->RemoveAurasDueToSpell(28734);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -4217,21 +4217,22 @@ void Spell::EffectWeaponDmg(uint32 i)
|
||||||
// Devastate bonus and sunder armor refresh
|
// Devastate bonus and sunder armor refresh
|
||||||
else if(m_spellInfo->SpellVisual[0] == 671 && m_spellInfo->SpellIconID == 1508)
|
else if(m_spellInfo->SpellVisual[0] == 671 && m_spellInfo->SpellIconID == 1508)
|
||||||
{
|
{
|
||||||
customBonusDamagePercentMod = true;
|
uint32 stack = 0;
|
||||||
bonusDamagePercentMod = 0.0f; // only applied if auras found
|
// Need refresh all Sunder Armor auras from this caster
|
||||||
|
Unit::AuraMap& suAuras = unitTarget->GetAuras();
|
||||||
Unit::AuraList const& list = unitTarget->GetAurasByType(SPELL_AURA_MOD_RESISTANCE);
|
for(Unit::AuraMap::iterator itr = suAuras.begin(); itr != suAuras.end(); ++itr)
|
||||||
for(Unit::AuraList::const_iterator itr=list.begin();itr!=list.end();++itr)
|
|
||||||
{
|
{
|
||||||
SpellEntry const *proto = (*itr)->GetSpellProto();
|
SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
|
||||||
if(proto->SpellVisual[0] == 406 && proto->SpellIconID == 565)
|
if( spellInfo->SpellFamilyName == SPELLFAMILY_WARRIOR &&
|
||||||
|
spellInfo->SpellFamilyFlags & 0x0000000000004000LL &&
|
||||||
|
(*itr).second->GetCasterGUID() == m_caster->GetGUID())
|
||||||
{
|
{
|
||||||
int32 duration = GetSpellDuration(proto);
|
(*itr).second->RefreshAura();
|
||||||
(*itr)->SetAuraDuration(duration);
|
stack = (*itr).second->GetStackAmount();
|
||||||
(*itr)->SendAuraUpdate(false);
|
|
||||||
bonusDamagePercentMod += 1.0f; // +100%
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (stack)
|
||||||
|
spell_bonus += stack * CalculateDamage(2, unitTarget);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -4644,12 +4645,11 @@ void Spell::EffectScriptEffect(uint32 effIndex)
|
||||||
}
|
}
|
||||||
// Brittle Armor - need remove one 24575 Brittle Armor aura
|
// Brittle Armor - need remove one 24575 Brittle Armor aura
|
||||||
case 24590:
|
case 24590:
|
||||||
unitTarget->RemoveSingleAuraFromStack(24575, 0);
|
unitTarget->RemoveSingleSpellAurasFromStack(24575);
|
||||||
unitTarget->RemoveSingleAuraFromStack(24575, 1);
|
|
||||||
return;
|
return;
|
||||||
// Mercurial Shield - need remove one 26464 Mercurial Shield aura
|
// Mercurial Shield - need remove one 26464 Mercurial Shield aura
|
||||||
case 26465:
|
case 26465:
|
||||||
unitTarget->RemoveSingleAuraFromStack(26464, 0);
|
unitTarget->RemoveSingleSpellAurasFromStack(26464);
|
||||||
return;
|
return;
|
||||||
// Orb teleport spells
|
// Orb teleport spells
|
||||||
case 25140:
|
case 25140:
|
||||||
|
|
@ -4900,8 +4900,7 @@ void Spell::EffectScriptEffect(uint32 effIndex)
|
||||||
if (!(familyFlag & 0x000000800000C000LL))
|
if (!(familyFlag & 0x000000800000C000LL))
|
||||||
continue;
|
continue;
|
||||||
// Refresh aura duration
|
// Refresh aura duration
|
||||||
aura->SetAuraDuration(aura->GetAuraMaxDuration());
|
aura->RefreshAura();
|
||||||
aura->SendAuraUpdate(false);
|
|
||||||
|
|
||||||
// Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting.
|
// Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting.
|
||||||
if (familyFlag & 0x0000000000004000LL && aura->GetEffIndex() == 0)
|
if (familyFlag & 0x0000000000004000LL && aura->GetEffIndex() == 0)
|
||||||
|
|
|
||||||
|
|
@ -1131,10 +1131,7 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss)
|
||||||
{
|
{
|
||||||
SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
|
SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
|
||||||
if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID()))
|
if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID()))
|
||||||
{
|
(*itr).second->RefreshAura();
|
||||||
(*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration());
|
|
||||||
(*itr).second->SendAuraUpdate(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Call default DealDamage
|
// Call default DealDamage
|
||||||
|
|
@ -1490,10 +1487,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)
|
||||||
{
|
{
|
||||||
SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
|
SpellEntry const *spellInfo = (*itr).second->GetSpellProto();
|
||||||
if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID()))
|
if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID()))
|
||||||
{
|
(*itr).second->RefreshAura();
|
||||||
(*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration());
|
|
||||||
(*itr).second->SendAuraUpdate(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3195,48 +3189,45 @@ bool Unit::AddAura(Aura *Aur)
|
||||||
// passive and persistent auras can stack with themselves any number of times
|
// passive and persistent auras can stack with themselves any number of times
|
||||||
if (!Aur->IsPassive() && !Aur->IsPersistent())
|
if (!Aur->IsPassive() && !Aur->IsPersistent())
|
||||||
{
|
{
|
||||||
// replace aura if next will > spell StackAmount
|
for(AuraMap::iterator i2 = m_Auras.lower_bound(spair); i2 != m_Auras.upper_bound(spair); ++i2)
|
||||||
if(aurSpellInfo->StackAmount)
|
|
||||||
{
|
{
|
||||||
if(m_Auras.count(spair) >= aurSpellInfo->StackAmount)
|
if(i2->second->GetCasterGUID()==Aur->GetCasterGUID())
|
||||||
RemoveAura(i,AURA_REMOVE_BY_STACK);
|
|
||||||
}
|
|
||||||
// if StackAmount==0 not allow auras from same caster
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(AuraMap::iterator i2 = m_Auras.lower_bound(spair); i2 != m_Auras.upper_bound(spair); ++i2)
|
|
||||||
{
|
{
|
||||||
if(i2->second->GetCasterGUID()==Aur->GetCasterGUID())
|
// Aura can stack on self -> Stack it;
|
||||||
|
if(aurSpellInfo->StackAmount)
|
||||||
{
|
{
|
||||||
|
i2->second->modStackAmount(1);
|
||||||
|
delete Aur;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// can be only single (this check done at _each_ aura add
|
||||||
|
RemoveAura(i2,AURA_REMOVE_BY_STACK);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stop = false;
|
||||||
|
switch(aurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()])
|
||||||
|
{
|
||||||
|
// DoT/HoT/etc
|
||||||
|
case SPELL_AURA_PERIODIC_DAMAGE: // allow stack
|
||||||
|
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
|
||||||
|
case SPELL_AURA_PERIODIC_LEECH:
|
||||||
|
case SPELL_AURA_PERIODIC_HEAL:
|
||||||
|
case SPELL_AURA_OBS_MOD_HEALTH:
|
||||||
|
case SPELL_AURA_PERIODIC_MANA_LEECH:
|
||||||
|
case SPELL_AURA_PERIODIC_ENERGIZE:
|
||||||
|
case SPELL_AURA_OBS_MOD_MANA:
|
||||||
|
case SPELL_AURA_POWER_BURN_MANA:
|
||||||
|
break;
|
||||||
|
default: // not allow
|
||||||
// can be only single (this check done at _each_ aura add
|
// can be only single (this check done at _each_ aura add
|
||||||
RemoveAura(i2,AURA_REMOVE_BY_STACK);
|
RemoveAura(i2,AURA_REMOVE_BY_STACK);
|
||||||
break;
|
stop = true;
|
||||||
}
|
|
||||||
|
|
||||||
bool stop = false;
|
|
||||||
switch(aurSpellInfo->EffectApplyAuraName[Aur->GetEffIndex()])
|
|
||||||
{
|
|
||||||
// DoT/HoT/etc
|
|
||||||
case SPELL_AURA_PERIODIC_DAMAGE: // allow stack
|
|
||||||
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
|
|
||||||
case SPELL_AURA_PERIODIC_LEECH:
|
|
||||||
case SPELL_AURA_PERIODIC_HEAL:
|
|
||||||
case SPELL_AURA_OBS_MOD_HEALTH:
|
|
||||||
case SPELL_AURA_PERIODIC_MANA_LEECH:
|
|
||||||
case SPELL_AURA_PERIODIC_ENERGIZE:
|
|
||||||
case SPELL_AURA_OBS_MOD_MANA:
|
|
||||||
case SPELL_AURA_POWER_BURN_MANA:
|
|
||||||
break;
|
|
||||||
default: // not allow
|
|
||||||
// can be only single (this check done at _each_ aura add
|
|
||||||
RemoveAura(i2,AURA_REMOVE_BY_STACK);
|
|
||||||
stop = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(stop)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(stop)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3591,7 +3582,16 @@ void Unit::RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex)
|
||||||
{
|
{
|
||||||
AuraMap::iterator iter = m_Auras.find(spellEffectPair(spellId, effindex));
|
AuraMap::iterator iter = m_Auras.find(spellEffectPair(spellId, effindex));
|
||||||
if(iter != m_Auras.end())
|
if(iter != m_Auras.end())
|
||||||
RemoveAura(iter);
|
{
|
||||||
|
if (iter->second->modStackAmount(-1))
|
||||||
|
RemoveAura(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Unit::RemoveSingleSpellAurasFromStack(uint32 spellId)
|
||||||
|
{
|
||||||
|
for (int i=0; i<3; ++i)
|
||||||
|
RemoveSingleAuraFromStack(spellId, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unit::RemoveAurasDueToSpell(uint32 spellId, Aura* except)
|
void Unit::RemoveAurasDueToSpell(uint32 spellId, Aura* except)
|
||||||
|
|
@ -4265,15 +4265,14 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu
|
||||||
if (!procSpell || procSpell->Id == 24659)
|
if (!procSpell || procSpell->Id == 24659)
|
||||||
return false;
|
return false;
|
||||||
// Need remove one 24659 aura
|
// Need remove one 24659 aura
|
||||||
RemoveSingleAuraFromStack(24659, 0);
|
RemoveSingleSpellAurasFromStack(24659);
|
||||||
RemoveSingleAuraFromStack(24659, 1);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Restless Strength
|
// Restless Strength
|
||||||
case 24661:
|
case 24661:
|
||||||
{
|
{
|
||||||
// Need remove one 24662 aura
|
// Need remove one 24662 aura
|
||||||
RemoveSingleAuraFromStack(24662, 0);
|
RemoveSingleSpellAurasFromStack(24662);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Adaptive Warding (Frostfire Regalia set)
|
// Adaptive Warding (Frostfire Regalia set)
|
||||||
|
|
@ -5851,14 +5850,10 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
||||||
return false;
|
return false;
|
||||||
// stacking
|
// stacking
|
||||||
CastSpell(this, 37658, true, NULL, triggeredByAura);
|
CastSpell(this, 37658, true, NULL, triggeredByAura);
|
||||||
// counting
|
|
||||||
uint32 count = 0;
|
Aura * dummy = GetDummyAura(37658);
|
||||||
AuraList const& dummyAura = GetAurasByType(SPELL_AURA_DUMMY);
|
|
||||||
for(AuraList::const_iterator itr = dummyAura.begin(); itr != dummyAura.end(); ++itr)
|
|
||||||
if((*itr)->GetId()==37658)
|
|
||||||
++count;
|
|
||||||
// release at 3 aura in stack (cont contain in basepoint of trigger aura)
|
// release at 3 aura in stack (cont contain in basepoint of trigger aura)
|
||||||
if(count < triggerAmount)
|
if(!dummy || dummy->GetStackAmount() < triggerAmount)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
RemoveAurasDueToSpell(37658);
|
RemoveAurasDueToSpell(37658);
|
||||||
|
|
@ -5872,17 +5867,14 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB
|
||||||
return false;
|
return false;
|
||||||
// stacking
|
// stacking
|
||||||
CastSpell(this, 54842, true, NULL, triggeredByAura);
|
CastSpell(this, 54842, true, NULL, triggeredByAura);
|
||||||
|
|
||||||
// counting
|
// counting
|
||||||
uint32 count = 0;
|
Aura * dummy = GetDummyAura(54842);
|
||||||
AuraList const& dummyAura = GetAurasByType(SPELL_AURA_DUMMY);
|
|
||||||
for(AuraList::const_iterator itr = dummyAura.begin(); itr != dummyAura.end(); ++itr)
|
|
||||||
if((*itr)->GetId()==54842)
|
|
||||||
++count;
|
|
||||||
// release at 3 aura in stack (cont contain in basepoint of trigger aura)
|
// release at 3 aura in stack (cont contain in basepoint of trigger aura)
|
||||||
if(count < triggerAmount)
|
if(!dummy || dummy->GetStackAmount() < triggerAmount)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
RemoveAurasDueToSpell(54842);
|
RemoveAurasDueToSpell(54842);
|
||||||
trigger_spell_id = 54843;
|
trigger_spell_id = 54843;
|
||||||
target = pVictim;
|
target = pVictim;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1087,6 +1087,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
|
||||||
|
|
||||||
void RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
|
void RemoveAura(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
|
||||||
void RemoveAura(uint32 spellId, uint32 effindex, Aura* except = NULL);
|
void RemoveAura(uint32 spellId, uint32 effindex, Aura* except = NULL);
|
||||||
|
void RemoveSingleSpellAurasFromStack(uint32 spellId);
|
||||||
void RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex);
|
void RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex);
|
||||||
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);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "7048"
|
#define REVISION_NR "7049"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue