mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-21 07:22:02 -04:00
Make spellsteal respect dispel-resistances - patch by dr.tenma (thank you!)
This changes the way SPELL_AURA_MOD_DISPEL_RESIST works and fixes mages root diminishing returns Closes issue #1045. --HG-- branch : trunk
This commit is contained in:
+98
-42
@@ -3766,12 +3766,13 @@ void Spell::EffectLearnSpell(uint32 i)
|
||||
}
|
||||
|
||||
typedef std::list< std::pair<uint32, uint64> > DispelList;
|
||||
typedef std::list< std::pair<Aura *, uint8> > DispelChargesList;
|
||||
void Spell::EffectDispel(uint32 i)
|
||||
{
|
||||
if (!unitTarget)
|
||||
return;
|
||||
|
||||
Unit::AuraList dispel_list;
|
||||
DispelChargesList dispel_list;
|
||||
|
||||
// Create dispel mask by dispel type
|
||||
uint32 dispel_type = m_spellInfo->EffectMiscValue[i];
|
||||
@@ -3796,10 +3797,13 @@ void Spell::EffectDispel(uint32 i)
|
||||
continue;
|
||||
}
|
||||
|
||||
// The charges / stack amounts don't count towards the total number of auras that can be dispelled.
|
||||
// Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
|
||||
// Polymorph instead of 1 / (5 + 1) -> 16%.
|
||||
bool dispel_charges = aura->GetSpellProto()->AttributesEx7 & SPELL_ATTR_EX7_DISPEL_CHARGES;
|
||||
|
||||
for (uint8 i = dispel_charges ? aura->GetCharges() : aura->GetStackAmount(); i; --i)
|
||||
dispel_list.push_back(aura);
|
||||
uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
|
||||
if (charges > 0)
|
||||
dispel_list.push_back(std::make_pair(aura, charges));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3811,28 +3815,41 @@ void Spell::EffectDispel(uint32 i)
|
||||
DispelList success_list;
|
||||
WorldPacket dataFail(SMSG_DISPEL_FAILED, 8+8+4+4+damage*4);
|
||||
// dispel N = damage buffs (or while exist buffs for dispel)
|
||||
for (int32 count = 0; count < damage && !dispel_list.empty(); ++count)
|
||||
for (int32 count = 0; count < damage && !dispel_list.empty();)
|
||||
{
|
||||
// Random select buff for dispel
|
||||
Unit::AuraList::iterator itr = dispel_list.begin();
|
||||
DispelChargesList::iterator itr = dispel_list.begin();
|
||||
std::advance(itr, urand(0, dispel_list.size() - 1));
|
||||
|
||||
if (GetDispelChance((*itr)->GetCaster(), (*itr)->GetId()))
|
||||
bool success = false;
|
||||
// 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
|
||||
if (GetDispelChance(itr->first->GetCaster(), unitTarget, itr->first->GetId(), !unitTarget->IsFriendlyTo(m_caster), &success) > 99)
|
||||
{
|
||||
success_list.push_back(std::make_pair((*itr)->GetId(), (*itr)->GetCasterGUID()));
|
||||
dispel_list.erase(itr);
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!failCount)
|
||||
if (success)
|
||||
{
|
||||
// Failed to dispell
|
||||
dataFail << uint64(m_caster->GetGUID()); // Caster GUID
|
||||
dataFail << uint64(unitTarget->GetGUID()); // Victim GUID
|
||||
dataFail << uint32(m_spellInfo->Id); // dispel spell id
|
||||
success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
|
||||
--itr->second;
|
||||
if (itr->second <= 0)
|
||||
dispel_list.erase(itr);
|
||||
}
|
||||
++failCount;
|
||||
dataFail << uint32((*itr)->GetId()); // Spell Id
|
||||
else
|
||||
{
|
||||
if (!failCount)
|
||||
{
|
||||
// Failed to dispell
|
||||
dataFail << uint64(m_caster->GetGUID()); // Caster GUID
|
||||
dataFail << uint64(unitTarget->GetGUID()); // Victim GUID
|
||||
dataFail << uint32(m_spellInfo->Id); // dispel spell id
|
||||
}
|
||||
++failCount;
|
||||
dataFail << uint32(itr->first->GetId()); // Spell Id
|
||||
}
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7127,10 +7144,10 @@ void Spell::EffectDispelMechanic(uint32 i)
|
||||
Aura * aura = itr->second;
|
||||
if (!aura->GetApplicationOfTarget(unitTarget->GetGUID()))
|
||||
continue;
|
||||
if ((GetAllSpellMechanicMask(aura->GetSpellProto()) & (1<<(mechanic))) && GetDispelChance(aura->GetCaster(), aura->GetId()))
|
||||
{
|
||||
bool success = false;
|
||||
GetDispelChance(aura->GetCaster(), unitTarget, aura->GetId(), !unitTarget->IsFriendlyTo(m_caster), &success);
|
||||
if((GetAllSpellMechanicMask(aura->GetSpellProto()) & (1<<(mechanic))) && success)
|
||||
dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID()));
|
||||
}
|
||||
}
|
||||
|
||||
for (; dispel_list.size(); dispel_list.pop())
|
||||
@@ -7481,7 +7498,8 @@ void Spell::EffectStealBeneficialBuff(uint32 i)
|
||||
if (!unitTarget || unitTarget == m_caster) // can't steal from self
|
||||
return;
|
||||
|
||||
Unit::AuraList steal_list;
|
||||
DispelChargesList steal_list;
|
||||
|
||||
// Create dispel mask by dispel type
|
||||
uint32 dispelMask = GetDispellMask(DispelType(m_spellInfo->EffectMiscValue[i]));
|
||||
Unit::AuraMap const& auras = unitTarget->GetOwnedAuras();
|
||||
@@ -7498,43 +7516,81 @@ void Spell::EffectStealBeneficialBuff(uint32 i)
|
||||
if (!aurApp->IsPositive() || aura->IsPassive() || aura->GetSpellProto()->AttributesEx4 & SPELL_ATTR_EX4_NOT_STEALABLE)
|
||||
continue;
|
||||
|
||||
// The charges / stack amounts don't count towards the total number of auras that can be dispelled.
|
||||
// Ie: A dispel on a target with 5 stacks of Winters Chill and a Polymorph has 1 / (1 + 1) -> 50% chance to dispell
|
||||
// Polymorph instead of 1 / (5 + 1) -> 16%.
|
||||
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);
|
||||
uint8 charges = dispel_charges ? aura->GetCharges() : aura->GetStackAmount();
|
||||
if (charges > 0)
|
||||
steal_list.push_back(std::make_pair(aura, charges));
|
||||
}
|
||||
}
|
||||
|
||||
if (steal_list.empty())
|
||||
return;
|
||||
|
||||
// Ok if exist some buffs for dispel try dispel it
|
||||
if (uint32 list_size = steal_list.size())
|
||||
uint32 failCount = 0;
|
||||
DispelList success_list;
|
||||
WorldPacket dataFail(SMSG_DISPEL_FAILED, 8+8+4+4+damage*4);
|
||||
// dispel N = damage buffs (or while exist buffs for dispel)
|
||||
for (int32 count = 0; count < damage && !steal_list.empty();)
|
||||
{
|
||||
DispelList success_list;
|
||||
// Random select buff for dispel
|
||||
DispelChargesList::iterator itr = steal_list.begin();
|
||||
std::advance(itr, urand(0, steal_list.size() - 1));
|
||||
|
||||
// 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())
|
||||
bool success = false;
|
||||
// 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance."
|
||||
if (GetDispelChance(itr->first->GetCaster(), unitTarget, itr->first->GetId(), !unitTarget->IsFriendlyTo(m_caster), &success) > 99)
|
||||
{
|
||||
// Random select buff for dispel
|
||||
Unit::AuraList::iterator itr = steal_list.begin();
|
||||
std::advance(itr, urand(0, list_size-1));
|
||||
success_list.push_back(std::make_pair((*itr)->GetId(), (*itr)->GetCasterGUID()));
|
||||
steal_list.erase(itr);
|
||||
continue;
|
||||
}
|
||||
if (success_list.size())
|
||||
else
|
||||
{
|
||||
WorldPacket data(SMSG_SPELLSTEALLOG, 8+8+4+1+4+damage*5);
|
||||
data.append(unitTarget->GetPackGUID()); // Victim GUID
|
||||
data.append(m_caster->GetPackGUID()); // Caster GUID
|
||||
data << uint32(m_spellInfo->Id); // dispel spell id
|
||||
data << uint8(0); // not used
|
||||
data << uint32(success_list.size()); // count
|
||||
for (DispelList::iterator itr = success_list.begin(); itr != success_list.end(); ++itr)
|
||||
if (success)
|
||||
{
|
||||
data << uint32(itr->first); // Spell Id
|
||||
data << uint8(0); // 0 - steals !=0 transfers
|
||||
unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
|
||||
success_list.push_back(std::make_pair(itr->first->GetId(), itr->first->GetCasterGUID()));
|
||||
--itr->second;
|
||||
if (itr->second <= 0)
|
||||
steal_list.erase(itr);
|
||||
}
|
||||
m_caster->SendMessageToSet(&data, true);
|
||||
else
|
||||
{
|
||||
if (!failCount)
|
||||
{
|
||||
// Failed to dispell
|
||||
dataFail << uint64(m_caster->GetGUID()); // Caster GUID
|
||||
dataFail << uint64(unitTarget->GetGUID()); // Victim GUID
|
||||
dataFail << uint32(m_spellInfo->Id); // dispel spell id
|
||||
}
|
||||
++failCount;
|
||||
dataFail << uint32(itr->first->GetId()); // Spell Id
|
||||
}
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
if (failCount)
|
||||
m_caster->SendMessageToSet(&dataFail, true);
|
||||
|
||||
if (success_list.empty())
|
||||
return;
|
||||
|
||||
WorldPacket dataSuccess(SMSG_SPELLSTEALLOG, 8+8+4+1+4+damage*5);
|
||||
dataSuccess.append(unitTarget->GetPackGUID()); // Victim GUID
|
||||
dataSuccess.append(m_caster->GetPackGUID()); // Caster GUID
|
||||
dataSuccess << uint32(m_spellInfo->Id); // dispel spell id
|
||||
dataSuccess << uint8(0); // not used
|
||||
dataSuccess << uint32(success_list.size()); // count
|
||||
for (DispelList::iterator itr = success_list.begin(); itr!=success_list.end(); ++itr)
|
||||
{
|
||||
dataSuccess << uint32(itr->first); // Spell Id
|
||||
dataSuccess << uint8(0); // 0 - steals !=0 transfers
|
||||
unitTarget->RemoveAurasDueToSpellBySteal(itr->first, itr->second, m_caster);
|
||||
}
|
||||
m_caster->SendMessageToSet(&dataSuccess, true);
|
||||
}
|
||||
|
||||
void Spell::EffectKillCreditPersonal(uint32 i)
|
||||
|
||||
Reference in New Issue
Block a user