From 67ae76e22657f1bebe649b2053ffacc363e2fbcb Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Wed, 24 Jun 2026 07:12:17 +0000 Subject: [PATCH] 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 0000000000..543368ef67 --- /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 0000000000..824d4fccb6 --- /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 0000000000..78cd163aa1 --- /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