From 1957775427730e4c5da7dbf3964b2939fd160d41 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Mon, 20 Apr 2026 07:43:50 +1000 Subject: [PATCH] Fix crash on import I'm not sure if this is an issue due to poe.ninja cluster rendering but for some reason importing some builds show the clusters as being disconnected and it causes a crash --- src/Classes/PassiveSpec.lua | 53 ++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/Classes/PassiveSpec.lua b/src/Classes/PassiveSpec.lua index 1c76f94fd0..e28e74a86b 100644 --- a/src/Classes/PassiveSpec.lua +++ b/src/Classes/PassiveSpec.lua @@ -898,30 +898,39 @@ function PassiveSpecClass:BuildPathFromNode(root) o = o + 1 local curDist = node.pathDist -- Iterate through all nodes that are connected to this one - for _, other in ipairs(node.linked) do - -- Paths must obey these rules: - -- 1. They must not pass through class or ascendancy class start nodes (but they can start from such nodes) - -- 2. They cannot pass between different ascendancy classes or between an ascendancy class and the main tree - -- The one exception to that rule is that a path may start from an ascendancy node and pass into the main tree - -- This permits pathing from the Ascendant 'Path of the X' nodes into the respective class start areas - -- 3. They must not pass away from mastery nodes - if not other.pathDist then - ConPrintTable(other, true) + for index, other in ipairs(node.linked) do + -- Cluster subgraph rebuilds can replace node objects while retaining IDs. + -- Normalize stale link references to the canonical node object. + local canonicalNode = other and other.id and self.nodes[other.id] + if not canonicalNode then + other = nil + elseif canonicalNode ~= other then + node.linked[index] = canonicalNode + other = canonicalNode end - if node.type ~= "Mastery" and other.type ~= "ClassStart" and other.type ~= "AscendClassStart" and other.pathDist > curDist and (node.ascendancyName == other.ascendancyName or (curDist == 0 and not other.ascendancyName)) then - -- The shortest path to the other node is through the current node - other.pathDist = curDist - if not other.alloc then - other.pathDist = other.pathDist + 1 - end - other.path = wipeTable(other.path) - other.path[1] = other - for i, n in ipairs(node.path) do - other.path[i+1] = n + if other then + -- Paths must obey these rules: + -- 1. They must not pass through class or ascendancy class start nodes (but they can start from such nodes) + -- 2. They cannot pass between different ascendancy classes or between an ascendancy class and the main tree + -- The one exception to that rule is that a path may start from an ascendancy node and pass into the main tree + -- This permits pathing from the Ascendant 'Path of the X' nodes into the respective class start areas + -- 3. They must not pass away from mastery nodes + local otherPathDist = other.pathDist or 1000 + if node.type ~= "Mastery" and other.type ~= "ClassStart" and other.type ~= "AscendClassStart" and otherPathDist > curDist and (node.ascendancyName == other.ascendancyName or (curDist == 0 and not other.ascendancyName)) then + -- The shortest path to the other node is through the current node + other.pathDist = curDist + if not other.alloc then + other.pathDist = other.pathDist + 1 + end + other.path = wipeTable(other.path) + other.path[1] = other + for i, n in ipairs(node.path) do + other.path[i+1] = n + end + -- Add the other node to the end of the queue + queue[i] = other + i = i + 1 end - -- Add the other node to the end of the queue - queue[i] = other - i = i + 1 end end end