From 2e97a24cdfd20b9a5ce19337fe7b9c33f59e1fb6 Mon Sep 17 00:00:00 2001 From: Jacul Date: Thu, 16 Jul 2026 22:59:06 -0400 Subject: [PATCH 1/3] Add support for Baryanic Leylines notable Parses "Non-Unique Time-Lost Jewels have 40% increased radius" and applies it to socketed non-unique Time-Lost jewels. Adds 40% increased versions of the four base radii to data.jewelRadius. PassiveSpec:GetJewelRadiusIndex() now remaps Time-Lost jewel's index to the new versions when the notable is allocated. The lookup goes through the spec instead of the item, so loadouts and tree compare can disagree for the same jewel. Tree view rings, hover previews, and tooltips are updated to use the effective index. ModCache is also regenerated for the new parser entry. --- src/Classes/PassiveSpec.lua | 16 ++++++++++++++++ src/Classes/PassiveTreeView.lua | 21 ++++++++++++++------- src/Data/ModCache.lua | 2 +- src/Modules/CalcSetup.lua | 7 ++++--- src/Modules/Data.lua | 11 +++++++++++ src/Modules/ModParser.lua | 1 + 6 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/Classes/PassiveSpec.lua b/src/Classes/PassiveSpec.lua index ffed6f6ff2..be698339a1 100644 --- a/src/Classes/PassiveSpec.lua +++ b/src/Classes/PassiveSpec.lua @@ -1391,6 +1391,18 @@ function PassiveSpecClass:NodesInIntuitiveLeapLikeRadius(node) return result end +-- Returns the radius index a jewel actually uses in this spec, accounting for +-- "Non-Unique Time-Lost Jewels have 40% increased radius" (Baryanic Leylines) +function PassiveSpecClass:GetJewelRadiusIndex(item) + local radiusIndex = item.jewelRadiusIndex + if radiusIndex and self.hasTimeLostJewelRadiusIncrease + and item.rarity ~= "UNIQUE" and item.rarity ~= "RELIC" + and item.baseName and item.baseName:find("Time%-Lost") then + return data.timeLostJewelIncreasedRadiusIndex[radiusIndex] or radiusIndex + end + return radiusIndex +end + -- Rebuilds dependencies and paths for all nodes function PassiveSpecClass:BuildAllDependsAndPaths() -- This table will keep track of which nodes have been visited during each path-finding attempt @@ -1413,6 +1425,7 @@ function PassiveSpecClass:BuildAllDependsAndPaths() end end wipeTable(intuitiveLeapLikeNodes) + self.hasTimeLostJewelRadiusIncrease = false for id, node in pairs(self.allocNodes) do if node.ascendancyName then -- avoid processing potentially replaceable nodes self.tree:ProcessStats(node) @@ -1421,6 +1434,9 @@ function PassiveSpecClass:BuildAllDependsAndPaths() t_insert(intuitiveLeapLikeNodes, radius) end end + if node.modList:Sum("INC", nil, "NonUniqueTimeLostJewelRadius") > 0 then + self.hasTimeLostJewelRadiusIncrease = true + end processed[id] = true end end diff --git a/src/Classes/PassiveTreeView.lua b/src/Classes/PassiveTreeView.lua index 8c1aa57644..27d7cca95d 100644 --- a/src/Classes/PassiveTreeView.lua +++ b/src/Classes/PassiveTreeView.lua @@ -1098,8 +1098,10 @@ function PassiveTreeViewClass:Draw(build, viewPort, inputEvents) end else -- Jewel in socket is not Thread of Hope or similar + -- Use the increased radii instead of the base ones if the socketed jewel benefits from them + local isIncreased = jewel and build.spec:GetJewelRadiusIndex(jewel) ~= jewel.jewelRadiusIndex for index, data in ipairs(build.data.jewelRadius) do - if hoverNode.nodesInRadius[index][node.id] then + if (not data.increased) == (not isIncreased) and hoverNode.nodesInRadius[index][node.id] then -- Draw normal jewel radii if data.inner == 0 then SetDrawColor(data.col) @@ -1221,8 +1223,8 @@ function PassiveTreeViewClass:Draw(build, viewPort, inputEvents) end -- Draw ring overlays for jewel sockets - local function drawJewelRadius(jewel, scrX, scrY, tint) - local radData = build.data.jewelRadius[jewel.jewelRadiusIndex] + local function drawJewelRadius(jewel, scrX, scrY, tint, jewelSpec) + local radData = build.data.jewelRadius[jewelSpec:GetJewelRadiusIndex(jewel)] local outerSize = radData.outer * data.gameConstants["PassiveTreeJewelDistanceMultiplier"] * scale local innerSize = radData.inner * data.gameConstants["PassiveTreeJewelDistanceMultiplier"] * scale * 1.06 SetDrawColor(tint[1], tint[2], tint[3], tint[4]) @@ -1270,6 +1272,9 @@ function PassiveTreeViewClass:Draw(build, viewPort, inputEvents) if node == hoverNode then local effectiveJewel = jewel or cJewel local isThreadOfHope = effectiveJewel and effectiveJewel.jewelRadiusLabel == "Variable" + -- Preview the increased radii instead of the base ones if the socketed jewel benefits from them + local jewelSpec = jewel and spec or self.compareSpec + local isIncreased = effectiveJewel and jewelSpec and jewelSpec:GetJewelRadiusIndex(effectiveJewel) ~= effectiveJewel.jewelRadiusIndex for _, radData in ipairs(build.data.jewelRadius) do local outerSize = radData.outer * data.gameConstants["PassiveTreeJewelDistanceMultiplier"] * scale local innerSize = radData.inner * data.gameConstants["PassiveTreeJewelDistanceMultiplier"] * scale @@ -1282,7 +1287,7 @@ function PassiveTreeViewClass:Draw(build, viewPort, inputEvents) end else -- Standard jewel: draw the full-disc radii (inner == 0) - if innerSize == 0 then + if innerSize == 0 and (not radData.increased) == (not isIncreased) then SetDrawColor(radData.col) DrawImage(self.ring, scrX - outerSize, scrY - outerSize, outerSize * 2, outerSize * 2) end @@ -1295,10 +1300,10 @@ function PassiveTreeViewClass:Draw(build, viewPort, inputEvents) local sameJewel = compareJewelsEqual(jewel, cJewel) if pHasRadius then local tint = (not self.compareSpec or sameJewel) and JEWEL_RADIUS_TINT_NEUTRAL or JEWEL_RADIUS_TINT_PRIMARY_ONLY - drawJewelRadius(jewel, scrX, scrY, tint) + drawJewelRadius(jewel, scrX, scrY, tint, spec) end if cHasRadius and not sameJewel then - drawJewelRadius(cJewel, scrX, scrY, JEWEL_RADIUS_TINT_COMPARE_ONLY) + drawJewelRadius(cJewel, scrX, scrY, JEWEL_RADIUS_TINT_COMPARE_ONLY, self.compareSpec) end end end @@ -1800,7 +1805,9 @@ function PassiveTreeViewClass:AddNodeTooltip(tooltip, node, build, incSmallPassi local isInRadius = false for id, socket in pairs(build.itemsTab.sockets) do if build.itemsTab.activeSocketList and socket.inactive == false or socket.inactive == nil then - isInRadius = isInRadius or (build.spec.nodes[id] and build.spec.nodes[id].nodesInRadius and build.spec.nodes[id].nodesInRadius[4][node.id] ~= nil) + -- index 4 is Very Large; its increased version covers the largest possible Time-Lost radius + local maxRadiusIndex = build.spec.hasTimeLostJewelRadiusIncrease and data.timeLostJewelIncreasedRadiusIndex[4] or 4 + isInRadius = isInRadius or (build.spec.nodes[id] and build.spec.nodes[id].nodesInRadius and build.spec.nodes[id].nodesInRadius[maxRadiusIndex][node.id] ~= nil) if isInRadius then break end end end diff --git a/src/Data/ModCache.lua b/src/Data/ModCache.lua index 96c7f933cb..9395dea401 100644 --- a/src/Data/ModCache.lua +++ b/src/Data/ModCache.lua @@ -6337,7 +6337,7 @@ c["Non-Keystone Passive Skills in Medium Radius of allocated Keystone Passive Sk c["Non-Minion Skills have 50% less Reservation Efficiency"]={{[1]={[1]={neg=true,skillType=6,type="SkillType"},flags=0,keywordFlags=0,name="ReservationEfficiency",type="MORE",value=-50}},nil} c["Non-Unique Life Flasks apply their Effects constantly"]={nil,"Non-Unique Life Flasks apply their Effects constantly "} c["Non-Unique Life Flasks apply their Effects constantly Recovery from Life Flasks cannot be Instant"]={nil,"Non-Unique Life Flasks apply their Effects constantly Recovery from Life Flasks cannot be Instant "} -c["Non-Unique Time-Lost Jewels have 40% increased radius"]={nil,"Non-Unique Time-Lost Jewels have 40% increased radius "} +c["Non-Unique Time-Lost Jewels have 40% increased radius"]={{[1]={flags=0,keywordFlags=0,name="NonUniqueTimeLostJewelRadius",type="INC",value=40}},nil} c["Oasis"]={{[1]={flags=0,keywordFlags=0,name="Keystone",type="LIST",value="Oasis"}},nil} c["Off-hand Hits inflict Runefather's Challenge"]={nil,"Off-hand Hits inflict Runefather's Challenge "} c["Off-hand Hits inflict Runefather's Challenge Inflicts Runefather's Challenge on enemies 6 metres in front of you when raised, no more than once every 2 seconds"]={nil,"Off-hand Hits inflict Runefather's Challenge Inflicts Runefather's Challenge on enemies 6 metres in front of you when raised, no more than once every 2 seconds "} diff --git a/src/Modules/CalcSetup.lua b/src/Modules/CalcSetup.lua index 5ba727778c..63b0a171fd 100644 --- a/src/Modules/CalcSetup.lua +++ b/src/Modules/CalcSetup.lua @@ -964,6 +964,7 @@ function calcs.initEnv(build, mode, override, specEnv) end if item and not (node and node.sinister) and ( item.jewelRadiusIndex or (override and override.extraJewelFuncs and #override.extraJewelFuncs > 0) ) then -- Jewel has a radius, add it to the list + local radiusIndex = env.spec:GetJewelRadiusIndex(item) local funcList = (item.jewelData and item.jewelData.funcList) or { { type = "Self", func = function(node, out, data) -- Default function just tallies all stats in radius if node then @@ -974,19 +975,19 @@ function calcs.initEnv(build, mode, override, specEnv) end } } for _, func in ipairs(funcList) do t_insert(env.radiusJewelList, { - nodes = node.nodesInRadius and node.nodesInRadius[item.jewelRadiusIndex] or { }, + nodes = node.nodesInRadius and node.nodesInRadius[radiusIndex] or { }, func = func.func, type = func.type, item = item, nodeId = slot.nodeId, - attributes = node.attributesInRadius and node.attributesInRadius[item.jewelRadiusIndex] or { }, + attributes = node.attributesInRadius and node.attributesInRadius[radiusIndex] or { }, data = { }, -- store this to compare with cache later jewelHash = getHashFromString(item.modSource..item.raw) }) if func.type ~= "Self" and node.nodesInRadius then -- Add nearby unallocated nodes to the extra node list - for nodeId, node in pairs(node.nodesInRadius[item.jewelRadiusIndex]) do + for nodeId, node in pairs(node.nodesInRadius[radiusIndex]) do if not env.allocNodes[nodeId] then env.extraRadiusNodeList[nodeId] = env.spec.nodes[nodeId] end diff --git a/src/Modules/Data.lua b/src/Modules/Data.lua index 56d22b13aa..81a16911a8 100644 --- a/src/Modules/Data.lua +++ b/src/Modules/Data.lua @@ -669,9 +669,20 @@ data.jewelRadii = { { inner = 1400, outer = 1700, col = "^xFFCC00", label = "Variable" }, { inner = 1650, outer = 1950, col = "^xFF6600", label = "Variable" }, { inner = 1800, outer = 2100, col = "^x0099FF", label = "Variable" }, + + -- 40% increased versions of the four base radii, used for non-Unique Time-Lost + -- jewels when "Non-Unique Time-Lost Jewels have 40% increased radius" is allocated + -- (Baryanic Leylines). `increased` keeps them out of the generic radius previews. + { inner = 0, outer = 1400, col = "^xBB6600", label = "Increased Small", increased = true }, + { inner = 0, outer = 1610, col = "^x66FFCC", label = "Increased Medium", increased = true }, + { inner = 0, outer = 1820, col = "^x2222CC", label = "Increased Large", increased = true }, + { inner = 0, outer = 2100, col = "^xC100FF", label = "Increased Very Large", increased = true }, } } +-- Maps a Time-Lost jewel's base radius index to its 40% increased counterpart above +data.timeLostJewelIncreasedRadiusIndex = { [1] = 13, [2] = 14, [3] = 15, [4] = 16 } + data.jewelRadius = data.setJewelRadiiGlobally(latestTreeVersion) -- Stat descriptions diff --git a/src/Modules/ModParser.lua b/src/Modules/ModParser.lua index 52fa3b4316..cd793d0332 100644 --- a/src/Modules/ModParser.lua +++ b/src/Modules/ModParser.lua @@ -5525,6 +5525,7 @@ local specialModList = { ["upgrades radius to medium"] = { mod("JewelData", "LIST", { key = "timeLostJewelRadiusOverride", value = 2 })}, ["upgrades radius to large"] = { mod("JewelData", "LIST", { key = "timeLostJewelRadiusOverride", value = 3 })}, ["upgrades radius to very large"] = { mod("JewelData", "LIST", { key = "timeLostJewelRadiusOverride", value = 4 })}, + ["non%-unique time%-lost jewels have (%d+)%% increased radius"] = function(num) return { mod("NonUniqueTimeLostJewelRadius", "INC", num) } end, ["primordial"] = { mod("Multiplier:PrimordialItem", "BASE", 1) }, ["spectres have a base duration of (%d+) seconds"] = { mod("SkillData", "LIST", { key = "duration", value = 6 }, { type = "SkillName", skillName = "Raise Spectre", includeTransfigured = true }) }, ["flasks applied to you have (%d+)%% increased effect"] = function(num) return { mod("FlaskEffect", "INC", num, { type = "ActorCondition", actor = "player"}) } end, From 796a71d2d8d240ab13ec273883d1a1cc91ccdd19 Mon Sep 17 00:00:00 2001 From: Jacul Date: Sun, 19 Jul 2026 22:38:10 -0400 Subject: [PATCH 2/3] Fix node hover tooltip not reflecting Baryanic Leylines radius change --- src/Classes/PassiveSpec.lua | 8 +------- src/Modules/CalcSetup.lua | 5 ++++- src/Modules/Data.lua | 12 ++++++++++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Classes/PassiveSpec.lua b/src/Classes/PassiveSpec.lua index be698339a1..2672432aeb 100644 --- a/src/Classes/PassiveSpec.lua +++ b/src/Classes/PassiveSpec.lua @@ -1394,13 +1394,7 @@ end -- Returns the radius index a jewel actually uses in this spec, accounting for -- "Non-Unique Time-Lost Jewels have 40% increased radius" (Baryanic Leylines) function PassiveSpecClass:GetJewelRadiusIndex(item) - local radiusIndex = item.jewelRadiusIndex - if radiusIndex and self.hasTimeLostJewelRadiusIncrease - and item.rarity ~= "UNIQUE" and item.rarity ~= "RELIC" - and item.baseName and item.baseName:find("Time%-Lost") then - return data.timeLostJewelIncreasedRadiusIndex[radiusIndex] or radiusIndex - end - return radiusIndex + return data.getTimeLostJewelRadiusIndex(item, self.hasTimeLostJewelRadiusIncrease) end -- Rebuilds dependencies and paths for all nodes diff --git a/src/Modules/CalcSetup.lua b/src/Modules/CalcSetup.lua index 63b0a171fd..11a969d4cd 100644 --- a/src/Modules/CalcSetup.lua +++ b/src/Modules/CalcSetup.lua @@ -833,6 +833,9 @@ function calcs.initEnv(build, mode, override, specEnv) local nodesModsList = calcs.buildModListForNodeList(env, env.allocNodes, true, true) env.useAltGemQualityStats = nodesModsList:Flag(nil, "GemlingQuality") + -- Check the environment's own node list rather than the spec's allocation, so that + -- simulated allocations (e.g. node hover tooltips) see the radius change too + local timeLostJewelRadiusIncrease = nodesModsList:Sum("INC", nil, "NonUniqueTimeLostJewelRadius") > 0 if allocatedNotableCount and allocatedNotableCount > 0 then modDB:NewMod("Multiplier:AllocatedNotable", "BASE", allocatedNotableCount) @@ -964,7 +967,7 @@ function calcs.initEnv(build, mode, override, specEnv) end if item and not (node and node.sinister) and ( item.jewelRadiusIndex or (override and override.extraJewelFuncs and #override.extraJewelFuncs > 0) ) then -- Jewel has a radius, add it to the list - local radiusIndex = env.spec:GetJewelRadiusIndex(item) + local radiusIndex = data.getTimeLostJewelRadiusIndex(item, timeLostJewelRadiusIncrease) local funcList = (item.jewelData and item.jewelData.funcList) or { { type = "Self", func = function(node, out, data) -- Default function just tallies all stats in radius if node then diff --git a/src/Modules/Data.lua b/src/Modules/Data.lua index 81a16911a8..742c841879 100644 --- a/src/Modules/Data.lua +++ b/src/Modules/Data.lua @@ -683,6 +683,18 @@ data.jewelRadii = { -- Maps a Time-Lost jewel's base radius index to its 40% increased counterpart above data.timeLostJewelIncreasedRadiusIndex = { [1] = 13, [2] = 14, [3] = 15, [4] = 16 } +-- Returns the radius index a jewel uses given whether the Time-Lost radius increase +-- (Baryanic Leylines) applies; only non-unique Time-Lost jewels are remapped +data.getTimeLostJewelRadiusIndex = function(item, timeLostJewelRadiusIncrease) + local radiusIndex = item.jewelRadiusIndex + if radiusIndex and timeLostJewelRadiusIncrease + and item.rarity ~= "UNIQUE" and item.rarity ~= "RELIC" + and item.baseName and item.baseName:find("Time%-Lost") then + return data.timeLostJewelIncreasedRadiusIndex[radiusIndex] or radiusIndex + end + return radiusIndex +end + data.jewelRadius = data.setJewelRadiiGlobally(latestTreeVersion) -- Stat descriptions From 51dd1aa2a5a1c657bece8c6170833d2081fd5d72 Mon Sep 17 00:00:00 2001 From: Jacul Date: Sun, 19 Jul 2026 23:46:16 -0400 Subject: [PATCH 3/3] Update item slot preview to accommodate increased jewel radius Zoom out if the socketed jewel's radius ring won't fit the default zoom level 17. Adding a 5% margin on top of the ring's diameter. --- src/Modules/ItemSlotHelper.lua | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Modules/ItemSlotHelper.lua b/src/Modules/ItemSlotHelper.lua index 4d9524c9ea..c051233492 100644 --- a/src/Modules/ItemSlotHelper.lua +++ b/src/Modules/ItemSlotHelper.lua @@ -18,6 +18,15 @@ function M.DrawViewer(itemsTab, nodeId, x, y, w, h) local viewer = itemsTab.socketViewer viewer.zoom = 17 + -- Zoom out if needed so the socketed jewel's radius ring (including the Time-Lost + -- radius increase from Baryanic Leylines) fits inside the preview: the ring's + -- diameter must fit min(w,h), with ~5% margin so the ring stroke isn't clipped + local _, jewel = itemsTab:GetSocketAndJewelForNodeID(nodeId) + if jewel and jewel.jewelRadiusIndex then + local radData = data.jewelRadius[itemsTab.build.spec:GetJewelRadiusIndex(jewel)] + local ringSize = radData.outer * data.gameConstants["PassiveTreeJewelDistanceMultiplier"] + viewer.zoom = math.min(viewer.zoom, itemsTab.build.spec.tree.size / (2 * ringSize) / 1.05) + end local viewPortSize = math.min(w, h) local scale = itemsTab.build.spec.tree.size / (viewPortSize * viewer.zoom)