@@ -19,10 +19,31 @@ local orderHalls = {
1919 [" DEMONHUNTER" ] = 125 ,
2020}
2121
22+ local tocVersion = select (4 , GetBuildInfo ())
23+
2224local increment = CreateCounter ();
2325ResearchViewer .talentTrees = {
26+ [" The War Within" ] = {
27+ order = increment (),
28+ tocVersion >= 110107 and { isTraitTree = true , id = 1061 , name = GENERIC_TRAIT_FRAME_TITAN_CONSOLE_TITLE } or nil ,
29+ { isTraitTree = true , id = 1057 , name = GENERIC_TRAIT_FRAME_VISIONS_TITLE },
30+ { isTraitTree = true , id = 1056 , name = GENERIC_TRAIT_FRAME_DRIVE_TITLE },
31+ { isTraitTree = true , id = 1060 , name = " Brann Delve Season 2" },
32+ { isTraitTree = true , id = 1046 , name = GENERIC_TRAIT_FRAME_THE_VIZIER_TITLE },
33+ { isTraitTree = true , id = 1045 , name = GENERIC_TRAIT_FRAME_THE_GENERAL_TITLE },
34+ { isTraitTree = true , id = 1042 , name = GENERIC_TRAIT_FRAME_THE_WEAVER_TITLE },
35+ { isTraitTree = true , id = 1054 , name = " ??" },
36+ { isTraitTree = true , id = 898 , name = " ??" },
37+ { isTraitTree = true , id = 876 , name = " ??" },
38+ { isTraitTree = true , id = 875 , name = " ??" },
39+ { isTraitTree = true , id = 775 , name = " ??" },
40+ { isTraitTree = true , id = 751 , name = " ??" },
41+ { isTraitTree = true , id = 672 , name = GENERIC_TRAIT_FRAME_DRAGONRIDING_TITLE },
42+ { isTraitTree = true , id = 874 , name = " Brann Delve Season 1" },
43+ },
2444 Dragonflight = {
2545 order = increment (),
46+ { isTraitTree = true , id = 672 , name = GENERIC_TRAIT_FRAME_DRAGONRIDING_TITLE },
2647 { type = 111 , id = 489 , name = " Expedition Supplies" },
2748 { type = 111 , id = 493 , name = " Cobalt Assembly Arcana" },
2849 { type = 111 , id = 486 , name = " Select Your Companion" },
@@ -154,8 +175,24 @@ ResearchViewer.neverImplemented = {
154175 },
155176}
156177
157- EventUtil .ContinueOnAddOnLoaded (name , function ()
158- ResearchViewer :OnInitialize ()
178+ local f = CreateFrame (" Frame" )
179+ f :RegisterEvent (" ADDON_LOADED" )
180+ f :SetScript (" OnEvent" , function (_ , _ , addonName )
181+ if addonName == name then
182+ ResearchViewer :OnInitialize ()
183+ end
184+ if addonName == " Blizzard_OrderHallUI" then
185+ ResearchViewer :MakeDropDownButton (OrderHallTalentFrame )
186+ OrderHallTalentFrame :HookScript (" OnHide" , function ()
187+ ResearchViewer .selectedTreeInfo = nil
188+ end )
189+ end
190+ if addonName == " Blizzard_GenericTraitUI" then
191+ ResearchViewer :MakeDropDownButton (GenericTraitFrame )
192+ GenericTraitFrame :HookScript (" OnHide" , function ()
193+ ResearchViewer .selectedTreeInfo = nil
194+ end )
195+ end
159196end )
160197
161198function ResearchViewer :OnInitialize ()
@@ -171,32 +208,32 @@ function ResearchViewer:OnInitialize()
171208 end
172209
173210 local original = C_Garrison .GetCurrentGarrTalentTreeID
174- C_Garrison .GetCurrentGarrTalentTreeID = function ()
175- if ResearchViewer .selectedTreeInfo then return ResearchViewer .selectedTreeInfo .id end
211+ C_Garrison .GetCurrentGarrTalentTreeID = function () --- @diagnostic disable-line : duplicate-set-field
212+ if self .selectedTreeInfo then return self .selectedTreeInfo .id end
176213
177214 return original ()
178215 end
179216
180217 local ResearchViewerLDB = LibStub (" LibDataBroker-1.1" ):NewDataObject (
181- name ,
182- {
183- type = " launcher" ,
184- text = " Research Viewer" ,
185- icon = " interface/icons/inv_misc_book_11.blp" ,
186- OnClick = function ()
187- if IsShiftKeyDown () then
188- ResearchViewer .db .ldbOptions .hide = true
189- LibDBIcon :Hide (name )
190- return
191- end
192- ResearchViewer :OpenResearchView ()
193- end ,
194- OnTooltipShow = function (tooltip )
195- tooltip :AddLine (" Research Viewer" )
196- tooltip :AddLine (" |cffeda55fClick|r to view various research trees from the field." )
197- tooltip :AddLine (" |cffeda55fShift-Click|r to hide this button. ('/rv reset' to restore)" )
198- end ,
199- }
218+ name ,
219+ {
220+ type = " launcher" ,
221+ text = " Research Viewer" ,
222+ icon = " interface/icons/inv_misc_book_11.blp" ,
223+ OnClick = function ()
224+ if IsShiftKeyDown () then
225+ self .db .ldbOptions .hide = true
226+ LibDBIcon :Hide (name )
227+ return
228+ end
229+ self :OpenResearchView ()
230+ end ,
231+ OnTooltipShow = function (tooltip )
232+ tooltip :AddLine (" Research Viewer" )
233+ tooltip :AddLine (" |cffeda55fClick|r to view various research/generic talent trees from the field." )
234+ tooltip :AddLine (" |cffeda55fShift-Click|r to hide this button. ('/rv reset' to restore)" )
235+ end ,
236+ }
200237 )
201238 LibDBIcon :Register (" ResearchViewer" , ResearchViewerLDB , self .db .ldbOptions )
202239
@@ -233,34 +270,31 @@ function ResearchViewer:OnInitialize()
233270 -- the first time you get tree info after launching the game, it's very slow
234271 -- so instead of having a full second of lag when you open the research viewer,
235272 -- we'll just get the info now, and spread it out a bit over time
236- local treeIds = self :GetTreeList ()
237- local treeIdList = {}
238- for _ , treeId in pairs (treeIds ) do
239- table.insert (treeIdList , treeId )
240- end
273+ local treeIDList = GetValuesArray (self :GetTreeList ())
241274 local ticker
242275 local i = 0
243276 ticker = C_Timer .NewTicker (0.2 , function ()
244277 i = i + 1
245- local treeId = treeIdList [i ]
246- if not treeId then
278+ local treeID = treeIDList [i ]
279+ if not treeID then
247280 ticker :Cancel ()
248281 return
249282 end
250- ResearchViewer :TreeExists (treeId )
283+ ResearchViewer :TreeExists (treeID )
251284 end )
252285end
253286
287+ --- @return table<number , number>
254288function ResearchViewer :GetTreeList (treeList , tables )
255289 treeList = treeList or {}
256290 tables = tables or { ni = self .neverImplemented , tt = self .talentTrees }
257291
258292 for key , value in pairs (tables ) do
259- if ( type (key ) == " number" ) then
260- if value .id then
293+ if value and type (key ) == " number" then
294+ if value .id and not value . isTraitTree then
261295 treeList [value .id ] = value .id
262296 end
263- elseif key ~= " order" then
297+ elseif value and key ~= " order" then
264298 self :GetTreeList (treeList , value )
265299 end
266300 end
@@ -279,11 +313,11 @@ function ResearchViewer:GetOrderedTreeIDs(list, subItems)
279313 local temp = {}
280314 local orderOffset = # subItems + 10
281315 for key , value in pairs (subItems ) do
282- if type (key ) == " number" then
316+ if value and type (key ) == " number" then
283317 if not value .special then
284318 table.insert (temp , { id = value .id , order = key })
285319 end
286- elseif key ~= " order" then
320+ elseif value and key ~= " order" then
287321 table.insert (temp , { subItems = value , order = value .order + orderOffset })
288322 end
289323 end
@@ -316,11 +350,12 @@ function ResearchViewer:AlreadyAdded(textLine, tooltip)
316350 end
317351end
318352
319- function ResearchViewer :MakeDropDownButton ()
320- local dropdown = CreateFrame (" DropdownButton" , nil , OrderHallTalentFrame , " WowStyle1DropdownTemplate" );
353+ --- @param parent GenericTraitFrame | OrderHallTalentFrame
354+ function ResearchViewer :MakeDropDownButton (parent )
355+ local dropdown = CreateFrame (" DropdownButton" , nil , parent , " WowStyle1DropdownTemplate" );
321356
322- dropdown :OverrideText (" Select another Research tree" )
323- dropdown :SetWidth (230 )
357+ dropdown :OverrideText (" Select another tree" )
358+ dropdown :SetWidth (165 )
324359 dropdown :SetPoint (" TOPRIGHT" , 10 , 20 )
325360 dropdown :EnableMouseWheel (true )
326361 function dropdown :PickTreeID (treeID )
@@ -331,6 +366,7 @@ function ResearchViewer:MakeDropDownButton()
331366 end )
332367 end
333368 function dropdown :Increment ()
369+ if not ResearchViewer .selectedTreeInfo then return end
334370 local currentTreeID = ResearchViewer .selectedTreeInfo .id
335371 local currentIndex = ResearchViewer .orderedTreeIDsMap [currentTreeID ]
336372 local nextIndex = currentIndex + 1
@@ -340,6 +376,7 @@ function ResearchViewer:MakeDropDownButton()
340376 self :PickTreeID (ResearchViewer .orderedTreeIDs [nextIndex ])
341377 end
342378 function dropdown :Decrement ()
379+ if not ResearchViewer .selectedTreeInfo then return end
343380 local currentTreeID = ResearchViewer .selectedTreeInfo .id
344381 local currentIndex = ResearchViewer .orderedTreeIDsMap [currentTreeID ]
345382 local nextIndex = currentIndex - 1
@@ -350,11 +387,9 @@ function ResearchViewer:MakeDropDownButton()
350387 end
351388
352389 dropdown :SetupMenu (function (_ , rootDescription )
353- self :GenerateMenu (rootDescription )
390+ self :GenerateMenu (rootDescription , parent )
354391 end )
355392
356- dropdown :Hide ()
357-
358393 if C_AddOns .IsAddOnLoaded (" ElvUI" ) and ElvUI then
359394 ElvUI [1 ]:GetModule (" Skins" ):HandleDropDownBox (dropdown )
360395 end
@@ -364,25 +399,37 @@ end
364399
365400function ResearchViewer :OpenResearchView ()
366401 OrderHall_LoadUI ()
367- self .selectedTreeInfo = self .charDb and self .charDb .lastSelected or self .talentTrees .Shadowlands [1 ]
368- self :OpenSelectedResearch ()
402+ self .selectedTreeInfo = self .charDb and self .charDb .lastSelected or self .talentTrees [' The War Within' ][1 ] or self .talentTrees [' The War Within' ][2 ]
403+ if self .selectedTreeInfo .isTraitTree then
404+ self :OpenGenericTalentTree (self .selectedTreeInfo .id )
405+ else
406+ self :OpenSelectedResearch ()
407+ end
369408end
370409
371- local hooked = false
372- function ResearchViewer :OpenSelectedResearch ()
373- OrderHallTalentFrame :SetGarrisonType (self .selectedTreeInfo .type , self .selectedTreeInfo .id )
410+ function ResearchViewer :OpenGenericTalentTree (treeID )
374411 self .charDb .lastSelected = self .selectedTreeInfo
375- ToggleOrderHallTalentUI ()
376- self .dropdownButton = self .dropdownButton or self :MakeDropDownButton ()
377- self .dropdownButton :Show ()
378- if not hooked then
379- hooked = true
380- OrderHallTalentFrame :HookScript (" OnHide" , function ()
381- ResearchViewer .selectedTreeInfo = nil
382- end )
412+ local systemID = C_Traits .GetSystemIDByTreeID (treeID )
413+
414+ GenericTraitUI_LoadUI ();
415+ GenericTraitFrame :Hide ();
416+ GenericTraitFrame :SetSystemID (systemID );
417+ GenericTraitFrame :SetTreeID (treeID );
418+ ShowUIPanel (GenericTraitFrame );
419+ if GenericTraitFrame :GetNumPoints () == 0 then
420+ GenericTraitFrame :SetPoint (' TOPLEFT' , 16 , - 116 ); -- roughly where it would normally open
421+ end
422+ if not tIndexOf (UISpecialFrames , ' GenericTraitFrame' ) then
423+ table.insert (UISpecialFrames , ' GenericTraitFrame' );
383424 end
384425end
385426
427+ function ResearchViewer :OpenSelectedResearch ()
428+ self .charDb .lastSelected = self .selectedTreeInfo
429+ OrderHallTalentFrame :SetGarrisonType (self .selectedTreeInfo .type , self .selectedTreeInfo .id )
430+ ShowUIPanel (OrderHallTalentFrame );
431+ end
432+
386433local treeExistsCache = {}
387434function ResearchViewer :TreeExists (treeId )
388435 if treeExistsCache [treeId ] ~= nil then
@@ -396,23 +443,51 @@ function ResearchViewer:TreeExists(treeId)
396443 return exists
397444end
398445
446+ function ResearchViewer :TraitTreeExists (treeId )
447+ return not not C_Traits .GetConfigIDByTreeID (treeId )
448+ end
449+
399450--- @param rootDescription RootMenuDescriptionProxy
400- function ResearchViewer :GenerateMenu (rootDescription )
451+ --- @param owner GenericTraitFrame | OrderHallTalentFrame
452+ function ResearchViewer :GenerateMenu (rootDescription , owner )
401453 if not self .orderedTreeIDs then
402454 self .orderedTreeIDs = self :GetOrderedTreeIDs ()
403455 self .orderedTreeIDsMap = tInvert (self .orderedTreeIDs )
404456 end
405457 local function openTree (data )
406- ToggleOrderHallTalentUI ()
458+ HideUIPanel (owner )
459+
460+ self .selectedTreeInfo = data
461+ if data .isTraitTree then
462+ HideUIPanel (GenericTraitFrame )
407463
408- ResearchViewer .selectedTreeInfo = data
409- ResearchViewer :OpenSelectedResearch ()
464+ self :OpenGenericTalentTree (data .id )
465+ else
466+ HideUIPanel (OrderHallTalentFrame )
467+
468+ self :OpenSelectedResearch ()
469+ end
410470 end
411471 local function isSelected (data )
412- return data [self .selectedTreeInfo .id ] or (data .id == self .selectedTreeInfo .id and data .type == self .selectedTreeInfo .type )
472+ if self .selectedTreeInfo then
473+ return
474+ data [(self .selectedTreeInfo .isTraitTree and ' T' or ' R' ) .. self .selectedTreeInfo .id ]
475+ or (
476+ data .id == self .selectedTreeInfo .id
477+ and (data .type == self .selectedTreeInfo .type or data .isTraitTree == self .selectedTreeInfo .isTraitTree )
478+ )
479+ elseif owner == GenericTraitFrame and GenericTraitFrame :GetTalentTreeID () then
480+ return
481+ data .isTraitTree and data .id == GenericTraitFrame :GetTalentTreeID ()
482+ or (
483+ data [' T' .. GenericTraitFrame :GetTalentTreeID ()]
484+ )
485+ end
486+
487+ return false
413488 end
414489
415- rootDescription :CreateTitle (' Select another Research tree' )
490+ rootDescription :CreateTitle (' Select another tree' )
416491 self :GenerateSubMenuButtons (rootDescription , self .talentTrees , isSelected , openTree )
417492 local neverImplementedData = {}
418493 local neverImplemented = rootDescription :CreateRadio (" Never Implemented" , isSelected , openTree , neverImplementedData )
@@ -425,16 +500,20 @@ end
425500--- @param isSelectedFunc fun ( data : any ): boolean
426501function ResearchViewer :GenerateSubMenuButtons (parentDescription , list , isSelectedFunc , setValueFunc , parentDataTables )
427502 local orderedList = {}
503+ local notAvailableList = {}
428504 local orderOffset = # list + 10
429505 for key , value in pairs (list ) do
430506 if type (key ) == " number" then
431- local treeExists = self :TreeExists (value .id )
432- table.insert (orderedList , {
433- name = (" %s (%d%s)" ):format (value .name , value .id , (treeExists and ' ' or ' - not available' )),
434- order = key ,
435- value = value ,
436- isTree = true ,
437- })
507+ local treeExists = (value .isTraitTree and self :TraitTreeExists (value .id )) or (not value .isTraitTree and self :TreeExists (value .id ))
508+ table.insert (
509+ treeExists and orderedList or notAvailableList ,
510+ {
511+ name = (" %s (%s%d%s)" ):format (value .name , (value .isTraitTree and ' T' or ' R' ), value .id , (treeExists and ' ' or ' - not available' )),
512+ order = key ,
513+ value = value ,
514+ isTree = true ,
515+ }
516+ )
438517 elseif key ~= " order" then
439518 table.insert (orderedList , { name = key , order = value .order + orderOffset , value = value , isTree = false })
440519 end
@@ -447,7 +526,7 @@ function ResearchViewer:GenerateSubMenuButtons(parentDescription, list, isSelect
447526 data = entry .value
448527 if parentDataTables then
449528 for _ , parentData in ipairs (parentDataTables ) do
450- parentData [entry .value .id ] = true
529+ parentData [( entry . value . isTraitTree and ' T ' or ' R ' ) .. entry .value .id ] = true
451530 end
452531 end
453532 else
@@ -460,4 +539,16 @@ function ResearchViewer:GenerateSubMenuButtons(parentDescription, list, isSelect
460539 self :GenerateSubMenuButtons (subMenuButton , entry .value , isSelectedFunc , setValueFunc , dataTables )
461540 end
462541 end
542+ if next (notAvailableList ) then
543+ local dataTables = CreateFromMixins (parentDataTables or {})
544+ local data = {}
545+ table.insert (dataTables , data )
546+ local subParent = parentDescription :CreateRadio (" Not Available" , isSelectedFunc , setValueFunc , data )
547+ for _ , entry in ipairs (notAvailableList ) do
548+ subParent :CreateRadio (entry .name , isSelectedFunc , setValueFunc , entry .value )
549+ for _ , parentData in ipairs (dataTables ) do
550+ parentData [(entry .value .isTraitTree and ' T' or ' R' ) .. entry .value .id ] = true
551+ end
552+ end
553+ end
463554end
0 commit comments