@@ -13,6 +13,7 @@ local t_remove = table.remove
1313local m_max = math.max
1414local m_min = math.min
1515local m_ceil = math.ceil
16+ local s_format = string.format
1617
1718local baseSlots = { " Weapon 1" , " Weapon 2" , " Helmet" , " Body Armour" , " Gloves" , " Boots" , " Amulet" , " Ring 1" , " Ring 2" , " Belt" , " Flask 1" , " Flask 2" , " Flask 3" , " Flask 4" , " Flask 5" }
1819
@@ -28,7 +29,7 @@ local TradeQueryClass = newClass("TradeQuery", function(self, itemsTab)
2829 self .itemIndexTbl = { }
2930
3031 -- default set of trade item sort selection
31- self .pbSortSelectionIndex = 1
32+ self .pbItemSortSelectionIndex = 1
3233 self .pbCurrencyConversion = { }
3334 self .currencyConversionTradeMap = { }
3435 self .lastCurrencyConversionRequest = 0
@@ -280,31 +281,61 @@ You can click this button to enter your POESESSID.
280281- You can generate weighted search URLs but have to visit the trade site and manually import items.
281282- You can only generate weighted searches for public leagues. (Generated searches can be modified
282283on trade site to work on other leagues and realms)]]
284+
285+ -- Stat sort popup button
286+ self .statSortSelectionList = { }
287+ t_insert (self .statSortSelectionList , {
288+ label = " Full DPS" ,
289+ stat = " FullDPS" ,
290+ weightMult = 1.0 ,
291+ })
292+ t_insert (self .statSortSelectionList , {
293+ label = " Effective Hit Pool" ,
294+ stat = " TotalEHP" ,
295+ weightMult = 0.5 ,
296+ })
297+ self .controls .StatWeightMultipliersButton = new (" ButtonControl" , {" TOPRIGHT" , nil , " TOPRIGHT" }, - 12 , 19 , 100 , 18 , " ^7Sort Calc By:" , function ()
298+ self :SetStatWeights ()
299+ end )
300+ self .controls .StatWeightMultipliersButton .tooltipFunc = function (tooltip )
301+ tooltip :Clear ()
302+ tooltip :AddLine (16 , " Sorts the weights by the stats selected multiplied by a value" )
303+ tooltip :AddLine (16 , " Currently sorting by:" )
304+ for _ , stat in ipairs (self .statSortSelectionList ) do
305+ tooltip :AddLine (16 , s_format (" %s: %.2f" , stat .label , stat .weightMult ))
306+ end
307+ end
283308 self .sortModes = {
284- DPS = " DPS " ,
285- DPS_PRICE = " DPS / Price" ,
286- PRICE_ASCENDING = " Price (Lowest)" ,
287- WEIGHT = " Weighted Sum" ,
309+ StatValue = " (Highest) Stat Value " ,
310+ StatValuePRICE = " Stat Value / Price" ,
311+ PRICE = " (Lowest) Price " ,
312+ WEIGHT = " (Highest) Weighted Sum" ,
288313 }
289314 -- Item sort dropdown
290- self .sortSelectionList = {
291- self .sortModes .DPS ,
292- self .sortModes .DPS_PRICE ,
293- self .sortModes .PRICE_ASCENDING ,
315+ self .itemSortSelectionList = {
316+ self .sortModes .StatValue ,
317+ self .sortModes .StatValuePRICE ,
318+ self .sortModes .PRICE ,
294319 self .sortModes .WEIGHT ,
295320 }
296- self .controls .itemSortSelection = new (" DropDownControl" , {" TOPRIGHT" , nil , " TOPRIGHT " }, - 12 , 19 , 100 , 18 , self .sortSelectionList , function (index , value )
297- self .pbSortSelectionIndex = index
321+ self .controls .itemSortSelection = new (" DropDownControl" , {" TOPRIGHT" ,self . controls . StatWeightMultipliersButton , " BOTTOMRIGHT " }, 0 , 4 , 154 , 18 , self .itemSortSelectionList , function (index , value )
322+ self .pbItemSortSelectionIndex = index
298323 for index , _ in pairs (self .resultTbl ) do
299324 self :UpdateControlsWithItems (slotTables [index ], index )
300325 end
301326 end )
302- self .controls .itemSortSelection .tooltipText = " Weighted Sum searches will always sort\n using descending weighted sum."
303- self .controls .itemSortSelection :SetSel (self .pbSortSelectionIndex )
304- self .controls .itemSortSelectionLabel = new (" LabelControl" , {" TOPRIGHT" , self .controls .itemSortSelection , " TOPLEFT" }, - 4 , 0 , 60 , 16 , " ^7Sort By:" )
327+ self .controls .itemSortSelection .tooltipText =
328+ [[ Weighted Sum searches will always sort using descending weighted sum
329+ Additional post filtering options can be done these include:
330+ Highest Stat Value - Sort from highest to lowest Stat Value change of equipping item
331+ Highest Stat Value / Price - Sorts from highest to lowest Stat Value per currency
332+ Lowest Price - Sorts from lowest to highest price of retrieved items
333+ Highest Weight - Displays the order retrieved from trade]]
334+ self .controls .itemSortSelection :SetSel (self .pbItemSortSelectionIndex )
335+ self .controls .itemSortSelectionLabel = new (" LabelControl" , {" TOPRIGHT" , self .controls .itemSortSelection , " TOPLEFT" }, - 4 , 0 , 100 , 16 , " ^7Sort Items By:" )
305336
306337 self .maxFetchPerSearchDefault = 2
307- self .controls .fetchCountEdit = new (" EditControl" , {" TOPRIGHT" ,self .controls .itemSortSelection , " BOTTOMRIGHT " }, 0 , 4 , 154 , row_height , " " , " Fetch Pages" , " %D" , 3 , function (buf )
338+ self .controls .fetchCountEdit = new (" EditControl" , {" TOPRIGHT" , self .controls .itemSortSelectionLabel , " TOPLEFT " }, - 8 , 0 , 150 , row_height , " " , " Fetch Pages" , " %D" , 3 , function (buf )
308339 self .maxFetchPages = m_min (m_max (tonumber (buf ) or self .maxFetchPerSearchDefault , 1 ), 10 )
309340 self .tradeQueryRequests .maxFetchPerSearch = 10 * self .maxFetchPages
310341 self .controls .fetchCountEdit .focusValue = self .maxFetchPages
@@ -395,6 +426,91 @@ on trade site to work on other leagues and realms)]]
395426 main :OpenPopup (pane_width , pane_height , " Trader" , self .controls )
396427end
397428
429+ -- Popup to set stat weight multipliers for sorting
430+ function TradeQueryClass :SetStatWeights ()
431+
432+ local controls = { }
433+ local statList = { }
434+ local sliderController = { index = 1 }
435+ local popupHeight = 285
436+
437+ controls .ListControl = new (" TradeStatWeightMultiplierListControl" , { " TOPLEFT" , nil , " TOPRIGHT" }, - 410 , 45 , 400 , 200 , statList , sliderController )
438+
439+ for id , stat in pairs (data .powerStatList ) do
440+ if not stat .ignoreForItems and stat .label ~= " Name" then
441+ t_insert (statList , {
442+ label = " 0 : " .. stat .label ,
443+ stat = {
444+ label = stat .label ,
445+ stat = stat .stat ,
446+ transform = stat .transform ,
447+ weightMult = 0 ,
448+ }
449+ })
450+ end
451+ end
452+
453+ controls .SliderLabel = new (" LabelControl" , { " TOPLEFT" , nil , " TOPRIGHT" }, - 410 , 20 , 0 , 16 , " ^7" .. statList [1 ].stat .label .. " :" )
454+ controls .Slider = new (" SliderControl" , { " TOPLEFT" , controls .SliderLabel , " TOPRIGHT" }, 20 , 0 , 150 , 16 , function (value )
455+ if value == 0 then
456+ controls .SliderValue .label = " ^7Disabled"
457+ statList [sliderController .index ].stat .weightMult = 0
458+ statList [sliderController .index ].label = s_format (" %d : " , 0 ).. statList [sliderController .index ].stat .label
459+ else
460+ controls .SliderValue .label = s_format (" ^7%.2f" , 0.01 + value * 0.99 )
461+ statList [sliderController .index ].stat .weightMult = 0.01 + value * 0.99
462+ statList [sliderController .index ].label = s_format (" %.2f : " , 0.01 + value * 0.99 ).. statList [sliderController .index ].stat .label
463+ end
464+ end )
465+ controls .SliderValue = new (" LabelControl" , { " TOPLEFT" , controls .Slider , " TOPRIGHT" }, 20 , 0 , 0 , 16 , " ^7Disabled" )
466+ controls .Slider .tooltip .realDraw = controls .Slider .tooltip .Draw
467+ controls .Slider .tooltip .Draw = function (self , x , y , width , height , viewPort )
468+ local sliderOffsetX = round (184 * (1 - controls .Slider .val ))
469+ local tooltipWidth , tooltipHeight = self :GetSize ()
470+ if main .screenW >= 1338 - sliderOffsetX then
471+ return controls [stat .label .. " Slider" ].tooltip .realDraw (self , x - 8 - sliderOffsetX , y - 4 - tooltipHeight , width , height , viewPort )
472+ end
473+ return controls .Slider .tooltip .realDraw (self , x , y , width , height , viewPort )
474+ end
475+ sliderController .SliderLabel = controls .SliderLabel
476+ sliderController .Slider = controls .Slider
477+ sliderController .SliderValue = controls .SliderValue
478+
479+
480+ for _ , statBase in ipairs (self .statSortSelectionList ) do
481+ for _ , stat in ipairs (statList ) do
482+ if stat .stat .stat == statBase .stat then
483+ stat .stat .weightMult = statBase .weightMult
484+ stat .label = s_format (" %.2f : " , statBase .weightMult ).. statBase .label
485+ if statList [sliderController .index ].stat .stat == statBase .stat then
486+ controls .Slider :SetVal (statBase .weightMult == 1 and 1 or statBase .weightMult - 0.01 )
487+ end
488+ end
489+ end
490+ end
491+
492+ controls .finalise = new (" ButtonControl" , { " BOTTOM" , nil , " BOTTOM" }, - 45 , - 10 , 80 , 20 , " Save" , function ()
493+ main :ClosePopup ()
494+
495+ -- this needs to save the weights somewhere, maybe the XML? its not necessary but possibly useful QoL
496+ local statSortSelectionList = {}
497+ for stat , statTable in pairs (statList ) do
498+ if statTable .stat .weightMult > 0 then
499+ t_insert (statSortSelectionList , statTable .stat )
500+ end
501+ end
502+ if (# statSortSelectionList ) > 0 then
503+ -- THIS SHOULD REALLY GIVE A WARNING NOT JUST USE PREVIOUS
504+ self .statSortSelectionList = statSortSelectionList
505+ end
506+ end )
507+ controls .cancel = new (" ButtonControl" , { " BOTTOM" , nil , " BOTTOM" }, 45 , - 10 , 80 , 20 , " Cancel" , function ()
508+ main :ClosePopup ()
509+ end )
510+ main :OpenPopup (420 , popupHeight , " Stat Weight Multipliers" , controls )
511+ end
512+
513+
398514-- Method to update the Currency Conversion button label
399515function TradeQueryClass :SetCurrencyConversionButton ()
400516 local currencyLabel = " Update Currency Conversion Rates"
@@ -459,12 +575,13 @@ end
459575
460576-- Method to update controls after a search is completed
461577function TradeQueryClass :UpdateControlsWithItems (slotTbl , index )
462- local sortMode = self .sortSelectionList [self .pbSortSelectionIndex ]
578+ local sortMode = self .itemSortSelectionList [self .pbItemSortSelectionIndex ]
463579 local sortedItems , errMsg = self :SortFetchResults (slotTbl , index , sortMode )
464580 if errMsg == " MissingConversionRates" then
465- self :SetNotice (self .controls .pbNotice , " ^4Price sorting is not available, falling back to DPS sort." )
466- sortedItems , errMsg = self :SortFetchResults (slotTbl , index , self .sortModes .DPS )
467- elseif errMsg then
581+ self :SetNotice (self .controls .pbNotice , " ^4Price sorting is not available, falling back to Stat Value sort." )
582+ sortedItems , errMsg = self :SortFetchResults (slotTbl , index , self .sortModes .StatValue )
583+ end
584+ if errMsg then
468585 self :SetNotice (self .controls .pbNotice , " Error: " .. errMsg )
469586 return
470587 else
@@ -473,7 +590,7 @@ function TradeQueryClass:UpdateControlsWithItems(slotTbl, index)
473590
474591 self .sortedResultTbl [index ] = sortedItems
475592 self .itemIndexTbl [index ] = self .sortedResultTbl [index ][1 ].index
476- self .controls [" priceButton" .. index ].tooltipText = " Sorted by " .. self .sortSelectionList [self .pbSortSelectionIndex ]
593+ self .controls [" priceButton" .. index ].tooltipText = " Sorted by " .. self .itemSortSelectionList [self .pbItemSortSelectionIndex ]
477594 local pb_index = self .sortedResultTbl [index ][1 ].index
478595 self .totalPrice [index ] = {
479596 currency = self .resultTbl [index ][pb_index ].currency ,
@@ -501,17 +618,28 @@ function TradeQueryClass:SetFetchResultReturn(slotIndex, index)
501618 end
502619end
503620
621+ -- Method to sort the fetched results
504622function TradeQueryClass :SortFetchResults (slotTbl , trade_index , mode )
505- local function getDpsTable ()
623+ local function getStatValueTable ()
506624 local out = {}
507625 local slotName = slotTbl .ref and " Jewel " .. tostring (slotTbl .ref ) or slotTbl .name
508- local calcFunc , _ = self .itemsTab .build .calcsTab :GetMiscCalculator ()
626+ local storedFullDPS = GlobalCache .useFullDPS
627+ GlobalCache .useFullDPS = GlobalCache .numActiveSkillInFullDPS > 0
628+ local calcFunc , calcBase = self .itemsTab .build .calcsTab :GetMiscCalculator ()
509629 for index , tbl in pairs (self .resultTbl [trade_index ]) do
510630 local item = new (" Item" , tbl .item_string )
511631 local output = calcFunc ({ repSlotName = slotName , repItem = item }, {})
512- local newDPS = GlobalCache .useFullDPS and output .FullDPS or m_max (output .TotalDPS , m_max (output .TotalDot , output .CombinedAvg ))
513- out [index ] = newDPS
632+ local newStatValue = 0
633+ for _ , statTable in ipairs (self .statSortSelectionList ) do
634+ if statTable .stat == " FullDPS" and not GlobalCache .useFullDPS then
635+ newStatValue = newStatValue + m_max (output .TotalDPS or 0 , m_max (output .TotalDot or 0 , output .CombinedAvg or 0 )) * statTable .weightMult
636+ else
637+ newStatValue = newStatValue + ( output [statTable .stat ] or 0 ) * statTable .weightMult
638+ end
639+ end
640+ out [index ] = newStatValue
514641 end
642+ GlobalCache .useFullDPS = storedFullDPS
515643 return out
516644 end
517645 local function getPriceTable ()
@@ -534,23 +662,23 @@ function TradeQueryClass:SortFetchResults(slotTbl, trade_index, mode)
534662 t_insert (newTbl , { outputAttr = index , index = index })
535663 end
536664 return newTbl
537- elseif mode == self .sortModes .DPS then
538- local dpsTable = getDpsTable ()
539- for index , dps in pairs (dpsTable ) do
540- t_insert (newTbl , { outputAttr = dps , index = index })
665+ elseif mode == self .sortModes .StatValue then
666+ local StatValueTable = getStatValueTable ()
667+ for index , statValue in pairs (StatValueTable ) do
668+ t_insert (newTbl , { outputAttr = statValue , index = index })
541669 end
542670 table.sort (newTbl , function (a ,b ) return a .outputAttr > b .outputAttr end )
543- elseif mode == self .sortModes .DPS_PRICE then
544- local dpsTable = getDpsTable ()
671+ elseif mode == self .sortModes .StatValuePRICE then
672+ local StatValueTable = getStatValueTable ()
545673 local priceTable = getPriceTable ()
546674 if priceTable == nil then
547675 return nil , " MissingConversionRates"
548676 end
549- for index , dps in pairs (dpsTable ) do
550- t_insert (newTbl , { outputAttr = dps / priceTable [index ], index = index })
677+ for index , statValue in pairs (StatValueTable ) do
678+ t_insert (newTbl , { outputAttr = statValue / priceTable [index ], index = index })
551679 end
552680 table.sort (newTbl , function (a ,b ) return a .outputAttr > b .outputAttr end )
553- elseif mode == self .sortModes .PRICE_ASCENDING then
681+ elseif mode == self .sortModes .PRICE then
554682 local priceTable = getPriceTable ()
555683 if priceTable == nil then
556684 return nil , " MissingConversionRates"
@@ -585,7 +713,7 @@ function TradeQueryClass:PriceItemRowDisplay(str_cnt, slotTbl, top_pane_alignmen
585713 local activeSlotRef = slotTbl .ref and self .itemsTab .activeItemSet [slotTbl .ref ] or self .itemsTab .activeItemSet [slotTbl .name ]
586714 controls [" name" .. str_cnt ] = new (" LabelControl" , top_pane_alignment_ref , top_pane_alignment_width , top_pane_alignment_height , 100 , row_height - 4 , " ^7" .. slotTbl .name )
587715 controls [" bestButton" .. str_cnt ] = new (" ButtonControl" , {" TOPLEFT" ,controls [" name" .. str_cnt ]," TOPLEFT" }, 100 + 8 , 0 , 80 , row_height , " Find best" , function ()
588- self .tradeQueryGenerator :RequestQuery (slotTbl .ref and self .itemsTab .sockets [slotTbl .ref ] or self .itemsTab .slots [slotTbl .name ], { slotTbl = slotTbl , controls = controls , str_cnt = str_cnt }, function (context , query , errMsg )
716+ self .tradeQueryGenerator :RequestQuery (slotTbl .ref and self .itemsTab .sockets [slotTbl .ref ] or self .itemsTab .slots [slotTbl .name ], { slotTbl = slotTbl , controls = controls , str_cnt = str_cnt }, self . statSortSelectionList , function (context , query , errMsg )
589717 if errMsg then
590718 self :SetNotice (context .controls .pbNotice , colorCodes .NEGATIVE .. errMsg )
591719 return
@@ -598,7 +726,7 @@ function TradeQueryClass:PriceItemRowDisplay(str_cnt, slotTbl, top_pane_alignmen
598726 controls [" uri" .. context .str_cnt ]:SetText (url , true )
599727 return
600728 end
601- self .pbSortSelectionIndex = 1
729+ self .pbItemSortSelectionIndex = 1
602730 context .controls [" priceButton" .. context .str_cnt ].label = " Searching..."
603731 self .tradeQueryRequests :SearchWithQueryWeightAdjusted (self .pbRealm , self .pbLeague , query ,
604732 function (items , errMsg )
@@ -623,7 +751,7 @@ function TradeQueryClass:PriceItemRowDisplay(str_cnt, slotTbl, top_pane_alignmen
623751 end )
624752 end )
625753 controls [" bestButton" .. str_cnt ].shown = function () return not self .resultTbl [str_cnt ] end
626- controls [" bestButton" .. str_cnt ].tooltipText = " Creates a weighted search to find the highest DPS items for this slot."
754+ controls [" bestButton" .. str_cnt ].tooltipText = " Creates a weighted search to find the highest Stat Value items for this slot."
627755 controls [" uri" .. str_cnt ] = new (" EditControl" , {" TOPLEFT" ,controls [" bestButton" .. str_cnt ]," TOPRIGHT" }, 8 , 0 , 518 , row_height , nil , nil , " ^%C\t\n " , nil , function (buf )
628756 local subpath = buf :match (" https://www.pathofexile.com/trade/search/(.+)$" ) or " "
629757 local paths = {}
0 commit comments