@@ -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