diff --git a/spec/System/TestSkills_spec.lua b/spec/System/TestSkills_spec.lua index af8896f64c..cc7144abef 100644 --- a/spec/System/TestSkills_spec.lua +++ b/spec/System/TestSkills_spec.lua @@ -405,6 +405,17 @@ describe("TestSkills", function() assert.are.equals(7, round(finalCost)) end) + it("rounds Supreme Ego mana reservation down", function() + build.skillsTab:PasteSocketGroup("Precision 1/0 1\n") + local supremeEgo = build.spec.tree.keystoneMap["Supreme Ego"] + build.spec:AllocNode(build.spec.nodes[supremeEgo.id]) + build.spec:BuildAllDependsAndPaths() + runCallback("OnFrame") + + -- 22 base + floor(40% of 22) = 30, rather than round(22 * 1.4) = 31. + assert.are.equals(30, build.calcsTab.mainEnv.player.mainSkill.skillData.ManaReservedBase) + end) + it("evaluates BaseFlag tags using PoB 1 skill data", function() build.skillsTab:PasteSocketGroup("Absolution 20/0 1\n") runCallback("OnFrame") diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index 95e90c3825..3d63a97c47 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -1964,7 +1964,9 @@ function calcs.perform(env, skipEHP) activeSkill.skillData["ManaReservationPercentForced"] = nil end for name, values in pairs(pool) do - values.more = skillModList:More(skillCfg, name.."Reserved", "Reserved") + values.resourceMore = skillModList:More(skillCfg, name.."Reserved") + values.genericMore = skillModList:More(skillCfg, "Reserved") + values.more = values.resourceMore * values.genericMore values.inc = skillModList:Sum("INC", skillCfg, name.."Reserved", "Reserved") values.efficiency = m_max(skillModList:Sum("INC", skillCfg, name.."ReservationEfficiency", "ReservationEfficiency"), -100) values.efficiencyMore = skillModList:More(skillCfg, name.."ReservationEfficiency", "ReservationEfficiency") @@ -1973,19 +1975,26 @@ function calcs.perform(env, skipEHP) if activeSkill.skillData[name.."ReservationFlatForced"] then values.reservedFlat = activeSkill.skillData[name.."ReservationFlatForced"] else - local baseFlatVal = m_floor(values.baseFlat * mult) + local baseFlatVal = m_modf(values.baseFlat * mult) values.reservedFlat = 0 - if values.more > 0 and values.inc > -100 and baseFlatVal ~= 0 then - values.reservedFlat = m_max(round(baseFlatVal * (100 + values.inc) / 100 * values.more / (1 + values.efficiency / 100) / values.efficiencyMore, 0), 0) + if baseFlatVal ~= 0 then + -- Reservation modifiers use separate integer stages before efficiency. + local modifiedFlat = baseFlatVal + m_modf(baseFlatVal * values.inc / 100) + modifiedFlat = modifiedFlat + m_modf(modifiedFlat * (values.resourceMore - 1)) + modifiedFlat = modifiedFlat + m_modf(modifiedFlat * (values.genericMore - 1)) + values.reservedFlat = m_max(round(modifiedFlat / (1 + values.efficiency / 100) / values.efficiencyMore, 0), 0) end end if activeSkill.skillData[name.."ReservationPercentForced"] then values.reservedPercent = activeSkill.skillData[name.."ReservationPercentForced"] else - local basePercentVal = values.basePercent * mult + local basePercentVal = m_modf(values.basePercent * 100 * mult) values.reservedPercent = 0 - if values.more > 0 and values.inc > -100 and basePercentVal ~= 0 then - values.reservedPercent = m_max(round(basePercentVal * (100 + values.inc) / 100 * values.more / (1 + values.efficiency / 100) / values.efficiencyMore, 2), 0) + if basePercentVal ~= 0 then + local modifiedPercent = basePercentVal + m_modf(basePercentVal * values.inc / 100) + modifiedPercent = modifiedPercent + m_modf(modifiedPercent * (values.resourceMore - 1)) + modifiedPercent = modifiedPercent + m_modf(modifiedPercent * (values.genericMore - 1)) + values.reservedPercent = m_max(round(modifiedPercent / (1 + values.efficiency / 100) / values.efficiencyMore, 0) / 100, 0) end end if activeSkill.activeMineCount then