Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
a70e899
Add radius jewel finder
mcagnion May 23, 2026
a10db01
Add radius jewel finder tests
mcagnion May 23, 2026
0977150
Clarify radius jewel variant selection
mcagnion May 23, 2026
200f935
Derive radius jewel data from item text
mcagnion May 23, 2026
e167e38
Derive radius jewel family filter options
mcagnion May 24, 2026
503aed7
Clarify radius jewel variant filtering
mcagnion May 24, 2026
ab2fbd3
Support Foulborn variants in Radius Jewel Finder
mcagnion Jul 28, 2026
fbaa18a
Rebuild radius jewel specs for historic replacements
mcagnion Aug 3, 2026
9c74cdc
Reuse ordinary Impossible Escape cache
mcagnion Aug 3, 2026
ad226d1
Show replaced jewels in Apply tooltip
mcagnion Aug 3, 2026
1f1892a
Show replaced jewel tooltips
mcagnion Aug 3, 2026
3e8bcc1
Rebuild cluster trees for jewel comparisons
mcagnion Aug 3, 2026
aa7bd79
Label replaced jewels by base type
mcagnion Aug 3, 2026
b0b74ef
Allow ordinary jewels in safe sockets
mcagnion Aug 3, 2026
733f79e
Label special radius jewel sockets
mcagnion Aug 3, 2026
0a987bf
Handle Abyss Timeless replacements
mcagnion Aug 3, 2026
b9686ce
Regenerate manifest after Radius Jewel rebase
mcagnion Aug 5, 2026
e05a2d9
Adapt radius jewel constructors to current class syntax
mcagnion Aug 15, 2026
9d114d1
Share passive tree comparison classification
mcagnion Aug 16, 2026
fa2d836
Extract radius jewel result controls
mcagnion Aug 16, 2026
34348e3
Unify radius jewel result sort keys
mcagnion Aug 16, 2026
c6694d7
Clarify radius jewel module ownership
mcagnion Aug 16, 2026
e5c017f
Share radius jewel presentation helpers
mcagnion Aug 16, 2026
a5b57b8
Decompose Impossible Escape evaluation
mcagnion Aug 16, 2026
b13435e
Extract radius jewel popup workflows
mcagnion Aug 16, 2026
386c02f
Split radius jewel system specs
mcagnion Aug 16, 2026
117b479
Spell out radius jewel point labels
mcagnion Aug 16, 2026
63d5e68
Reduce radius jewel result cache memory
mcagnion Aug 16, 2026
eb69dce
Remove unused radius jewel module surface
mcagnion Aug 16, 2026
6d81e4f
Model canonical radius jewel variants
mcagnion Aug 16, 2026
7c62da7
Bind radius jewel results to build context
mcagnion Aug 17, 2026
af7c3b0
Execute radius jewel result actions safely
mcagnion Aug 17, 2026
4d9a812
Keep Thread plans attached to their sockets
mcagnion Aug 17, 2026
0ebcfc7
Isolate Impossible Escape result groups
mcagnion Aug 17, 2026
abee7f4
Restore Split Personality state on every exit
mcagnion Aug 17, 2026
7d50870
Evaluate every Fast radius jewel plan
mcagnion Aug 17, 2026
6e7ac2e
Give radius jewel computation an explicit owner
mcagnion Aug 17, 2026
55fef0c
Replace positional radius jewel compute arguments
mcagnion Aug 17, 2026
a340b4c
Route radius jewels through explicit strategies
mcagnion Aug 17, 2026
bbc6e5e
Extract radius jewel result state
mcagnion Aug 17, 2026
5707008
Extract radius jewel result actions
mcagnion Aug 17, 2026
5635663
Extract radius jewel result presentation
mcagnion Aug 18, 2026
a5f2eff
Keep stale radius jewel results visible
mcagnion Aug 18, 2026
8053e95
Clarify Find availability for jewel variants
mcagnion Aug 18, 2026
5a3c743
Enforce Max points in radius jewel Find
mcagnion Aug 19, 2026
301727b
Streamline radius jewel result details
mcagnion Aug 20, 2026
9024d1b
Simplify radius jewel result data and state
mcagnion Aug 21, 2026
77893e9
Extract radius jewel item actions
mcagnion Aug 22, 2026
599d158
Clarify radius jewel result contracts
mcagnion Aug 22, 2026
d1ca4ee
Consolidate radius jewel strategy capabilities
mcagnion Aug 22, 2026
e032de0
Refresh radius jewel manifest after realignment
mcagnion Aug 26, 2026
846ca4b
Simplify Impossible Escape result fan-out
mcagnion Aug 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions manifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@
<File name="Classes/ItemListControl.lua" part="program" sha1="fcfdc29c1e1a69c5d8840286ff325886c91fc2ef" />
<File name="Classes/ItemSetListControl.lua" part="program" sha1="443038191a6ba3a17c3ce6683b96ab2797cf5d39" />
<File name="Classes/ItemSlotControl.lua" part="program" sha1="f353849939ff90f259110baaf59bced890b0994e" />
<File name="Classes/ItemsTab.lua" part="program" sha1="75b76c44dfd9f9c472a2f9d26a48b2998f84fba6" />
<File name="Classes/ItemsTab.lua" part="program" sha1="5330b7ae2f5f84d7be502ee7a8b0574c337eb57f" />
<File name="Classes/LabelControl.lua" part="program" sha1="b6c56903b054e14c302a5e4e60ed8e91764bc6a0" />
<File name="Classes/ListControl.lua" part="program" sha1="b51a294cd00391400bc5d0ad101319bb126dc6a0" />
<File name="Classes/MinionListControl.lua" part="program" sha1="b9324d7c16d20ac4d7508ecd151c2e9838fdb98c" />
Expand All @@ -162,7 +162,7 @@
<File name="Classes/NotesTab.lua" part="program" sha1="de067274e65a7d71940caead279c3a1f8d6fce3e" />
<File name="Classes/PartyTab.lua" part="program" sha1="a2763e12e81f8708d9e179e887bde63016e79d24" />
<File name="Classes/PassiveMasteryControl.lua" part="program" sha1="d26082d3fa6485b0813c3a988d180208fdd652ef" />
<File name="Classes/PassiveSpec.lua" part="program" sha1="b9ea628f8f365795aa0375c1f3fe67ba671ffad9" />
<File name="Classes/PassiveSpec.lua" part="program" sha1="e4178911779ed63533f783da6d436f8924032e8e" />
<File name="Classes/PassiveSpecListControl.lua" part="program" sha1="694d7b088e895348857b97a78babb00d612469f8" />
<File name="Classes/PassiveTree.lua" part="program" sha1="3c1e123c7563640ddfe83e197dbee7a12ad33725" />
<File name="Classes/PassiveTreeView.lua" part="program" sha1="28e5dcdd5e470db6f04fd454957c36c791d87524" />
Expand All @@ -171,6 +171,13 @@
<File name="Classes/PoEAPI.lua" part="program" sha1="8d2d4ac10133002f869fc0a2e157605ceba32ea4" />
<File name="Classes/PopupDialog.lua" part="program" sha1="f37b60b6589d4ff0c721c2418d78409f2dc69452" />
<File name="Classes/PowerReportListControl.lua" part="program" sha1="c9d51d41962a7d8d3a7508765758e10d3ebcb3c7" />
<File name="Classes/RadiusJewelCompute.lua" part="program" sha1="2fc47abb521460c1adf3e2c27696f012ded6c68b" />
<File name="Classes/RadiusJewelData.lua" part="program" sha1="6d4607a936d51849913e99253c7d294a811a8121" />
<File name="Classes/RadiusJewelDetailListControl.lua" part="program" sha1="fc651bf47cc714d5460e2e2e36f341715bbb4039" />
<File name="Classes/RadiusJewelFinder.lua" part="program" sha1="c9d28c8a1c7e145952786aeb96ce52236cda7616" />
<File name="Classes/RadiusJewelItemActions.lua" part="program" sha1="5fba2b7595c46e9217e1c20c47d8c818df9d07cb" />
<File name="Classes/RadiusJewelResultsListControl.lua" part="program" sha1="78bbfb0bf09739a76a88a119653a33fa27ab91de" />
<File name="Classes/RadiusJewelTooltipPlacement.lua" part="program" sha1="768fe21dcb1dff1809f4d6180d94b49374899082" />
<File name="Classes/RectangleOutlineControl.lua" part="program" sha1="4da285dbe76549deae46d3835e00c382c59c18b4" />
<File name="Classes/ResizableEditControl.lua" part="program" sha1="1270c263bd762759cc1121c3eeb4906018136e05" />
<File name="Classes/ScrollBarControl.lua" part="program" sha1="58f68ca961c625d3aba4c8946f7894371c74d335" />
Expand All @@ -193,7 +200,7 @@
<File name="Classes/TradeQueryRateLimiter.lua" part="program" sha1="d7c4f5655b36e911ccf4597e8ab6a3c1e3a27ec5" />
<File name="Classes/TradeQueryRequests.lua" part="program" sha1="0f8342ef30c9240ce96028defbad5838b8a22306" />
<File name="Classes/TradeStatWeightMultiplierListControl.lua" part="program" sha1="df442a192fcaf26558e7485b9c31d2b4e79dc6fc" />
<File name="Classes/TreeTab.lua" part="program" sha1="a3af8fff50d314f3119362c79670a0e7d3e6dce1" />
<File name="Classes/TreeTab.lua" part="program" sha1="616e02c2c89e6c509231b780d0966c3b9ff0a2ae" />
<File name="Classes/UndoHandler.lua" part="program" sha1="ce4835c384c834da0de47b0302b1e774c8300c6b" />
<File name="Data/Bases/amulet.lua" part="program" sha1="0c35de0a6731169f674fee440af79e5215ba627e" />
<File name="Data/Bases/axe.lua" part="program" sha1="0b7a87867c677b95ccf1bdd0937f0874857f35af" />
Expand Down Expand Up @@ -1394,4 +1401,4 @@
<File name="TreeData/VaalJewelCircle2.png" part="tree" sha1="facc5d2fea2f0027d09fdb6e4692f9f298aff293" />
<File name="TreeData/VerdantOil.png" part="tree" sha1="97e77b6e96accf440c17a81d622bf629b8c78fe7" />
<File name="TreeData/VioletOil.png" part="tree" sha1="1e9e4f0683a5156c27cb7ddafada8bed877e1c25" />
</PoBVersion>
</PoBVersion>
157 changes: 157 additions & 0 deletions spec/System/RadiusJewelFinderTestSupport.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
-- Shared fixture helpers and state checks for Radius Jewel system specs.

