Skip to content

Commit 2474b83

Browse files
Extend default gem level functionality (#4724)
* Extend default gem level functionality * Improve hovered gem tooltip behavior .. and add awakened maximum gem level option. * Add default gem level dropdown tooltips * Remove WIP comment * Clean up variables * Merge #4761 + Change default gem level list order Merged "Hide gems when using match gems to character level if they are above character level" from #4761 by @QuickStick123 Reordered default gem level list so "normal maximum" is first, as "match character level" has potentially confusing behavior (hiding gems below character level) that users need to opt-in to. Co-Authored-By: QuickStick <31533893+QuickStick123@users.noreply.github.com> * Rebuild sort cache on defaultLevel change .. and skip rebuilding sort cache on character level change if we don't care about the character level. * Fix default gem level missing initialization .. and slightly improve sortCache behavior. * Misc formatting improvements * Call PopulateGemList() on sortCache initialization This fixes a bug where the gem list was never initialized correctly on new/empty socket groups. * Update GemSelectControl.lua * Handle legacy configuration settings Co-authored-by: QuickStick <31533893+QuickStick123@users.noreply.github.com>
1 parent dedba3d commit 2474b83

File tree

2 files changed

+215
-148
lines changed

2 files changed

+215
-148
lines changed

src/Classes/GemSelectControl.lua

Lines changed: 71 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ local altQualMap = {
2121

2222
local GemSelectClass = newClass("GemSelectControl", "EditControl", function(self, anchor, x, y, width, height, skillsTab, index, changeFunc, forceTooltip)
2323
self.EditControl(anchor, x, y, width, height, nil, nil, "^ %a':-")
24-
self.controls.scrollBar = new("ScrollBarControl", {"TOPRIGHT",self,"TOPRIGHT"}, -1, 0, 18, 0, (height - 4) * 4)
24+
self.controls.scrollBar = new("ScrollBarControl", { "TOPRIGHT", self, "TOPRIGHT" }, -1, 0, 18, 0, (height - 4) * 4)
2525
self.controls.scrollBar.y = function()
2626
local width, height = self:GetSize()
2727
return height + 1
@@ -62,16 +62,21 @@ function GemSelectClass:PopulateGemList()
6262
local showAll = self.skillsTab.showSupportGemTypes == "ALL"
6363
local showAwakened = self.skillsTab.showSupportGemTypes == "AWAKENED"
6464
local showNormal = self.skillsTab.showSupportGemTypes == "NORMAL"
65+
local matchLevel = self.skillsTab.defaultGemLevel == "characterLevel"
66+
local characterLevel = self.skillsTab.build and self.skillsTab.build.characterLevel or 1
6567
for gemId, gemData in pairs(self.skillsTab.build.data.gems) do
66-
if (showAwakened or showAll) and gemData.grantedEffect.plusVersionOf then
67-
self.gems["Default:" .. gemId] = gemData
68-
elseif showNormal or showAll then
69-
if self.skillsTab.showAltQualityGems and self.skillsTab.defaultGemQuality or 0 > 0 then
70-
for _, altQual in ipairs(self.skillsTab:getGemAltQualityList(gemData)) do
71-
self.gems[altQual.type .. ":" .. gemId] = gemData
72-
end
73-
else
68+
local levelRequirement = gemData.grantedEffect.levels[1].levelRequirement or 1
69+
if characterLevel >= levelRequirement or not matchLevel then
70+
if (showAwakened or showAll) and gemData.grantedEffect.plusVersionOf then
7471
self.gems["Default:" .. gemId] = gemData
72+
elseif showNormal or showAll then
73+
if self.skillsTab.showAltQualityGems and (self.skillsTab.defaultGemQuality or 0) > 0 then
74+
for _, altQual in ipairs(self.skillsTab:getGemAltQualityList(gemData)) do
75+
self.gems[altQual.type .. ":" .. gemId] = gemData
76+
end
77+
else
78+
self.gems["Default:" .. gemId] = gemData
79+
end
7580
end
7681
end
7782
end
@@ -102,15 +107,15 @@ function GemSelectClass:BuildList(buf)
102107

103108
-- split the buffer using :
104109
-- Remove the first entry as the name search term (can be blank)
105-
tagsList = self.searchStr:split(':')
110+
tagsList = self.searchStr:split(":")
106111
searchTerm = tagsList[1]
107-
t_remove(tagsList,1)
112+
t_remove(tagsList, 1)
108113

109114
-- Search for gem name using increasingly broad search patterns
110115
local patternList = {
111-
"^ "..searchTerm:lower().."$", -- Exact match
112-
"^"..searchTerm:lower():gsub("%a", " %0%%l+").."$", -- Simple abbreviation ("CtF" -> "Cold to Fire")
113-
"^ "..searchTerm:lower(), -- Starts with
116+
"^ " .. searchTerm:lower().."$", -- Exact match
117+
"^" .. searchTerm:lower():gsub("%a", " %0%%l+") .. "$", -- Simple abbreviation ("CtF" -> "Cold to Fire")
118+
"^ " .. searchTerm:lower(), -- Starts with
114119
searchTerm:lower(), -- Contains
115120
}
116121
for i, pattern in ipairs(patternList) do
@@ -121,7 +126,7 @@ function GemSelectClass:BuildList(buf)
121126
if #tagsList > 0 then
122127
for _, tag in ipairs(tagsList) do
123128
local tagName = tag:gsub("%s+", ""):lower()
124-
local negateTag = tagName:sub(1, 1) == '-'
129+
local negateTag = tagName:sub(1, 1) == "-"
125130
if negateTag then tagName = tagName:sub(2) end
126131
if tagName == "active" then
127132
tagName = "active_skill"
@@ -134,7 +139,7 @@ function GemSelectClass:BuildList(buf)
134139
end
135140
-- for :melee we want to exclude gems that DON'T have this tag
136141
-- for :-melee we want to exclude gems that DO have this tag
137-
-- EG: :active:fire:-aura <-- No Anger (Calming ?)
142+
-- EG: :active:fire:-aura <-- No Anger (Calming ?)
138143
if negateTag then
139144
if gemData.tags[tagName] and gemData.tags[tagName] == true then addThisGem = false end
140145
else
@@ -171,7 +176,7 @@ function GemSelectClass:BuildList(buf)
171176
end
172177
end
173178
else
174-
--nothing in buffer
179+
-- nothing in buffer
175180
for gemId, gemData in pairs(self.gems) do
176181
if self:FilterSupport(gemId, gemData) then
177182
t_insert(self.list, gemId)
@@ -190,20 +195,23 @@ end
190195
function GemSelectClass:UpdateSortCache()
191196
--local start = GetTime()
192197
local sortCache = self.sortCache
193-
--Don't update the cache if no settings have changed that would impact the ordering
194-
if sortCache and sortCache.socketGroup == self.skillsTab.displayGroup and sortCache.gemInstance == self.skillsTab.displayGroup.gemList[self.index] and
195-
sortCache.outputRevision == self.skillsTab.build.outputRevision and sortCache.defaultLevel == self.skillsTab.defaultGemLevel
196-
and sortCache.defaultQuality == self.skillsTab.defaultGemQuality and sortCache.sortType == self.skillsTab.sortGemsByDPSField
197-
and sortCache.considerAlternates == self.skillsTab.showAltQualityGems and sortCache.considerAwakened == self.skillsTab.showSupportGemTypes then
198+
-- Don't update the cache if no settings have changed that would impact the ordering
199+
if sortCache and sortCache.socketGroup == self.skillsTab.displayGroup and sortCache.gemInstance == self.skillsTab.displayGroup.gemList[self.index]
200+
and sortCache.outputRevision == self.skillsTab.build.outputRevision and sortCache.defaultLevel == self.skillsTab.defaultGemLevel
201+
and (sortCache.characterLevel == self.skillsTab.build.characterLevel or self.skillsTab.defaultGemLevel ~= "characterLevel")
202+
and sortCache.defaultQuality == self.skillsTab.defaultGemQuality and sortCache.sortType == self.skillsTab.sortGemsByDPSField
203+
and sortCache.considerAlternates == self.skillsTab.showAltQualityGems and sortCache.considerAwakened == self.skillsTab.showSupportGemTypes then
198204
return
199205
end
200206

201-
if sortCache and (sortCache.considerAlternates ~= self.skillsTab.showAltQualityGems or sortCache.considerGemType ~= self.skillsTab.showSupportGemTypes
202-
or sortCache.defaultQuality ~= self.skillsTab.defaultGemQuality) then
207+
if not sortCache or (sortCache.considerAlternates ~= self.skillsTab.showAltQualityGems or sortCache.considerGemType ~= self.skillsTab.showSupportGemTypes
208+
or sortCache.defaultQuality ~= self.skillsTab.defaultGemQuality
209+
or sortCache.defaultLevel ~= self.skillsTab.defaultGemLevel
210+
or (sortCache.characterLevel ~= self.skillsTab.build.characterLevel and self.skillsTab.defaultGemLevel == "characterLevel")) then
203211
self:PopulateGemList()
204212
end
205213

206-
--Initialize a new sort cache
214+
-- Initialize a new sort cache
207215
sortCache = {
208216
considerGemType = self.skillsTab.showSupportGemTypes,
209217
considerAlternates = self.skillsTab.showAltQualityGems,
@@ -212,13 +220,14 @@ function GemSelectClass:UpdateSortCache()
212220
outputRevision = self.skillsTab.build.outputRevision,
213221
defaultLevel = self.skillsTab.defaultGemLevel,
214222
defaultQuality = self.skillsTab.defaultGemQuality,
223+
characterLevel = self.skillsTab.build and self.skillsTab.build.characterLevel or 1,
215224
canSupport = { },
216225
dps = { },
217226
dpsColor = { },
218227
sortType = self.skillsTab.sortGemsByDPSField
219228
}
220229
self.sortCache = sortCache
221-
--Determine supports that affect the active skill
230+
-- Determine supports that affect the active skill
222231
if self.skillsTab.displayGroup.displaySkillList and self.skillsTab.displayGroup.displaySkillList[1] then
223232
for gemId, gemData in pairs(self.gems) do
224233
if gemData.grantedEffect.support then
@@ -239,25 +248,28 @@ function GemSelectClass:UpdateSortCache()
239248

240249
for gemId, gemData in pairs(self.gems) do
241250
sortCache.dps[gemId] = baseDPS
242-
--Ignore gems that don't support the active skill
251+
-- Ignore gems that don't support the active skill
243252
if sortCache.canSupport[gemId] or gemData.grantedEffect.hasGlobalEffect then
244253
local gemList = self.skillsTab.displayGroup.gemList
245254
local oldGem
246255
if gemList[self.index] then
247256
oldGem = copyTable(gemList[self.index], true)
248257
else
249-
gemList[self.index] = { level = self.skillsTab.defaultGemLevel or gemData.defaultLevel, qualityId = self:GetQualityType(gemId), quality = self.skillsTab.defaultGemQuality or 0, enabled = true, enableGlobal1 = true }
250-
end
258+
gemList[self.index] = {
259+
level = gemData.defaultLevel,
260+
qualityId = self:GetQualityType(gemId),
261+
quality = self.skillsTab.defaultGemQuality or 0,
262+
enabled = true,
263+
enableGlobal1 = true,
264+
enableGlobal2 = true
265+
}
266+
end
267+
-- Create gemInstance to represent the hovered gem
251268
local gemInstance = gemList[self.index]
252-
if gemInstance.gemData and gemInstance.gemData.defaultLevel ~= gemData.defaultLevel then
253-
gemInstance.level = self.skillsTab.defaultGemLevel or gemData.defaultLevel
254-
end
269+
gemInstance.level = self.skillsTab:ProcessGemLevel(gemData)
255270
gemInstance.gemData = gemData
256-
if (gemData.grantedEffect.plusVersionOf and gemInstance.level > gemData.defaultLevel) or not gemData.grantedEffect.levels[gemInstance.level] then
257-
gemInstance.level = gemData.defaultLevel
258-
end
259-
--Calculate the impact of using this gem
260-
local output = calcFunc({}, { allocNodes = true, requirementsItems = true })
271+
-- Calculate the impact of using this gem
272+
local output = calcFunc({ }, { allocNodes = true, requirementsItems = true })
261273
if oldGem then
262274
gemInstance.gemData = oldGem.gemData
263275
gemInstance.level = oldGem.level
@@ -267,7 +279,7 @@ function GemSelectClass:UpdateSortCache()
267279
-- Check for nil because some fields may not be populated, default to 0
268280
sortCache.dps[gemId] = (dpsField == "FullDPS" and output[dpsField] ~= nil and output[dpsField]) or (output.Minion and output.Minion.CombinedDPS) or (output[dpsField] ~= nil and output[dpsField]) or 0
269281
end
270-
--Color based on the dps
282+
-- Color based on the DPS
271283
if sortCache.dps[gemId] > baseDPS then
272284
sortCache.dpsColor[gemId] = "^x228866"
273285
elseif sortCache.dps[gemId] < baseDPS then
@@ -417,13 +429,18 @@ function GemSelectClass:Draw(viewPort, noTooltip)
417429
if gemList[self.index] then
418430
oldGem = copyTable(gemList[self.index], true)
419431
else
420-
gemList[self.index] = { level = self.skillsTab:MatchGemLevelToCharacterLevel(gemData, m_min(self.skillsTab.defaultGemLevel or gemData.defaultLevel, gemData.defaultLevel + 1)), qualityId = self:GetQualityType(self.list[self.hoverSel]), quality = self.skillsTab.defaultGemQuality or 0, enabled = true, enableGlobal1 = true }
432+
gemList[self.index] = {
433+
level = gemData.defaultLevel,
434+
qualityId = self:GetQualityType(self.list[self.hoverSel]),
435+
quality = self.skillsTab.defaultGemQuality or 0,
436+
enabled = true,
437+
enableGlobal1 = true,
438+
enableGlobal2 = true
439+
}
421440
end
422441
-- Create gemInstance to represent the hovered gem
423442
local gemInstance = gemList[self.index]
424-
if gemInstance.gemData and gemInstance.gemData.defaultLevel ~= gemData.defaultLevel then
425-
gemInstance.level = self.skillsTab:MatchGemLevelToCharacterLevel(gemData, m_min(self.skillsTab.defaultGemLevel or gemData.defaultLevel, gemData.defaultLevel + 1))
426-
end
443+
gemInstance.level = self.skillsTab:ProcessGemLevel(gemData)
427444
gemInstance.gemData = gemData
428445
-- Clear the displayEffect so it only displays the temporary gem instance
429446
gemInstance.displayEffect = nil
@@ -498,19 +515,19 @@ function GemSelectClass:AddGemTooltip(gemInstance)
498515
if secondary and (not secondary.support or gemInstance.gemData.secondaryEffectName) then
499516
local grantedEffect = gemInstance.gemData.VaalGem and secondary or primary
500517
local grantedEffectSecondary = gemInstance.gemData.VaalGem and primary or secondary
501-
self.tooltip:AddLine(20, colorCodes.GEM..altQualMap[gemInstance.qualityId]..grantedEffect.name)
518+
self.tooltip:AddLine(20, colorCodes.GEM .. altQualMap[gemInstance.qualityId]..grantedEffect.name)
502519
self.tooltip:AddSeparator(10)
503-
self.tooltip:AddLine(16, "^x7F7F7F"..gemInstance.gemData.tagString)
520+
self.tooltip:AddLine(16, "^x7F7F7F" .. gemInstance.gemData.tagString)
504521
self:AddCommonGemInfo(gemInstance, grantedEffect, true)
505522
self.tooltip:AddSeparator(10)
506-
self.tooltip:AddLine(20, colorCodes.GEM..(gemInstance.gemData.secondaryEffectName or grantedEffectSecondary.name))
523+
self.tooltip:AddLine(20, colorCodes.GEM .. (gemInstance.gemData.secondaryEffectName or grantedEffectSecondary.name))
507524
self.tooltip:AddSeparator(10)
508525
self:AddCommonGemInfo(gemInstance, grantedEffectSecondary)
509526
else
510527
local grantedEffect = gemInstance.gemData.grantedEffect
511-
self.tooltip:AddLine(20, colorCodes.GEM..altQualMap[gemInstance.qualityId]..grantedEffect.name)
528+
self.tooltip:AddLine(20, colorCodes.GEM .. altQualMap[gemInstance.qualityId]..grantedEffect.name)
512529
self.tooltip:AddSeparator(10)
513-
self.tooltip:AddLine(16, "^x7F7F7F"..gemInstance.gemData.tagString)
530+
self.tooltip:AddLine(16, "^x7F7F7F" .. gemInstance.gemData.tagString)
514531
self:AddCommonGemInfo(gemInstance, grantedEffect, true, secondary and secondary.support and secondary)
515532
end
516533
end
@@ -521,7 +538,7 @@ function GemSelectClass:AddCommonGemInfo(gemInstance, grantedEffect, addReq, mer
521538
if addReq then
522539
self.tooltip:AddLine(16, string.format("^x7F7F7FLevel: ^7%d%s%s",
523540
gemInstance.level,
524-
((displayInstance.level > gemInstance.level) and " ("..colorCodes.MAGIC.."+"..(displayInstance.level - gemInstance.level).."^7)") or ((displayInstance.level < gemInstance.level) and " ("..colorCodes.WARNING.."-"..(gemInstance.level - displayInstance.level).."^7)") or "",
541+
((displayInstance.level > gemInstance.level) and " (" .. colorCodes.MAGIC .. "+" .. (displayInstance.level - gemInstance.level) .. "^7)") or ((displayInstance.level < gemInstance.level) and " (" .. colorCodes.WARNING .. "-" .. (gemInstance.level - displayInstance.level) .. "^7)") or "",
525542
(gemInstance.level >= gemInstance.gemData.defaultLevel) and " (Max)" or ""
526543
))
527544
end
@@ -532,7 +549,7 @@ function GemSelectClass:AddCommonGemInfo(gemInstance, grantedEffect, addReq, mer
532549
local reservation
533550
for name, res in pairs(self.reservationMap) do
534551
if grantedEffectLevel[name] then
535-
reservation = (reservation and (reservation..", ") or "")..self.costs[isValueInArrayPred(self.costs, function(v) return v.Resource == res end)].ResourceString:gsub("{0}", string.format("%d", grantedEffectLevel[name]))
552+
reservation = (reservation and (reservation .. ", ") or "") .. self.costs[isValueInArrayPred(self.costs, function(v) return v.Resource == res end)].ResourceString:gsub("{0}", string.format("%d", grantedEffectLevel[name]))
536553
end
537554
end
538555
if reservation then
@@ -545,16 +562,16 @@ function GemSelectClass:AddCommonGemInfo(gemInstance, grantedEffect, addReq, mer
545562
local reservation
546563
for name, res in pairs(self.reservationMap) do
547564
if grantedEffectLevel[name] then
548-
reservation = (reservation and (reservation..", ") or "")..self.costs[isValueInArrayPred(self.costs, function(v) return v.Resource == res end)].ResourceString:gsub("{0}", string.format("%d", grantedEffectLevel[name]))
565+
reservation = (reservation and (reservation..", ") or "") .. self.costs[isValueInArrayPred(self.costs, function(v) return v.Resource == res end)].ResourceString:gsub("{0}", string.format("%d", grantedEffectLevel[name]))
549566
end
550567
end
551568
if reservation then
552-
self.tooltip:AddLine(16, "^x7F7F7FReservation: ^7"..reservation)
569+
self.tooltip:AddLine(16, "^x7F7F7FReservation: ^7" .. reservation)
553570
end
554571
local cost
555572
for _, res in ipairs(self.costs) do
556573
if grantedEffectLevel.cost and grantedEffectLevel.cost[res.Resource] then
557-
cost = (cost and (cost..", ") or "")..res.ResourceString:gsub("{0}", string.format("%g", round(grantedEffectLevel.cost[res.Resource] / res.Divisor, 2)))
574+
cost = (cost and (cost..", ") or "") .. res.ResourceString:gsub("{0}", string.format("%g", round(grantedEffectLevel.cost[res.Resource] / res.Divisor, 2)))
558575
end
559576
end
560577
if cost then
@@ -638,12 +655,12 @@ function GemSelectClass:AddCommonGemInfo(gemInstance, grantedEffect, addReq, mer
638655
end
639656
line = line .. " ^2" .. devText
640657
end
641-
self.tooltip:AddLine(16, colorCodes.MAGIC..line)
658+
self.tooltip:AddLine(16, colorCodes.MAGIC .. line)
642659
else
643660
if launch.devModeAlt then
644661
line = line .. " ^1" .. lineMap[line]
645662
end
646-
self.tooltip:AddLine(16, colorCodes.UNSUPPORTED..line)
663+
self.tooltip:AddLine(16, colorCodes.UNSUPPORTED .. line)
647664
end
648665
end
649666
end

0 commit comments

Comments
 (0)