Skip to content

Commit 9068e35

Browse files
committed
Preserve main skill selection across character reimports
Keep exact state matching for unchanged groups. When a group's gems change, relocate it by source skill and preferred slot, then restore the selected active effect after its skill list is rebuilt. Use the existing group guess only when the source skill disappears. Addresses issue 10199.
1 parent bcbca9b commit 9068e35

3 files changed

Lines changed: 108 additions & 0 deletions

File tree

‎spec/System/TestImportReimport_spec.lua‎

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,22 @@ describe("TestImportReimport", function()
5555
}
5656
end
5757

58+
local function pasteSocketGroups(mainSocketGroup, ...)
59+
for _, lines in ipairs({ ... }) do
60+
build.skillsTab:PasteSocketGroup(table.concat(lines, "\n") .. "\n")
61+
end
62+
build.mainSocketGroup = mainSocketGroup
63+
runCallback("OnFrame")
64+
end
65+
66+
local function makeImportItemWithGems(itemTypeLine, inventoryId, ...)
67+
local socketedItems = { }
68+
for index, gemName in ipairs({ ... }) do
69+
socketedItems[index] = makeSocketedGemEntry(index - 1, gemName:match(" Support$") ~= nil, gemName, 20)
70+
end
71+
return makeImportItem(itemTypeLine, inventoryId, socketedItems, "test-import-item-" .. inventoryId)
72+
end
73+
5874
local function reimportSocketedItemsWithOptions(itemTypeLine, inventoryId, socketedItems, clearItems)
5975
build.importTab:ImportItemsAndSkills(buildImportPayload({
6076
makeImportItem(itemTypeLine, inventoryId, socketedItems),
@@ -228,6 +244,52 @@ Blight 20/0 1
228244
assert.is_false(groupsBySlot.Gloves.enabled)
229245
end)
230246

247+
it("preserves the main socket group by skill when supports change", function()
248+
pasteSocketGroups(1,
249+
{ "Slot: Body Armour", "Cleave 20/0 1", "Added Fire Damage 20/0 DISABLED 1" }
250+
)
251+
252+
build.importTab:ImportItemsAndSkills(buildImportPayload({
253+
makeImportItemWithGems("Rawhide Gloves", "Gloves", "Cleave"),
254+
makeImportItemWithGems("Plate Vest", "BodyArmour", "Cleave", "Faster Attacks Support"),
255+
}), false, true, true)
256+
runCallback("OnFrame")
257+
258+
local mainSocketGroup = build.skillsTab.socketGroupList[build.mainSocketGroup]
259+
assert.are.equal("Body Armour", mainSocketGroup.slot)
260+
assert.is_true(mainSocketGroup.gemList[2].enabled)
261+
end)
262+
263+
it("preserves a support-granted main skill when supports change", function()
264+
pasteSocketGroups(1,
265+
{ "Slot: Body Armour", "Cleave 20/0 1", "Prismatic Burst 20/0 1", "Added Fire Damage 20/0 1" }
266+
)
267+
build.skillsTab.socketGroupList[1].mainActiveSkill = 2
268+
269+
build.importTab:ImportItemsAndSkills(buildImportPayload({
270+
makeImportItemWithGems("Plate Vest", "BodyArmour", "Cleave", "Prismatic Burst Support", "Faster Attacks Support"),
271+
}), false, true, true)
272+
runCallback("OnFrame")
273+
274+
local mainSocketGroup = build.skillsTab.socketGroupList[build.mainSocketGroup]
275+
assert.are.equal("PrismaticBurst", mainSocketGroup.displaySkillList[mainSocketGroup.mainActiveSkill].activeEffect.grantedEffect.id)
276+
end)
277+
278+
it("guesses a new main socket group when the previous main skill is gone", function()
279+
pasteSocketGroups(1,
280+
{ "Slot: Body Armour", "Cleave 20/0 1" },
281+
{ "Slot: Boots", "Frostblink 20/0 1" }
282+
)
283+
284+
build.importTab:ImportItemsAndSkills(buildImportPayload({
285+
makeImportItemWithGems("Iron Greaves", "Boots", "Frostblink"),
286+
makeImportItemWithGems("Rawhide Gloves", "Gloves", "Fireball", "Added Fire Damage Support"),
287+
}), false, true, true)
288+
runCallback("OnFrame")
289+
290+
assert.are.equal("Gloves", build.skillsTab.socketGroupList[build.mainSocketGroup].slot)
291+
end)
292+
231293
it("preserves skill part selection when reimporting items and skills", function()
232294
assertReimportPreservesSkillSubstate("Helmet", "Iron Hat", "Helm", "Blight", "skillPart", 2)
233295
end)

‎src/Classes/ImportTab.lua‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,22 @@ local function getSocketGroupReimportKey(socketGroup)
12671267
}, SOCKET_GROUP_REIMPORT_KEY_SEPARATOR)
12681268
end
12691269

