[8905] Dispel work with aura stacks fixes.

* Implement set of remove aura functions for remove single aura from stack.
  Also some order function declarations for more clear show different aura remove functions.
* Change Spell::EffectDispel to dispel single aura instead all similar auras from caster.
This commit is contained in:
VladimirMangos 2009-12-02 21:41:14 +03:00
parent d63e4798b2
commit 03e16dd08b
4 changed files with 77 additions and 53 deletions

View file

@ -3599,7 +3599,8 @@ void Spell::EffectDispel(uint32 i)
if (positive == unitTarget->IsFriendlyTo(m_caster))
continue;
}
// Add aura to dispel list
// Add aura to dispel list (all stack cases)
for(int k = 0; k < aur->GetStackAmount(); ++k)
dispel_list.push_back(aur);
}
}
@ -3618,7 +3619,10 @@ void Spell::EffectDispel(uint32 i)
for (int32 count=0; count < damage && list_size > 0; ++count)
{
// Random select buff for dispel
Aura *aur = dispel_list[urand(0, list_size-1)];
std::vector<Aura*>::iterator dispel_itr = dispel_list.begin();
std::advance(dispel_itr,urand(0, list_size-1));
Aura *aur = *dispel_itr;
SpellEntry const* spellInfo = aur->GetSpellProto();
// Base dispel chance
@ -3632,21 +3636,12 @@ void Spell::EffectDispel(uint32 i)
}
// Try dispel
if (roll_chance_i(miss_chance))
fail_list.push_back(aur->GetId());
fail_list.push_back(spellInfo->Id);
else
success_list.push_back(std::pair<uint32,uint64>(aur->GetId(),aur->GetCasterGUID()));
// Remove buff from list for prevent doubles
for (std::vector<Aura *>::iterator j = dispel_list.begin(); j != dispel_list.end(); )
{
Aura *dispeled = *j;
if (dispeled->GetId() == aur->GetId() && dispeled->GetCasterGUID() == aur->GetCasterGUID())
{
j = dispel_list.erase(j);
--list_size;
}
else
++j;
}
// remove entry from dispel_list
dispel_list.erase(dispel_itr);
}
// Send success log and really remove auras
if (!success_list.empty())
@ -3655,7 +3650,7 @@ void Spell::EffectDispel(uint32 i)
WorldPacket data(SMSG_SPELLDISPELLOG, 8+8+4+1+4+count*5);
data.append(unitTarget->GetPackGUID()); // Victim GUID
data.append(m_caster->GetPackGUID()); // Caster GUID
data << uint32(m_spellInfo->Id); // Dispell spell id
data << uint32(m_spellInfo->Id); // Dispel spell id
data << uint8(0); // not used
data << uint32(count); // count
for (std::list<std::pair<uint32,uint64> >::iterator j = success_list.begin(); j != success_list.end(); ++j)
@ -3663,7 +3658,7 @@ void Spell::EffectDispel(uint32 i)
SpellEntry const* spellInfo = sSpellStore.LookupEntry(j->first);
data << uint32(spellInfo->Id); // Spell Id
data << uint8(0); // 0 - dispeled !=0 cleansed
unitTarget->RemoveAurasDueToSpellByDispel(spellInfo->Id, j->second, m_caster);
unitTarget->RemoveSingleAuraDueToSpellByDispel(spellInfo->Id, j->second, m_caster);
}
m_caster->SendMessageToSet(&data, true);

View file

