diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 9c5669ddb4..fe01306eea 100755 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -2711,7 +2711,7 @@ c["50% of Chaos damage you prevent when Hit Recouped as Life and Mana during eff c["50% of Cold and Lightning Damage taken as Fire Damage"]={{[1]={flags=0,keywordFlags=0,name="ColdDamageTakenAsFire",type="BASE",value=50},[2]={flags=0,keywordFlags=0,name="LightningDamageTakenAsFire",type="BASE",value=50}},nil} c["50% of Damage taken Recouped as Mana"]={{[1]={flags=0,keywordFlags=0,name="ManaRecoup",type="BASE",value=50}},nil} c["50% of Elemental Damage taken as Chaos Damage"]={{[1]={flags=0,keywordFlags=0,name="ElementalDamageTakenAsChaos",type="BASE",value=50}},nil} -c["50% of Evasion Rating also grants Elemental Damage reduction"]={{[1]={flags=0,keywordFlags=0,name="Evasion",type="BASE",value=50}}," also grants Elemental Damage reduction "} +c["50% of Evasion Rating also grants Elemental Damage reduction"]={{[1]={flags=0,keywordFlags=0,name="EvasionAppliesToFireDamageTaken",type="BASE",value=50},[2]={flags=0,keywordFlags=0,name="EvasionAppliesToColdDamageTaken",type="BASE",value=50},[3]={flags=0,keywordFlags=0,name="EvasionAppliesToLightningDamageTaken",type="BASE",value=50}},nil} c["50% of Maximum Life Converted to Energy Shield"]={{[1]={flags=0,keywordFlags=0,name="LifeConvertToEnergyShield",type="BASE",value=50}},nil} c["50% of Physical Damage prevented Recouped as Life"]={{[1]={flags=0,keywordFlags=0,name="PhysicalDamage",type="BASE",value=50}}," prevented Recouped as Life "} c["50% of Skill Mana costs Converted to Life Costs during any Life Flask Effect"]={{[1]={flags=0,keywordFlags=0,name="ManaCost",type="BASE",value=50}}," Skill s Converted to Life Costs during any Life Flask Effect "} @@ -5099,7 +5099,7 @@ c["Passives in radius of Whispers of Doom can be Allocated without being connect c["Passives in radius of Zealot's Oath can be Allocated without being connected to your tree"]={{[1]={flags=0,keywordFlags=0,name="JewelData",type="LIST",value={key="fromNothingKeystone",value="zealot's oath"}},[2]={flags=0,keywordFlags=0,name="FromNothingKeystones",type="LIST",value={key="zealot's oath",value=true}}},nil} c["Permanently Intimidate enemies on Block"]={{[1]={[1]={type="Condition",var="BlockedRecently"},flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={flags=0,keywordFlags=0,name="Condition:Intimidated",type="FLAG",value=true}}}},nil} c["Persistent Buffs have 50% less Reservation"]={{[1]={[1]={skillType=139,type="SkillType"},[2]={skillType=5,type="SkillType"},flags=0,keywordFlags=0,name="Reserved",type="MORE",value=-50}},nil} -c["Physical Damage Reduction from Armour is based on your combined Armour and Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="EvasionAddsToPdr",type="FLAG",value=true}},nil} +c["Physical Damage Reduction from Armour is based on your combined Armour and Evasion Rating"]={{[1]={flags=0,keywordFlags=0,name="EvasionAppliesToPhysicalDamageTaken",type="BASE",value=100}},nil} c["Physical Damage is Pinning"]={nil,"Physical Damage is Pinning "} c["Physical Spell Critical Hits build Pin"]={nil,"Physical Spell Critical Hits build Pin "} c["Physical damage based on their Skill Level"]={nil,"Physical damage based on their Skill Level "} diff --git a/src/Modules/CalcDefence.lua b/src/Modules/CalcDefence.lua index 55ec997eae..2ad65dc87b 100644 --- a/src/Modules/CalcDefence.lua +++ b/src/Modules/CalcDefence.lua @@ -367,9 +367,12 @@ function calcs.applyDmgTakenConversion(activeSkill, output, breakdown, sourceTyp local reductMult = 1 local percentOfArmourApplies = (not activeSkill.skillModList:Flag(nil, "ArmourDoesNotApplyTo"..damageType.."DamageTaken") and activeSkill.skillModList:Sum("BASE", nil, "ArmourAppliesTo"..damageType.."DamageTaken") or 0) - if percentOfArmourApplies > 0 then - local effArmour = (output.Armour * percentOfArmourApplies / 100) * (1 + output.ArmourDefense) - -- effArmour needs to consider the "EvasionAddsToPdr" flag mod, and add the evasion to armour + local percentOfEvasionApplies = (not activeSkill.skillModList:Flag(nil, "EvasionDoesNotApplyTo"..damageType.."DamageTaken") and activeSkill.skillModList:Sum("BASE", nil, "EvasionAppliesTo"..damageType.."DamageTaken") or 0) + if (percentOfArmourApplies > 0) or (percentOfEvasionApplies > 0) then + local effArmourFromArmour = (output.Armour * percentOfArmourApplies / 100) * (1 + output.ArmourDefense) + local effArmourFromEvasion = (output.Evasion * percentOfEvasionApplies / 100) + local effArmour = effArmourFromArmour + effArmourFromEvasion + armourReduct = round(effArmour ~= 0 and damage ~= 0 and calcs.armourReductionF(effArmour, damage) or 0) armourReduct = m_min(output[damageType.."DamageReductionMax"], armourReduct) end @@ -2259,9 +2262,9 @@ function calcs.buildDefenceEstimations(env, actor) local effectiveAppliedArmour = (output.Armour * percentOfArmourApplies / 100) * (1 + output.ArmourDefense) local effectiveArmourFromArmour = effectiveAppliedArmour; local effectiveArmourFromOther = { } - local evasionAddsToPdr = modDB:Flag(nil, "EvasionAddsToPdr") and damageType == "Physical" - if evasionAddsToPdr then - effectiveArmourFromOther["Evasion"] = output.Evasion + local percentOfEvasionApplies = (not modDB:Flag(nil, "EvasionDoesNotApplyTo"..damageType.."DamageTaken") and modDB:Sum("BASE", nil, "EvasionAppliesTo"..damageType.."DamageTaken") or 0) + if percentOfEvasionApplies > 0 then + effectiveArmourFromOther["Evasion"] = m_max((output.Evasion * percentOfEvasionApplies / 100), 0) end for source, amount in pairs(effectiveArmourFromOther) do -- should this be done BEFORE percentOfArmourApplies and ArmourDefense is used? Probably needs GGG confirmation @@ -2279,7 +2282,7 @@ function calcs.buildDefenceEstimations(env, actor) takenFlat = takenFlat + modDB:Sum("BASE", nil, "DamageTakenFromAttacks", damageType.."DamageTakenFromAttacks") / 2 + modDB:Sum("BASE", nil, damageType.."DamageTakenFromProjectileAttacks") / 4 + modDB:Sum("BASE", nil, "DamageTakenFromSpells", damageType.."DamageTakenFromSpells") / 2 + modDB:Sum("BASE", nil, "DamageTakenFromSpellProjectiles", damageType.."DamageTakenFromSpellProjectiles") / 4 end output[damageType.."takenFlat"] = takenFlat - if percentOfArmourApplies > 0 then + if effectiveAppliedArmour > 0 then armourReduct = calcs.armourReduction(effectiveAppliedArmour, damage) armourReduct = m_min(output[damageType.."DamageReductionMax"], armourReduct) if impaleDamage > 0 then @@ -2296,18 +2299,19 @@ function calcs.buildDefenceEstimations(env, actor) if breakdown then breakdown[damageType.."DamageReduction"] = { } if armourReduct ~= 0 then - if percentOfArmourApplies ~= 100 then - t_insert(breakdown[damageType.."DamageReduction"], s_format("%d%% percent of armour applies", percentOfArmourApplies)) + if (percentOfArmourApplies ~= (damageType == "Physical" and 100 or 0)) and (percentOfArmourApplies > 0) then + t_insert(breakdown[damageType.."DamageReduction"], s_format("%d%% percent of Armour applies", percentOfArmourApplies)) end if effectiveArmourFromArmour == effectiveAppliedArmour then t_insert(breakdown[damageType.."DamageReduction"], s_format("Reduction from Armour: %d%%", armourReduct)) else t_insert(breakdown[damageType.."DamageReduction"], s_format("Armour contributing to reduction: %d", effectiveArmourFromArmour)) for source, amount in pairs(effectiveArmourFromOther) do + t_insert(breakdown[damageType.."DamageReduction"], s_format("%d%% percent of %s applies", percentOfEvasionApplies, source)) t_insert(breakdown[damageType.."DamageReduction"], s_format("%s contributing to reduction: %d",source, amount)) end - t_insert(breakdown[damageType.."DamageReduction"], s_format("Combined Armour used for reduction: %d", effectiveAppliedArmour)) - t_insert(breakdown[damageType.."DamageReduction"], s_format("Reduction from combined Armour: %d%%", armourReduct)) + t_insert(breakdown[damageType.."DamageReduction"], s_format("Combined Defence used for reduction: %d", effectiveAppliedArmour)) + t_insert(breakdown[damageType.."DamageReduction"], s_format("Reduction from combined Defence: %d%%", armourReduct)) end if resMult ~= 1 then t_insert(breakdown[damageType.."DamageReduction"], s_format("Enemy Hit Damage After Resistance: %d ^8(total incoming damage)", damage * resMult)) @@ -2356,18 +2360,21 @@ function calcs.buildDefenceEstimations(env, actor) t_insert(breakdown[damageType.."TakenHitMult"], s_format("Base %s Damage Taken: %.2f", damageType, 1 - reduction / 100)) end if armourReduct ~= 0 then - if percentOfArmourApplies ~= 100 then - t_insert(breakdown[damageType.."TakenHitMult"], s_format("%d%% percent of armour applies", percentOfArmourApplies)) + if (percentOfArmourApplies ~= (damageType == "Physical" and 100 or 0)) and (percentOfArmourApplies > 0) then + t_insert(breakdown[damageType.."TakenHitMult"], s_format("%d%% percent of Armour applies", percentOfArmourApplies)) end if effectiveArmourFromArmour == effectiveAppliedArmour then t_insert(breakdown[damageType.."TakenHitMult"], s_format("Reduction from Armour: %.2f", 1 - armourReduct / 100)) else - t_insert(breakdown[damageType.."TakenHitMult"], s_format("Armour contributing to reduction: %d", effectiveArmourFromArmour)) + if effectiveArmourFromArmour > 0 then + t_insert(breakdown[damageType.."TakenHitMult"], s_format("Armour contributing to reduction: %d", effectiveArmourFromArmour)) + end for source, amount in pairs(effectiveArmourFromOther) do + t_insert(breakdown[damageType.."TakenHitMult"], s_format("%d%% percent of %s applies", percentOfEvasionApplies, source)) t_insert(breakdown[damageType.."TakenHitMult"], s_format("%s contributing to reduction: %d",source, amount)) end - t_insert(breakdown[damageType.."TakenHitMult"], s_format("Combined Armour used for reduction: %d", effectiveAppliedArmour)) - t_insert(breakdown[damageType.."TakenHitMult"], s_format("Reduction from combined Armour: %.2f", 1 - armourReduct / 100)) + t_insert(breakdown[damageType.."TakenHitMult"], s_format("Combined Defence used for reduction: %d", effectiveAppliedArmour)) + t_insert(breakdown[damageType.."TakenHitMult"], s_format("Reduction from combined Defence: %.2f", 1 - armourReduct / 100)) end end if enemyOverwhelm ~= 0 then diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index f02d0111cb..845c6412c8 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -2909,6 +2909,11 @@ local specialModList = { } end, ["double the number of your poisons that targets can be affected by at the same time"] = function(num) return { flag("PoisonCanStack"), mod("PoisonStacks", "MORE", 100) } end, ["your speed is unaffected by slows"] = { flag("UnaffectedBySlows") }, + ["(%d+)%% of evasion rating also grants elemental damage reduction"] = function(num) return { + mod("EvasionAppliesToFireDamageTaken", "BASE", num), + mod("EvasionAppliesToColdDamageTaken", "BASE", num), + mod("EvasionAppliesToLightningDamageTaken", "BASE", num), + } end, -- Raider ["nearby enemies have (%d+)%% less accuracy rating while you have phasing"] = function(num) return { mod("EnemyModifier", "LIST", { mod = mod("Accuracy", "MORE", -num) }, { type = "Condition", var = "Phasing" }) } end, ["immun[ei]t?y? to elemental ailments while phasing"] = { flag("ElementalAilmentImmune", { type = "Condition", var = "Phasing" }), }, @@ -3031,6 +3036,7 @@ local specialModList = { ["critical hits ignore non%-negative enemy monster elemental resistances"] = { flag("IgnoreNonNegativeEleRes", { type = "Condition", var = "CriticalStrike" }) }, ["(%d+)%% chance on shocking enemies to created shocked ground"] = { mod("ShockBase", "BASE", data.nonDamagingAilment["Shock"].default, { type = "ActorCondition", actor = "enemy", var = "OnShockedGround" }) }, ["on freezing enemies create chilled ground"] = { mod("ChillBase", "BASE", data.nonDamagingAilment["Chill"].default, { type = "ActorCondition", actor = "enemy", var = "OnChilledGround" }) }, + ["physical damage reduction from armour is based on your combined armour and evasion rating"] = { mod("EvasionAppliesToPhysicalDamageTaken", "BASE", 100) }, -- Chronomancer ["skills have (%d+)%% chance to not consume a cooldown when used"] = function(num) return { mod("CooldownChanceNotConsume", "BASE", num / 100, { type = "SkillType", skillType = SkillType.Cooldown }) @@ -5585,7 +5591,6 @@ local specialModList = { ["nearby allies have (%d+)%% chance to block attack damage per (%d+) strength you have"] = function(block, _, str) return { mod("ExtraAura", "LIST", { onlyAllies = true, mod = mod("BlockChance", "BASE", block) }, { type = "PerStat", stat = "Str", div = tonumber(str) }), } end, - ["physical damage reduction from armour is based on your combined armour and evasion rating"] = { mod("EvasionAddsToPdr", "FLAG", true) } } for _, name in pairs(data.keystones) do specialModList[name:lower()] = { mod("Keystone", "LIST", name) }