Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
5818033
Add radius jewel finder
mcagnion May 23, 2026
c6505d2
Add radius jewel finder tests
mcagnion May 23, 2026
eba7949
Clarify radius jewel variant selection
mcagnion May 23, 2026
2196baf
Derive radius jewel data from item text
mcagnion May 23, 2026
bf1e8ce
Derive radius jewel family filter options
mcagnion May 24, 2026
badd694
Clarify radius jewel variant filtering
mcagnion May 24, 2026
e728bf3
Support Foulborn variants in Radius Jewel Finder
mcagnion Jul 28, 2026
dcd946d
Rebuild radius jewel specs for historic replacements
mcagnion Aug 3, 2026
f41e4d7
Reuse ordinary Impossible Escape cache
mcagnion Aug 3, 2026
3430459
Show replaced jewels in Apply tooltip
mcagnion Aug 3, 2026
3bd5631
Show replaced jewel tooltips
mcagnion Aug 3, 2026
da89597
Rebuild cluster trees for jewel comparisons
mcagnion Aug 3, 2026
2b15072
Label replaced jewels by base type
mcagnion Aug 3, 2026
c732061
Allow ordinary jewels in safe sockets
mcagnion Aug 3, 2026
d355125
Label special radius jewel sockets
mcagnion Aug 3, 2026
f2638c0
Handle Abyss Timeless replacements
mcagnion Aug 3, 2026
2272051
Regenerate manifest after Radius Jewel rebase
mcagnion Aug 5, 2026
d33c7aa
Adapt radius jewel constructors to current class syntax
mcagnion Aug 15, 2026
f1c2771
Share passive tree comparison classification
mcagnion Aug 16, 2026
b28d6d3
Extract radius jewel result controls
mcagnion Aug 16, 2026
c569b24
Unify radius jewel result sort keys
mcagnion Aug 16, 2026
ba55406
Clarify radius jewel module ownership
mcagnion Aug 16, 2026
e015521
Share radius jewel presentation helpers
mcagnion Aug 16, 2026
542d810
Decompose Impossible Escape evaluation
mcagnion Aug 16, 2026
8e97a3f
Extract radius jewel popup workflows
mcagnion Aug 16, 2026
c8e7b55
Split radius jewel system specs
mcagnion Aug 16, 2026
2e8d65c
Spell out radius jewel point labels
mcagnion Aug 16, 2026
db25244
Reduce radius jewel result cache memory
mcagnion Aug 16, 2026
9fcdd81
Remove unused radius jewel module surface
mcagnion Aug 16, 2026
bdb8d79
Model canonical radius jewel variants
mcagnion Aug 16, 2026
0b5dde7
Bind radius jewel results to build context
mcagnion Aug 17, 2026
bf9d3ba
Execute radius jewel result actions safely
mcagnion Aug 17, 2026
840ba30
Keep Thread plans attached to their sockets
mcagnion Aug 17, 2026
a0c5d26
Isolate Impossible Escape result groups
mcagnion Aug 17, 2026
0368300
Restore Split Personality state on every exit
mcagnion Aug 17, 2026
dfb1da5
Evaluate every Fast radius jewel plan
mcagnion Aug 17, 2026
8626ee7
Give radius jewel computation an explicit owner
mcagnion Aug 17, 2026
c3faa9a
Replace positional radius jewel compute arguments
mcagnion Aug 17, 2026
eb5588d
Route radius jewels through explicit strategies
mcagnion Aug 17, 2026
340a10d
Extract radius jewel result state
mcagnion Aug 17, 2026
a734670
Extract radius jewel result actions
mcagnion Aug 17, 2026
0ace697
Extract radius jewel result presentation
mcagnion Aug 18, 2026
3f98103
Keep stale radius jewel results visible
mcagnion Aug 18, 2026
c74b4c2
Clarify Find availability for jewel variants
mcagnion Aug 18, 2026
5e39fab
Enforce Max points in radius jewel Find
mcagnion Aug 19, 2026
2bb1764
Streamline radius jewel result details
mcagnion Aug 20, 2026
923d9b1
Simplify radius jewel result data and state
mcagnion Aug 21, 2026
cdc8a1b
Merge current dev into radius jewel finder
mcagnion Aug 21, 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
14 changes: 10 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="2369721be67531d5c81f200f0c61d6f1336da544" />
<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="cadafc285f3f79729baeaa44326e8ccc7b7453d2" />
<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,12 @@
<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="d8ee5b10355901155e8df01bafbcc0c967fd2594" />
<File name="Classes/RadiusJewelData.lua" part="program" sha1="8b0d3b83d0b11875e459b3cf89a4276829e23f33" />
<File name="Classes/RadiusJewelDetailListControl.lua" part="program" sha1="fc651bf47cc714d5460e2e2e36f341715bbb4039" />
<File name="Classes/RadiusJewelFinder.lua" part="program" sha1="9c67ae0eaed3764d736f431516ebf8c9343748cd" />
<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 +199,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="66fe760b608234ef7c48b718c844486483b3a4d7" />
<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 +1400,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