local support = { }

support.occVortex = LoadModule("../spec/TestBuilds/3.13/OccVortex.lua")
support.mirageArcherToxicRain = LoadModule("../spec/TestBuilds/3.13/Mirage Archer Toxic Rain.lua")
support.RadiusJewelData = LoadModule("Classes/RadiusJewelData")

support.MIGHT_OF_MEEK_RAW_TEXT = [[Might of the Meek
Crimson Jewel
Radius: Large
50% increased Effect of non-Keystone Passive Skills in Radius
Notable Passive Skills in Radius grant nothing]]

support.UNNATURAL_INSTINCT_RAW_TEXT = [[Unnatural Instinct
Viridian Jewel
Limited to: 1
Radius: Small
Allocated Small Passive Skills in Radius grant nothing
Grants all bonuses of Unallocated Small Passive Skills in Radius]]

support.ANATOMICAL_KNOWLEDGE_RAW_TEXT = [[Anatomical Knowledge
Cobalt Jewel
Source: No longer obtainable
Radius: Large
8% increased maximum Life
Adds 1 to Maximum Life per 3 Intelligence Allocated in Radius]]

function support.buildSplitPersonalityRawText(modLine)
return table.concat({
"Split Personality",
"Crimson Jewel",
"Variable",
"This Jewel's Socket has 25% increased effect per Allocated Passive Skill between it and your Class' starting location",
modLine,
"Corrupted",
}, "\n")
end