1270+
local function findSocketGroupBySkillId(socketGroupList, skillId, preferredSlot)
1271+
local fallbackIndex
1272+
for index, socketGroup in ipairs(socketGroupList) do
1273+
for _, gem in ipairs(socketGroup.gemList) do
1274+
if gem.skillId == skillId then
1275+
if socketGroup.slot == preferredSlot then
1276+
return index
1277+
end
1278+
fallbackIndex = fallbackIndex or index
1279+
break
1280+
end
1281+
end
1282+
end
1283+
return fallbackIndex
1284+
end
1285+
12701286
local function snapshotSocketGroupReimportState(socketGroup, isMainGroup)
12711287
local gemStates = { }
12721288
for gemIndex, gem in ipairs(socketGroup.gemList) do
@@ -1390,7 +1406,18 @@ function ImportTabClass:ImportItemsAndSkills(charData, clearItems, clearSkills,
13901406
local mainSkillEmpty = #self.build.skillsTab.socketGroupList == 0
13911407
local skillOrder
13921408
local preservedSocketGroupStateByKey
1409+
local preservedMainSkillId
1410+
local preservedMainSkillSlot
1411+
local preservedMainActiveSkillId
13931412
if clearSkills then
1413+
local mainSocketGroup = self.build.skillsTab.socketGroupList[self.build.mainSocketGroup]
1414+
local mainActiveSkill = mainSocketGroup and mainSocketGroup.displaySkillList
1415+
and mainSocketGroup.displaySkillList[mainSocketGroup.mainActiveSkill or 1]
1416+
local mainActiveEffect = mainActiveSkill and mainActiveSkill.activeEffect
1417+
local mainSkillSource = mainActiveEffect and mainActiveEffect.srcInstance
1418+
preservedMainSkillId = mainSkillSource and mainSkillSource.skillId
1419+
preservedMainSkillSlot = mainSocketGroup and mainSocketGroup.slot
1420+
preservedMainActiveSkillId = mainActiveEffect and mainActiveEffect.grantedEffect and mainActiveEffect.grantedEffect.id
13941421
skillOrder = { }
13951422
preservedSocketGroupStateByKey = { }
13961423
for _, socketGroup in ipairs(self.build.skillsTab.socketGroupList) do
@@ -1472,6 +1499,15 @@ function ImportTabClass:ImportItemsAndSkills(charData, clearItems, clearSkills,
14721499
end
14731500
if restoredMainSocketGroup then
14741501
self.build.mainSocketGroup = restoredMainSocketGroup
1502+
elseif not mainSkillEmpty then
1503+
local matchingMainSocketGroup = preservedMainSkillId
1504+
and findSocketGroupBySkillId(self.build.skillsTab.socketGroupList, preservedMainSkillId, preservedMainSkillSlot)
1505+
if matchingMainSocketGroup then
1506+
self.build.mainSocketGroup = matchingMainSocketGroup
1507+
self.build.skillsTab.socketGroupList[matchingMainSocketGroup].pendingMainActiveSkillId = preservedMainActiveSkillId
1508+
else
1509+
self.build.mainSocketGroup = self:GuessMainSocketGroup()
1510+
end
14751511
end
14761512
end
14771513
if mainSkillEmpty then

‎src/Modules/CalcSetup.lua‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,6 +1773,15 @@ function calcs.initEnv(build, mode, override, specEnv)
17731773
env.player.modDB:AddMod(modLib.setSource(value.value, groupCfg.slotName or ""))
17741774
end
17751775

1776+
if index == env.mainSocketGroup and env.mode == "MAIN" and group.pendingMainActiveSkillId then
1777+
for activeSkillIndex, activeSkill in ipairs(socketGroupSkillList) do
1778+
if activeSkill.activeEffect.grantedEffect.id == group.pendingMainActiveSkillId then
1779+
group.mainActiveSkill = activeSkillIndex
1780+
break
1781+
end
1782+
end
1783+
end
1784+
17761785
if index == env.mainSocketGroup and #socketGroupSkillList > 0 then
17771786
-- Select the main skill from this socket group
17781787
local activeSkillIndex
@@ -1790,6 +1799,7 @@ function calcs.initEnv(build, mode, override, specEnv)
17901799
end
17911800

17921801
if env.mode == "MAIN" then
1802+
group.pendingMainActiveSkillId = nil
17931803
-- Create display label for the socket group if the user didn't specify one
17941804
if group.label and group.label:match("%S") then
17951805
group.displayLabel = group.label

0 commit comments

Comments
 (0)