Skip to content

Commit b0ddd85

Browse files
committed
Fix saved rolls shifting when old mod lines are now item properties
PoB 2.66 and older saved in-game property lines such as "Intangibility: 5%" and "Memory Strands: 58", and flask lines such as "Lasts 4.00 Seconds", as mod lines with a ModRange entry each. 2.67 reads them as item properties or skips them, so ItemsTab:Load applied every later ModRange one line too early: an Entropy Grip saved in 2.66 loaded its "+(10-13) to all Attributes" roll at 0.5 instead of 1. Save writes at most one ModRange per mod line, so more entries than lines means the saved positions no longer match. The entries are then ignored and the {range:} tags of the item text are kept. The line count leaves out talisman enchants added from the base data, as the ModRange id loop already does; both now use countSavedModLines.
1 parent 3f443a7 commit b0ddd85

2 files changed

Lines changed: 40 additions & 3 deletions

File tree

‎spec/System/TestItemParse_spec.lua‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,28 @@ Implicits: 0
10531053
assert.are.equals(1, #item.explicitModLines)
10541054
end)
10551055

1056+
it("keeps saved rolls when a property was saved among the modifier lines", function()
1057+
loadBuildFromXML([[
1058+
<PathOfBuilding>
1059+
<Build level="1" targetVersion="3_0" className="Scion" ascendClassName="None" mainSocketGroup="1"/>
1060+
<Items activeItemSet="1">
1061+
<Item id="1">
1062+
Rarity: RARE
1063+
Pain Shell
1064+
Vaal Regalia
1065+
Implicits: 0
1066+
Intangibility: 7%
1067+
{range:0}+(10-13) to all Attributes
1068+
<ModRange id="1" range="0.5"/>
1069+
<ModRange id="2" range="0"/>
1070+
</Item>
1071+
<ItemSet id="1"/>
1072+
</Items>
1073+
</PathOfBuilding>]])
1074+
1075+
assert.are.equals(0, build.itemsTab.items[1].explicitModLines[1].range)
1076+
end)
1077+
10561078
it("preserves cluster jewel enchants from advanced copy", function()
10571079
newBuild()
10581080
runCallback("onFrame")

‎src/Classes/ItemsTab.lua‎

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1218,6 +1218,11 @@ function ItemsTabClass:Load(xml, dbFileName)
12181218
self.itemSets = { }
12191219
self.itemSetOrderList = { }
12201220
self.tradeQuery.statSortSelectionList = { }
1221+
-- Enchants from the base data are only added to an item text without enchants and were not in the saved text,
1222+
-- so saved ModRange ids skip the whole list
1223+
local function countSavedModLines(modLines)
1224+
return modLines[1] and modLines[1].addedFromBase and 0 or #modLines
1225+
end
12211226
for _, node in ipairs(xml) do
12221227
if node.elem == "Item" then
12231228
local item = new("Item"):Item("")
@@ -1243,19 +1248,29 @@ function ItemsTabClass:Load(xml, dbFileName)
12431248
item.hasAltVariant5 = true
12441249
item.variantAlt5 = tonumber(node.attrib.variantAlt5)
12451250
end
1251+
local modRangeCount = 0
1252+
for _, child in ipairs(node) do
1253+
if type(child) == "table" and child.elem == "ModRange" then
1254+
modRangeCount = modRangeCount + 1
1255+
end
1256+
end
1257+
local ignoreModRanges
12461258
for _, child in ipairs(node) do
12471259
if type(child) == "string" then
12481260
item:ParseRaw(child)
1249-
elseif child.elem == "ModRange" then
1261+
-- Save writes at most one ModRange per mod line. More entries than lines means some saved lines are
1262+
-- no longer mod lines (e.g. Intangibility before 2.67), so the ids no longer match their lines and the
1263+
-- {range:} tags of the item text are kept instead
1264+
ignoreModRanges = modRangeCount > countSavedModLines(item.enchantModLines) + #item.scourgeModLines + #item.implicitModLines + #item.explicitModLines + #item.crucibleModLines
1265+
elseif child.elem == "ModRange" and not ignoreModRanges then
12501266
local id = tonumber(child.attrib.id) or 0
12511267
local range = tonumber(child.attrib.range) or 1
12521268
-- This is garbage, but needed due to change to separate mod line lists
12531269
-- 'ModRange' elements are legacy though, so is this actually needed? :<
12541270
-- Maybe it is? Maybe it isn't? Maybe up is down? Maybe good is bad? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
12551271
-- Sorry, cluster jewels are making me crazy(-ier)
12561272
for _, list in ipairs{item.buffModLines, item.enchantModLines, item.scourgeModLines, item.implicitModLines, item.explicitModLines, item.crucibleModLines} do
1257-
-- Enchants added from the base data were not in the saved item text, so saved ids skip them
1258-
local savedLineCount = list[1] and list[1].addedFromBase and 0 or #list
1273+
local savedLineCount = countSavedModLines(list)
12591274
if id <= savedLineCount then
12601275
-- Versions that could not parse "value(min-max)" lines saved them as is with a default ModRange
12611276
if not list[id].rangeFromValue then

0 commit comments

Comments
 (0)