function support.buildImpossibleEscapeRawText(keystoneName)
return table.concat({
"Impossible Escape",
"Viridian Jewel",
"Limited to: 1",
"Small",
"Passive Skills in radius of " .. keystoneName .. " can be allocated without being connected to your tree",
"Corrupted",
}, "\n")
end

function support.makeFinder()
return new("RadiusJewelFinder"):RadiusJewelFinder({ build = build })
end

local function getRadiusIndex(label)
local radiusIndexByLabel = { }
for i, radius in ipairs(data.jewelRadius) do
if radius.inner == 0 and not radiusIndexByLabel[radius.label] then
radiusIndexByLabel[radius.label] = i
end
end
return radiusIndexByLabel[label]
end

function support.getLargeRadiusIndex()
return getRadiusIndex("Large")
end

function support.getSmallRadiusIndex()
return getRadiusIndex("Small")
end

function support.getRadiusIndexFromRawText(rawText)
local item = new("Item"):Item("Rarity: Unique\n" .. rawText)
return item.jewelRadiusIndex
end

function support.makeImpossibleEscapeTestVariant()
local smallRadiusIndex = support.getSmallRadiusIndex()
local allocNodes = build.spec.allocNodes
for keystoneName, node in pairs(build.spec.tree.keystoneMap or { }) do
if node and node.nodesInRadius and node.nodesInRadius[smallRadiusIndex] then
local hasCandidate = false
for nodeId, radiusNode in pairs(node.nodesInRadius[smallRadiusIndex]) do
if not allocNodes[nodeId] and not radiusNode.ascendancyName
and radiusNode.type ~= "Socket" and radiusNode.type ~= "ClassStart"
and radiusNode.type ~= "AscendClassStart" and radiusNode.type ~= "Mastery" then
hasCandidate = true
break
end
end
if hasCandidate then
return {
name = keystoneName,
keystoneName = keystoneName,
rawText = support.buildImpossibleEscapeRawText(keystoneName),
}
end
end
end
end

