Skip to content

Commit 66a598c

Browse files
committed
Added nodeInfo.isApexTalent
1 parent 8fd5a18 commit 66a598c

File tree

3 files changed

+99
-101
lines changed

3 files changed

+99
-101
lines changed

LibTalentTree-1.0.lua

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
-- the data for LibTalentTree will be loaded (and cached) from blizzard's APIs when the Lib loads
22
-- @curseforge-project-slug: libtalenttree@
3+
--- @diagnostic disable: duplicate-set-field
34

4-
local MAJOR, MINOR = "LibTalentTree-1.0", 29;
5+
local MAJOR, MINOR = "LibTalentTree-1.0", 30;
56
--- @class LibTalentTree-1.0
67
local LibTalentTree = LibStub:NewLibrary(MAJOR, MINOR);
78

@@ -27,6 +28,7 @@ local isMidnight = select(4, GetBuildInfo()) >= 120000;
2728
local MAX_LEVEL = 100; -- seems to not break if set too high, but can break things when set too low
2829
local MAX_SUB_TREE_CURRENCY = isMidnight and 13 or 10; -- blizzard incorrectly reports 20 when asking for the maxQuantity of the currency
2930
local HERO_TREE_REQUIRED_LEVEL = 71; -- while `C_ClassTalents.GetHeroTalentSpecsForClassSpec` returns this info, it's not immediately available on initial load
31+
local APEX_TALENT_LEVEL = 81
3032

