Skip to content

Commit 8877eea

Browse files
committed
Merge branch 'dev' into cn_local
2 parents 6dea0d7 + e0cc037 commit 8877eea

8 files changed

Lines changed: 129 additions & 55 deletions

File tree

.editorconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
trim_trailing_whitespace = false
33
indent_style = tab
44
max_line_length = 360
5+
align_array_table = false

CHANGELOG.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Changelog
22

3+
## [v2.66.2](https://github.com/PathOfBuildingCommunity/PathOfBuilding-PoE2/tree/v2.66.2) (2026/07/25)
4+
5+
[Full Changelog](https://github.com/PathOfBuildingCommunity/PathOfBuilding/compare/v2.66.1...v2.66.2)
6+
7+
8+
## What's Changed
9+
### Fixed Crashes
10+
- Fix Warden import crash [\#10002](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/10002) ([vaisest](https://github.com/vaisest))
11+
### Fixed Calculations
12+
- Fix Cost efficiency math and add mods to breakdown [\#10004](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/10004) ([vaisest](https://github.com/vaisest))
13+
14+
15+
316
## [v2.66.1](https://github.com/PathOfBuildingCommunity/PathOfBuilding-PoE2/tree/v2.66.1) (2026/07/25)
417

518
[Full Changelog](https://github.com/PathOfBuildingCommunity/PathOfBuilding/compare/v2.66.0...v2.66.1)
@@ -53,7 +66,7 @@
5366
- Add support for Sinistral and Dextral Catalysts [\#9811](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/9811) ([Peechey](https://github.com/Peechey))
5467
- Add support to auto calculate minion count for mods on Bonemeld and Farrul Bloodline [\#9832](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/9832) ([LocalIdentity](https://github.com/LocalIdentity))
5568
- Add support for Companionship Support [\#9833](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/9833) ([LocalIdentity](https://github.com/LocalIdentity))
56-
- Add support for Cast on Ward Break + Celestial Mathmatics + Ward bypass / chance to not break Bloodline nodes [\#9831](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/9831) ([LocalIdentity](https://github.com/LocalIdentity))
69+
- Add support for Cast on Ward Break + Celestial Mathematics + Ward bypass / chance to not break Bloodline nodes [\#9831](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/9831) ([LocalIdentity](https://github.com/LocalIdentity))
5770
- Add alt aura variant for Impresence [\#9937](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/9937) ([vaisest](https://github.com/vaisest))
5871
- Add support for Loyalty/damage taken from Companion's Life before you [\#9922](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/9922) ([ltogniolli](https://github.com/ltogniolli))
5972
- Add support for Runegraft of the Agile [\#9963](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/9963) ([czarandy](https://github.com/czarandy))
@@ -97,7 +110,7 @@
97110
- Fix Brutal Restraint missing Balbala variant (The Traitor) [\#9890](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/9890) ([Sentinent](https://github.com/Sentinent))
98111
- Fix parsing Vaal Unique modifiers on items [\#9933](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/9933) ([vaisest](https://github.com/vaisest))
99112
- Fix searching for Low Life in Config tab [\#9914](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/9914) ([Blitz54](https://github.com/Blitz54))
100-
- Fix mods that were "Not Supported" in mastery losing poisition when assigning masteries [\#9893](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/9893) ([soratidus999](https://github.com/soratidus999))
113+
- Fix mods that were "Not Supported" in mastery losing position when assigning masteries [\#9893](https://github.com/PathOfBuildingCommunity/PathOfBuilding/pull/9893) ([soratidus999](https://github.com/soratidus999))
101114

102115

103116
## [v2.65.0](https://github.com/PathOfBuildingCommunity/PathOfBuilding-PoE2/tree/v2.65.0) (2026/04/20)

changelog.txt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
VERSION[2.66.2][2026/07/25]
2+
3+
--- Fixed Crashes ---
4+
* Fix Warden import crash (vaisest)
5+
6+
--- Fixed Calculations ---
7+
* Fix Cost efficiency math and add mods to breakdown (vaisest)
8+
9+
110
VERSION[2.66.1][2026/07/25]
211

312
--- Fixed Crashes ---
@@ -42,7 +51,7 @@ VERSION[2.66.0][2026/07/25]
4251
* Add support for Sinistral and Dextral Catalysts (Peechey)
4352
* Add support to auto calculate minion count for mods on Bonemeld and Farrul Bloodline (LocalIdentity)
4453
* Add support for Companionship Support (LocalIdentity)
45-
* Add support for Cast on Ward Break + Celestial Mathmatics + Ward bypass / chance to not break Bloodline nodes (LocalIdentity)
54+
* Add support for Cast on Ward Break + Celestial Mathematics + Ward bypass / chance to not break Bloodline nodes (LocalIdentity)
4655
* Add alt aura variant for Impresence (vaisest)
4756
* Add support for Loyalty/damage taken from Companion's Life before you (ltogniolli)
4857
* Add support for Runegraft of the Agile (czarandy)
@@ -91,7 +100,7 @@ VERSION[2.66.0][2026/07/25]
91100
* Fix Brutal Restraint missing Balbala variant (The Traitor) (Sentinent)
92101
* Fix parsing Vaal Unique modifiers on items (vaisest)
93102
* Fix searching for Low Life in Config tab (Blitz54)
94-
* Fix mods that were "Not Supported" in mastery losing poisition when assigning masteries (soratidus999)
103+
* Fix mods that were "Not Supported" in mastery losing position when assigning masteries (soratidus999)
95104

96105
VERSION[2.65.0][2026/04/20]
97106

manifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version='1.0' encoding='UTF-8'?>
22
<PoBVersion>
3-
<Version number="2.66.1" />
3+
<Version number="2.66.2" />
44
<Source part="default" url="https://raw.githubusercontent.com/PathOfBuildingCommunity/PathOfBuilding/{branch}/" />
55
<Source part="runtime" platform="win32" url="https://raw.githubusercontent.com/PathOfBuildingCommunity/PathOfBuilding/{branch}/runtime/" />
66
<Source part="program" url="https://raw.githubusercontent.com/PathOfBuildingCommunity/PathOfBuilding/{branch}/src/" />

spec/System/TestSkills_spec.lua

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,42 @@ describe("TestAttacks", function()
216216
assert.True(math.abs(finalCost - 12) < 0.1) -- floor(12 * 1.5) / 1.5
217217
end)
218218

219+
it("Test flat cost is added before cost efficiency", function()
220+
-- In-game order is ((base cost * multipliers) + flat cost) / (1 + cost efficiency)
221+
build.skillsTab:PasteSocketGroup("Hydrosphere 1/0 1\n")
222+
223+
-- Hydrosphere 12 base mana cost
224+
build.configTab.input.customMods = "+10 to Total Mana Cost\n50% increased Mana Cost Efficiency"
225+
build.configTab:BuildModList()
226+
runCallback("OnFrame")
227+
228+
local finalCost = build.calcsTab.mainOutput.ManaCost
229+
-- (12 + 10) / 1.5 = 14.667
230+
assert.True(math.abs(finalCost - 22 / 1.5) < 0.001)
231+
end)
232+
it("Test flat cost is added before cost efficiency for life costs", function()
233+
build.skillsTab:PasteSocketGroup("Hydrosphere 1/0 1\n")
234+
235+
-- Convert Hydrosphere's 12 base cost to life, then add +10 flat and 50% efficiency
236+
build.configTab.input.customMods = "Skills Cost Life instead of Mana\n+10 to Total Cost\n50% increased Cost Efficiency"
237+
build.configTab:BuildModList()
238+
runCallback("OnFrame")
239+
240+
-- (12 + 10) / 1.5 = 14.667
241+
assert.True(math.abs(build.calcsTab.mainOutput.LifeCost - 22 / 1.5) < 0.001)
242+
end)
243+
244+
it("Test flat cost is added before cost efficiency for energy shield costs (#10003)", function()
245+
build.skillsTab:PasteSocketGroup("Hydrosphere 1/0 1\n")
246+
247+
-- Convert Hydrosphere's 12 base cost to ES, then add +10 flat and 50% efficiency
248+
build.configTab.input.customMods = "Skills Cost Energy Shield instead of Mana or Life\n+10 to Total Cost\n50% increased Cost Efficiency"
249+
build.configTab:BuildModList()
250+
runCallback("OnFrame")
251+
252+
-- (12 + 10) / 1.5 = 14.667
253+
assert.True(math.abs(build.calcsTab.mainOutput.ESCost - 22 / 1.5) < 0.001)
254+
end)
219255
it("Test mana cost efficiency with support gems", function()
220256
-- Test interaction between cost efficiency and cost multipliers
221257
build.skillsTab:PasteSocketGroup("Contagion 6/0 1\nMagnified Area I 1/0 1")

src/Classes/PassiveTree.lua

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -106,33 +106,6 @@ local PassiveTreeClass = newClass("PassiveTree", function(self, treeVersion)
106106
self.internalAscendNameMap = {}
107107
self.classNotables = {}
108108

109-
for classId, class in pairs(self.classes) do
110-
if versionNum >= 3.10 then
111-
-- Migrate to old format
112-
class.classes = class.ascendancies
113-
end
114-
class.classes[0] = { name = "None" }
115-
self.classNameMap[class.name] = classId
116-
for ascendClassId, ascendClass in pairs(class.classes) do
117-
self.ascendNameMap[ascendClass.id or ascendClass.name] = {
118-
classId = classId,
119-
class = class,
120-
ascendClassId = ascendClassId,
121-
ascendClass = ascendClass,
122-
flavourText = ascendClass.flavourText,
123-
flavourTextRect = ascendClass.flavourTextRect,
124-
}
125-
if ascendClass.internalId then
126-
self.internalAscendNameMap[ascendClass.internalId] = {
127-
classId = classId,
128-
class = class,
129-
ascendClassId = ascendClassId,
130-
ascendClass = ascendClass
131-
}
132-
end
133-
end
134-
end
135-
136109
-- hide legacy alternate ascendancies that are no longer obtainable
137110
if self.alternate_ascendancies then
138111
local legacyAlternateAscendancyIds = {
@@ -178,7 +151,37 @@ local PassiveTreeClass = newClass("PassiveTree", function(self, treeVersion)
178151
self.alternate_ascendancies = nil
179152
end
180153
end
181-
154+
155+
for classId, class in pairs(self.classes) do
156+
if versionNum >= 3.10 then
157+
-- Migrate to old format
158+
class.classes = class.ascendancies
159+
end
160+
class.classes[0] = { name = "None" }
161+
self.classNameMap[class.name] = classId
162+
for ascendClassId, ascendClass in pairs(class.classes) do
163+
local entry = {
164+
classId = classId,
165+
class = class,
166+
ascendClassId = ascendClassId,
167+
ascendClass = ascendClass,
168+
flavourText = ascendClass.flavourText,
169+
flavourTextRect = ascendClass.flavourTextRect,
170+
}
171+
if ascendClass.id then
172+
self.ascendNameMap[ascendClass.id] = entry
173+
end
174+
self.ascendNameMap[ascendClass.name] = entry
175+
if ascendClass.internalId then
176+
self.internalAscendNameMap[ascendClass.internalId] = {
177+
classId = classId,
178+
class = class,
179+
ascendClassId = ascendClassId,
180+
ascendClass = ascendClass
181+
}
182+
end
183+
end
184+
end
182185
if self.alternate_ascendancies then
183186
self.secondaryAscendNameMap = { }
184187
local alternate_ascendancies_class = {

src/Modules/CalcOffence.lua

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1756,7 +1756,7 @@ function calcs.offence(env, actor, activeSkill)
17561756
moreType = skillModList:More(skillCfg, val.type.."Cost")
17571757
moreCost = skillModList:More(skillCfg, "Cost")
17581758
inc = skillModList:Sum("INC", skillCfg, val.type.."Cost", "Cost")
1759-
output[costNameRaw] = val.baseCostRaw and m_max(0, m_max(0, (1 + inc / 100) * val.baseCostRaw * moreType * moreCost / costEfficiency) + val.totalCost)
1759+
output[costNameRaw] = val.baseCostRaw and m_max(0, m_max(0, (1 + inc / 100) * val.baseCostRaw * moreType * moreCost) + val.totalCost) / costEfficiency
17601760
if inc < 0 then
17611761
output[costName] = m_max(0, m_ceil((1 + inc / 100) * output[costName]))
17621762
else
@@ -1772,9 +1772,9 @@ function calcs.offence(env, actor, activeSkill)
17721772
else
17731773
output[costName] = m_max(0, m_floor(moreCost * output[costName]))
17741774
end
1775+
output[costName] = m_max(0, output[costName] + val.totalCost)
17751776
-- Apply cost efficiency (similar to reservation efficiency)
17761777
output[costName] = m_max(0, output[costName] / costEfficiency)
1777-
output[costName] = m_max(0, output[costName] + val.totalCost)
17781778
if val.type == "Mana" and hybridLifeCost > 0 then -- Life/Mana Mastery
17791779
output[costName] = m_max(0, m_floor((1 - hybridLifeCost) * output[costName]))
17801780
output[costNameRaw] = output[costNameRaw] and m_max(0, (1 - hybridLifeCost) * output[costNameRaw])
@@ -1785,10 +1785,10 @@ function calcs.offence(env, actor, activeSkill)
17851785
output[costName] = m_floor(val.baseCost + val.baseCostNoMult)
17861786
output[costName] = m_max(0, (1 + inc / 100) * output[costName])
17871787
output[costName] = m_max(0, moreType * output[costName])
1788+
output[costName] = m_max(0, output[costName] + val.totalCost)
17881789
-- Apply cost efficiency for unaffected costs too
17891790
output[costName] = m_max(0, output[costName] / costEfficiency)
1790-
output[costName] = m_max(0, output[costName] + val.totalCost)
1791-
output[costNameRaw] = val.baseCostRaw and m_max(0, m_max(0, (1 + inc / 100) * (val.baseCostRaw + val.baseCostNoMult) * moreType / costEfficiency) + val.totalCost)
1791+
output[costNameRaw] = val.baseCostRaw and m_max(0, m_max(0, (1 + inc / 100) * (val.baseCostRaw + val.baseCostNoMult) * moreType) + val.totalCost) / costEfficiency
17921792
end
17931793
if breakdown and hasCost then
17941794
breakdown[costName] = {
@@ -1815,16 +1815,16 @@ function calcs.offence(env, actor, activeSkill)
18151815
if moreType ~= 1 then
18161816
t_insert(breakdown[costName], s_format("x %.2f ^8(more/less "..val.text.." cost)", moreType))
18171817
end
1818+
if val.totalCost ~= 0 then
1819+
t_insert(breakdown[costName], s_format("%+d ^8(total " .. val.text .. " cost)", val.totalCost))
1820+
end
18181821
if costEfficiency ~= 1 then
18191822
t_insert(breakdown[costName], s_format("/ %.2f ^8(" .. val.text .. " cost efficiency)", costEfficiency))
18201823
end
1821-
if val.totalCost ~= 0 then
1822-
t_insert(breakdown[costName], s_format("%+d ^8(total "..val.text.." cost)", val.totalCost))
1823-
end
18241824
if val.type == "Mana" and hybridLifeCost > 0 then
18251825
t_insert(breakdown[costName], s_format("x %.2f ^8(%d%% paid for with life)", (1-hybridLifeCost), hybridLifeCost*100))
18261826
end
1827-
t_insert(breakdown[costName], s_format("= %"..(val.upfront and "d" or ".2f")..(val.percent and "%%" or ""), output[costName]))
1827+
t_insert(breakdown[costName], s_format("= %" .. (val.upfront and "d" or ".2f") .. (val.percent and "%%" or ""), m_ceil(output[costName])))
18281828
end
18291829
end
18301830
end

0 commit comments

Comments
 (0)