* Use pair<uint32, uint64> lists instead of <Aura*> lists in Dispel/SpellSteal effects handlers (prevent reference to aura removed from unit)
* Correctly fill EffectStealBeneficialBuff list with Stackable/Chargeable auras --HG-- branch : trunk
This commit is contained in:
+18
-14
@@ -3727,7 +3727,7 @@ void Spell::EffectLearnSpell(uint32 i)
|
|||||||
sLog.outDebug("Spell: Player %u has learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow());
|
sLog.outDebug("Spell: Player %u has learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow());
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::list< uint32 > DispelList;
|
typedef std::list< std::pair<uint32, uint64> > DispelList;
|
||||||
void Spell::EffectDispel(uint32 i)
|
void Spell::EffectDispel(uint32 i)
|
||||||
{
|
{
|
||||||
if(!unitTarget)
|
if(!unitTarget)
|
||||||
@@ -3777,8 +3777,7 @@ void Spell::EffectDispel(uint32 i)
|
|||||||
|
|
||||||
if (GetDispelChance((*itr)->GetCaster(), (*itr)->GetId()))
|
if (GetDispelChance((*itr)->GetCaster(), (*itr)->GetId()))
|
||||||
{
|
{
|
||||||
unitTarget->RemoveAurasDueToSpellByDispel(*itr, m_caster);
|
success_list.push_back(std::make_pair((*itr)->GetId(), (*itr)->GetCasterGUID()));
|
||||||
success_list.push_back((*itr)->GetId());
|
|
||||||
dispel_list.erase(itr);
|
dispel_list.erase(itr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -3811,8 +3810,9 @@ void Spell::EffectDispel(uint32 i)
|
|||||||
for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
|
for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
|
||||||
{
|
{
|
||||||
// Send dispelled spell info
|
// Send dispelled spell info
|
||||||
dataSuccess << uint32(*itr); // Spell Id
|
dataSuccess << uint32(itr->first); // Spell Id
|
||||||
dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
|
dataSuccess << uint8(0); // 0 - dispelled !=0 cleansed
|
||||||
|
unitTarget->RemoveAurasDueToSpellByDispel(itr->first, itr->second, m_caster);
|
||||||
}
|
}
|
||||||
m_caster->SendMessageToSet(&dataSuccess, true);
|
m_caster->SendMessageToSet(&dataSuccess, true);
|
||||||
|
|
||||||
@@ -7166,7 +7166,7 @@ void Spell::EffectStealBeneficialBuff(uint32 i)
|
|||||||
if(!unitTarget || unitTarget==m_caster) // can't steal from self
|
if(!unitTarget || unitTarget==m_caster) // can't steal from self
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::list <Aura *> steal_list;
|
Unit::AuraList steal_list;
|
||||||
// Create dispel mask by dispel type
|
// Create dispel mask by dispel type
|
||||||
uint32 dispelMask = GetDispellMask( DispelType(m_spellInfo->EffectMiscValue[i]) );
|
uint32 dispelMask = GetDispellMask( DispelType(m_spellInfo->EffectMiscValue[i]) );
|
||||||
Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
|
Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
|
||||||
@@ -7176,24 +7176,27 @@ void Spell::EffectStealBeneficialBuff(uint32 i)
|
|||||||
if ((1<<aura->GetSpellProto()->Dispel) & dispelMask)
|
if ((1<<aura->GetSpellProto()->Dispel) & dispelMask)
|
||||||
{
|
{
|
||||||
// Need check for passive? this
|
// Need check for passive? this
|
||||||
if (aura->IsPositive(unitTarget) && !aura->IsPassive() && !(aura->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_NOT_STEALABLE))
|
if (aura->IsPositive(unitTarget) || aura->IsPassive() || aura->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_NOT_STEALABLE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
bool dispel_charges = aura->GetSpellProto()->AttributesEx7 & SPELL_ATTR_EX7_DISPEL_CHARGES;
|
||||||
|
|
||||||
|
for (uint8 i = dispel_charges ? aura->GetCharges() : aura->GetStackAmount(); i; --i)
|
||||||
steal_list.push_back(aura);
|
steal_list.push_back(aura);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Ok if exist some buffs for dispel try dispel it
|
// Ok if exist some buffs for dispel try dispel it
|
||||||
if (uint32 list_size = steal_list.size())
|
if (uint32 list_size = steal_list.size())
|
||||||
{
|
{
|
||||||
std::list < Aura * > success_list;
|
DispelList success_list;
|
||||||
|
|
||||||
// dispel N = damage buffs (or while exist buffs for dispel)
|
// dispel N = damage buffs (or while exist buffs for dispel)
|
||||||
for (int32 count=0; count < damage && list_size > 0; ++count, list_size = steal_list.size())
|
for (int32 count=0; count < damage && list_size > 0; ++count, list_size = steal_list.size())
|
||||||
{
|
{
|
||||||
// Random select buff for dispel
|
// Random select buff for dispel
|
||||||
std::list < Aura * > ::iterator itr = steal_list.begin();
|
Unit::AuraList::iterator itr = steal_list.begin();
|
||||||
for (uint32 i=urand(0, list_size-1); i>0; --i)
|
std::advance(itr, urand(0, list_size-1));
|
||||||
itr++;
|
success_list.push_back(std::make_pair((*itr)->GetId(), (*itr)->GetCasterGUID()));
|
||||||
success_list.push_back(*itr);
|
|
||||||
unitTarget->RemoveAurasDueToSpellBySteal(*itr, m_caster);
|
|
||||||
steal_list.erase(itr);
|
steal_list.erase(itr);
|
||||||
}
|
}
|
||||||
if (success_list.size())
|
if (success_list.size())
|
||||||
@@ -7204,10 +7207,11 @@ void Spell::EffectStealBeneficialBuff(uint32 i)
|
|||||||
data << uint32(m_spellInfo->Id); // dispel spell id
|
data << uint32(m_spellInfo->Id); // dispel spell id
|
||||||
data << uint8(0); // not used
|
data << uint8(0); // not used
|
||||||
data << uint32(success_list.size()); // count
|
data << uint32(success_list.size()); // count
|
||||||
for (std::list < Aura * >::iterator itr = success_list.begin(); itr!=success_list.end(); ++itr)
|
for (DispelList::iterator itr = success_list.begin(); itr!=success_list.end(); ++itr)
|
||||||
{
|
{
|
||||||
data << uint32((*itr)->GetId()); // Spell Id
|
data << uint32(itr->first); // Spell Id
|
||||||
data << uint8(0); // 0 - steals !=0 transfers
|
data << uint8(0); // 0 - steals !=0 transfers
|
||||||
|
unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
|
||||||
}
|
}
|
||||||
m_caster->SendMessageToSet(&data, true);
|
m_caster->SendMessageToSet(&data, true);
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-14
@@ -3977,16 +3977,12 @@ inline void Unit::RemoveAuraFromStack(AuraMap::iterator &iter, AuraRemoveMode re
|
|||||||
RemoveOwnedAura(iter, removeMode);
|
RemoveOwnedAura(iter, removeMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unit::RemoveAurasDueToSpellByDispel(Aura * aura, Unit *dispeller)
|
void Unit::RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeller)
|
||||||
{
|
{
|
||||||
if (aura->IsRemoved())
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint32 spellId = aura->GetId();
|
|
||||||
|
|
||||||
for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);)
|
for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);)
|
||||||
{
|
{
|
||||||
if (aura == iter->second)
|
Aura * aura = iter->second;
|
||||||
|
if (aura->GetCasterGUID() == casterGUID)
|
||||||
{
|
{
|
||||||
if (aura->GetSpellProto()->AttributesEx7 & SPELL_ATTR_EX7_DISPEL_CHARGES)
|
if (aura->GetSpellProto()->AttributesEx7 & SPELL_ATTR_EX7_DISPEL_CHARGES)
|
||||||
aura->DropCharge();
|
aura->DropCharge();
|
||||||
@@ -4039,16 +4035,12 @@ void Unit::RemoveAurasDueToSpellByDispel(Aura * aura, Unit *dispeller)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unit::RemoveAurasDueToSpellBySteal(Aura * aura, Unit *stealer)
|
void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer)
|
||||||
{
|
{
|
||||||
if (aura->IsRemoved())
|
|
||||||
return;
|
|
||||||
|
|
||||||
uint32 spellId = aura->GetId();
|
|
||||||
|
|
||||||
for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);)
|
for (AuraMap::iterator iter = m_ownedAuras.lower_bound(spellId); iter != m_ownedAuras.upper_bound(spellId);)
|
||||||
{
|
{
|
||||||
if (aura == iter->second)
|
Aura * aura = iter->second;
|
||||||
|
if (aura->GetCasterGUID() == casterGUID)
|
||||||
{
|
{
|
||||||
int32 damage[MAX_SPELL_EFFECTS];
|
int32 damage[MAX_SPELL_EFFECTS];
|
||||||
int32 baseDamage[MAX_SPELL_EFFECTS];
|
int32 baseDamage[MAX_SPELL_EFFECTS];
|
||||||
|
|||||||
+2
-2
@@ -1562,8 +1562,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
|
|||||||
void RemoveAurasDueToSpell(uint32 spellId, uint64 caster = NULL, uint8 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
|
void RemoveAurasDueToSpell(uint32 spellId, uint64 caster = NULL, uint8 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
|
||||||
void RemoveAuraFromStack(uint32 spellId, uint64 caster = NULL, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
|
void RemoveAuraFromStack(uint32 spellId, uint64 caster = NULL, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
|
||||||
inline void RemoveAuraFromStack(AuraMap::iterator &iter,AuraRemoveMode removeMode);
|
inline void RemoveAuraFromStack(AuraMap::iterator &iter,AuraRemoveMode removeMode);
|
||||||
void RemoveAurasDueToSpellByDispel(Aura * aura, Unit *dispeller);
|
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint64 casterGUID, Unit *dispeller);
|
||||||
void RemoveAurasDueToSpellBySteal(Aura * aura, Unit *stealer);
|
void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit *stealer);
|
||||||
void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId);
|
void RemoveAurasDueToItemSpell(Item* castItem,uint32 spellId);
|
||||||
void RemoveAurasByType(AuraType auraType, uint64 casterGUID = 0, Aura * except = NULL, bool negative = true, bool positive = true);
|
void RemoveAurasByType(AuraType auraType, uint64 casterGUID = 0, Aura * except = NULL, bool negative = true, bool positive = true);
|
||||||
void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0);
|
void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0);
|
||||||
|
|||||||
Reference in New Issue
Block a user