Skip to content

Commit 7eab5fc

Browse files
committed
extract shared config visibility logic and use it in both the ConfigTab and CompareTab
1 parent dc13ca6 commit 7eab5fc

3 files changed

Lines changed: 171 additions & 38 deletions

File tree

src/Classes/CompareTab.lua

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ local tradeHelpers = LoadModule("Classes/CompareTradeHelpers")
1414
local buySimilar = LoadModule("Classes/CompareBuySimilar")
1515
local calcsHelpers = LoadModule("Classes/CompareCalcsHelpers")
1616
local buildListHelpers = LoadModule("Modules/BuildListHelpers")
17+
local configVisibility = LoadModule("Modules/ConfigVisibility")
1718

1819
-- Node IDs below this value are normal passive tree nodes; IDs at or above are cluster jewel nodes
1920
local CLUSTER_NODE_OFFSET = 65536
@@ -1114,31 +1115,11 @@ function CompareTabClass:RebuildConfigControls(compareEntry)
11141115
self.controls["cfg_p_" .. varData.var] = pCtrl
11151116
self.controls["cfg_c_" .. varData.var] = cCtrl
11161117

1117-
-- Determine eligibility category (matches ConfigTab's isShowAllConfig logic)
1118-
local isHardConditional = varData.ifOption or varData.ifSkill
1119-
or varData.ifSkillData or varData.ifSkillFlag or varData.legacy
1120-
local isKeywordExcluded = false
1121-
if varData.label then
1122-
local labelLower = varData.label:lower()
1123-
for _, kw in ipairs({"recently", "in the last", "in the past", "in last", "in past", "pvp"}) do
1124-
if labelLower:find(kw) then
1125-
isKeywordExcluded = true
1126-
break
1127-
end
1128-
end
1129-
end
1130-
local hasAnyCondition = varData.ifCond or varData.ifOption or varData.ifSkill
1131-
or varData.ifSkillFlag or varData.ifSkillData or varData.ifSkillList
1132-
or varData.ifNode or varData.ifMod or varData.ifMult
1133-
or varData.ifEnemyStat or varData.ifEnemyCond or varData.legacy
1134-
11351118
local ctrlInfo = {
11361119
primaryControl = pCtrl,
11371120
compareControl = cCtrl,
11381121
varData = varData,
11391122
visible = false,
1140-
alwaysShow = not hasAnyCondition and not isKeywordExcluded,
1141-
showWithToggle = not isHardConditional and not isKeywordExcluded,
11421123
}
11431124
self.configControls[varData.var] = ctrlInfo
11441125
t_insert(self.configControlList, ctrlInfo)
@@ -1921,8 +1902,13 @@ function CompareTabClass:LayoutConfigView(contentVP, compareEntry)
19211902
local isDiff = tostring(pVal) ~= tostring(cVal)
19221903
if isDiff then
19231904
t_insert(diffs, ctrlInfo)
1924-
elseif ctrlInfo.alwaysShow or (self.configToggle and ctrlInfo.showWithToggle) then
1925-
t_insert(commons, ctrlInfo)
1905+
else
1906+
local varData = ctrlInfo.varData
1907+
local relevant = configVisibility.isRelevantForBuild(varData, self.primaryBuild)
1908+
or configVisibility.isRelevantForBuild(varData, compareEntry)
1909+
if relevant or (self.configToggle and not configVisibility.isShowAllExcluded(varData)) then
1910+
t_insert(commons, ctrlInfo)
1911+
end
19261912
end
19271913
end
19281914
end

src/Classes/ConfigTab.lua

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ local m_floor = math.floor
1010
local s_upper = string.upper
1111

1212
local varList = LoadModule("Modules/ConfigOptions")
13+
local configVisibility = LoadModule("Modules/ConfigVisibility")
1314

1415
local ConfigTabClass = newClass("ConfigTab", "UndoHandler", "ControlHost", "Control", function(self, build)
1516
self.UndoHandler()
@@ -73,23 +74,9 @@ local ConfigTabClass = newClass("ConfigTab", "UndoHandler", "ControlHost", "Cont
7374
return true
7475
end
7576

76-
-- blacklist for Show All Configurations
77+
-- Override for Show All Configurations: when the toggle is on, show options that aren't on the shared exclusion list.
7778
local function isShowAllConfig(varData)
78-
local labelMatch = varData.label:lower()
79-
local excludeKeywords = { "recently", "in the last", "in the past", "in last", "in past", "pvp" }
80-
81-
if not self.toggleConfigs then
82-
return false
83-
end
84-
if varData.ifOption or varData.ifSkill or varData.ifSkillData or varData.ifSkillFlag or varData.legacy then
85-
return false
86-
end
87-
for _, keyword in pairs(excludeKeywords) do
88-
if labelMatch:find(keyword) then
89-
return false
90-
end
91-
end
92-
return true
79+
return self.toggleConfigs and not configVisibility.isShowAllExcluded(varData)
9380
end
9481

9582
local function implyCond(varData)

src/Modules/ConfigVisibility.lua

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
-- Path of Building
2+
--
3+
-- Module: Config Visibility
4+
-- Shared helpers that decide which entries in ConfigOptions should be visible for a given build.
5+
-- Used by both the main Config tab and the Compare tab's Config view so their "Show All
6+
-- Configurations" toggles stay in sync when the predicate list in ConfigOptions grows.
7+
--
8+
9+
-- Labels containing any of these keywords stay hidden even when "Show All Configurations" is on.
10+
local EXCLUDE_KEYWORDS = { "recently", "in the last", "in the past", "in last", "in past", "pvp" }
11+
12+
-- Simple predicates of the form `varData.ifX` → `mainEnv.YUsed[opt]`, with imply-cond fallback when `impliable` is true.
13+
local SIMPLE_PREDICATES = {
14+
{ key = "ifCond", env = "conditionsUsed", impliable = true },
15+
{ key = "ifMinionCond", env = "minionConditionsUsed", impliable = true },
16+
{ key = "ifEnemyCond", env = "enemyConditionsUsed", impliable = true },
17+
{ key = "ifMult", env = "multipliersUsed", impliable = true },
18+
{ key = "ifEnemyMult", env = "enemyMultipliersUsed", impliable = true },
19+
{ key = "ifEnemyStat", env = "enemyPerStatsUsed", impliable = true },
20+
{ key = "ifTagType", env = "tagTypesUsed", impliable = true },
21+
{ key = "ifMod", env = "modsUsed", impliable = true },
22+
}
23+
24+
-- Run `predicate` against either a single value or a list of values.
25+
local function anyIfValue(ifOption, predicate)
26+
if type(ifOption) == "table" then
27+
for _, opt in ipairs(ifOption) do
28+
if predicate(opt) then return true end
29+
end
30+
return false
31+
end
32+
return predicate(ifOption) and true or false
33+
end
34+
35+
-- When the option has an input value and one of its implied conditions is currently used, treat gated predicates as passing.
36+
local function implyCondActive(varData, build)
37+
local configTab = build and build.configTab
38+
if not configTab then return false end
39+
local activeSet = configTab.configSets and configTab.configSets[configTab.activeConfigSetId]
40+
if not activeSet or not activeSet.input[varData.var] then return false end
41+
local mainEnv = build.calcsTab and build.calcsTab.mainEnv
42+
if not mainEnv then return false end
43+
if varData.implyCondList then
44+
for _, implyCond in ipairs(varData.implyCondList) do
45+
if implyCond and mainEnv.conditionsUsed[implyCond] then return true end
46+
end
47+
end
48+
return (varData.implyCond and mainEnv.conditionsUsed[varData.implyCond])
49+
or (varData.implyMinionCond and mainEnv.minionConditionsUsed[varData.implyMinionCond])
50+
or (varData.implyEnemyCond and mainEnv.enemyConditionsUsed[varData.implyEnemyCond])
51+
or false
52+
end
53+
54+
-- True if every `ifX` predicate on `varData` currently passes for `build`
55+
local function isRelevantForBuild(varData, build)
56+
if not build then return false end
57+
local mainEnv = build.calcsTab and build.calcsTab.mainEnv
58+
if not mainEnv then return false end
59+
local player = mainEnv.player
60+
local mainSkill = player and player.mainSkill
61+
local spec = build.spec
62+
local configTab = build.configTab
63+
local activeInput = configTab and configTab.configSets
64+
and configTab.configSets[configTab.activeConfigSetId]
65+
and configTab.configSets[configTab.activeConfigSetId].input
66+
or {}
67+
68+
local impliedCache
69+
local function implied()
70+
if impliedCache == nil then
71+
impliedCache = implyCondActive(varData, build) or false
72+
end
73+
return impliedCache
74+
end
75+
76+
for _, p in ipairs(SIMPLE_PREDICATES) do
77+
local ifVal = varData[p.key]
78+
if ifVal then
79+
local envTable = mainEnv[p.env] or {}
80+
if not anyIfValue(ifVal, function(opt)
81+
return envTable[opt] or (p.impliable and implied())
82+
end) then return false end
83+
end
84+
end
85+
86+
if varData.ifNode and spec then
87+
if not anyIfValue(varData.ifNode, function(opt)
88+
if spec.allocNodes[opt] then return true end
89+
local node = spec.nodes[opt]
90+
if node and node.type == "Keystone" then
91+
return mainEnv.keystonesAdded and mainEnv.keystonesAdded[node.dn]
92+
end
93+
return false
94+
end) then return false end
95+
end
96+
if varData.ifOption then
97+
if not anyIfValue(varData.ifOption, function(opt) return activeInput[opt] end) then return false end
98+
end
99+
if varData.ifCondTrue then
100+
if not anyIfValue(varData.ifCondTrue, function(opt) return player and player.modDB.conditions[opt] end) then return false end
101+
end
102+
if varData.ifStat then
103+
if not anyIfValue(varData.ifStat, function(opt)
104+
return mainEnv.perStatsUsed[opt] or mainEnv.enemyMultipliersUsed[opt] or implied()
105+
end) then return false end
106+
end
107+
if varData.ifFlag then
108+
if not mainSkill then return false end
109+
local skillFlags = mainSkill.skillFlags or {}
110+
local skillModList = mainSkill.skillModList
111+
if not anyIfValue(varData.ifFlag, function(opt)
112+
return skillFlags[opt] or (skillModList and skillModList:Flag(nil, opt))
113+
end) then return false end
114+
end
115+
if varData.ifSkill then
116+
local skillsUsed = mainEnv.skillsUsed or {}
117+
if varData.includeTransfigured then
118+
if not anyIfValue(varData.ifSkill, function(opt)
119+
if not calcLib.getGameIdFromGemName(opt, true) then return false end
120+
for skill, _ in pairs(skillsUsed) do
121+
if calcLib.isGemIdSame(skill, opt, true) then return true end
122+
end
123+
return false
124+
end) then return false end
125+
else
126+
if not anyIfValue(varData.ifSkill, function(opt) return skillsUsed[opt] end) then return false end
127+
end
128+
end
129+
if varData.ifSkillFlag or varData.ifSkillData then
130+
local skillList = (player and player.activeSkillList) or {}
131+
local function anySkillHas(field, opt)
132+
for _, s in ipairs(skillList) do
133+
if s[field][opt] then return true end
134+
end
135+
return false
136+
end
137+
if varData.ifSkillFlag and not anyIfValue(varData.ifSkillFlag, function(opt) return anySkillHas("skillFlags", opt) end) then return false end
138+
if varData.ifSkillData and not anyIfValue(varData.ifSkillData, function(opt) return anySkillHas("skillData", opt) end) then return false end
139+
end
140+
return true
141+
end
142+
143+
-- Options with these properties or label keywords stay hidden even when "Show All Configurations" is on.
144+
local function isShowAllExcluded(varData)
145+
if varData.ifOption or varData.ifSkill or varData.ifSkillData or varData.ifSkillFlag or varData.legacy then
146+
return true
147+
end
148+
if varData.label then
149+
local labelLower = varData.label:lower()
150+
for _, kw in ipairs(EXCLUDE_KEYWORDS) do
151+
if labelLower:find(kw) then return true end
152+
end
153+
end
154+
return false
155+
end
156+
157+
return {
158+
isRelevantForBuild = isRelevantForBuild,
159+
isShowAllExcluded = isShowAllExcluded,
160+
}

0 commit comments

Comments
 (0)