diff --git a/src/Classes/PassiveSpec.lua b/src/Classes/PassiveSpec.lua index 06aed46260..c67b7ac27e 100644 --- a/src/Classes/PassiveSpec.lua +++ b/src/Classes/PassiveSpec.lua @@ -81,6 +81,9 @@ function PassiveSpecClass:Init(treeVersion, convert) -- Keys are node IDs, values are the replacement node self.hashOverrides = { } + + -- Cached highlight path for Split Personality jewels + self.splitPersonalityPath = { } end function PassiveSpecClass:Load(xml, dbFileName) @@ -950,6 +953,67 @@ function PassiveSpecClass:SetNodeDistanceToClassStart(root) end end +-- Determine the shortest path from the given node to the class' start +-- Only allocated nodes can be traversed +function PassiveSpecClass:GetShortestPathToClassStart(rootId) + local root = self.nodes[rootId] + if not root or not root.alloc or not root.connectedToStart then + return nil + end + + -- Stop once the current class' starting node is reached + local targetNodeId = self.curClass.startNodeId + + local parent = { } + parent[root.id] = nil + + local queue = { root } + local o, i = 1, 2 -- Out, in + while o < i do + local node = queue[o] + o = o + 1 + -- Iterate through all nodes that are connected to this one + for _, other in ipairs(node.linked) do + -- If this connected node is the correct class start node, then construct and return the path + if other.id == targetNodeId then + local path = { [root.id] = true, [other.id] = true } + local cur = node + while cur do + path[cur.id] = true + cur = parent[cur.id] + end + return path + end + + -- Otherwise, record the parent of this node if it hasn't already been visited + if other.alloc and node.type ~= "Mastery" and other.type ~= "ClassStart" and other.type ~= "AscendClassStart" and not parent[other.id] and other.id ~= root.id then + parent[other.id] = node + + -- Add the other node to the end of the queue + queue[i] = other + i = i + 1 + end + end + end + return nil +end + +function PassiveSpecClass:BuildSplitPersonalityPath() + local splitPersonalityPath = { } + for nodeId, itemId in pairs(self.jewels) do + local item = self.build.itemsTab.items[itemId] + if item and item.jewelData and item.jewelData.jewelIncEffectFromClassStart then + local path = self:GetShortestPathToClassStart(nodeId) + if path then + for id in pairs(path) do + splitPersonalityPath[id] = true + end + end + end + end + self.splitPersonalityPath = splitPersonalityPath +end + function PassiveSpecClass:AddMasteryEffectOptionsToNode(node) node.sd = {} if node.masteryEffects ~= nil and #node.masteryEffects > 0 then @@ -1470,6 +1534,8 @@ function PassiveSpecClass:BuildAllDependsAndPaths() end end end + + self:BuildSplitPersonalityPath() end function PassiveSpecClass:ReplaceNode(old, newNode) diff --git a/src/Classes/PassiveTreeView.lua b/src/Classes/PassiveTreeView.lua index cde8e5e16e..3370a436e2 100644 --- a/src/Classes/PassiveTreeView.lua +++ b/src/Classes/PassiveTreeView.lua @@ -273,6 +273,9 @@ function PassiveTreeViewClass:Draw(build, viewPort, inputEvents) end end + -- Split Personality highlight + local splitPersonalityPath = spec.splitPersonalityPath or { } + if treeClick == "LEFT" then if hoverNode then -- User left-clicked on a node @@ -547,7 +550,13 @@ function PassiveTreeViewClass:Draw(build, viewPort, inputEvents) end local function renderConnector(connector) local node1, node2 = spec.nodes[connector.nodeId1], spec.nodes[connector.nodeId2] - setConnectorColor(1, 1, 1) + local connectorDefaultColor = "^xFFFFFF" + + if splitPersonalityPath[node1.id] and splitPersonalityPath[node2.id] then + connectorDefaultColor = colorCodes.SPLITPERSONALITY + end + + setConnectorColor(connectorDefaultColor) local state = getState(node1, node2) local baseState = state if self.compareSpec then @@ -633,6 +642,12 @@ function PassiveTreeViewClass:Draw(build, viewPort, inputEvents) local base, overlay, effect local isAlloc = node.alloc or build.calcsTab.mainEnv.grantedPassives[nodeId] or (compareNode and compareNode.alloc) + local nodeDefaultColor = "^xFFFFFF" + + if splitPersonalityPath[node.id] then + nodeDefaultColor = colorCodes.SPLITPERSONALITY + end + SetDrawLayer(nil, 25) if node.type == "ClassStart" then overlay = isAlloc and node.startArt or "PSStartNodeBackgroundInactive" @@ -778,11 +793,11 @@ function PassiveTreeViewClass:Draw(build, viewPort, inputEvents) -- Node is a mastery, both have it allocated, but mastery changed, color it blue SetDrawColor(0, 0, 1) else - -- Both have or both have not, use white - SetDrawColor(1, 1, 1) + -- Both have or both have not + SetDrawColor(nodeDefaultColor) end else - SetDrawColor(1, 1, 1) + SetDrawColor(nodeDefaultColor) end end elseif launch.devModeAlt then @@ -806,11 +821,11 @@ function PassiveTreeViewClass:Draw(build, viewPort, inputEvents) -- Node is a mastery, both have it allocated, but mastery changed, color it blue SetDrawColor(0, 0, 1) else - -- Both have or both have not, use white - SetDrawColor(1, 1, 1) - end + -- Both have or both have not + SetDrawColor(nodeDefaultColor) + end else - SetDrawColor(1, 1, 1) + SetDrawColor(nodeDefaultColor) end end diff --git a/src/Data/Global.lua b/src/Data/Global.lua index 2482f8117d..71393a6123 100644 --- a/src/Data/Global.lua +++ b/src/Data/Global.lua @@ -56,7 +56,8 @@ colorCodes = { BRITTLEBG = "^x00122b", SAPBG = "^x261500", SCOURGE = "^xFF6E25", - CRUCIBLE = "^xFFA500" + CRUCIBLE = "^xFFA500", + SPLITPERSONALITY = "^xFFD62A" } colorCodes.STRENGTH = colorCodes.MARAUDER colorCodes.DEXTERITY = colorCodes.RANGER