From 67ae76e22657f1bebe649b2053ffacc363e2fbcb Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Wed, 24 Jun 2026 07:12:17 +0000 Subject: [PATCH 1/2] Apply changes from https://github.com/PathOfBuildingCommunity/PathOfBuilding-PoE2/pull/2177 --- spec/System/TestSkills_spec.lua.rej | 22 ++++++++++++ src/Modules/CalcBreakdown.lua.rej | 45 ++++++++++++++++++++++++ src/Modules/CalcOffence.lua.rej | 54 +++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+) create mode 100644 spec/System/TestSkills_spec.lua.rej create mode 100644 src/Modules/CalcBreakdown.lua.rej create mode 100644 src/Modules/CalcOffence.lua.rej diff --git a/spec/System/TestSkills_spec.lua.rej b/spec/System/TestSkills_spec.lua.rej new file mode 100644 index 00000000000..543368ef678 --- /dev/null +++ b/spec/System/TestSkills_spec.lua.rej @@ -0,0 +1,22 @@ +diff a/spec/System/TestSkills_spec.lua b/spec/System/TestSkills_spec.lua (rejected hunks) +@@ -798,6 +798,20 @@ describe("TestSkills", function() + assert.True(build.calcsTab.mainEnv.enemyDB:Sum("BASE", nil, "FireResist") < fireResistWithoutPotentExposure) + end) + ++ it("averages inverted elemental resistance after penetration", function() ++ build.skillsTab:PasteSocketGroup("Fireball 20/0 1") ++ build.configTab.input.enemyIsBoss = "None" ++ build.configTab.input.enemyFireResist = 50 ++ build.configTab.input.customMods = "Hits have 50% chance to treat Enemy Monster Elemental Resistance values as inverted\nDamage Penetrates 50% of Enemy Fire Resistance" ++ build.configTab:BuildModList() ++ runCallback("OnFrame") ++ ++ assert.are.equals(1.25, build.calcsTab.calcsOutput.FireEffMult) ++ local breakdownText = table.concat(build.calcsTab.calcsEnv.player.breakdown.FireEffMult, "\n") ++ assert.truthy(breakdownText:match("inverted hit")) ++ assert.truthy(breakdownText:match("weighted average")) ++ end) ++ + it("Test granted skills with exposure stats make exposure configurable", function() + build.skillsTab:PasteSocketGroup("Fireball 20/0 1") + local spec = build.spec diff --git a/src/Modules/CalcBreakdown.lua.rej b/src/Modules/CalcBreakdown.lua.rej new file mode 100644 index 00000000000..824d4fccb6c --- /dev/null +++ b/src/Modules/CalcBreakdown.lua.rej @@ -0,0 +1,45 @@ +diff a/src/Modules/CalcBreakdown.lua b/src/Modules/CalcBreakdown.lua (rejected hunks) +@@ -110,20 +110,29 @@ function breakdown.area(base, areaMod, total, incBreakpoint, moreBreakpoint, red + return out + end + +-function breakdown.effMult(damageType, resist, pen, taken, mult, takenMore, sourceRes, useRes, invertChance, minPen) ++function breakdown.effMult(damageType, resist, pen, taken, mult, takenMore, sourceRes, useRes, invertChance, minPen, effectiveResist) + local out = { } + local resistForm = (damageType == "Physical") and "physical damage reduction" or "resistance" + local resistLabel = resistForm +- +- if invertChance and invertChance ~= 0 then +- resistLabel = "average inverted "..resistForm ++ minPen = minPen or 0 ++ local calcPenResist = function(resist) ++ return resist > minPen and m_max(resist - pen, minPen) or resist + end ++ effectiveResist = effectiveResist or calcPenResist(resist) ++ + if sourceRes and sourceRes ~= damageType then + t_insert(out, s_format("Enemy %s: %d%% ^8(%s)", resistLabel, resist, sourceRes)) + elseif resist ~= 0 then + t_insert(out, s_format("Enemy %s: %d%%", resistLabel, resist)) + end +- if pen ~= 0 or not useRes then ++ if invertChance and invertChance ~= 0 and useRes then ++ local normalResist = calcPenResist(resist) ++ local invertedResist = calcPenResist(-resist) ++ t_insert(out, "Effective resistance:") ++ t_insert(out, s_format("%g%% ^8(non-inverted hit after penetration)", normalResist)) ++ t_insert(out, s_format("%g%% ^8(inverted hit after penetration)", invertedResist)) ++ t_insert(out, s_format("= %g%% ^8(weighted average from %.0f%% inversion chance)", effectiveResist, invertChance * 100)) ++ elseif pen ~= 0 or not useRes then + t_insert(out, "Effective resistance:") + t_insert(out, s_format("%d%% ^8(resistance)", resist)) + if pen < 0 then +@@ -145,7 +154,7 @@ function breakdown.effMult(damageType, resist, pen, taken, mult, takenMore, sour + if useRes then + breakdown.multiChain(out, { + label = "Effective DPS modifier:", +- { "%.2f ^8(%s)", 1 - (math.max(resist - pen,0)) / 100, resistForm }, ++ { "%.2f ^8(%s)", 1 - effectiveResist / 100, resistForm }, + { "%.2f ^8(increased/reduced damage taken)", 1 + taken / 100 }, + { "%.2f ^8(more/less damage taken)", takenMore }, + total = s_format("= %.3f", mult), diff --git a/src/Modules/CalcOffence.lua.rej b/src/Modules/CalcOffence.lua.rej new file mode 100644 index 00000000000..78cd163aa18 --- /dev/null +++ b/src/Modules/CalcOffence.lua.rej @@ -0,0 +1,54 @@ +diff a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua (rejected hunks) +@@ -4157,11 +4157,7 @@ function calcs.offence(env, actor, activeSkill) + end + end + +- local invertChance = m_max(m_min(skillModList:Sum("CHANCE", cfg, "HitsInvertEleResChance"), 1), 0) +- if isElemental[damageType] and invertChance > 0 then +- -- resist = (1 - invertChance) * resist + invertChance * (-1 * resist) +- resist = resist - 2 * invertChance * resist +- end ++ local invertChance = isElemental[damageType] and m_max(m_min(skillModList:Sum("CHANCE", cfg, "HitsInvertEleResChance"), 1), 0) or 0 + sourceRes = env.modDB:Flag(nil, "Enemy"..sourceRes.."ResistEqualToYours") and "Your "..sourceRes.." Resistance" or (env.partyMembers.modDB:Flag(nil, "Enemy"..sourceRes.."ResistEqualToYours") and "Party Member "..sourceRes.." Resistance" or sourceRes) + if skillFlags.projectile then + takenInc = takenInc + enemyDB:Sum("INC", nil, "ProjectileDamageTaken") +@@ -4174,10 +4170,20 @@ function calcs.offence(env, actor, activeSkill) + end + local effMult = (1 + takenInc / 100) * takenMore + local useRes = useThisResist(damageType) ++ local effectiveResist = resist ++ local calcPenResist = function(resist) ++ return resist > minPen and m_max(resist - pen, minPen) or resist ++ end + if skillModList:Flag(cfg, isElemental[damageType] and "CannotElePenIgnore" or nil) then +- effMult = effMult * (1 - resist / 100) ++ effectiveResist = (isElemental[damageType] and invertChance > 0) and (resist - 2 * invertChance * resist) or resist ++ effMult = effMult * (1 - effectiveResist / 100) + elseif useRes then +- effMult = effMult * (1 - (resist > minPen and m_max(resist - pen, minPen) or resist) / 100) ++ if isElemental[damageType] and invertChance > 0 then ++ effectiveResist = calcPenResist(resist) * (1 - invertChance) + calcPenResist(-resist) * invertChance ++ else ++ effectiveResist = calcPenResist(resist) ++ end ++ effMult = effMult * (1 - effectiveResist / 100) + end + damageTypeHitMin = damageTypeHitMin * effMult + damageTypeHitMax = damageTypeHitMax * effMult +@@ -4185,12 +4191,12 @@ function calcs.offence(env, actor, activeSkill) + if env.mode == "CALCS" then + output[damageType.."EffMult"] = effMult + end +- if pass == 2 and breakdown and (effMult ~= 1 or sourceRes ~= damageType) and skillModList:Flag(cfg, isElemental[damageType] and "CannotElePenIgnore" or nil) then ++ if pass == 2 and breakdown and (effMult ~= 1 or sourceRes ~= damageType or invertChance > 0) and skillModList:Flag(cfg, isElemental[damageType] and "CannotElePenIgnore" or nil) then + t_insert(breakdown[damageType], s_format("x %.3f ^8(effective DPS modifier)", effMult)) +- breakdown[damageType.."EffMult"] = breakdown.effMult(damageType, resist, 0, takenInc, effMult, takenMore, sourceRes, useRes, invertChance, minPen) +- elseif pass == 2 and breakdown and (effMult ~= 1 or (resist - pen) < minPen or sourceRes ~= damageType) then ++ breakdown[damageType.."EffMult"] = breakdown.effMult(damageType, resist, 0, takenInc, effMult, takenMore, sourceRes, useRes, invertChance, minPen, effectiveResist) ++ elseif pass == 2 and breakdown and (effMult ~= 1 or (resist - pen) < minPen or sourceRes ~= damageType or invertChance > 0) then + t_insert(breakdown[damageType], s_format("x %.3f ^8(effective DPS modifier)", effMult)) +- breakdown[damageType.."EffMult"] = breakdown.effMult(damageType, resist, pen, takenInc, effMult, takenMore, sourceRes, useRes, invertChance, minPen) ++ breakdown[damageType.."EffMult"] = breakdown.effMult(damageType, resist, pen, takenInc, effMult, takenMore, sourceRes, useRes, invertChance, minPen, effectiveResist) + end + end + if pass == 2 and breakdown then From 634f3aa50ac476e6e7b05d28d16c0feeaea51731 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Thu, 23 Jul 2026 09:31:06 +1000 Subject: [PATCH 2/2] Fix merge --- spec/System/TestSkills_spec.lua | 18 +++++++++- spec/System/TestSkills_spec.lua.rej | 22 ------------ src/Modules/CalcBreakdown.lua | 17 +++++---- src/Modules/CalcBreakdown.lua.rej | 45 ------------------------ src/Modules/CalcOffence.lua | 28 +++++++-------- src/Modules/CalcOffence.lua.rej | 54 ----------------------------- 6 files changed, 42 insertions(+), 142 deletions(-) delete mode 100644 spec/System/TestSkills_spec.lua.rej delete mode 100644 src/Modules/CalcBreakdown.lua.rej delete mode 100644 src/Modules/CalcOffence.lua.rej diff --git a/spec/System/TestSkills_spec.lua b/spec/System/TestSkills_spec.lua index 831ac254660..5f0026c3512 100644 --- a/spec/System/TestSkills_spec.lua +++ b/spec/System/TestSkills_spec.lua @@ -150,4 +150,20 @@ describe("TestAttacks", function() assert.True(preAdrenalineMaxStages < build.calcsTab.mainEnv.player.activeSkillList[1].skillModList:Sum("BASE", nil, "Multiplier:BlightMaxStages")) end) -end) \ No newline at end of file + + it("averages inverted elemental resistance after penetration", function() + build.skillsTab:PasteSocketGroup("Fireball 20/0 1") + build.configTab.input.enemyIsBoss = "None" + build.configTab.input.enemyFireResist = 50 + build.configTab.input.customMods = "Hits have 50% chance to treat Enemy Monster Elemental Resistance values as inverted\nDamage Penetrates 50% of Enemy Fire Resistance" + build.configTab:BuildModList() + runCallback("OnFrame") + + -- Unlike PoE 2, PoE 1 penetration can lower resistance below zero: + -- 50% of hits use 0% resistance and 50% use -100% resistance. + assert.are.equals(1.5, build.calcsTab.calcsOutput.FireEffMult) + local breakdownText = table.concat(build.calcsTab.calcsEnv.player.breakdown.FireEffMult, "\n") + assert.is_truthy(breakdownText:match("inverted hit")) + assert.is_truthy(breakdownText:match("weighted average")) + end) +end) diff --git a/spec/System/TestSkills_spec.lua.rej b/spec/System/TestSkills_spec.lua.rej deleted file mode 100644 index 543368ef678..00000000000 --- a/spec/System/TestSkills_spec.lua.rej +++ /dev/null @@ -1,22 +0,0 @@ -diff a/spec/System/TestSkills_spec.lua b/spec/System/TestSkills_spec.lua (rejected hunks) -@@ -798,6 +798,20 @@ describe("TestSkills", function() - assert.True(build.calcsTab.mainEnv.enemyDB:Sum("BASE", nil, "FireResist") < fireResistWithoutPotentExposure) - end) - -+ it("averages inverted elemental resistance after penetration", function() -+ build.skillsTab:PasteSocketGroup("Fireball 20/0 1") -+ build.configTab.input.enemyIsBoss = "None" -+ build.configTab.input.enemyFireResist = 50 -+ build.configTab.input.customMods = "Hits have 50% chance to treat Enemy Monster Elemental Resistance values as inverted\nDamage Penetrates 50% of Enemy Fire Resistance" -+ build.configTab:BuildModList() -+ runCallback("OnFrame") -+ -+ assert.are.equals(1.25, build.calcsTab.calcsOutput.FireEffMult) -+ local breakdownText = table.concat(build.calcsTab.calcsEnv.player.breakdown.FireEffMult, "\n") -+ assert.truthy(breakdownText:match("inverted hit")) -+ assert.truthy(breakdownText:match("weighted average")) -+ end) -+ - it("Test granted skills with exposure stats make exposure configurable", function() - build.skillsTab:PasteSocketGroup("Fireball 20/0 1") - local spec = build.spec diff --git a/src/Modules/CalcBreakdown.lua b/src/Modules/CalcBreakdown.lua index 6df1f18d867..a264a8dddbf 100644 --- a/src/Modules/CalcBreakdown.lua +++ b/src/Modules/CalcBreakdown.lua @@ -108,20 +108,25 @@ function breakdown.area(base, areaMod, total, incBreakpoint, moreBreakpoint, red return out end -function breakdown.effMult(damageType, resist, pen, taken, mult, takenMore, sourceRes, useRes, invertChance) +function breakdown.effMult(damageType, resist, pen, taken, mult, takenMore, sourceRes, useRes, invertChance, effectiveResist) local out = { } local resistForm = (damageType == "Physical") and "physical damage reduction" or "resistance" local resistLabel = resistForm + effectiveResist = effectiveResist or resist - pen - if invertChance and invertChance ~= 0 then - resistLabel = "average inverted "..resistForm - end if sourceRes and sourceRes ~= damageType then t_insert(out, s_format("Enemy %s: %d%% ^8(%s)", resistLabel, resist, sourceRes)) elseif resist ~= 0 then t_insert(out, s_format("Enemy %s: %d%%", resistLabel, resist)) end - if pen ~= 0 or not useRes then + if invertChance and invertChance ~= 0 and useRes then + local normalResist = resist - pen + local invertedResist = -resist - pen + t_insert(out, "Effective resistance:") + t_insert(out, s_format("%g%% ^8(non-inverted hit after penetration)", normalResist)) + t_insert(out, s_format("%g%% ^8(inverted hit after penetration)", invertedResist)) + t_insert(out, s_format("= %g%% ^8(weighted average from %.0f%% inversion chance)", effectiveResist, invertChance * 100)) + elseif pen ~= 0 or not useRes then t_insert(out, "Effective resistance:") t_insert(out, s_format("%d%% ^8(resistance)", resist)) if pen < 0 then @@ -139,7 +144,7 @@ function breakdown.effMult(damageType, resist, pen, taken, mult, takenMore, sour if useRes then breakdown.multiChain(out, { label = "Effective DPS modifier:", - { "%.2f ^8(%s)", 1 - (resist - pen) / 100, resistForm }, + { "%.2f ^8(%s)", 1 - effectiveResist / 100, resistForm }, { "%.2f ^8(increased/reduced damage taken)", 1 + taken / 100 }, { "%.2f ^8(more/less damage taken)", takenMore }, total = s_format("= %.3f", mult), diff --git a/src/Modules/CalcBreakdown.lua.rej b/src/Modules/CalcBreakdown.lua.rej deleted file mode 100644 index 824d4fccb6c..00000000000 --- a/src/Modules/CalcBreakdown.lua.rej +++ /dev/null @@ -1,45 +0,0 @@ -diff a/src/Modules/CalcBreakdown.lua b/src/Modules/CalcBreakdown.lua (rejected hunks) -@@ -110,20 +110,29 @@ function breakdown.area(base, areaMod, total, incBreakpoint, moreBreakpoint, red - return out - end - --function breakdown.effMult(damageType, resist, pen, taken, mult, takenMore, sourceRes, useRes, invertChance, minPen) -+function breakdown.effMult(damageType, resist, pen, taken, mult, takenMore, sourceRes, useRes, invertChance, minPen, effectiveResist) - local out = { } - local resistForm = (damageType == "Physical") and "physical damage reduction" or "resistance" - local resistLabel = resistForm -- -- if invertChance and invertChance ~= 0 then -- resistLabel = "average inverted "..resistForm -+ minPen = minPen or 0 -+ local calcPenResist = function(resist) -+ return resist > minPen and m_max(resist - pen, minPen) or resist - end -+ effectiveResist = effectiveResist or calcPenResist(resist) -+ - if sourceRes and sourceRes ~= damageType then - t_insert(out, s_format("Enemy %s: %d%% ^8(%s)", resistLabel, resist, sourceRes)) - elseif resist ~= 0 then - t_insert(out, s_format("Enemy %s: %d%%", resistLabel, resist)) - end -- if pen ~= 0 or not useRes then -+ if invertChance and invertChance ~= 0 and useRes then -+ local normalResist = calcPenResist(resist) -+ local invertedResist = calcPenResist(-resist) -+ t_insert(out, "Effective resistance:") -+ t_insert(out, s_format("%g%% ^8(non-inverted hit after penetration)", normalResist)) -+ t_insert(out, s_format("%g%% ^8(inverted hit after penetration)", invertedResist)) -+ t_insert(out, s_format("= %g%% ^8(weighted average from %.0f%% inversion chance)", effectiveResist, invertChance * 100)) -+ elseif pen ~= 0 or not useRes then - t_insert(out, "Effective resistance:") - t_insert(out, s_format("%d%% ^8(resistance)", resist)) - if pen < 0 then -@@ -145,7 +154,7 @@ function breakdown.effMult(damageType, resist, pen, taken, mult, takenMore, sour - if useRes then - breakdown.multiChain(out, { - label = "Effective DPS modifier:", -- { "%.2f ^8(%s)", 1 - (math.max(resist - pen,0)) / 100, resistForm }, -+ { "%.2f ^8(%s)", 1 - effectiveResist / 100, resistForm }, - { "%.2f ^8(increased/reduced damage taken)", 1 + taken / 100 }, - { "%.2f ^8(more/less damage taken)", takenMore }, - total = s_format("= %.3f", mult), diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index f78d34f7d31..88f76c77094 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -3314,14 +3314,8 @@ function calcs.offence(env, actor, activeSkill) end end local invertChanceEle = m_max(m_min(skillModList:Sum("CHANCE", cfg, "HitsInvertEleResChance"), 1), 0) - if isElemental[damageType] and invertChanceEle > 0 then - -- resist = (1 - invertChanceEle) * resist + invertChanceEle * (-1 * resist) - resist = resist - 2 * invertChanceEle * resist - end local invertChanceChaos = m_max(m_min(skillModList:Sum("CHANCE", cfg, "HitsInvertChaosResChance"), 1), 0) - if damageType == "Chaos" and invertChanceChaos > 0 then - resist = resist - 2 * invertChanceChaos * resist - end + local invertChance = (isElemental[damageType] and invertChanceEle) or (damageType == "Chaos" and invertChanceChaos) or 0 sourceRes = env.modDB:Flag(nil, "Enemy"..sourceRes.."ResistEqualToYours") and "Your "..sourceRes.." Resistance" or (env.partyMembers.modDB:Flag(nil, "Enemy"..sourceRes.."ResistEqualToYours") and "Party Member "..sourceRes.." Resistance" or sourceRes) if skillFlags.projectile then takenInc = takenInc + enemyDB:Sum("INC", nil, "ProjectileDamageTaken") @@ -3335,10 +3329,17 @@ function calcs.offence(env, actor, activeSkill) local effMult = (1 + takenInc / 100) * takenMore local useResChance = useThisResist(damageType) local useRes = useResChance > 0 + local effectiveResist = resist if skillModList:Flag(cfg, isElemental[damageType] and "CannotElePenIgnore" or nil) then - effMult = effMult * (1 - resist / 100) + effectiveResist = invertChance > 0 and (resist - 2 * invertChance * resist) or resist + effMult = effMult * (1 - effectiveResist / 100) elseif useRes then - effMult = effMult * (1 - ((resist - pen) * useResChance) / 100) + if invertChance > 0 then + effectiveResist = ((resist - pen) * (1 - invertChance) + (-resist - pen) * invertChance) * useResChance + else + effectiveResist = (resist - pen) * useResChance + end + effMult = effMult * (1 - effectiveResist / 100) end damageTypeHitMin = damageTypeHitMin * effMult damageTypeHitMax = damageTypeHitMax * effMult @@ -3346,13 +3347,12 @@ function calcs.offence(env, actor, activeSkill) if env.mode == "CALCS" then output[damageType.."EffMult"] = effMult end - local invertChance = (isElemental[damageType] and invertChanceEle) or (damageType == "Chaos" and invertChanceChaos) or 0 - if pass == 2 and breakdown and (effMult ~= 1 or sourceRes ~= damageType) and skillModList:Flag(cfg, isElemental[damageType] and "CannotElePenIgnore" or nil) then + if pass == 2 and breakdown and (effMult ~= 1 or sourceRes ~= damageType or invertChance > 0) and skillModList:Flag(cfg, isElemental[damageType] and "CannotElePenIgnore" or nil) then t_insert(breakdown[damageType], s_format("x %.3f ^8(effective DPS modifier)", effMult)) - breakdown[damageType.."EffMult"] = breakdown.effMult(damageType, resist, 0, takenInc, effMult, takenMore, sourceRes, useRes, invertChance) - elseif pass == 2 and breakdown and (effMult ~= 1 or sourceRes ~= damageType) then + breakdown[damageType.."EffMult"] = breakdown.effMult(damageType, resist, 0, takenInc, effMult, takenMore, sourceRes, useRes, invertChance, effectiveResist) + elseif pass == 2 and breakdown and (effMult ~= 1 or sourceRes ~= damageType or invertChance > 0) then t_insert(breakdown[damageType], s_format("x %.3f ^8(effective DPS modifier)", effMult)) - breakdown[damageType.."EffMult"] = breakdown.effMult(damageType, resist, pen, takenInc, effMult, takenMore, sourceRes, useRes, invertChance) + breakdown[damageType.."EffMult"] = breakdown.effMult(damageType, resist, pen, takenInc, effMult, takenMore, sourceRes, useRes, invertChance, effectiveResist) end end if pass == 2 and breakdown then diff --git a/src/Modules/CalcOffence.lua.rej b/src/Modules/CalcOffence.lua.rej deleted file mode 100644 index 78cd163aa18..00000000000 --- a/src/Modules/CalcOffence.lua.rej +++ /dev/null @@ -1,54 +0,0 @@ -diff a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua (rejected hunks) -@@ -4157,11 +4157,7 @@ function calcs.offence(env, actor, activeSkill) - end - end - -- local invertChance = m_max(m_min(skillModList:Sum("CHANCE", cfg, "HitsInvertEleResChance"), 1), 0) -- if isElemental[damageType] and invertChance > 0 then -- -- resist = (1 - invertChance) * resist + invertChance * (-1 * resist) -- resist = resist - 2 * invertChance * resist -- end -+ local invertChance = isElemental[damageType] and m_max(m_min(skillModList:Sum("CHANCE", cfg, "HitsInvertEleResChance"), 1), 0) or 0 - sourceRes = env.modDB:Flag(nil, "Enemy"..sourceRes.."ResistEqualToYours") and "Your "..sourceRes.." Resistance" or (env.partyMembers.modDB:Flag(nil, "Enemy"..sourceRes.."ResistEqualToYours") and "Party Member "..sourceRes.." Resistance" or sourceRes) - if skillFlags.projectile then - takenInc = takenInc + enemyDB:Sum("INC", nil, "ProjectileDamageTaken") -@@ -4174,10 +4170,20 @@ function calcs.offence(env, actor, activeSkill) - end - local effMult = (1 + takenInc / 100) * takenMore - local useRes = useThisResist(damageType) -+ local effectiveResist = resist -+ local calcPenResist = function(resist) -+ return resist > minPen and m_max(resist - pen, minPen) or resist -+ end - if skillModList:Flag(cfg, isElemental[damageType] and "CannotElePenIgnore" or nil) then -- effMult = effMult * (1 - resist / 100) -+ effectiveResist = (isElemental[damageType] and invertChance > 0) and (resist - 2 * invertChance * resist) or resist -+ effMult = effMult * (1 - effectiveResist / 100) - elseif useRes then -- effMult = effMult * (1 - (resist > minPen and m_max(resist - pen, minPen) or resist) / 100) -+ if isElemental[damageType] and invertChance > 0 then -+ effectiveResist = calcPenResist(resist) * (1 - invertChance) + calcPenResist(-resist) * invertChance -+ else -+ effectiveResist = calcPenResist(resist) -+ end -+ effMult = effMult * (1 - effectiveResist / 100) - end - damageTypeHitMin = damageTypeHitMin * effMult - damageTypeHitMax = damageTypeHitMax * effMult -@@ -4185,12 +4191,12 @@ function calcs.offence(env, actor, activeSkill) - if env.mode == "CALCS" then - output[damageType.."EffMult"] = effMult - end -- if pass == 2 and breakdown and (effMult ~= 1 or sourceRes ~= damageType) and skillModList:Flag(cfg, isElemental[damageType] and "CannotElePenIgnore" or nil) then -+ if pass == 2 and breakdown and (effMult ~= 1 or sourceRes ~= damageType or invertChance > 0) and skillModList:Flag(cfg, isElemental[damageType] and "CannotElePenIgnore" or nil) then - t_insert(breakdown[damageType], s_format("x %.3f ^8(effective DPS modifier)", effMult)) -- breakdown[damageType.."EffMult"] = breakdown.effMult(damageType, resist, 0, takenInc, effMult, takenMore, sourceRes, useRes, invertChance, minPen) -- elseif pass == 2 and breakdown and (effMult ~= 1 or (resist - pen) < minPen or sourceRes ~= damageType) then -+ breakdown[damageType.."EffMult"] = breakdown.effMult(damageType, resist, 0, takenInc, effMult, takenMore, sourceRes, useRes, invertChance, minPen, effectiveResist) -+ elseif pass == 2 and breakdown and (effMult ~= 1 or (resist - pen) < minPen or sourceRes ~= damageType or invertChance > 0) then - t_insert(breakdown[damageType], s_format("x %.3f ^8(effective DPS modifier)", effMult)) -- breakdown[damageType.."EffMult"] = breakdown.effMult(damageType, resist, pen, takenInc, effMult, takenMore, sourceRes, useRes, invertChance, minPen) -+ breakdown[damageType.."EffMult"] = breakdown.effMult(damageType, resist, pen, takenInc, effMult, takenMore, sourceRes, useRes, invertChance, minPen, effectiveResist) - end - end - if pass == 2 and breakdown then