3133
-- taken from ClassTalentUtil.GetVisualsForClassID
3234
local CLASS_OFFSETS = {
@@ -130,7 +132,7 @@ do
130132
treeCurrencyMap = {},
131133
--- @type table<number, libNodeInfo[]> # treeID -> {nodeID -> nodeInfo}
132134
nodeData = {},
133-
--- @type table<number, table<number, gateInfo>> # treeID -> {conditionID -> gateInfo}
135+
--- @type table<number, table<number, { currencyID: number, spentAmountRequired: number }>> # treeID -> {conditionID -> gateInfo}
134136
gateData = {},
135137
--- @type table<number, entryInfo[]> # treeID -> {entryID -> entryData}
136138
entryData = {},
@@ -219,14 +221,16 @@ do
219221
data.entryIDs = nodeInfo.entryIDs;
220222
data.subTreeID = nodeInfo.subTreeID;
221223
data.isSubTreeSelection = nodeInfo.type == Enum.TraitNodeType.SubTreeSelection;
224+
data.isApexTalent = false;
225+
data.requiredPlayerLevel = 0;
222226

223-
data.visibleEdges = data.visibleEdges or {}
227+
data.visibleEdges = data.visibleEdges or {};
224228
mergeTables(data.visibleEdges, nodeInfo.visibleEdges, 'targetNode');
225229

226-
data.conditionIDs = data.conditionIDs or {}
230+
data.conditionIDs = data.conditionIDs or {};
227231
mergeTables(data.conditionIDs, nodeInfo.conditionIDs);
228232

229-
data.groupIDs = data.groupIDs or {}
233+
data.groupIDs = data.groupIDs or {};
230234
mergeTables(data.groupIDs, nodeInfo.groupIDs);
231235
for entryIndex, entryID in pairs(nodeInfo.entryIDs) do
232236
cache.entryTreeMap[entryID] = treeID;
@@ -247,7 +251,8 @@ do
247251
cache.subTreeSpecMap[entryInfo.subTreeID][specID] = true;
248252
-- I previously used C_ClassTalents.GetHeroTalentSpecsForClassSpec, but it returns nil on initial load
249253
-- it's not actually required to retrieve the data though
250-
local subTreeInfo = C_Traits.GetSubTreeInfo(configID, entryInfo.subTreeID);
254+
--- @type subTreeInfo|nil
255+
local subTreeInfo = C_Traits.GetSubTreeInfo(configID, entryInfo.subTreeID); --- @diagnostic disable-line: assign-type-mismatch
251256
if subTreeInfo then
252257
subTreeInfo.requiredPlayerLevel = HERO_TREE_REQUIRED_LEVEL;
253258
subTreeInfo.maxCurrency = MAX_SUB_TREE_CURRENCY;
@@ -266,10 +271,20 @@ do
266271

267272
for _, conditionID in pairs(data.conditionIDs) do
268273
local cInfo = C_Traits.GetConditionInfo(configID, conditionID)
269-
if cInfo and cInfo.isMet and cInfo.ranksGranted and cInfo.ranksGranted > 0 then
270-
data.grantedForSpecs[specID] = true;
274+
if cInfo then
275+
if cInfo.isMet and cInfo.ranksGranted and cInfo.ranksGranted > 0 then
276+
data.grantedForSpecs[specID] = true;
277+
end
278+
if cInfo.playerLevel then
279+
data.requiredPlayerLevel = math.max(data.requiredPlayerLevel, cInfo.playerLevel);
280+
end
271281
end
272282
end
283+
if data.requiredPlayerLevel == 0 then
284+
data.requiredPlayerLevel = nil;
285+
elseif data.requiredPlayerLevel >= APEX_TALENT_LEVEL then
286+
data.isApexTalent = true;
287+
end
273288

274289
if nil == data.isClassNode then
275290
data.isClassNode = false;

README.md

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -152,23 +152,25 @@ nodeInfo = LibTalentTree:GetLibNodeInfo(nodeID)
152152
#### Returns
153153
* `table|nil` nodeInfo, nil if not found
154154
##### nodeInfo
155-
| Field | Differences from C_Traits | Extra info |
156-
|------------------------------|---------------------------|------------------------------------------------------------------------------------------|
157-
| `number` ID | None | |
158-
| `number` posX | None | some class trees have a global offset |
159-
| `number` posY | None | some class trees have a global offset |
160-
| `number` type | None | see Enum.TraitNodeType |
161-
| `number` maxRanks | None | |
162-
| `number` flags | None | see Enum.TraitNodeFlag |
163-
| `number[]` groupIDs | None | list of `number` groupIDs |
164-
| `table` visibleEdges | isActive field is missing | list of `table` visibleEdges |
165-
| `number[]` conditionIDs | None | list of `number` conditionIDs |
166-
| `number[]` entryIDs | None | list of `number` entryIDs; generally, choice nodes will have 2, otherwise there's just 1 |
167-
| `number?` subTreeID | None | hero spec / subTree ID if applicable, nil otherwise |
168-
| `table` visibleForSpecs | Lib-only field | `specID` = true/false - true if a node is visible for a spec |
169-
| `table` grantedForSpecs | Lib-only field | `specID` = true/false - true if a node is granted for free, for a spec |
170-
| `boolean` isClassNode | Lib-only field | true if the node is part of the class tree, false if it's a spec or hero spec node |
171-
| `boolean` isSubTreeSelection | Lib-only field | true for sub tree selection nodes |
155+
| Field | Differences from C_Traits | Extra info |
156+
|-------------------------------|---------------------------|----------------------------------------------------------------------------------------------------------------------------|
157+
| `number` ID | None | |
158+
| `number` posX | None | some class trees have a global offset |
159+
| `number` posY | None | some class trees have a global offset |
160+
| `number` type | None | see Enum.TraitNodeType |
161+
| `number` maxRanks | None | |
162+
| `number` flags | None | see Enum.TraitNodeFlag |
163+
| `number[]` groupIDs | None | list of `number` groupIDs |
164+
| `table` visibleEdges | isActive field is missing | list of `table` visibleEdges |
165+
| `number[]` conditionIDs | None | list of `number` conditionIDs |
166+
| `number[]` entryIDs | None | list of `number` entryIDs; generally, choice nodes will have 2, otherwise there's just 1 |
167+
| `number?` subTreeID | None | hero spec / subTree ID if applicable, nil otherwise |
168+
| `table` visibleForSpecs | Lib-only field | `specID` = true/false - true if a node is visible for a spec |
169+
| `table` grantedForSpecs | Lib-only field | `specID` = true/false - true if a node is granted for free, for a spec |
170+
| `boolean` isClassNode | Lib-only field | true if the node is part of the class tree, false if it's a spec or hero spec node |
171+
| `boolean` isSubTreeSelection | Lib-only field | true for sub tree selection nodes |
172+
| `boolean` isApexTalent | Lib-only field | true for "apex" talents (Midnight lvl 81+ talents) |
173+
| `number?` requiredPlayerLevel | Lib-only field | the required level, even if all other conditions are met (such as gates and edges), currently only applies to Apex talents |
172174
##### visibleEdges
173175
| Field | Differences from C_Traits | Extra info |
174176
|----------------------|---------------------------|-------------------------------|

types.lua

Lines changed: 57 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,65 @@
11
--- @meta _
2+
--- @diagnostic disable: duplicate-doc-field, duplicate-doc-alias
23
-- this file contains some of the type definitions used in this library
34

4-
---@class treeCurrencyInfo
5-
---@field traitCurrencyID number
6-
---@field quantity number
7-
---@field maxQuantity number?
8-
---@field spent number
9-
---@field isClassCurrency boolean? # true if the currency is a class currency, nil otherwise
10-
---@field isSpecCurrency boolean? # true if the currency is a spec currency, nil otherwise
11-
---@field subTreeID number? # DEPRECATED the sub tree ID that the currency is associated with if any, nil otherwise
12-
---@field subTreeIDs number[]? # list of sub trees that the currency is associated with if any, nil otherwise
5+
--- @class treeCurrencyInfo: TreeCurrencyInfo
6+
--- @field traitCurrencyID number
7+
--- @field quantity number
8+
--- @field maxQuantity number?
9+
--- @field spent number
10+
--- @field isClassCurrency boolean? # true if the currency is a class currency, nil otherwise
11+
--- @field isSpecCurrency boolean? # true if the currency is a spec currency, nil otherwise
12+
--- @field subTreeID number? # DEPRECATED the sub tree ID that the currency is associated with if any, nil otherwise
13+
--- @field subTreeIDs number[]? # list of sub trees that the currency is associated with if any, nil otherwise
1314

14-
---@alias edgeType
15-
---| 0 # VisualOnly
16-
---| 1 # DeprecatedRankConnection
17-
---| 2 # SufficientForAvailability
18-
---| 3 # RequiredForAvailability
19-
---| 4 # MutuallyExclusive
20-
---| 5 # DeprecatedSelectionOption
15+
--- @class visibleEdge: TraitOutEdgeInfo
16+
--- @field type Enum.TraitEdgeType
17+
--- @field visualStyle Enum.TraitEdgeVisualStyle
18+
--- @field targetNode number # TraitNodeID
19+
--- @field isActive boolean
2120

22-
---@alias visualStyle
23-
---| 0 # None
24-
---| 1 # Straight
21+
--- @class libNodeInfo: TraitNodeInfo
22+
--- @field ID number # TraitNodeID
23+
--- @field posX number
24+
--- @field posY number
25+
--- @field type Enum.TraitNodeType
26+
--- @field maxRanks number
27+
--- @field flags Enum.TraitNodeFlag
28+
--- @field groupIDs number[]
29+
--- @field visibleEdges visibleEdge[] # The order does not always match C_Traits
30+
--- @field conditionIDs number[]
31+
--- @field entryIDs number[] # TraitEntryID - generally, choice nodes will have 2, otherwise there's just 1
32+
--- @field visibleForSpecs table<number, boolean> # specID: true/false, true if a node is visible for a spec
33+
--- @field grantedForSpecs table<number, boolean> # specID: true/false, true if a node is granted for free, for a spec
34+
--- @field isClassNode boolean
35+
--- @field subTreeID number? # the sub tree ID that the node is associated with if any, nil otherwise
36+
--- @field isSubTreeSelection boolean? # true if the node is a sub tree selection node, nil otherwise
37+
--- @field isApexTalent boolean # true for "apex" talents (Midnight lvl 81+ talents)
38+
--- @field requiredPlayerLevel number? # the required level, even if all other conditions are met (such as gates and edges), currently only applies to Apex talents
2539

26-
---@alias nodeType
27-
---| 0 # single
28-
---| 1 # Tiered
29-
---| 2 # Selection
40+
--- @class entryInfo: TraitEntryInfo
41+
--- @field definitionID number # TraitDefinitionID
42+
--- @field type Enum.TraitNodeEntryType
43+
--- @field maxRanks number
44+
--- @field isAvailable boolean # LibTalentTree always returns true
45+
--- @field conditionIDs number[] # list of TraitConditionID, LibTalentTree always returns an empty table
46+
--- @field subTreeID number? # the sub tree ID that the entry will select if any, nil otherwise
3047

31-
---@alias nodeFlags
32-
---| 1 # ShowMultipleIcons
33-
---| 2 # NeverPurchasable
34-
---| 4 # TestPositionLocked
35-
---| 8 # TestGridPositioned
48+
--- @class gateInfo: TraitGateInfo
49+
--- @field topLeftNodeID number # TraitNodeID - the node that is the top left corner of the gate
50+
--- @field conditionID number # TraitConditionID
51+
--- @field spentAmountRequired number # the total amount of currency required to unlock the gate
52+
--- @field traitCurrencyID number # TraitCurrencyID
3653

37-
---@class visibleEdge
38-
---@field type edgeType # see Enum.TraitNodeEdgeType
39-
---@field visualStyle visualStyle # see Enum.TraitEdgeVisualStyle
40-
---@field targetNode number # TraitNodeID
41-
42-
---@class libNodeInfo
43-
---@field ID number # TraitNodeID
44-
---@field posX number
45-
---@field posY number
46-
---@field type nodeType # see Enum.TraitNodeType
47-
---@field maxRanks number
48-
---@field flags nodeFlags # see Enum.TraitNodeFlag
49-
---@field groupIDs number[]
50-
---@field visibleEdges visibleEdge[] # The order does not always match C_Traits
51-
---@field conditionIDs number[]
52-
---@field entryIDs number[] # TraitEntryID - generally, choice nodes will have 2, otherwise there's just 1
53-
---@field visibleForSpecs table<number, boolean> # specID: true/false, true if a node is visible for a spec
54-
---@field grantedForSpecs table<number, boolean> # specID: true/false, true if a node is granted for free, for a spec
55-
---@field isClassNode boolean
56-
---@field subTreeID number? # the sub tree ID that the node is associated with if any, nil otherwise
57-
---@field isSubTreeSelection boolean? # true if the node is a sub tree selection node, nil otherwise
58-
59-
---@class entryInfo
60-
---@field definitionID number # TraitDefinitionID
61-
---@field type number # see Enum.TraitNodeEntryType
62-
---@field maxRanks number
63-
---@field isAvailable boolean # LibTalentTree always returns true
64-
---@field conditionIDs number[] # list of TraitConditionID, LibTalentTree always returns an empty table
65-
---@field subTreeID number? # the sub tree ID that the entry will select if any, nil otherwise
66-
67-
---@class gateInfo
68-
---@field topLeftNodeID number # TraitNodeID - the node that is the top left corner of the gate
69-
---@field conditionID number # TraitConditionID
70-
---@field spentAmountRequired number # the total amount of currency required to unlock the gate
71-
---@field traitCurrencyID number # TraitCurrencyID
72-
73-
---@class subTreeInfo
74-
---@field ID number # SubTreeID
75-
---@field name string # localized name
76-
---@field description string # localized description
77-
---@field iconElementID string # icon atlas
78-
---@field maxCurrency number # the maximum amount of currency that can be spent in this sub tree
79-
---@field posX number # generally corresponds to posX of the top center node (generally the initial starting node)
80-
---@field posY number # generally corresponds to posY of the top center node (generally the initial starting node)
81-
---@field requiredPlayerLevel number
82-
---@field traitCurrencyID number # TraitCurrencyID spent when learning talents in this sub tree
83-
---@field subTreeSelectionNodeIDs number[] # TraitNodeID - the selection nodes that specify whether the sub tree is selected
84-
---@field isActive boolean # hardcoded to false
54+
--- @class subTreeInfo: TraitSubTreeInfo
55+
--- @field ID number # SubTreeID
56+
--- @field name string # localized name
57+
--- @field description string # localized description
58+
--- @field iconElementID string # icon atlas
59+
--- @field maxCurrency number # the maximum amount of currency that can be spent in this sub tree
60+
--- @field posX number # generally corresponds to posX of the top center node (generally the initial starting node)
61+
--- @field posY number # generally corresponds to posY of the top center node (generally the initial starting node)
62+
--- @field requiredPlayerLevel number
63+
--- @field traitCurrencyID number # TraitCurrencyID spent when learning talents in this sub tree
64+
--- @field subTreeSelectionNodeIDs number[] # TraitNodeID - the selection nodes that specify whether the sub tree is selected
65+
--- @field isActive boolean # hardcoded to false

0 commit comments

Comments
 (0)