Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 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
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="1803a24ce6886c8c7d3e07b74fbc17d3981acd3d" />
<File name="Classes/RadiusJewelData.lua" part="program" sha1="563f29e9a20937694ab3d13fb8963a3f091923b0" />
<File name="Classes/RadiusJewelDetailListControl.lua" part="program" sha1="f938b23b5b703e21084983d0ea2517838159ac0b" />
<File name="Classes/RadiusJewelFinder.lua" part="program" sha1="9f15fc90d9f6ab82bddb75c4bb6b1584f19ff584" />
<File name="Classes/RadiusJewelResultsListControl.lua" part="program" sha1="517b6b2d9a58cf208ba004ca9e5dd568d39b368e" />
<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>
160 changes: 160 additions & 0 deletions spec/System/RadiusJewelFinderTestSupport.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
-- 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()
local names = { "Small", "Medium", "Large", "Very Large", "Massive" }
local variants = { }
local variantIndex = 1
for radiusIndex, radius in ipairs(data.jewelRadius) do
if radius.inner > 0 then
variants[#variants + 1] = {
name = names[variantIndex] or ("Ring " .. variantIndex),
radiusIndex = radiusIndex,
}
variantIndex = variantIndex + 1
end
end
return variants
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
for _ in pairs(build.itemsTab.items) do
itemCount = itemCount + 1
end

return {
socketSelItemIds = socketSelItemIds,
itemOrderList = itemOrderList,
itemCount = itemCount,
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.jewels, after.jewels)
end

return support
Loading
Loading