@ -3863,34 +3863,27 @@ void Unit::RemoveAurasByCasterSpell(uint32 spellId, uint32 effindex, uint64 cast
}
}
void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler)
{
for (AuraMap::iterator iter = m_Auras.begin(); iter != m_Auras.end(); )
{
Aura *aur = iter->second;
if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID)
void Unit::RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler)
{
SpellEntry const* spellEntry = sSpellStore.LookupEntry(spellId);
// Custom dispel case
// Unstable Affliction
if (aur->GetSpellProto()->SpellFamilyName == SPELLFAMILY_WARLOCK && (aur->GetSpellProto()->SpellFamilyFlags & UI64LIT(0x010000000000)))
if(spellEntry->SpellFamilyName == SPELLFAMILY_WARLOCK && (spellEntry->SpellFamilyFlags & UI64LIT(0x010000000000)))
{
int32 damage = aur->GetModifier()->m_amount*9;
uint64 caster_guid = aur->GetCasterGUID();
if (Aura* dotAura = GetAura(SPELL_AURA_PERIODIC_DAMAGE,SPELLFAMILY_WARLOCK,UI64LIT(0x010000000000),0x00000000,casterGUID))
{
int32 damage = dotAura->GetModifier()->m_amount*9;
// Remove aura
RemoveAura(iter, AURA_REMOVE_BY_DISPEL);
// Remove spell auras from stack
RemoveSingleSpellAurasByCasterSpell(spellId, casterGUID, AURA_REMOVE_BY_DISPEL);
// backfire damage and silence
dispeler->CastCustomSpell(dispeler, 31117, &damage, NULL, NULL, true, NULL, NULL,caster_guid);
iter = m_Auras.begin(); // iterator can be invalidate at cast if self-dispel
dispeler->CastCustomSpell(dispeler, 31117, &damage, NULL, NULL, true, NULL, NULL,casterGUID);
}
}
else
RemoveAura(iter, AURA_REMOVE_BY_DISPEL);
}
else
++iter;
}
RemoveSingleSpellAurasByCasterSpell(spellId, casterGUID, AURA_REMOVE_BY_DISPEL);
}
void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer)
@ -3960,21 +3953,46 @@ void Unit::RemoveAurasWithDispelType( DispelType type )
}
}
void Unit::RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex)
void Unit::RemoveSingleAuraFromStack(AuraMap::iterator &i, AuraRemoveMode mode)
{
if (i->second->modStackAmount(-1))
RemoveAura(i,mode);
}
void Unit::RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex, AuraRemoveMode mode)
{
AuraMap::iterator iter = m_Auras.find(spellEffectPair(spellId, effindex));
if(iter != m_Auras.end())
RemoveSingleAuraFromStack(iter,mode);
}
void Unit::RemoveSingleSpellAurasFromStack(uint32 spellId, AuraRemoveMode mode)
{
if (iter->second->modStackAmount(-1))
RemoveAura(iter);
for (int i=0; i<3; ++i)
RemoveSingleAuraFromStack(spellId, i, mode);
}
void Unit::RemoveSingleSpellAurasByCasterSpell(uint32 spellId, uint64 casterGUID, AuraRemoveMode mode)
{
for (int i=0; i<3; ++i)
RemoveSingleAuraByCasterSpell(spellId, i, casterGUID, mode);
}
void Unit::RemoveSingleAuraByCasterSpell(uint32 spellId, uint32 effindex, uint64 casterGUID, AuraRemoveMode mode)
{
spellEffectPair spair = spellEffectPair(spellId, effindex);
for(AuraMap::iterator iter = m_Auras.lower_bound(spair); iter != m_Auras.upper_bound(spair); ++iter)
{
Aura *aur = iter->second;
if (aur->GetId() == spellId && aur->GetCasterGUID() == casterGUID)
{
RemoveSingleAuraFromStack(iter,mode);
break;
}
}
}
void Unit::RemoveSingleSpellAurasFromStack(uint32 spellId)
{
for (int i=0; i<3; ++i)
RemoveSingleAuraFromStack(spellId, i);
}
void Unit::RemoveAurasDueToSpell(uint32 spellId, Aura* except)
{

View file

@ -1235,31 +1235,42 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
bool AddAura(Aura *aur);
// removing specific aura stack
void RemoveAura(Aura* aura, 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 RemoveSingleSpellAurasFromStack(uint32 spellId);
void RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex);
// removing specific aura stacks by diff reasons and selections
void RemoveAurasDueToSpell(uint32 spellId, Aura* except = NULL);
void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId);
void RemoveAurasByCasterSpell(uint32 spellId, uint64 casterGUID);
void RemoveAurasByCasterSpell(uint32 spellId, uint32 effindex, uint64 casterGUID);
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler);
void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer);
void RemoveAurasDueToSpellByCancel(uint32 spellId);
void RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo);
// removing unknown aura stacks by diff reasons and selections
void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0);
void RemoveAurasAtMechanicImmunity(uint32 mechMask, uint32 exceptSpellId, bool non_positive = false);
void RemoveSpellsCausingAura(AuraType auraType);
void RemoveRankAurasDueToSpell(uint32 spellId);
bool RemoveNoStackAurasDueToAura(Aura *Aur);
void RemoveAurasWithInterruptFlags(uint32 flags);
void RemoveAurasWithDispelType( DispelType type );
void RemoveAllAuras(AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
void RemoveArenaAuras(bool onleave = false);
void RemoveAllAurasOnDeath();
// removing specific aura FROM stack
void RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
void RemoveSingleAuraFromStack(AuraMap::iterator &i, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
// removing specific aura FROM stack by diff reasons and selections
void RemoveSingleSpellAurasFromStack(uint32 spellId, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
void RemoveSingleSpellAurasByCasterSpell(uint32 spellId, uint64 casterGUID, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
void RemoveSingleAuraByCasterSpell(uint32 spellId, uint32 effindex, uint64 casterGUID, AuraRemoveMode mode = AURA_REMOVE_BY_DEFAULT);
void RemoveSingleAuraDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeler);
void DelayAura(uint32 spellId, uint32 effindex, int32 delaytime);
float GetResistanceBuffMods(SpellSchools school, bool positive) const { return GetFloatValue(positive ? UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE+school ); }

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "8904"
#define REVISION_NR "8905"
#endif // __REVISION_NR_H__