@@ -1696,34 +1696,74 @@ function CompareTabClass:DrawSkills(vp, compareEntry)
16961696 local pGroups = self .primaryBuild .skillsTab and self .primaryBuild .skillsTab .socketGroupList or {}
16971697 local cGroups = compareEntry .skillsTab and compareEntry .skillsTab .socketGroupList or {}
16981698
1699- -- Helper: get the main (non-support) skill name from a socket group
1700- local function getMainSkillName (group )
1699+ -- Helper: get the set of gem names in a socket group
1700+ local function getGemNameSet (group )
1701+ local set = {}
17011702 for _ , gem in ipairs (group .gemList or {}) do
1702- if gem .grantedEffect and not gem .grantedEffect .support then
1703- return gem .grantedEffect .name
1703+ local name = gem .grantedEffect and gem .grantedEffect .name or gem .nameSpec
1704+ if name then
1705+ set [name ] = true
17041706 end
17051707 end
1706- return group . displayLabel or group . label
1708+ return set
17071709 end
17081710
1709- -- Build lookup: main skill name → compare group index
1710- local cNameToIndex = {}
1711+ -- Helper: compute Jaccard similarity between two gem name sets
1712+ local function groupSimilarity (setA , setB )
1713+ local intersection = 0
1714+ local union = 0
1715+ local allKeys = {}
1716+ for k in pairs (setA ) do allKeys [k ] = true end
1717+ for k in pairs (setB ) do allKeys [k ] = true end
1718+ for k in pairs (allKeys ) do
1719+ union = union + 1
1720+ if setA [k ] and setB [k ] then
1721+ intersection = intersection + 1
1722+ end
1723+ end
1724+ if union == 0 then return 0 end
1725+ return intersection / union
1726+ end
1727+
1728+ -- Build gem name sets for all groups
1729+ local pSets = {}
1730+ for i , group in ipairs (pGroups ) do
1731+ pSets [i ] = getGemNameSet (group )
1732+ end
1733+ local cSets = {}
17111734 for i , group in ipairs (cGroups ) do
1712- local name = getMainSkillName (group )
1713- if name and not cNameToIndex [name ] then
1714- cNameToIndex [name ] = i
1735+ cSets [i ] = getGemNameSet (group )
1736+ end
1737+
1738+ -- Compute all pairwise similarity scores
1739+ local scorePairs = {}
1740+ for pi = 1 , # pGroups do
1741+ for ci = 1 , # cGroups do
1742+ local score = groupSimilarity (pSets [pi ], cSets [ci ])
1743+ if score > 0 then
1744+ t_insert (scorePairs , { pIdx = pi , cIdx = ci , score = score })
1745+ end
17151746 end
17161747 end
17171748
1718- -- Match primary groups to compare groups by main skill name
1719- local renderPairs = {}
1749+ -- Sort by similarity descending (best matches first)
1750+ table.sort (scorePairs , function (a , b ) return a .score > b .score end )
1751+
1752+ -- Greedy matching: assign best pairs first, each group used at most once
1753+ local pMatched = {}
17201754 local cMatched = {}
1721- for i , group in ipairs (pGroups ) do
1722- local name = getMainSkillName (group )
1723- if name and cNameToIndex [name ] and not cMatched [cNameToIndex [name ]] then
1724- t_insert (renderPairs , { pIdx = i , cIdx = cNameToIndex [name ] })
1725- cMatched [cNameToIndex [name ]] = true
1726- else
1755+ local renderPairs = {}
1756+ for _ , sp in ipairs (scorePairs ) do
1757+ if not pMatched [sp .pIdx ] and not cMatched [sp .cIdx ] then
1758+ t_insert (renderPairs , { pIdx = sp .pIdx , cIdx = sp .cIdx })
1759+ pMatched [sp .pIdx ] = true
1760+ cMatched [sp .cIdx ] = true
1761+ end
1762+ end
1763+
1764+ -- Add unmatched primary groups
1765+ for i = 1 , # pGroups do
1766+ if not pMatched [i ] then
17271767 t_insert (renderPairs , { pIdx = i , cIdx = nil })
17281768 end
17291769 end
0 commit comments