From d6357c184144a35029f7014de28586e09db9cfc9 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Fri, 15 May 2026 07:35:30 +0300 Subject: [PATCH 1/7] Add abyss sockets to comparison tab items subtab --- src/Classes/CompareTab.lua | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Classes/CompareTab.lua b/src/Classes/CompareTab.lua index 0e2869f0fb..ebba4988b7 100644 --- a/src/Classes/CompareTab.lua +++ b/src/Classes/CompareTab.lua @@ -3550,6 +3550,25 @@ function CompareTabClass:DrawItems(vp, compareEntry, inputEvents) if self:ShouldShowRing3(compareEntry) then t_insert(baseSlots, 10, "Ring 3") end + + -- abyssal sockets + local socketSet = {} + local function saveActiveAbyssSocket(k, v) + if type(k) == "string" and k:match("Abyssal Socket") + and v.selItemId and v.selItemId ~= 0 then + socketSet[k] = true + end + end + for k, v in pairs(compareEntry.itemsTab.activeItemSet) do + saveActiveAbyssSocket(k, v) + end + for k, v in pairs(self.primaryBuild.itemsTab.activeItemSet) do + saveActiveAbyssSocket(k, v) + end + for k, _ in pairs(socketSet) do + t_insert(baseSlots, k) + end + local primaryEnv = self.primaryBuild.calcsTab and self.primaryBuild.calcsTab.mainEnv local primaryHasRing3 = primaryEnv and primaryEnv.modDB:Flag(nil, "AdditionalRingSlot") local lineHeight = 20 From 5b17e5b074b21ae6dd8b016ebde718f229c21e92 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Fri, 15 May 2026 07:54:01 +0300 Subject: [PATCH 2/7] Also add abyssal sockets to power report --- src/Classes/CompareTab.lua | 51 +++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/src/Classes/CompareTab.lua b/src/Classes/CompareTab.lua index ebba4988b7..861e0fcb2c 100644 --- a/src/Classes/CompareTab.lua +++ b/src/Classes/CompareTab.lua @@ -2477,6 +2477,28 @@ function CompareTabClass:ComparePowerBuilder(compareEntry, powerStat, categories if self:ShouldShowRing3(compareEntry) then t_insert(baseSlots, 10, "Ring 3") end + + -- abyssal sockets + local socketSet = {} + local function saveActiveAbyssSocket(k, v) + if type(k) == "string" and k:match("Abyssal Socket") + and v.shown() then + socketSet[k] = (socketSet[k] or 0) + 1 + end + end + for k, v in pairs(compareEntry.itemsTab.slots) do + saveActiveAbyssSocket(k, v) + end + for k, v in pairs(self.primaryBuild.itemsTab.slots) do + saveActiveAbyssSocket(k, v) + end + -- consider only if both have the socket allocated + for k, count in pairs(socketSet) do + if count == 2 then + t_insert(baseSlots, k) + end + end + for _, slotName in ipairs(baseSlots) do local cSlot = compareEntry.itemsTab and compareEntry.itemsTab.slots[slotName] local cItem = cSlot and compareEntry.itemsTab.items[cSlot.selItemId] @@ -2641,6 +2663,28 @@ function CompareTabClass:ComparePowerBuilder(compareEntry, powerStat, categories if self:ShouldShowRing3(compareEntry) then t_insert(baseSlots, 10, "Ring 3") end + + -- abyssal sockets + local socketSet = {} + local function saveActiveAbyssSocket(k, v) + if type(k) == "string" and k:match("Abyssal Socket") + and v.shown() then + socketSet[k] = (socketSet[k] or 0) + 1 + end + end + for k, v in pairs(compareEntry.itemsTab.slots) do + saveActiveAbyssSocket(k, v) + end + for k, v in pairs(self.primaryBuild.itemsTab.slots) do + saveActiveAbyssSocket(k, v) + end + -- consider only if both have the socket allocated + for k, count in pairs(socketSet) do + if count == 2 then + t_insert(baseSlots, k) + end + end + for _, slotName in ipairs(baseSlots) do local cSlot = compareEntry.itemsTab and compareEntry.itemsTab.slots[slotName] local cItem = cSlot and compareEntry.itemsTab.items[cSlot.selItemId] @@ -3555,16 +3599,17 @@ function CompareTabClass:DrawItems(vp, compareEntry, inputEvents) local socketSet = {} local function saveActiveAbyssSocket(k, v) if type(k) == "string" and k:match("Abyssal Socket") - and v.selItemId and v.selItemId ~= 0 then + and v.shown() then socketSet[k] = true end end - for k, v in pairs(compareEntry.itemsTab.activeItemSet) do + for k, v in pairs(compareEntry.itemsTab.slots) do saveActiveAbyssSocket(k, v) end - for k, v in pairs(self.primaryBuild.itemsTab.activeItemSet) do + for k, v in pairs(self.primaryBuild.itemsTab.slots) do saveActiveAbyssSocket(k, v) end + -- show if either has a socket allocated for k, _ in pairs(socketSet) do t_insert(baseSlots, k) end From a24670facb0d040b2799343aa8b3ca9d2de45fa5 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Sun, 17 May 2026 05:34:53 +0300 Subject: [PATCH 3/7] Fix comparison abyss socket ordering --- src/Classes/CompareTab.lua | 84 ++++++++++++-------------------------- 1 file changed, 25 insertions(+), 59 deletions(-) diff --git a/src/Classes/CompareTab.lua b/src/Classes/CompareTab.lua index 861e0fcb2c..3b31478a6c 100644 --- a/src/Classes/CompareTab.lua +++ b/src/Classes/CompareTab.lua @@ -2478,26 +2478,8 @@ function CompareTabClass:ComparePowerBuilder(compareEntry, powerStat, categories t_insert(baseSlots, 10, "Ring 3") end - -- abyssal sockets - local socketSet = {} - local function saveActiveAbyssSocket(k, v) - if type(k) == "string" and k:match("Abyssal Socket") - and v.shown() then - socketSet[k] = (socketSet[k] or 0) + 1 - end - end - for k, v in pairs(compareEntry.itemsTab.slots) do - saveActiveAbyssSocket(k, v) - end - for k, v in pairs(self.primaryBuild.itemsTab.slots) do - saveActiveAbyssSocket(k, v) - end - -- consider only if both have the socket allocated - for k, count in pairs(socketSet) do - if count == 2 then - t_insert(baseSlots, k) - end - end + -- we only use jewel slots if both sides have them available + self:AddAbyssSockets(compareEntry, baseSlots, true) for _, slotName in ipairs(baseSlots) do local cSlot = compareEntry.itemsTab and compareEntry.itemsTab.slots[slotName] @@ -2664,27 +2646,9 @@ function CompareTabClass:ComparePowerBuilder(compareEntry, powerStat, categories t_insert(baseSlots, 10, "Ring 3") end - -- abyssal sockets - local socketSet = {} - local function saveActiveAbyssSocket(k, v) - if type(k) == "string" and k:match("Abyssal Socket") - and v.shown() then - socketSet[k] = (socketSet[k] or 0) + 1 - end - end - for k, v in pairs(compareEntry.itemsTab.slots) do - saveActiveAbyssSocket(k, v) - end - for k, v in pairs(self.primaryBuild.itemsTab.slots) do - saveActiveAbyssSocket(k, v) - end - -- consider only if both have the socket allocated - for k, count in pairs(socketSet) do - if count == 2 then - t_insert(baseSlots, k) - end - end - + -- we only use jewel slots if both sides have them available + self:AddAbyssSockets(compareEntry, baseSlots, true) + for _, slotName in ipairs(baseSlots) do local cSlot = compareEntry.itemsTab and compareEntry.itemsTab.slots[slotName] local cItem = cSlot and compareEntry.itemsTab.items[cSlot.selItemId] @@ -3589,30 +3553,32 @@ function CompareTabClass:ShouldShowRing3(compareEntry) return primaryHas or compareHas end +--- @param comparison table +--- @param destTable string[] +--- @param requireBothSides boolean +function CompareTabClass:AddAbyssSockets(comparison, destTable, requireBothSides) + local equipmentSlots = {"Weapon 1", "Weapon 2", "Helmet", "Body Armour", "Gloves", "Boots", "Belt"} + + for _, slot in ipairs(equipmentSlots) do + for number = 1, 6 do + local abyssalSocketName = string.format("%s Abyssal Socket %d", slot, number) + local mainHas = self.primaryBuild.itemsTab.slots[abyssalSocketName].shown() + local comparisonHas = comparison.itemsTab.slots[abyssalSocketName].shown() + if (requireBothSides and mainHas and comparisonHas) + or ((not requireBothSides) and (mainHas or comparisonHas)) then + table.insert(destTable, abyssalSocketName) + end + end + end +end + function CompareTabClass:DrawItems(vp, compareEntry, inputEvents) local baseSlots = { "Weapon 1", "Weapon 2", "Helmet", "Body Armour", "Gloves", "Boots", "Amulet", "Ring 1", "Ring 2", "Belt", "Flask 1", "Flask 2", "Flask 3", "Flask 4", "Flask 5" } if self:ShouldShowRing3(compareEntry) then t_insert(baseSlots, 10, "Ring 3") end - -- abyssal sockets - local socketSet = {} - local function saveActiveAbyssSocket(k, v) - if type(k) == "string" and k:match("Abyssal Socket") - and v.shown() then - socketSet[k] = true - end - end - for k, v in pairs(compareEntry.itemsTab.slots) do - saveActiveAbyssSocket(k, v) - end - for k, v in pairs(self.primaryBuild.itemsTab.slots) do - saveActiveAbyssSocket(k, v) - end - -- show if either has a socket allocated - for k, _ in pairs(socketSet) do - t_insert(baseSlots, k) - end + self:AddAbyssSockets(compareEntry, baseSlots, false) local primaryEnv = self.primaryBuild.calcsTab and self.primaryBuild.calcsTab.mainEnv local primaryHasRing3 = primaryEnv and primaryEnv.modDB:Flag(nil, "AdditionalRingSlot") From 16eb05659b7eab454a3e9ddb1a6642a1d034abb8 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Sun, 17 May 2026 06:08:28 +0300 Subject: [PATCH 4/7] Unequip jewels from inactive abyss sockets --- src/Classes/ItemSlotControl.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Classes/ItemSlotControl.lua b/src/Classes/ItemSlotControl.lua index c6cceeaeb4..d7b549f3a2 100644 --- a/src/Classes/ItemSlotControl.lua +++ b/src/Classes/ItemSlotControl.lua @@ -102,6 +102,11 @@ function ItemSlotClass:Populate() end for i, abyssalSocket in ipairs(self.abyssalSocketList) do abyssalSocket.inactive = i > abyssalSocketCount + if abyssalSocket.inactive then + -- this can be inconvenient, but otherwise it is possible to double + -- equip jewels by moving the jewel while the socket is inactive + abyssalSocket:SetSelItemId(0) + end end end From 7637829c2354cf9757b94187fc2207fe6512f4bc Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Sun, 17 May 2026 09:35:17 +0300 Subject: [PATCH 5/7] Account for abyss sockets in comparison power report --- src/Classes/CompareTab.lua | 47 +++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/Classes/CompareTab.lua b/src/Classes/CompareTab.lua index 3b31478a6c..7aa62ac6e3 100644 --- a/src/Classes/CompareTab.lua +++ b/src/Classes/CompareTab.lua @@ -2657,19 +2657,64 @@ function CompareTabClass:ComparePowerBuilder(compareEntry, powerStat, categories if cItem and cItem.raw and not (pItem and pItem.name == cItem.name) then local newItem = new("Item", cItem.raw) newItem:NormaliseQuality() + + -- if our comparison has abyssal jewels, but the primary build + -- doesn't, add those temporarily to the build to work around + -- calcfunc not being able to take in multiple items + local cmpJewels = {} + local oldEquipped = {} + if newItem.abyssalSocketCount > 0 then + for idx = 1, newItem.abyssalSocketCount do + local abyssSlotName = string.format("%s Abyssal Socket %d", slotName, idx) + local cmpJewelSlot = compareEntry.itemsTab.slots[abyssSlotName] + -- save old id and unequip existing + oldEquipped[abyssSlotName] = self.primaryBuild.itemsTab.slots[abyssSlotName] + self.primaryBuild.itemsTab.slots[abyssSlotName]:SetSelItemId(0) + if cmpJewelSlot.selItemId > 0 then + local cmpJewel = compareEntry.itemsTab.items[cmpJewelSlot.selItemId] + -- due to a previous bug where jewel slots didn't + -- get cleared when becoming inactive, so the item + -- might not exist + if cmpJewel then + -- copy item + local itemCopy = new("Item", cmpJewel:BuildRaw()) + table.insert(cmpJewels, itemCopy) + self.primaryBuild.itemsTab:AddItem(itemCopy, false) + + -- equip copied + self.primaryBuild.itemsTab.slots[abyssSlotName]:SetSelItemId(itemCopy.id) + end + end + end + end + + local output = calcFunc({ repSlotName = slotName, repItem = newItem }, useFullDPS) local impact = self.primaryBuild.calcsTab:CalculatePowerStat(powerStat, output, calcBase) local impactStr, impactVal, combinedImpactStr, impactPercent, impactIsZero = formatImpact(impact) + -- restore abyss jewel state + if newItem.abyssalSocketCount > 0 then + for k, v in pairs(oldEquipped) do + self.primaryBuild.itemsTab.slots[k]:SetSelItemId(v) + end + for _, item in ipairs(cmpJewels) do + self.primaryBuild.itemsTab:DeleteItem(item) + end + end + if not impactIsZero then -- Get rarity color for item name local rarityColor = colorCodes[cItem.rarity] or colorCodes.NORMAL + + local abyssJewelText = #cmpJewels > 0 and + s_format(", %d Jewel%s", #cmpJewels, #cmpJewels > 1 and "s" or "") or "" t_insert(results, { category = "Item", categoryColor = rarityColor, nameColor = rarityColor, - name = (cItem.name or "Unknown") .. ", " .. slotName, + name = (cItem.name or "Unknown") .. ", " .. slotName .. abyssJewelText, itemObj = newItem, slotName = slotName, impact = impactVal, From 3fdd642266ac2ad7c6bc3245b22bc5552cad7aad Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Sun, 17 May 2026 09:46:33 +0300 Subject: [PATCH 6/7] Add weapon swap to comparison items tab --- src/Classes/CompareTab.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Classes/CompareTab.lua b/src/Classes/CompareTab.lua index 7aa62ac6e3..300bbaa7b7 100644 --- a/src/Classes/CompareTab.lua +++ b/src/Classes/CompareTab.lua @@ -3602,8 +3602,8 @@ end --- @param destTable string[] --- @param requireBothSides boolean function CompareTabClass:AddAbyssSockets(comparison, destTable, requireBothSides) - local equipmentSlots = {"Weapon 1", "Weapon 2", "Helmet", "Body Armour", "Gloves", "Boots", "Belt"} - + local equipmentSlots = { "Weapon 1", "Weapon 2", "Weapon 1 Swap", "Weapon 2 Swap", "Helmet", "Body Armour", "Gloves", + "Boots", "Belt" } for _, slot in ipairs(equipmentSlots) do for number = 1, 6 do local abyssalSocketName = string.format("%s Abyssal Socket %d", slot, number) @@ -3618,7 +3618,8 @@ function CompareTabClass:AddAbyssSockets(comparison, destTable, requireBothSides end function CompareTabClass:DrawItems(vp, compareEntry, inputEvents) - local baseSlots = { "Weapon 1", "Weapon 2", "Helmet", "Body Armour", "Gloves", "Boots", "Amulet", "Ring 1", "Ring 2", "Belt", "Flask 1", "Flask 2", "Flask 3", "Flask 4", "Flask 5" } + local baseSlots = { "Weapon 1", "Weapon 2", "Weapon 1 Swap", "Weapon 2 Swap", "Helmet", "Body Armour", "Gloves", + "Boots", "Amulet", "Ring 1", "Ring 2", "Belt", "Flask 1", "Flask 2", "Flask 3", "Flask 4", "Flask 5" } if self:ShouldShowRing3(compareEntry) then t_insert(baseSlots, 10, "Ring 3") end From 5ac85f4cb989ba85515f390b97d7663aa4462105 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Sun, 17 May 2026 19:49:09 +1000 Subject: [PATCH 7/7] Fix abyss sockets removing when running compare We were not using the item id to use when resetting causing jewels to not equip after running the compare to another build with an abyss jewel --- src/Classes/CompareTab.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Classes/CompareTab.lua b/src/Classes/CompareTab.lua index 300bbaa7b7..24506313c6 100644 --- a/src/Classes/CompareTab.lua +++ b/src/Classes/CompareTab.lua @@ -2668,8 +2668,9 @@ function CompareTabClass:ComparePowerBuilder(compareEntry, powerStat, categories local abyssSlotName = string.format("%s Abyssal Socket %d", slotName, idx) local cmpJewelSlot = compareEntry.itemsTab.slots[abyssSlotName] -- save old id and unequip existing - oldEquipped[abyssSlotName] = self.primaryBuild.itemsTab.slots[abyssSlotName] - self.primaryBuild.itemsTab.slots[abyssSlotName]:SetSelItemId(0) + local primaryJewelSlot = self.primaryBuild.itemsTab.slots[abyssSlotName] + oldEquipped[abyssSlotName] = primaryJewelSlot.selItemId + primaryJewelSlot:SetSelItemId(0) if cmpJewelSlot.selItemId > 0 then local cmpJewel = compareEntry.itemsTab.items[cmpJewelSlot.selItemId] -- due to a previous bug where jewel slots didn't