Skip to content

Commit e6cf234

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 510e038 commit e6cf234

3 files changed

Lines changed: 110 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 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 preservedMainGroupSlot
1411+
local preservedMainGrantedEffectId
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 srcInstance = mainActiveEffect and mainActiveEffect.srcInstance
1418+
preservedMainSkillId = srcInstance and srcInstance.skillId
1419+
preservedMainGroupSlot = mainSocketGroup and mainSocketGroup.slot
1420+
preservedMainGrantedEffectId = 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, preservedMainGroupSlot)
1505+
if matchingMainSocketGroup then
1506+
self.build.mainSocketGroup = matchingMainSocketGroup
1507+
self.build.skillsTab.socketGroupList[matchingMainSocketGroup].pendingMainGrantedEffectId = preservedMainGrantedEffectId
1508+
else
1509+
self.build.mainSocketGroup = self:GuessMainSocketGroup()
1510+
end
14751511
end
14761512
end
14771513
if mainSkillEmpty then

‎src/Modules/CalcSetup.lua‎

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

1776+
-- Reimport can defer a support-granted selection until this MAIN skill list exists.
1777+
-- Consume it once, then clear it below.
1778+
if index == env.mainSocketGroup and env.mode == "MAIN" and group.pendingMainGrantedEffectId then
1779+
for activeSkillIndex, activeSkill in ipairs(socketGroupSkillList) do
1780+
if activeSkill.activeEffect.grantedEffect.id == group.pendingMainGrantedEffectId then
1781+
group.mainActiveSkill = activeSkillIndex
1782+
break
1783+
end
1784+
end
1785+
end
1786+
17761787
if index == env.mainSocketGroup and #socketGroupSkillList > 0 then
17771788
-- Select the main skill from this socket group
17781789
local activeSkillIndex
@@ -1790,6 +1801,7 @@ function calcs.initEnv(build, mode, override, specEnv)
17901801
end
17911802

17921803
if env.mode == "MAIN" then
1804+
group.pendingMainGrantedEffectId = nil
17931805
-- Create display label for the socket group if the user didn't specify one
17941806
if group.label and group.label:match("%S") then
17951807
group.displayLabel = group.label

0 commit comments

Comments
 (0)