From ea05e1d6e50fad1842c8cd908640a889cc51e5a4 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Sun, 30 Aug 2026 10:37:52 +0000 Subject: [PATCH 1/2] Apply changes from https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/10263 --- src/Modules/CalcOffence.lua.rej | 58 +++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/Modules/CalcOffence.lua.rej diff --git a/src/Modules/CalcOffence.lua.rej b/src/Modules/CalcOffence.lua.rej new file mode 100644 index 0000000000..d074cc64f0 --- /dev/null +++ b/src/Modules/CalcOffence.lua.rej @@ -0,0 +1,58 @@ +diff a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua (rejected hunks) +@@ -87,11 +87,6 @@ local function calcDamage(activeSkill, output, cfg, breakdown, damageType, typeF + addMax = addMax + max * convMult + end + end +- if addMin ~= 0 and addMax ~= 0 then +- addMin = round(addMin) +- addMax = round(addMax) +- end +- + local baseMin = output[damageType.."MinBase"] + local baseMax = output[damageType.."MaxBase"] + if baseMin == 0 and baseMax == 0 then +@@ -99,13 +94,16 @@ local function calcDamage(activeSkill, output, cfg, breakdown, damageType, typeF + if breakdown and (addMin ~= 0 or addMax ~= 0) then + t_insert(breakdown.damageTypes, { + source = damageType, +- convSrc = (addMin ~= 0 or addMax ~= 0) and (addMin .. " to " .. addMax), +- total = addMin .. " to " .. addMax, ++ convSrc = (addMin ~= 0 or addMax ~= 0) and (round(addMin) .. " to " .. round(addMax)), ++ total = round(addMin) .. " to " .. round(addMax), + convDst = convDst and s_format("%d%% to %s", conversionTable[damageType].conversion[convDst] * 100, convDst), + gainDst = convDst and s_format("%d%% gained as %s", conversionTable[damageType].gain[convDst] * 100, convDst), + }) + end +- return addMin, addMax ++ if convDst then ++ return addMin, addMax ++ end ++ return round(addMin), round(addMax) + end + + -- Combine modifiers +@@ -125,15 +123,20 @@ local function calcDamage(activeSkill, output, cfg, breakdown, damageType, typeF + base = baseMin .. " to " .. baseMax, + inc = (inc ~= 1 and "x "..inc), + more = (more ~= 1 and "x "..more), +- convSrc = (addMin ~= 0 or addMax ~= 0) and (addMin .. " to " .. addMax), +- total = (round(baseMin * inc * more) + addMin) .. " to " .. (round(baseMax * inc * more) + addMax), ++ convSrc = (addMin ~= 0 or addMax ~= 0) and (round(addMin) .. " to " .. round(addMax)), ++ total = round(baseMin * inc * more + addMin) .. " to " .. round(baseMax * inc * more + addMax), + convDst = convDst and conversionTable[damageType].conversion[convDst] > 0 and s_format("%d%% to %s", conversionTable[damageType].conversion[convDst] * 100, convDst), + gainDst = convDst and conversionTable[damageType].gain[convDst] > 0 and s_format("%d%% gained as %s", conversionTable[damageType].gain[convDst] * 100, convDst), + }) + end + +- return round(((baseMin * inc * more) * genericMoreMinDamage + addMin) * moreMinDamage * incMinDamage), +- round(((baseMax * inc * more) * genericMoreMaxDamage + addMax) * moreMaxDamage * incMaxDamage) ++ local min = ((baseMin * inc * more) * genericMoreMinDamage + addMin) * moreMinDamage * incMinDamage ++ local max = ((baseMax * inc * more) * genericMoreMaxDamage + addMax) * moreMaxDamage * incMaxDamage ++ if convDst then ++ -- Converted paths stay fractional until they reach their final damage type. ++ return min, max ++ end ++ return round(min), round(max) + end + + local function calcAilmentSourceDamage(activeSkill, output, cfg, breakdown, damageType, typeFlags) From c74c71e4ed2003cf771bd691bfe589cfae43e10e Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Mon, 31 Aug 2026 01:35:30 +1000 Subject: [PATCH 2/2] fix port --- spec/System/TestOffence_spec.lua | 44 ++++++++++++++++++++++++ src/Modules/CalcOffence.lua | 20 +++++++---- src/Modules/CalcOffence.lua.rej | 58 -------------------------------- 3 files changed, 57 insertions(+), 65 deletions(-) create mode 100644 spec/System/TestOffence_spec.lua delete mode 100644 src/Modules/CalcOffence.lua.rej diff --git a/spec/System/TestOffence_spec.lua b/spec/System/TestOffence_spec.lua new file mode 100644 index 0000000000..2e8ca720f0 --- /dev/null +++ b/spec/System/TestOffence_spec.lua @@ -0,0 +1,44 @@ +describe("TestOffence", function() + before_each(function() + newBuild() + end) + + teardown(function() + -- newBuild() takes care of resetting everything in setup() + end) + + it("rounds each scaled damage conversion to a whole percent", function() + build.skillsTab:PasteSocketGroup("Fireball 20/0 1") + build.configTab.input.customMods = [[ + 40% of Physical Damage Converted to Lightning Damage + 40% of Physical Damage Converted to Cold Damage + 40% of Physical Damage Converted to Fire Damage + ]] + build.configTab:BuildModList() + runCallback("OnFrame") + + local conversion = build.calcsTab.mainEnv.player.mainSkill.conversionTable.Physical + assert.are.equals(0.33, conversion.Lightning) + assert.are.equals(0.33, conversion.Cold) + assert.are.equals(0.33, conversion.Fire) + assert.is_true(math.abs(conversion.mult - 0.01) < 0.000001) + end) + + it("keeps converted damage fractional until destination calculation", function() + build.itemsTab:CreateDisplayItemFromRaw([[ + New Item + Attuned Wand + Adds 2 to 2 Physical Damage to Spells + ]]) + build.itemsTab:AddDisplayItem() + build.skillsTab:PasteSocketGroup("Fireball 20/0 1") + build.configTab.input.customMods = [[ + 25% of Physical Damage Converted to Cold Damage + ]] + build.configTab:BuildModList() + runCallback("OnFrame") + + assert.are.equals(2, build.calcsTab.mainOutput.PhysicalMinBase) + assert.are.equals(0.5, build.calcsTab.mainOutput.ColdSummedMinBase) + end) +end) diff --git a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua index 40425570cc..4350d8f3b0 100644 --- a/src/Modules/CalcOffence.lua +++ b/src/Modules/CalcOffence.lua @@ -81,11 +81,6 @@ local function calcConvertedDamage(activeSkill, output, cfg, damageType) convertedMax = convertedMax + (max or 0) * convMult end end - if convertedMin ~= 0 and convertedMax ~= 0 then - convertedMin = round(convertedMin) - convertedMax = round(convertedMax) - end - return convertedMin, convertedMax end @@ -2390,6 +2385,17 @@ function calcs.offence(env, actor, activeSkill) end end + -- The game stores each final conversion destination as a whole percent. + local convertedTotal = 0 + for toType, amount in pairs(activeSkill.conversionTable[damageType]) do + if toType ~= "mult" then + local conversion = round(amount * 100) + activeSkill.conversionTable[damageType][toType] = conversion / 100 + convertedTotal = convertedTotal + conversion + end + end + activeSkill.conversionTable[damageType].mult = 1 - m_min(convertedTotal / 100, 1) + end -- Configure damage passes @@ -4029,10 +4035,10 @@ function calcs.offence(env, actor, activeSkill) t_insert(breakdown[damageType], "Base damage:") end if convertedMin ~= 0 or convertedMax ~= 0 then - t_insert(breakdown[damageType], s_format("+ %d to %d ^8(damage converted from other damage types)", convertedMin, convertedMax)) + t_insert(breakdown[damageType], s_format("+ %d to %d ^8(damage converted from other damage types)", round(convertedMin), round(convertedMax))) end if gainedMin ~= 0 or gainedMax ~= 0 then - t_insert(breakdown[damageType], s_format("+ %d to %d ^8(damage gained from other damage types)", gainedMin, gainedMax)) + t_insert(breakdown[damageType], s_format("+ %d to %d ^8(damage gained from other damage types)", round(gainedMin), round(gainedMax))) end t_insert(breakdown[damageType], s_format("= %.1f to %.1f", summedMin, summedMax)) end diff --git a/src/Modules/CalcOffence.lua.rej b/src/Modules/CalcOffence.lua.rej deleted file mode 100644 index d074cc64f0..0000000000 --- a/src/Modules/CalcOffence.lua.rej +++ /dev/null @@ -1,58 +0,0 @@ -diff a/src/Modules/CalcOffence.lua b/src/Modules/CalcOffence.lua (rejected hunks) -@@ -87,11 +87,6 @@ local function calcDamage(activeSkill, output, cfg, breakdown, damageType, typeF - addMax = addMax + max * convMult - end - end -- if addMin ~= 0 and addMax ~= 0 then -- addMin = round(addMin) -- addMax = round(addMax) -- end -- - local baseMin = output[damageType.."MinBase"] - local baseMax = output[damageType.."MaxBase"] - if baseMin == 0 and baseMax == 0 then -@@ -99,13 +94,16 @@ local function calcDamage(activeSkill, output, cfg, breakdown, damageType, typeF - if breakdown and (addMin ~= 0 or addMax ~= 0) then - t_insert(breakdown.damageTypes, { - source = damageType, -- convSrc = (addMin ~= 0 or addMax ~= 0) and (addMin .. " to " .. addMax), -- total = addMin .. " to " .. addMax, -+ convSrc = (addMin ~= 0 or addMax ~= 0) and (round(addMin) .. " to " .. round(addMax)), -+ total = round(addMin) .. " to " .. round(addMax), - convDst = convDst and s_format("%d%% to %s", conversionTable[damageType].conversion[convDst] * 100, convDst), - gainDst = convDst and s_format("%d%% gained as %s", conversionTable[damageType].gain[convDst] * 100, convDst), - }) - end -- return addMin, addMax -+ if convDst then -+ return addMin, addMax -+ end -+ return round(addMin), round(addMax) - end - - -- Combine modifiers -@@ -125,15 +123,20 @@ local function calcDamage(activeSkill, output, cfg, breakdown, damageType, typeF - base = baseMin .. " to " .. baseMax, - inc = (inc ~= 1 and "x "..inc), - more = (more ~= 1 and "x "..more), -- convSrc = (addMin ~= 0 or addMax ~= 0) and (addMin .. " to " .. addMax), -- total = (round(baseMin * inc * more) + addMin) .. " to " .. (round(baseMax * inc * more) + addMax), -+ convSrc = (addMin ~= 0 or addMax ~= 0) and (round(addMin) .. " to " .. round(addMax)), -+ total = round(baseMin * inc * more + addMin) .. " to " .. round(baseMax * inc * more + addMax), - convDst = convDst and conversionTable[damageType].conversion[convDst] > 0 and s_format("%d%% to %s", conversionTable[damageType].conversion[convDst] * 100, convDst), - gainDst = convDst and conversionTable[damageType].gain[convDst] > 0 and s_format("%d%% gained as %s", conversionTable[damageType].gain[convDst] * 100, convDst), - }) - end - -- return round(((baseMin * inc * more) * genericMoreMinDamage + addMin) * moreMinDamage * incMinDamage), -- round(((baseMax * inc * more) * genericMoreMaxDamage + addMax) * moreMaxDamage * incMaxDamage) -+ local min = ((baseMin * inc * more) * genericMoreMinDamage + addMin) * moreMinDamage * incMinDamage -+ local max = ((baseMax * inc * more) * genericMoreMaxDamage + addMax) * moreMaxDamage * incMaxDamage -+ if convDst then -+ -- Converted paths stay fractional until they reach their final damage type. -+ return min, max -+ end -+ return round(min), round(max) - end - - local function calcAilmentSourceDamage(activeSkill, output, cfg, breakdown, damageType, typeFlags)