function support.makeThreadVariants()
return support.RadiusJewelData.getThreadOfHopeVariants()
end

function support.isSorted(results, key)
for i = 2, #results do
if results[i - 1][key] < results[i][key] then
return false
end
end
return true
end

function support.snapshotFinderState()
local socketSelItemIds = { }
for socketId, slot in pairs(build.itemsTab.sockets) do
socketSelItemIds[socketId] = slot.selItemId
end

local itemOrderList = { }
for i, itemId in ipairs(build.itemsTab.itemOrderList) do
itemOrderList[i] = itemId
end

local itemCount = 0
local itemStateById = { }
for itemId, item in pairs(build.itemsTab.items) do
itemCount = itemCount + 1
itemStateById[itemId] = item.BuildRaw and item:BuildRaw() or {
title = item.title,
name = item.name,
baseName = item.baseName,
limit = item.limit,
}
end

return {
socketSelItemIds = socketSelItemIds,
itemOrderList = itemOrderList,
itemCount = itemCount,
itemStateById = itemStateById,
jewels = copyTable(build.spec.jewels, true),
}
end

function support.assertFinderStateUnchanged(before, check)
local after = support.snapshotFinderState()
check.are.same(before.socketSelItemIds, after.socketSelItemIds)
check.are.same(before.itemOrderList, after.itemOrderList)
check.are.equal(before.itemCount, after.itemCount)
check.are.same(before.itemStateById, after.itemStateById)
check.are.same(before.jewels, after.jewels)
end

return support
Loading
Loading