Skip to content

Commit 77d45b5

Browse files
committed
Refactor implicit mods into dropdown
1 parent 880f117 commit 77d45b5

1 file changed

Lines changed: 69 additions & 64 deletions

File tree

src/Classes/TradeQueryGenerator.lua

Lines changed: 69 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -919,38 +919,44 @@ function TradeQueryGeneratorClass:ExecuteQuery()
919919
end
920920
return
921921
end
922-
923922
local tradeMode = self.calcContext.options.tradeMode or 1
924923
local existingItemIsUnique = self.calcContext.options.existingItemIsUnique
924+
local implMode = self.calcContext.options.includeImplicits
925+
925926
if tradeMode ~= 4 and not existingItemIsUnique then
926927
-- Standard/Upgrade/Exact: generate explicit weights for rare items.
927928
-- Skipped for unique items — their explicit mods are fixed; only implicit/corrupted vary.
928929
self:GenerateModWeights(self.modData["Explicit"])
929-
if self.calcContext.options.includeImplicits then
930+
if implMode == "All" or implMode == "Without Eldritch" or implMode == "Eldritch limited" then
930931
self:GenerateModWeights(self.modData["Implicit"])
931932
end
932933
elseif existingItemIsUnique then
933-
-- Unique item search: only implicit/corrupted mods differ between copies.
934-
if self.calcContext.options.includeImplicits then
934+
-- Unique item search: only implicit and corrupted mods differ between copies.
935+
if implMode == "All" or implMode == "Without Eldritch" or implMode == "Eldritch limited" then
935936
self:GenerateModWeights(self.modData["Implicit"])
936937
end
937938
end
938-
if self.calcContext.options.includeCorrupted then
939+
-- Corrupted implicits share the "implicit.*" trade-ID namespace.
940+
-- When the user selects "None" for implicit mods they expect NO implicit-category
941+
-- stats in the weighted group, so skip corrupted weights in that case too.
942+
-- (The includeCorrupted checkbox still controls result filtering via misc_filters.)
943+
if self.calcContext.options.includeCorrupted and implMode ~= "None" then
939944
self:GenerateModWeights(self.modData["Corrupted"])
940945
end
941946
if self.calcContext.options.includeScourge then
942947
self:GenerateModWeights(self.modData["Scourge"])
943948
end
944-
if self.calcContext.options.includeEldritch ~= "None" and
945-
not (tradeMode == 4 and self.calcContext.options.isUnique) and
949+
-- Eldritch weights: "All" uses the full Eater/Exarch pool; "Eldritch limited" strips
950+
-- conditional boss-presence mods (PinnaclePresence/UniquePresence) to save filter slots.
951+
-- "Without Eldritch" and "None" intentionally skip this block.
952+
if (implMode == "All" or implMode == "Eldritch limited") and
946953
-- skip weights if we need an influenced item as they can produce really
947954
-- bad results due to the filter limit
948955
self.calcContext.options.influence1 == 1 and
949956
self.calcContext.options.influence2 == 1 then
950-
local omitConditional = self.calcContext.options.includeEldritch == "Omit While"
951957
local eaterMods = self.modData["Eater"]
952958
local exarchMods = self.modData["Exarch"]
953-
if omitConditional then
959+
if implMode == "Eldritch limited" then
954960
local function filterMods(mods)
955961
local filtered = {}
956962
for name, mod in pairs(mods) do
@@ -1345,6 +1351,10 @@ function TradeQueryGeneratorClass:FinishQuery()
13451351
-- Collect required mod filters from the current item's mods if requested
13461352
local requiredModFilters = {}
13471353
local craftedSlotFilters = {}
1354+
-- Implicit required filters apply to Modes 2 and 3 (same scope as explicit required filters).
1355+
-- Mode 1: weights only, no required filters.
1356+
-- Mode 4: implicits are the search target, not a required constraint.
1357+
local needImplicitFilters = (tradeMode == 2 or tradeMode == 3) and options.includeImplicits ~= "None"
13481358
if requireCurrentMods and originalItem then
13491359
-- Build separate normalized text -> tradeModId lookups so explicit and implicit
13501360
-- stat IDs are never confused with each other.
@@ -1393,7 +1403,9 @@ function TradeQueryGeneratorClass:FinishQuery()
13931403
local preferLocal = originalItem.base and (originalItem.base.weapon or originalItem.base.armour) and true or false
13941404
local explicitTextToId = buildTextLookup(self.modData.Explicit, preferLocal)
13951405
local implicitTextToId = buildTextLookup(self.modData.Implicit)
1396-
if options.includeEldritch and options.includeEldritch ~= "None" then
1406+
-- Augment the explicit lookup with Eldritch stat IDs so Eldritch mod lines on the item
1407+
-- are found when building required filters. Skipped for "None" and "Without Eldritch".
1408+
if options.includeImplicits ~= "None" and options.includeImplicits ~= "Without Eldritch" then
13971409
for _, eldritchModType in ipairs({ "Eater", "Exarch" }) do
13981410
for k, v in pairs(buildTextLookup(self.modData[eldritchModType])) do
13991411
explicitTextToId[k] = explicitTextToId[k] or v
@@ -1472,7 +1484,7 @@ function TradeQueryGeneratorClass:FinishQuery()
14721484
end
14731485
end
14741486
addModLines(originalItem.explicitModLines, explicitTextToId, nil)
1475-
if tradeMode ~= 4 and options.includeImplicits then
1487+
if needImplicitFilters then
14761488
addModLines(originalItem.implicitModLines, implicitTextToId, explicitTextToId)
14771489
end
14781490
-- Crafted mods are always in explicitModLines with modLine.crafted = true.
@@ -1648,13 +1660,21 @@ function TradeQueryGeneratorClass:RequestQuery(slot, context, statWeights, callb
16481660
local isWeaponSlot = slot and (slot.slotName == "Weapon 1" or slot.slotName == "Weapon 2")
16491661
local isEldritchModSlot = slot and eldritchModSlots[slot.slotName] == true
16501662

1663+
-- All controls are left-aligned in a single TOPLEFT chain.
1664+
-- The checkbox box sits at x≈176 (popup-relative); labels are drawn to its left.
1665+
-- Mirrored Items: top of chain, skip for unique items (they can't be mirrored).
1666+
local lastItemAnchor
1667+
if not context.slotTbl.unique then
1668+
controls.includeMirrored = new("CheckBoxControl", {"TOP",nil,"TOP"}, {-15, 30, 18}, "Mirrored items:", function(state) end)
1669+
controls.includeMirrored.state = (self.lastIncludeMirrored == nil or self.lastIncludeMirrored == true)
1670+
lastItemAnchor = controls.includeMirrored
1671+
end
16511672

16521673
-- removing checkbox until synthesis mods are supported
16531674
--controls.includeSynthesis = new("CheckBoxControl", {"TOPLEFT",controls.includeEldritch,"BOTTOMLEFT"}, {0, 5, 18}, "Synthesis Mods:", function(state) end)
16541675
--controls.includeSynthesis.state = (self.lastIncludeSynthesis == nil or self.lastIncludeSynthesis == true)
16551676

1656-
local lastItemAnchor = nil
1657-
local includeScourge = self.queryTab.pbLeagueRealName == "Standard" or self.queryTab.pbLeagueRealName == "Hardcore" or self.queryTab.pbLeague == "Standard" or self.queryTab.pbLeague == "Hardcore"
1677+
local includeScourge = self.queryTab.pbLeague == "Standard" or self.queryTab.pbLeague == "Hardcore"
16581678

16591679
local function updateLastAnchor(anchor, height)
16601680
lastItemAnchor = anchor
@@ -1665,17 +1685,16 @@ function TradeQueryGeneratorClass:RequestQuery(slot, context, statWeights, callb
16651685
options.special = { itemName = context.slotTbl.slotName }
16661686
end
16671687

1668-
-- these unique items cannot be mirrored
1669-
if not context.slotTbl.unique then
1670-
controls.includeMirrored = new("CheckBoxControl", {"TOP",nil,"TOP"}, {-15, 30, 18}, "Mirrored Items:", function(state) end)
1671-
controls.includeMirrored.state = (self.lastIncludeMirrored == nil or self.lastIncludeMirrored == true)
1688+
if controls.includeMirrored then
16721689
updateLastAnchor(controls.includeMirrored)
16731690
end
16741691

1675-
-- Corrupted Items: directly below Mirrored, before Mode.
1692+
-- Corrupted Items: below Mirrored (or at top for unique items where Mirrored is hidden).
16761693
-- Unchecked = exclude corrupted (adds corrupted=false to misc_filters, same pattern as mirrored).
16771694
-- Checked = allow corrupted (Any) + include corrupted implicit weights.
1678-
controls.includeCorrupted = new("CheckBoxControl", {"TOPLEFT",lastItemAnchor,"BOTTOMLEFT"}, {0, 5, 18}, "Corrupted Items:", function(state) end)
1695+
local corruptedAnchor = lastItemAnchor and {"TOPLEFT",lastItemAnchor,"BOTTOMLEFT"} or {"TOP",nil,"TOP"}
1696+
local corruptedRect = lastItemAnchor and {0, 5, 18} or {-15, 30, 18}
1697+
controls.includeCorrupted = new("CheckBoxControl", corruptedAnchor, corruptedRect, "Corrupted Items:", function(state) end)
16791698
controls.includeCorrupted.state = not context.slotTbl.alreadyCorrupted and (self.lastIncludeCorrupted == nil or self.lastIncludeCorrupted == true)
16801699
controls.includeCorrupted.enabled = not context.slotTbl.alreadyCorrupted
16811700
updateLastAnchor(controls.includeCorrupted)
@@ -1707,18 +1726,21 @@ function TradeQueryGeneratorClass:RequestQuery(slot, context, statWeights, callb
17071726
controls.includePseudo.tooltipText = "Consolidate related explicit/implicit mods into pseudo stat filters"
17081727
updateLastAnchor(controls.includePseudo)
17091728

1710-
-- Implicit Mods checkbox: below Pseudo Mods
1711-
controls.includeImplicits = new("CheckBoxControl", {"TOPLEFT",lastItemAnchor,"BOTTOMLEFT"}, {0, 5, 18}, "Implicit Mods:", function(state) end)
1712-
controls.includeImplicits.state = (self.lastIncludeImplicits == nil or self.lastIncludeImplicits == true)
1729+
-- Implicit Mods dropdown: controls which mods from the implicit/Eldritch pools
1730+
-- enter the weight and required-filter groups. Eldritch mods are a sub-pool.
1731+
controls.includeImplicits = new("DropDownControl",
1732+
{"TOPLEFT", lastItemAnchor, "BOTTOMLEFT"}, {0, 5, 120, 18},
1733+
{"None", "Without Eldritch", "Eldritch limited", "All"}, function(_state) end,
1734+
"Controls which implicit mods (including Eldritch) enter weight/filter groups.\n" ..
1735+
"None: skip implicits entirely.\n" ..
1736+
"Without Eldritch: regular implicits only, no Eldritch weights.\n" ..
1737+
"Eldritch limited: all implicits + Eldritch, skipping boss-conditional mods.\n" ..
1738+
"All: full implicit + Eldritch pool.")
1739+
controls.includeImplicitsLabel = new("LabelControl", {"RIGHT", controls.includeImplicits, "LEFT"}, {-4, 0, 80, 16}, "Implicit Mods:")
1740+
controls.includeImplicits:SetSel(self.lastIncludeImplicits or 4) -- default: All (index 4)
17131741
updateLastAnchor(controls.includeImplicits)
17141742
end
17151743

1716-
if isEldritchModSlot then
1717-
controls.includeEldritch = new("CheckBoxControl", {"TOPLEFT",lastItemAnchor,"BOTTOMLEFT"}, {0, 5, 18}, "Eldritch Mods:", function(state) end)
1718-
controls.includeEldritch.state = (self.lastIncludeEldritch == true)
1719-
updateLastAnchor(controls.includeEldritch)
1720-
end
1721-
17221744
if not isJewelSlot and not isAbyssalJewelSlot and includeScourge then
17231745
controls.includeScourge = new("CheckBoxControl", {"TOPLEFT",lastItemAnchor,"BOTTOMLEFT"}, {0, 5, 18}, "Scourge Mods:", function(state) end)
17241746
controls.includeScourge.state = (self.lastIncludeScourge == nil or self.lastIncludeScourge == true)
@@ -1731,28 +1753,19 @@ function TradeQueryGeneratorClass:RequestQuery(slot, context, statWeights, callb
17311753
updateLastAnchor(controls.includeTalisman)
17321754
end
17331755

1734-
-- Implicit mod and enchant behaviour in searching and sorting
1756+
-- Copy Current Implicits: post-fetch operation that replaces Eldritch implicits on
1757+
-- every result item with those from the currently equipped item.
1758+
-- Only meaningful for Eldritch-capable slots (Helmet/Body Armour/Gloves/Boots).
17351759
if isEldritchModSlot then
1736-
local eldritchTooltip = [[Controls the inclusion of eldritch mod weights in the weighted sum.
1737-
None: no weights are generated.
1738-
All: weights are generated for all eldritch implicit modifiers.
1739-
Omit while: weights are generated, but conditional "While unique/atlas boss" modifiers are skipped.
1740-
It is often not recommended to use "All" as this includes a lot of high power modifiers,
1741-
which will cause other useful modifiers to be left out in the weighted sum.]]
1742-
controls.includeEldritch = new("DropDownControl", { "TOPLEFT", lastItemAnchor, "BOTTOMLEFT" }, { 0, 5, 92, 18 },
1743-
{ "None", "All", "Omit While" }, function(_state) end, eldritchTooltip)
1744-
controls.includeEldritchLabel = new("LabelControl", { "RIGHT", controls.includeEldritch, "LEFT" },
1745-
{ -4, 0, 80, 16 }, "Eldritch Mods:")
1746-
controls.includeEldritch:SetSel(self.lastIncludeEldritch or 1)
1747-
updateLastAnchor(controls.includeEldritch)
1748-
1749-
local eldritchTooltip = "Replaces the eldritch modifiers on search results with the eldritch modifiers from your currently equipped item."
1750-
local labelText = "Copy Current Implicits:"
17511760
controls.copyEldritch = new("CheckBoxControl",
1752-
{ "TOPLEFT", lastItemAnchor, "BOTTOMLEFT" },
1753-
{ 0, 5, 18, 18 },
1754-
labelText, function(state) end, eldritchTooltip, false)
1755-
controls.copyEldritch.state = self.lastCopyEldritch or false
1761+
{"TOPLEFT", lastItemAnchor, "BOTTOMLEFT"}, {0, 5, 18},
1762+
"Copy Current Implicits:", function(state) end)
1763+
controls.copyEldritch.state = self.lastCopyEldritch == true
1764+
controls.copyEldritch.tooltipText =
1765+
"Replaces the Eldritch implicits on each result item with those from your\n" ..
1766+
"currently equipped item (skipped for corrupted, mirrored, or Unique items).\n" ..
1767+
"Consider setting Implicit Mods to None when using this — the Eldritch pool\n" ..
1768+
"will be copied from your item rather than searched."
17561769
updateLastAnchor(controls.copyEldritch)
17571770
end
17581771
if isAmuletSlot or isBeltSlot or isWeaponSlot then
@@ -1777,14 +1790,7 @@ Remove: %s will be removed from the search results.]], term, term, term)
17771790
controls.jewelTypeLabel = new("LabelControl", {"RIGHT",controls.jewelType,"LEFT"}, {-5, 0, 0, 16}, "Jewel Type:")
17781791
updateLastAnchor(controls.jewelType)
17791792
elseif slot and not isAbyssalJewelSlot and context.slotTbl.slotName ~= "Watcher's Eye" then
1780-
local selFunc = function()
1781-
-- influenced items can't have eldritch implicits
1782-
if controls.copyEldritch and isEldritchModSlot then
1783-
local hasInfluence1 = controls.influence1 and controls.influence1:GetSelValue() ~= "None"
1784-
local hasInfluence2 = controls.influence2 and controls.influence2:GetSelValue() ~= "None"
1785-
controls.copyEldritch.enabled = not hasInfluence1 and not hasInfluence2
1786-
end
1787-
end
1793+
local selFunc = function() end
17881794
controls.influence1 = new("DropDownControl", { "TOPLEFT", lastItemAnchor, "BOTTOMLEFT" }, { 0, 5, 100, 18 },
17891795
influenceDropdownNames, selFunc)
17901796
controls.influence1:SetSel(self.lastInfluence1 or 1)
@@ -1869,7 +1875,6 @@ Remove: %s will be removed from the search results.]], term, term, term)
18691875

