aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp101
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
2 files changed, 57 insertions, 46 deletions
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index ce0eb1d503d..cd97d0d4081 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -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;
+ if (effect->GetMiscValue() == power)
+ {
+ uint32 effectAmount = effect->GetAmount();
+ uint32 triggerSpell = effect->GetSpellEffectInfo().TriggerSpell;
- float oldValueCheck = oldVal;
- float newValueCheck = newVal;
+ float oldValueCheck = oldVal;
+ float newValueCheck = newVal;
- if (effect->GetAuraType() == SPELL_AURA_TRIGGER_SPELL_ON_POWER_PCT)
- {
- int32 maxPower = GetMaxPower(power);
- oldValueCheck = GetPctOf(oldVal, maxPower);
- newValueCheck = GetPctOf(newVal, maxPower);
- }
+ 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;
- }
+ 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);
+ 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)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index d12fbda04bd..e01d32067e5 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -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); }