Core/Auras: Use std::vector for temporary copies of aura lists
This commit is contained in:
@@ -762,6 +762,14 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) cons
|
||||
damage *= attacker->GetDamageMultiplierForTarget(victim);
|
||||
}
|
||||
|
||||
/*static*/ AuraEffectVector Unit::CopyAuraEffectList(Unit::AuraEffectList const& list)
|
||||
{
|
||||
AuraEffectVector effects;
|
||||
effects.resize(list.size());
|
||||
std::copy(list.begin(), list.end(), effects.begin());
|
||||
return effects;
|
||||
}
|
||||
|
||||
/*static*/ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellInfo const* spellProto, bool durabilityLoss)
|
||||
{
|
||||
uint32 damageDone = damage;
|
||||
@@ -830,9 +838,9 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) cons
|
||||
|
||||
// We're going to call functions which can modify content of the list during iteration over it's elements
|
||||
// Let's copy the list so we can prevent iterator invalidation
|
||||
AuraEffectList vCopyDamageCopy(victim->GetAuraEffectsByType(SPELL_AURA_SHARE_DAMAGE_PCT));
|
||||
AuraEffectVector vCopyDamageCopy = CopyAuraEffectList(victim->GetAuraEffectsByType(SPELL_AURA_SHARE_DAMAGE_PCT));
|
||||
// copy damage to casters of this aura
|
||||
for (AuraEffectList::iterator i = vCopyDamageCopy.begin(); i != vCopyDamageCopy.end(); ++i)
|
||||
for (auto i = vCopyDamageCopy.begin(); i != vCopyDamageCopy.end(); ++i)
|
||||
{
|
||||
// Check if aura was removed during iteration - we don't need to work on such auras
|
||||
if (!((*i)->GetBase()->IsAppliedOnTarget(victim->GetGUID())))
|
||||
@@ -941,7 +949,7 @@ bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) cons
|
||||
|
||||
if (damagetype != NODAMAGE && damagetype != SELF_DAMAGE && victim->HasAuraType(SPELL_AURA_SCHOOL_ABSORB_OVERKILL))
|
||||
{
|
||||
AuraEffectList vAbsorbOverkill = victim->GetAuraEffectsByType(SPELL_AURA_SCHOOL_ABSORB_OVERKILL);
|
||||
AuraEffectVector vAbsorbOverkill = CopyAuraEffectList(victim->GetAuraEffectsByType(SPELL_AURA_SCHOOL_ABSORB_OVERKILL));
|
||||
DamageInfo damageInfo = DamageInfo(attacker, victim, damageTaken, spellProto, damageSchoolMask, damagetype,
|
||||
cleanDamage ? cleanDamage->attackType : BASE_ATTACK);
|
||||
for (AuraEffect* absorbAurEff : vAbsorbOverkill)
|
||||
@@ -1535,7 +1543,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss)
|
||||
{
|
||||
// We're going to call functions which can modify content of the list during iteration over it's elements
|
||||
// Let's copy the list so we can prevent iterator invalidation
|
||||
AuraEffectList vDamageShieldsCopy(victim->GetAuraEffectsByType(SPELL_AURA_DAMAGE_SHIELD));
|
||||
AuraEffectVector vDamageShieldsCopy = CopyAuraEffectList(victim->GetAuraEffectsByType(SPELL_AURA_DAMAGE_SHIELD));
|
||||
for (AuraEffect const* aurEff : vDamageShieldsCopy)
|
||||
{
|
||||
SpellInfo const* spellInfo = aurEff->GetSpellInfo();
|
||||
@@ -1807,11 +1815,11 @@ void Unit::HandleEmoteCommand(Emote emoteId, Player* target /*=nullptr*/, Trinit
|
||||
|
||||
// We're going to call functions which can modify content of the list during iteration over it's elements
|
||||
// Let's copy the list so we can prevent iterator invalidation
|
||||
AuraEffectList vSchoolAbsorbCopy(damageInfo.GetVictim()->GetAuraEffectsByType(SPELL_AURA_SCHOOL_ABSORB));
|
||||
vSchoolAbsorbCopy.sort(Trinity::AbsorbAuraOrderPred());
|
||||
AuraEffectVector vSchoolAbsorbCopy = CopyAuraEffectList(damageInfo.GetVictim()->GetAuraEffectsByType(SPELL_AURA_SCHOOL_ABSORB));
|
||||
std::sort(vSchoolAbsorbCopy.begin(), vSchoolAbsorbCopy.end(), Trinity::AbsorbAuraOrderPred());
|
||||
|
||||
// absorb without mana cost
|
||||
for (AuraEffectList::iterator itr = vSchoolAbsorbCopy.begin(); (itr != vSchoolAbsorbCopy.end()) && (damageInfo.GetDamage() > 0); ++itr)
|
||||
for (auto itr = vSchoolAbsorbCopy.begin(); (itr != vSchoolAbsorbCopy.end()) && (damageInfo.GetDamage() > 0); ++itr)
|
||||
{
|
||||
AuraEffect* absorbAurEff = *itr;
|
||||
// Check if aura was removed during iteration - we don't need to work on such auras
|
||||
@@ -1877,8 +1885,8 @@ void Unit::HandleEmoteCommand(Emote emoteId, Player* target /*=nullptr*/, Trinit
|
||||
}
|
||||
|
||||
// absorb by mana cost
|
||||
AuraEffectList vManaShieldCopy(damageInfo.GetVictim()->GetAuraEffectsByType(SPELL_AURA_MANA_SHIELD));
|
||||
for (AuraEffectList::const_iterator itr = vManaShieldCopy.begin(); (itr != vManaShieldCopy.end()) && (damageInfo.GetDamage() > 0); ++itr)
|
||||
AuraEffectVector vManaShieldCopy = CopyAuraEffectList(damageInfo.GetVictim()->GetAuraEffectsByType(SPELL_AURA_MANA_SHIELD));
|
||||
for (auto itr = vManaShieldCopy.begin(); (itr != vManaShieldCopy.end()) && (damageInfo.GetDamage() > 0); ++itr)
|
||||
{
|
||||
AuraEffect* absorbAurEff = *itr;
|
||||
// Check if aura was removed during iteration - we don't need to work on such auras
|
||||
@@ -1958,8 +1966,8 @@ void Unit::HandleEmoteCommand(Emote emoteId, Player* target /*=nullptr*/, Trinit
|
||||
{
|
||||
// We're going to call functions which can modify content of the list during iteration over it's elements
|
||||
// Let's copy the list so we can prevent iterator invalidation
|
||||
AuraEffectList vSplitDamagePctCopy(damageInfo.GetVictim()->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_PCT));
|
||||
for (AuraEffectList::iterator itr = vSplitDamagePctCopy.begin(); itr != vSplitDamagePctCopy.end() && damageInfo.GetDamage() > 0; ++itr)
|
||||
AuraEffectVector vSplitDamagePctCopy = CopyAuraEffectList(damageInfo.GetVictim()->GetAuraEffectsByType(SPELL_AURA_SPLIT_DAMAGE_PCT));
|
||||
for (auto itr = vSplitDamagePctCopy.begin(); itr != vSplitDamagePctCopy.end() && damageInfo.GetDamage() > 0; ++itr)
|
||||
{
|
||||
// Check if aura was removed during iteration - we don't need to work on such auras
|
||||
AuraApplication const* aurApp = (*itr)->GetBase()->GetApplicationOfTarget(damageInfo.GetVictim()->GetGUID());
|
||||
@@ -2020,8 +2028,7 @@ void Unit::HandleEmoteCommand(Emote emoteId, Player* target /*=nullptr*/, Trinit
|
||||
if (!healInfo.GetHeal())
|
||||
return;
|
||||
|
||||
std::vector<AuraEffect*> vHealAbsorb(healInfo.GetTarget()->GetAuraEffectsByType(SPELL_AURA_SCHOOL_HEAL_ABSORB).begin(),
|
||||
healInfo.GetTarget()->GetAuraEffectsByType(SPELL_AURA_SCHOOL_HEAL_ABSORB).end());
|
||||
AuraEffectVector vHealAbsorb = CopyAuraEffectList(healInfo.GetTarget()->GetAuraEffectsByType(SPELL_AURA_SCHOOL_HEAL_ABSORB));
|
||||
for (auto i = vHealAbsorb.begin(); i != vHealAbsorb.end() && healInfo.GetHeal() > 0; ++i)
|
||||
{
|
||||
AuraEffect* absorbAurEff = *i;
|
||||
@@ -7892,7 +7899,7 @@ MountCapabilityEntry const* Unit::GetMountCapability(uint32 mountType) const
|
||||
|
||||
void Unit::UpdateMountCapability()
|
||||
{
|
||||
AuraEffectList mounts = GetAuraEffectsByType(SPELL_AURA_MOUNTED);
|
||||
AuraEffectVector mounts = CopyAuraEffectList(GetAuraEffectsByType(SPELL_AURA_MOUNTED));
|
||||
for (AuraEffect* aurEff : mounts)
|
||||
{
|
||||
aurEff->RecalculateAmount();
|
||||
@@ -8074,7 +8081,7 @@ void Unit::TriggerOnHealthChangeAuras(uint64 oldVal, uint64 newVal)
|
||||
if (!HasAuraType(SPELL_AURA_TRIGGER_SPELL_ON_HEALTH_PCT))
|
||||
return;
|
||||
|
||||
AuraEffectList effects = GetAuraEffectsByType(SPELL_AURA_TRIGGER_SPELL_ON_HEALTH_PCT);
|
||||
AuraEffectVector effects = CopyAuraEffectList(GetAuraEffectsByType(SPELL_AURA_TRIGGER_SPELL_ON_HEALTH_PCT));
|
||||
for (AuraEffect const* effect : effects)
|
||||
{
|
||||
uint32 triggerHealthPct = effect->GetAmount();
|
||||
@@ -9264,44 +9271,46 @@ void Unit::SetMaxPower(Powers power, int32 val)
|
||||
|
||||
void Unit::TriggerOnPowerChangeAuras(Powers power, int32 oldVal, int32 newVal)
|
||||
{
|
||||
AuraEffectList effects = GetAuraEffectsByType(SPELL_AURA_TRIGGER_SPELL_ON_POWER_PCT);
|
||||
AuraEffectList effectsAmount = GetAuraEffectsByType(SPELL_AURA_TRIGGER_SPELL_ON_POWER_AMOUNT);
|
||||
effects.splice(effects.end(), effectsAmount);
|
||||
|
||||
for (AuraEffect const* effect : effects)
|
||||
auto processAuras = [&](AuraEffectVector const& effects)
|
||||
{
|
||||
if (effect->GetMiscValue() == power)
|
||||
for (AuraEffect const* effect : effects)
|
||||
{
|
||||
uint32 effectAmount = effect->GetAmount();
|
||||
uint32 triggerSpell = effect->GetSpellEffectInfo().TriggerSpell;
|
||||
|
||||
float oldValueCheck = oldVal;
|
||||
float newValueCheck = newVal;
|
||||
|
||||
if (effect->GetAuraType() == SPELL_AURA_TRIGGER_SPELL_ON_POWER_PCT)
|
||||
if (effect->GetMiscValue() == power)
|
||||
{
|
||||
int32 maxPower = GetMaxPower(power);
|
||||
oldValueCheck = GetPctOf(oldVal, maxPower);
|
||||
newValueCheck = GetPctOf(newVal, maxPower);
|
||||
}
|
||||
uint32 effectAmount = effect->GetAmount();
|
||||
uint32 triggerSpell = effect->GetSpellEffectInfo().TriggerSpell;
|
||||
|
||||
switch (AuraTriggerOnPowerChangeDirection(effect->GetMiscValueB()))
|
||||
{
|
||||
case AuraTriggerOnPowerChangeDirection::Gain:
|
||||
if (oldValueCheck >= effect->GetAmount() || newValueCheck < effectAmount)
|
||||
continue;
|
||||
break;
|
||||
case AuraTriggerOnPowerChangeDirection::Loss:
|
||||
if (oldValueCheck <= effect->GetAmount() || newValueCheck > effectAmount)
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
float oldValueCheck = oldVal;
|
||||
float newValueCheck = newVal;
|
||||
|
||||
CastSpell(this, triggerSpell, effect);
|
||||
if (effect->GetAuraType() == SPELL_AURA_TRIGGER_SPELL_ON_POWER_PCT)
|
||||
{
|
||||
int32 maxPower = GetMaxPower(power);
|
||||
oldValueCheck = GetPctOf(oldVal, maxPower);
|
||||
newValueCheck = GetPctOf(newVal, maxPower);
|
||||
}
|
||||
|
||||
switch (AuraTriggerOnPowerChangeDirection(effect->GetMiscValueB()))
|
||||
{
|
||||
case AuraTriggerOnPowerChangeDirection::Gain:
|
||||
if (oldValueCheck >= effect->GetAmount() || newValueCheck < effectAmount)
|
||||
continue;
|
||||
break;
|
||||
case AuraTriggerOnPowerChangeDirection::Loss:
|
||||
if (oldValueCheck <= effect->GetAmount() || newValueCheck > effectAmount)
|
||||
continue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
CastSpell(this, triggerSpell, effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
processAuras(CopyAuraEffectList(GetAuraEffectsByType(SPELL_AURA_TRIGGER_SPELL_ON_POWER_PCT)));
|
||||
processAuras(CopyAuraEffectList(GetAuraEffectsByType(SPELL_AURA_TRIGGER_SPELL_ON_POWER_AMOUNT)));
|
||||
}
|
||||
|
||||
void Unit::AIUpdateTick(uint32 diff)
|
||||
|
||||
@@ -769,6 +769,8 @@ class TC_GAME_API Unit : public WorldObject
|
||||
struct VisibleAuraSlotCompare { bool operator()(AuraApplication* left, AuraApplication* right) const; };
|
||||
typedef std::set<AuraApplication*, VisibleAuraSlotCompare> VisibleAuraContainer;
|
||||
|
||||
static std::vector<AuraEffect*> CopyAuraEffectList(AuraEffectList const& list);
|
||||
|
||||
virtual ~Unit();
|
||||
|
||||
bool IsAIEnabled() const { return (i_AI != nullptr); }
|
||||
|
||||
Reference in New Issue
Block a user