18701876
self.tradeTypeIndex = context.controls.tradeTypeSelection.selIndex
18711877

1872-
self.lastCopyEldritch = controls.copyEldritch and controls.copyEldritch.state
18731878
self.lastCopyEnchantMode = controls.copyEnchantMode and controls.copyEnchantMode:GetSelValue()
18741879

18751880
if controls.includeMirrored then
@@ -1893,14 +1898,14 @@ Remove: %s will be removed from the search results.]], term, term, term)
18931898
-- if controls.includeSynthesis then
18941899
-- self.lastIncludeSynthesis, options.includeSynthesis = controls.includeSynthesis.state, controls.includeSynthesis.state
18951900
-- end
1896-
if controls.includeEldritch then
1897-
self.lastIncludeEldritch, options.includeEldritch = controls.includeEldritch.selIndex,
1898-
controls.includeEldritch:GetSelValue()
1899-
end
19001901
if controls.includeImplicits then
1901-
self.lastIncludeImplicits, options.includeImplicits = controls.includeImplicits.state, controls.includeImplicits.state
1902+
self.lastIncludeImplicits = controls.includeImplicits.selIndex
1903+
options.includeImplicits = controls.includeImplicits:GetSelValue()
19021904
else
1903-
options.includeImplicits = true
1905+
options.includeImplicits = "All"
1906+
end
1907+
if controls.copyEldritch then
1908+
self.lastCopyEldritch = controls.copyEldritch.state
19041909
end
19051910
if controls.includePseudo then
19061911
self.lastIncludePseudo, options.includePseudo = controls.includePseudo.state, controls.includePseudo.state
@@ -1955,4 +1960,4 @@ Remove: %s will be removed from the search results.]], term, term, term)
19551960
main:ClosePopup()
19561961
end)
19571962
main:OpenPopup(400, popupHeight, "Query Options", controls)
1958-
end
1963+
end

0 commit comments

Comments
 (0)