diff --git a/Source/Game/Entities/Creature/Creature.cs b/Source/Game/Entities/Creature/Creature.cs index 62be84663..f34042bb9 100644 --- a/Source/Game/Entities/Creature/Creature.cs +++ b/Source/Game/Entities/Creature/Creature.cs @@ -557,11 +557,7 @@ namespace Game.Entities addvalue = maxValue / 3; // Apply modifiers (if any). - var ModPowerRegenPCTAuras = GetAuraEffectsByType(AuraType.ModPowerRegenPercent); - foreach (var eff in ModPowerRegenPCTAuras) - if (eff.GetMiscValue() == (int)PowerType.Mana) - MathFunctions.AddPct(ref addvalue, eff.GetAmount()); - + addvalue *= (int)GetTotalAuraMultiplierByMiscValue(AuraType.ModPowerRegenPercent, (int)PowerType.Mana); addvalue += GetTotalAuraModifierByMiscValue(AuraType.ModPowerRegen, (int)PowerType.Mana) * SharedConst.CreatureRegenInterval / (5 * Time.InMilliseconds); ModifyPower(PowerType.Mana, addvalue); @@ -590,11 +586,8 @@ namespace Game.Entities addvalue = (long)maxValue / 3; // Apply modifiers (if any). - var ModPowerRegenPCTAuras = GetAuraEffectsByType(AuraType.ModHealthRegenPercent); - foreach (var eff in ModPowerRegenPCTAuras) - MathFunctions.AddPct(ref addvalue, eff.GetAmount()); - - addvalue += (uint)GetTotalAuraModifier(AuraType.ModRegen) * SharedConst.CreatureRegenInterval / (5 * Time.InMilliseconds); + addvalue *= (int)GetTotalAuraMultiplier(AuraType.ModHealthRegenPercent); + addvalue += GetTotalAuraModifier(AuraType.ModRegen) * SharedConst.CreatureRegenInterval / (5 * Time.InMilliseconds); ModifyHealth(addvalue); } @@ -628,11 +621,7 @@ namespace Game.Entities } // Apply modifiers (if any). - var ModPowerRegenPCTAuras = GetAuraEffectsByType(AuraType.ModPowerRegenPercent); - foreach (var i in ModPowerRegenPCTAuras) - if ((PowerType)i.GetMiscValue() == power) - MathFunctions.AddPct(ref addvalue, i.GetAmount()); - + addvalue *= GetTotalAuraMultiplierByMiscValue(AuraType.ModPowerRegenPercent, (int)power); addvalue += GetTotalAuraModifierByMiscValue(AuraType.ModPowerRegen, (int)power) * (IsHunterPet() ? SharedConst.PetFocusRegenInterval : SharedConst.CreatureRegenInterval) / (5 * Time.InMilliseconds); ModifyPower(power, (int)addvalue); diff --git a/Source/Game/Entities/Player/Player.cs b/Source/Game/Entities/Player/Player.cs index b2f970fc4..31ac73716 100644 --- a/Source/Game/Entities/Player/Player.cs +++ b/Source/Game/Entities/Player/Player.cs @@ -3789,11 +3789,7 @@ namespace Game.Entities // Mana regen calculated in Player.UpdateManaRegen() if (power != PowerType.Mana) { - var ModPowerRegenPCTAuras = GetAuraEffectsByType(AuraType.ModPowerRegenPercent); - foreach (var eff in ModPowerRegenPCTAuras) - if ((PowerType)eff.GetMiscValue() == power) - MathFunctions.AddPct(ref addvalue, eff.GetAmount()); - + addvalue *= GetTotalAuraMultiplierByMiscValue(AuraType.ModPowerRegenPercent, (int)power); addvalue += GetTotalAuraModifierByMiscValue(AuraType.ModPowerRegen, (int)power) * ((power != PowerType.Energy) ? m_regenTimerCount : m_regenTimer) / (5 * Time.InMilliseconds); } @@ -3873,43 +3869,40 @@ namespace Game.Entities return; float HealthIncreaseRate = WorldConfig.GetFloatValue(WorldCfg.RateHealth); - float addvalue = 0.0f; + float addValue = 0.0f; // polymorphed case if (IsPolymorphed()) - addvalue = (float)GetMaxHealth() / 3; + addValue = (float)GetMaxHealth() / 3; // normal regen case (maybe partly in combat case) else if (!IsInCombat() || HasAuraType(AuraType.ModRegenDuringCombat)) { - addvalue = HealthIncreaseRate; + addValue = HealthIncreaseRate; if (!IsInCombat()) { if (getLevel() < 15) - addvalue = (0.20f * (GetMaxHealth()) / getLevel() * HealthIncreaseRate); + addValue = (0.20f * (GetMaxHealth()) / getLevel() * HealthIncreaseRate); else - addvalue = 0.015f * (GetMaxHealth()) * HealthIncreaseRate; + addValue = 0.015f * (GetMaxHealth()) * HealthIncreaseRate; - var mModHealthRegenPct = GetAuraEffectsByType(AuraType.ModHealthRegenPercent); - foreach (var eff in mModHealthRegenPct) - MathFunctions.AddPct(ref addvalue, eff.GetAmount()); - - addvalue += GetTotalAuraModifier(AuraType.ModRegen) * 2 * Time.InMilliseconds / (5 * Time.InMilliseconds); + addValue *= GetTotalAuraMultiplier(AuraType.ModHealthRegenPercent); + addValue += GetTotalAuraModifier(AuraType.ModRegen) * 2 * Time.InMilliseconds / (5 * Time.InMilliseconds); } else if (HasAuraType(AuraType.ModRegenDuringCombat)) - MathFunctions.ApplyPct(ref addvalue, GetTotalAuraModifier(AuraType.ModRegenDuringCombat)); + MathFunctions.ApplyPct(ref addValue, GetTotalAuraModifier(AuraType.ModRegenDuringCombat)); if (!IsStandState()) - addvalue *= 1.5f; + addValue *= 1.5f; } // always regeneration bonus (including combat) - addvalue += GetTotalAuraModifier(AuraType.ModHealthRegenInCombat); - addvalue += m_baseHealthRegen / 2.5f; + addValue += GetTotalAuraModifier(AuraType.ModHealthRegenInCombat); + addValue += m_baseHealthRegen / 2.5f; - if (addvalue < 0) - addvalue = 0; + if (addValue < 0) + addValue = 0; - ModifyHealth((int)addvalue); + ModifyHealth((int)addValue); } public void ResetAllPowers() { @@ -4421,9 +4414,7 @@ namespace Game.Entities if (!IsAlive() || HasAuraType(AuraType.WaterBreathing) || GetSession().GetSecurity() >= (AccountTypes)WorldConfig.GetIntValue(WorldCfg.DisableBreathing)) return -1; int UnderWaterTime = 3 * Time.Minute * Time.InMilliseconds; - var mModWaterBreathing = GetAuraEffectsByType(AuraType.WaterBreathing); - foreach (var eff in mModWaterBreathing) - MathFunctions.AddPct(ref UnderWaterTime, eff.GetAmount()); + UnderWaterTime *= (int)GetTotalAuraMultiplier(AuraType.ModWaterBreathing); return UnderWaterTime; } case MirrorTimerType.Fire: diff --git a/Source/Game/Entities/StatSystem.cs b/Source/Game/Entities/StatSystem.cs index b443b0c06..ec0896447 100644 --- a/Source/Game/Entities/StatSystem.cs +++ b/Source/Game/Entities/StatSystem.cs @@ -660,14 +660,13 @@ namespace Game.Entities else chance += victim.GetTotalAuraModifier(AuraType.ModAttackerMeleeCritChance); - var critChanceForCaster = victim.GetAuraEffectsByType(AuraType.ModCritChanceForCaster); - foreach (AuraEffect aurEff in critChanceForCaster) + chance += victim.GetTotalAuraModifier(AuraType.ModCritChanceForCaster, aurEff => { - if (aurEff.GetCasterGUID() != GetGUID()) - continue; + if (aurEff.GetCasterGUID() == GetGUID()) + return true; - chance += aurEff.GetAmount(); - } + return false; + }); chance += victim.GetTotalAuraModifier(AuraType.ModAttackerSpellAndWeaponCritChance); @@ -1195,14 +1194,14 @@ namespace Game.Entities // Apply bonus from SPELL_AURA_MOD_RATING_FROM_STAT // stat used stored in miscValueB for this aura var modRatingFromStat = GetAuraEffectsByType(AuraType.ModRatingFromStat); - foreach (var i in modRatingFromStat) - if (Convert.ToBoolean(i.GetMiscValue() & (1 << (int)cr))) - amount += (int)MathFunctions.CalculatePct(GetStat((Stats)i.GetMiscValueB()), i.GetAmount()); + foreach (var aurEff in modRatingFromStat) + if (Convert.ToBoolean(aurEff.GetMiscValue() & (1 << (int)cr))) + amount += (int)MathFunctions.CalculatePct(GetStat((Stats)aurEff.GetMiscValueB()), aurEff.GetAmount()); var modRatingPct = GetAuraEffectsByType(AuraType.ModRatingPct); - foreach (var i in modRatingPct) - if (Convert.ToBoolean(i.GetMiscValue() & (1 << (int)cr))) - amount += MathFunctions.CalculatePct(amount, i.GetAmount()); + foreach (var aurEff in modRatingPct) + if (Convert.ToBoolean(aurEff.GetMiscValue() & (1 << (int)cr))) + amount += MathFunctions.CalculatePct(amount, aurEff.GetAmount()); if (amount < 0) amount = 0; @@ -1478,16 +1477,17 @@ namespace Game.Entities Item weapon = GetWeaponForAttack(attack, true); - var expAuras = GetAuraEffectsByType(AuraType.ModExpertise); - foreach (var eff in expAuras) + expertise += GetTotalAuraModifier(AuraType.ModExpertise, aurEff => { // item neutral spell - if ((int)eff.GetSpellInfo().EquippedItemClass == -1) - expertise += eff.GetAmount(); + if ((int)aurEff.GetSpellInfo().EquippedItemClass == -1) + return true; // item dependent spell - else if (weapon != null && weapon.IsFitToSpellRequirements(eff.GetSpellInfo())) - expertise += eff.GetAmount(); - } + else if (weapon != null && weapon.IsFitToSpellRequirements(aurEff.GetSpellInfo())) + return true; + + return false; + }); if (expertise < 0) expertise = 0; diff --git a/Source/Game/Entities/Unit/Unit.Combat.cs b/Source/Game/Entities/Unit/Unit.Combat.cs index 08eac1486..466fb3b46 100644 --- a/Source/Game/Entities/Unit/Unit.Combat.cs +++ b/Source/Game/Entities/Unit/Unit.Combat.cs @@ -2268,13 +2268,7 @@ namespace Game.Entities if (victimResistance > 0) { - int ignoredResistance = 0; - - var ResIgnoreAuras = GetAuraEffectsByType(AuraType.ModIgnoreTargetResist); - foreach (var eff in ResIgnoreAuras) - if (Convert.ToBoolean(eff.GetMiscValue() & (int)schoolMask)) - ignoredResistance += eff.GetAmount(); - + int ignoredResistance = GetTotalAuraModifierByMiscMask(AuraType.ModIgnoreTargetResist, (int)schoolMask); ignoredResistance = Math.Min(ignoredResistance, 100); MathFunctions.ApplyPct(ref victimResistance, 100 - ignoredResistance); } @@ -2320,18 +2314,16 @@ namespace Game.Entities // Ignore Absorption Auras float auraAbsorbMod = GetMaxPositiveAuraModifierByMiscMask(AuraType.ModTargetAbsorbSchool, (uint)damageInfo.GetSchoolMask()); - var abilityAbsorbAuras = GetAuraEffectsByType(AuraType.ModTargetAbilityAbsorbSchool); - foreach (AuraEffect aurEff in abilityAbsorbAuras) + auraAbsorbMod = Math.Max(auraAbsorbMod, (float)GetMaxPositiveAuraModifier(AuraType.ModTargetAbilityAbsorbSchool, aurEff => { if (!Convert.ToBoolean(aurEff.GetMiscValue() & (int)damageInfo.GetSchoolMask())) - continue; + return false; if (!aurEff.IsAffectingSpell(damageInfo.GetSpellInfo())) - continue; + return false; - if ((aurEff.GetAmount() > auraAbsorbMod)) - auraAbsorbMod = aurEff.GetAmount(); - } + return true; + })); MathFunctions.RoundToInterval(ref auraAbsorbMod, 0.0f, 100.0f); @@ -2596,7 +2588,7 @@ namespace Game.Entities var resIgnoreAuras = GetAuraEffectsByType(AuraType.ModIgnoreTargetResist); foreach (var eff in resIgnoreAuras) { - if (eff.GetMiscValue().HasAnyFlag((int)SpellSchoolMask.Normal)) + if (eff.GetMiscValue().HasAnyFlag((int)SpellSchoolMask.Normal) && eff.IsAffectingSpell(spellInfo)) armor = (float)Math.Floor(MathFunctions.AddPct(ref armor, -eff.GetAmount())); } @@ -2643,10 +2635,7 @@ namespace Game.Entities int DoneFlatBenefit = 0; // ..done - var mDamageDoneCreature = GetAuraEffectsByType(AuraType.ModDamageDoneCreature); - foreach (var eff in mDamageDoneCreature) - if (Convert.ToBoolean(creatureTypeMask & eff.GetMiscValue())) - DoneFlatBenefit += eff.GetAmount(); + DoneFlatBenefit += GetTotalAuraModifierByMiscMask(AuraType.ModDamageDoneCreature, (int)creatureTypeMask); // ..done // SPELL_AURA_MOD_DAMAGE_DONE included in weapon damage @@ -2659,20 +2648,14 @@ namespace Game.Entities APbonus += victim.GetTotalAuraModifier(AuraType.RangedAttackPowerAttackerBonus); // ..done (base at attack power and creature type) - var mCreatureAttackPower = GetAuraEffectsByType(AuraType.ModRangedAttackPowerVersus); - foreach (var eff in mCreatureAttackPower) - if (Convert.ToBoolean(creatureTypeMask & eff.GetMiscValue())) - APbonus += eff.GetAmount(); + APbonus += GetTotalAuraModifierByMiscMask(AuraType.ModRangedAttackPowerVersus, (int)creatureTypeMask); } else { APbonus += victim.GetTotalAuraModifier(AuraType.MeleeAttackPowerAttackerBonus); // ..done (base at attack power and creature type) - var mCreatureAttackPower = GetAuraEffectsByType(AuraType.ModMeleeAttackPowerVersus); - foreach (var eff in mCreatureAttackPower) - if (Convert.ToBoolean(creatureTypeMask & eff.GetMiscValue())) - APbonus += eff.GetAmount(); + APbonus += GetTotalAuraModifierByMiscMask(AuraType.ModMeleeAttackPowerVersus, (int)creatureTypeMask); } if (APbonus != 0) // Can be negative @@ -2701,16 +2684,15 @@ namespace Game.Entities } } - var mDamageDoneVersus = GetAuraEffectsByType(AuraType.ModDamageDoneVersus); - foreach (var eff in mDamageDoneVersus) - if (Convert.ToBoolean(creatureTypeMask & eff.GetMiscValue())) - MathFunctions.AddPct(ref DoneTotalMod, eff.GetAmount()); + DoneTotalMod *= GetTotalAuraMultiplierByMiscMask(AuraType.ModDamageDoneVersus, (uint)creatureTypeMask); // bonus against aurastate - var mDamageDoneVersusAurastate = GetAuraEffectsByType(AuraType.ModDamageDoneVersusAurastate); - foreach (var eff in mDamageDoneVersusAurastate) - if (victim.HasAuraState((AuraStateType)eff.GetMiscValue())) - MathFunctions.AddPct(ref DoneTotalMod, eff.GetAmount()); + DoneTotalMod *= GetTotalAuraMultiplier(AuraType.ModDamageDoneVersusAurastate, aurEff => + { + if (victim.HasAuraState((AuraStateType)aurEff.GetMiscValue())) + return true; + return false; + }); // Add SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC percent bonus if (spellProto != null) @@ -2739,18 +2721,10 @@ namespace Game.Entities // get all auras from caster that allow the spell to ignore resistance (sanctified wrath) int attackSchoolMask = (int)(spellProto != null ? spellProto.GetSchoolMask() : SpellSchoolMask.Normal); - var IgnoreResistAuras = attacker.GetAuraEffectsByType(AuraType.ModIgnoreTargetResist); - foreach (var eff in IgnoreResistAuras) - { - if (eff.GetMiscValue().HasAnyFlag(attackSchoolMask)) - TakenTotalCasterMod += eff.GetAmount(); - } + TakenTotalCasterMod += attacker.GetTotalAuraModifierByMiscMask(AuraType.ModIgnoreTargetResist, attackSchoolMask); // ..taken - var mDamageTaken = GetAuraEffectsByType(AuraType.ModDamageTaken); - foreach (var eff in mDamageTaken) - if (Convert.ToBoolean(eff.GetMiscValue() & (int)attacker.GetMeleeDamageSchoolMask())) - TakenFlatBenefit += eff.GetAmount(); + TakenFlatBenefit += GetTotalAuraModifierByMiscMask(AuraType.ModDamageTaken, (int)attacker.GetMeleeDamageSchoolMask()); if (attType != WeaponAttackType.RangedAttack) TakenFlatBenefit += GetTotalAuraModifier(AuraType.ModMeleeDamageTaken); @@ -2767,10 +2741,12 @@ namespace Game.Entities if (spellProto != null) { // From caster spells - var mOwnerTaken = GetAuraEffectsByType(AuraType.ModSpellDamageFromCaster); - foreach (var eff in mOwnerTaken) - if (eff.GetCasterGUID() == attacker.GetGUID() && eff.IsAffectingSpell(spellProto)) - MathFunctions.AddPct(ref TakenTotalMod, eff.GetAmount()); + TakenTotalMod *= GetTotalAuraMultiplier(AuraType.ModSpellDamageFromCaster, aurEff => + { + if (aurEff.GetCasterGUID() == attacker.GetGUID() && aurEff.IsAffectingSpell(spellProto)) + return true; + return false; + }); // Mod damage from spell mechanic uint mechanicMask = spellProto.GetAllEffectsMechanicMask(); @@ -2781,10 +2757,12 @@ namespace Game.Entities if (mechanicMask != 0) { - var mDamageDoneMechanic = GetAuraEffectsByType(AuraType.ModMechanicDamageTakenPercent); - foreach (var eff in mDamageDoneMechanic) - if (mechanicMask.HasAnyFlag((uint)(1 << eff.GetMiscValue()))) - MathFunctions.AddPct(ref TakenTotalMod, eff.GetAmount()); + TakenTotalMod *= GetTotalAuraMultiplier(AuraType.ModMechanicDamageTakenPercent, aurEff => + { + if ((mechanicMask & (1 << (aurEff.GetMiscValue()))) != 0) + return true; + return false; + }); } } @@ -2793,17 +2771,9 @@ namespace Game.Entities MathFunctions.AddPct(ref TakenTotalMod, cheatDeath.GetAmount()); if (attType != WeaponAttackType.RangedAttack) - { - var mModMeleeDamageTakenPercent = GetAuraEffectsByType(AuraType.ModMeleeDamageTakenPct); - foreach (var eff in mModMeleeDamageTakenPercent) - MathFunctions.AddPct(ref TakenTotalMod, eff.GetAmount()); - } + TakenTotalMod *= GetTotalAuraMultiplier(AuraType.ModMeleeDamageTakenPct); else - { - var mModRangedDamageTakenPercent = GetAuraEffectsByType(AuraType.ModRangedDamageTakenPct); - foreach (var eff in mModRangedDamageTakenPercent) - MathFunctions.AddPct(ref TakenTotalMod, eff.GetAmount()); - } + TakenTotalMod *= GetTotalAuraMultiplier(AuraType.ModRangedDamageTakenPct); float tmpDamage = 0.0f; diff --git a/Source/Game/Entities/Unit/Unit.Spells.cs b/Source/Game/Entities/Unit/Unit.Spells.cs index 55dc3dcc1..616f85032 100644 --- a/Source/Game/Entities/Unit/Unit.Spells.cs +++ b/Source/Game/Entities/Unit/Unit.Spells.cs @@ -53,14 +53,7 @@ namespace Game.Entities return (int)(MathFunctions.CalculatePct(GetTotalAttackPowerValue(WeaponAttackType.BaseAttack), overrideSP) + 0.5f); } - int DoneAdvertisedBenefit = 0; - - var mDamageDone = GetAuraEffectsByType(AuraType.ModDamageDone); - foreach (var eff in mDamageDone) - { - if ((eff.GetMiscValue() & (int)schoolMask) != 0) - DoneAdvertisedBenefit += eff.GetAmount(); - } + int DoneAdvertisedBenefit = GetTotalAuraModifierByMiscMask(AuraType.ModDamageDone, (int)schoolMask); if (IsTypeId(TypeId.Player)) { @@ -91,14 +84,7 @@ namespace Game.Entities public int SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) { - int TakenAdvertisedBenefit = 0; - - var mDamageTaken = GetAuraEffectsByType(AuraType.ModDamageTaken); - foreach (var eff in mDamageTaken) - if ((eff.GetMiscValue() & (int)schoolMask) != 0) - TakenAdvertisedBenefit += eff.GetAmount(); - - return TakenAdvertisedBenefit; + return GetTotalAuraModifierByMiscMask(AuraType.ModDamageTaken, (int)schoolMask); } public uint SpellDamageBonusDone(Unit victim, SpellInfo spellProto, uint pdamage, DamageEffectType damagetype, SpellEffectInfo effect, uint stack = 1) @@ -210,20 +196,15 @@ namespace Game.Entities uint creatureTypeMask = victim.GetCreatureTypeMask(); - var mDamageDoneVersus = GetAuraEffectsByType(AuraType.ModDamageDoneVersus); - foreach (var eff in mDamageDoneVersus) - { - if (creatureTypeMask.HasAnyFlag((uint)eff.GetMiscValue())) - MathFunctions.AddPct(ref DoneTotalMod, eff.GetAmount()); - } + DoneTotalMod *= GetTotalAuraMultiplierByMiscMask(AuraType.ModDamageDoneVersus, creatureTypeMask); // bonus against aurastate - var mDamageDoneVersusAurastate = GetAuraEffectsByType(AuraType.ModDamageDoneVersusAurastate); - foreach (var eff in mDamageDoneVersusAurastate) + DoneTotalMod *= GetTotalAuraMultiplier(AuraType.ModDamageDoneVersusAurastate, aurEff => { - if (victim.HasAuraState((AuraStateType)eff.GetMiscValue())) - MathFunctions.AddPct(ref DoneTotalMod, eff.GetAmount()); - } + if (victim.HasAuraState((AuraStateType)aurEff.GetMiscValue())) + return true; + return false; + }); // Add SPELL_AURA_MOD_DAMAGE_DONE_FOR_MECHANIC percent bonus MathFunctions.AddPct(ref DoneTotalMod, GetTotalAuraModifierByMiscValue(AuraType.ModDamageDoneForMechanic, (int)spellProto.Mechanic)); @@ -270,10 +251,12 @@ namespace Game.Entities uint mechanicMask = spellProto.GetAllEffectsMechanicMask(); if (mechanicMask != 0) { - var mDamageDoneMechanic = GetAuraEffectsByType(AuraType.ModMechanicDamageTakenPercent); - foreach (var eff in mDamageDoneMechanic) - if (Convert.ToBoolean(mechanicMask & (1 << eff.GetMiscValue()))) - MathFunctions.AddPct(ref TakenTotalMod, eff.GetAmount()); + TakenTotalMod *= GetTotalAuraMultiplier(AuraType.ModMechanicDamageTakenPercent, aurEff => + { + if ((mechanicMask & (1 << aurEff.GetMiscValue())) != 0) + return true; + return false; + }); } AuraEffect cheatDeath = GetAuraEffect(45182, 0); @@ -285,22 +268,19 @@ namespace Game.Entities if (!spellProto.HasAttribute(SpellAttr4.FixedDamage)) { // get all auras from caster that allow the spell to ignore resistance (sanctified wrath) - var IgnoreResistAuras = caster.GetAuraEffectsByType(AuraType.ModIgnoreTargetResist); - foreach (var eff in IgnoreResistAuras) - { - if (Convert.ToBoolean(eff.GetMiscValue() & (int)spellProto.GetSchoolMask())) - TakenTotalCasterMod += eff.GetAmount(); - } + TakenTotalCasterMod += GetTotalAuraModifierByMiscMask(AuraType.ModIgnoreTargetResist, (int)spellProto.GetSchoolMask()); // from positive and negative SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN // multiplicative bonus, for example Dispersion + Shadowform (0.10*0.85=0.085) TakenTotalMod *= GetTotalAuraMultiplierByMiscMask(AuraType.ModDamagePercentTaken, (uint)spellProto.GetSchoolMask()); // From caster spells - var mOwnerTaken = GetAuraEffectsByType(AuraType.ModSpellDamageFromCaster); - foreach (var eff in mOwnerTaken) - if (eff.GetCasterGUID() == caster.GetGUID() && eff.IsAffectingSpell(spellProto)) - MathFunctions.AddPct(ref TakenTotalMod, eff.GetAmount()); + TakenTotalMod *= GetTotalAuraMultiplier(AuraType.ModSpellDamageFromCaster, aurEff => + { + if (aurEff.GetCasterGUID() == caster.GetGUID() && aurEff.IsAffectingSpell(spellProto)) + return true; + return false; + }); int TakenAdvertisedBenefit = SpellBaseDamageBonusTaken(spellProto.GetSchoolMask()); @@ -351,12 +331,12 @@ namespace Game.Entities return (uint)(MathFunctions.CalculatePct(GetTotalAttackPowerValue(WeaponAttackType.BaseAttack), overrideSP) + 0.5f); } - uint advertisedBenefit = 0; - - var mHealingDone = GetAuraEffectsByType(AuraType.ModHealingDone); - foreach (var i in mHealingDone) - if (i.GetMiscValue() == 0 || (i.GetMiscValue() & (int)schoolMask) != 0) - advertisedBenefit += (uint)i.GetAmount(); + uint advertisedBenefit = (uint)GetTotalAuraModifier(AuraType.ModHealingDone, aurEff => + { + if (aurEff.GetMiscValue() == 0 || (aurEff.GetMiscValue() & (int)schoolMask) != 0) + return true; + return false; + }); // Healing bonus of spirit, intellect and strength if (IsTypeId(TypeId.Player)) @@ -388,14 +368,7 @@ namespace Game.Entities int SpellBaseHealingBonusTaken(SpellSchoolMask schoolMask) { - int advertisedBenefit = 0; - - var mDamageTaken = GetAuraEffectsByType(AuraType.ModHealing); - foreach (var i in mDamageTaken) - if ((i.GetMiscValue() & (int)schoolMask) != 0) - advertisedBenefit += i.GetAmount(); - - return advertisedBenefit; + return GetTotalAuraModifierByMiscMask(AuraType.ModHealing, (int)schoolMask); } public int SpellCriticalHealingBonus(SpellInfo spellProto, int damage, Unit victim) @@ -520,9 +493,7 @@ namespace Game.Entities float DoneTotalMod = 1.0f; // Healing done percent - var mHealingDonePct = GetAuraEffectsByType(AuraType.ModHealingDonePercent); - foreach (var eff in mHealingDonePct) - MathFunctions.AddPct(ref DoneTotalMod, eff.GetAmount()); + DoneTotalMod *= GetTotalAuraMultiplier(AuraType.ModHealingDonePercent); return DoneTotalMod; } @@ -586,10 +557,12 @@ namespace Game.Entities TakenTotal += (int)(TakenAdvertisedBenefit * coeff * stack); } - var mHealingGet = GetAuraEffectsByType(AuraType.ModHealingReceived); - foreach (var eff in mHealingGet) - if (caster.GetGUID() == eff.GetCasterGUID() && eff.IsAffectingSpell(spellProto)) - MathFunctions.AddPct(ref TakenTotalMod, eff.GetAmount()); + TakenTotalMod *= GetTotalAuraMultiplier(AuraType.ModHealingReceived, aurEff => + { + if (caster.GetGUID() == aurEff.GetCasterGUID() && aurEff.IsAffectingSpell(spellProto)) + return true; + return false; + }); foreach (SpellEffectInfo eff in spellProto.GetEffectsForDifficulty(GetMap().GetDifficultyID())) { @@ -731,10 +704,16 @@ namespace Game.Entities if (modOwner != null) modOwner.ApplySpellMod(spellProto.Id, SpellModOp.CriticalChance, ref crit_chance); - var critChanceForCaster = victim.GetAuraEffectsByType(AuraType.ModCritChanceForCaster); - foreach (AuraEffect aurEff in critChanceForCaster) - if (aurEff.GetCasterGUID() == GetGUID() && aurEff.IsAffectingSpell(spellProto)) - crit_chance += aurEff.GetAmount(); + // for this types the bonus was already added in GetUnitCriticalChance, do not add twice + if (spellProto.DmgClass != SpellDmgClass.Melee && spellProto.DmgClass != SpellDmgClass.Ranged) + { + crit_chance += victim.GetTotalAuraModifier(AuraType.ModCritChanceForCaster, aurEff => + { + if (aurEff.GetCasterGUID() == GetGUID() && aurEff.IsAffectingSpell(spellProto)) + return true; + return false; + }); + } return Math.Max(crit_chance, 0.0f); } @@ -778,10 +757,7 @@ namespace Game.Entities if (canReflect) { int reflectchance = victim.GetTotalAuraModifier(AuraType.ReflectSpells); - var mReflectSpellsSchool = victim.GetAuraEffectsByType(AuraType.ReflectSpellsSchool); - foreach (var eff in mReflectSpellsSchool) - if (Convert.ToBoolean(eff.GetMiscValue() & (int)spellInfo.GetSchoolMask())) - reflectchance += eff.GetAmount(); + reflectchance += victim.GetTotalAuraModifierByMiscMask(AuraType.ReflectSpellsSchool, (int)spellInfo.GetSchoolMask()); if (reflectchance > 0 && RandomHelper.randChance(reflectchance)) return SpellMissInfo.Reflect; @@ -3765,24 +3741,23 @@ namespace Game.Entities } } } - public bool HasAuraState(AuraStateType flag, SpellInfo spellProto = null, Unit Caster = null) + public bool HasAuraState(AuraStateType flag, SpellInfo spellProto = null, Unit caster = null) { - if (Caster != null) + if (caster != null) { if (spellProto != null) { - var stateAuras = Caster.GetAuraEffectsByType(AuraType.AbilityIgnoreAurastate); - foreach (var aura in stateAuras) - if (aura.IsAffectingSpell(spellProto)) - return true; + if (caster.HasAuraTypeWithAffectMask(AuraType.AbilityIgnoreAurastate, spellProto)) + return true; } + // Check per caster aura state // If aura with aurastate by caster not found return false if (Convert.ToBoolean((1 << (int)flag) & (int)AuraStateType.PerCasterAuraStateMask)) { var range = m_auraStateAuras.LookupByKey(flag); foreach (var auraApp in range) - if (auraApp.GetBase().GetCasterGUID() == Caster.GetGUID()) + if (auraApp.GetBase().GetCasterGUID() == caster.GetGUID()) return true; return false; } diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index 3efb673a7..302bc9fcd 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -4509,10 +4509,8 @@ namespace Game.Spells } } - var blockSpells = m_caster.GetAuraEffectsByType(AuraType.BlockSpellFamily); - foreach (var block in blockSpells) - if (block.GetMiscValue() == (int)m_spellInfo.SpellFamilyName) - return SpellCastResult.SpellUnavailable; + if (m_caster.HasAuraTypeWithMiscvalue(AuraType.BlockSpellFamily, (int)m_spellInfo.SpellFamilyName)) + return SpellCastResult.SpellUnavailable; bool reqCombat = true; var stateAuras = m_caster.GetAuraEffectsByType(AuraType.AbilityIgnoreAurastate);