Skip to content
53 changes: 50 additions & 3 deletions src/Classes/TradeQuery.lua
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,14 @@ Highest Weight - Displays the order retrieved from trade]]
return hideRowFunc(self, row_count)
end
row_count = row_count + 1
-- Watcher's Eye
self.slotTables[row_count] = { slotName = "Watcher's Eye", unique = true }
self:PriceItemRowDisplay(row_count, top_pane_alignment_ref, row_vertical_padding, row_height)
self.controls["name"..row_count].y = self.controls["name"..row_count].y + (row_height + row_vertical_padding)
self.controls["name"..row_count].shown = function()
return hideRowFunc(self, row_count) and self:findValidSlotForWatchersEye()
end
row_count = row_count + 1

local effective_row_count = row_count - ((scrollBarShown and #slotTables >= 19) and #slotTables-19 or 0) + 2 + 2 -- Two top menu rows, two bottom rows, slots after #19 overlap the other controls at the bottom of the pane
self.effective_rows_height = row_height * (effective_row_count - #slotTables + (18 - (#slotTables > 37 and 3 or 0))) -- scrollBar height, "18 - slotTables > 37" logic is fine tuning whitespace after last row
Expand Down Expand Up @@ -870,12 +878,31 @@ function TradeQueryClass:addChaosEquivalentPriceToItems(items)
return outputItems
end

-- return valid slot for Watcher's Eye
function TradeQueryClass:findValidSlotForWatchersEye()
local tmpWE=nil
for _,v in ipairs(data.uniques.generated) do
if v:find("Watcher's Eye") then
tmpWE= new("Item",v)
break
end
end
for _,v in pairs(self.itemsTab.sockets) do
if not v.inactive and self.itemsTab:IsItemValidForSlot(tmpWE,v.slotName,self.itemsTab.activeItemSet) then
return self.itemsTab.sockets[v.nodeId]
end
end
end

-- Method to generate pane elements for each item slot
function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, row_vertical_padding, row_height)
local controls = self.controls
local slotTbl = self.slotTables[row_idx]
local activeSlotRef = slotTbl.nodeId and self.itemsTab.activeItemSet[slotTbl.nodeId] or self.itemsTab.activeItemSet[slotTbl.slotName]
local activeSlot = slotTbl.nodeId and self.itemsTab.sockets[slotTbl.nodeId] or slotTbl.slotName and (self.itemsTab.slots[slotTbl.slotName] or slotTbl.fullName and self.itemsTab.slots[slotTbl.fullName]) -- fullName for Abyssal Sockets
local activeSlot = slotTbl.nodeId and self.itemsTab.sockets[slotTbl.nodeId] or
slotTbl.slotName and (self.itemsTab.slots[slotTbl.slotName] or
slotTbl.slotName == "Watcher's Eye" and self:findValidSlotForWatchersEye() or
slotTbl.fullName and self.itemsTab.slots[slotTbl.fullName]) -- fullName for Abyssal Sockets
local nameColor = slotTbl.unique and colorCodes.UNIQUE or "^7"
controls["name"..row_idx] = new("LabelControl", top_pane_alignment_ref, {0, row_idx*(row_height + row_vertical_padding), 100, row_height - 4}, nameColor..slotTbl.slotName)
controls["bestButton"..row_idx] = new("ButtonControl", { "LEFT", controls["name"..row_idx], "LEFT"}, {100 + 8, 0, 80, row_height}, "Find best", function()
Expand Down Expand Up @@ -1013,7 +1040,16 @@ function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, ro
local result = self.resultTbl[row_idx][pb_index]
local item = new("Item", result.item_string)
tooltip:Clear()
self.itemsTab:AddItemTooltip(tooltip, item, slotTbl)
if slotTbl.slotName == "Watcher's Eye" then
local firstValidSlot = self:findValidSlotForWatchersEye()
local currentItem = firstValidSlot.selItemId ~= 0 and self.itemsTab.items[firstValidSlot.selItemId]
local eyeEquipped = currentItem and currentItem.name:find("Watcher's Eye")
-- for watcher's eye we can compare to an already existing one, or
-- default to comparing with all active sockets
self.itemsTab:AddItemTooltip(tooltip, item, eyeEquipped and firstValidSlot or nil)
else
self.itemsTab:AddItemTooltip(tooltip, item, slotTbl)
end
addMegalomaniacCompareToTooltipIfApplicable(tooltip, pb_index)
tooltip:AddSeparator(10)
tooltip:AddLine(16, string.format("^7Price: %s %s", result.amount, result.currency))
Expand Down Expand Up @@ -1041,7 +1077,18 @@ function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, ro
-- item.baseName is nil and throws error in the following AddItemTooltip func
-- if the item is unidentified
local item = new("Item", item_string)
self.itemsTab:AddItemTooltip(tooltip, item, slotTbl, true)
-- for watcher's eye we can compare to an already existing one, or
-- default to comparing with all active sockets
if slotTbl.slotName == "Watcher's Eye" then
local firstValidSlot = self:findValidSlotForWatchersEye()
local currentItem = firstValidSlot.selItemId ~= 0 and self.itemsTab.items[firstValidSlot.selItemId]
local eyeEquipped = currentItem and currentItem.name:find("Watcher's Eye")
-- for watcher's eye we can compare to an already existing one, or
-- default to comparing with all active sockets
self.itemsTab:AddItemTooltip(tooltip, item, eyeEquipped and firstValidSlot or nil, true)
else
self.itemsTab:AddItemTooltip(tooltip, item, slotTbl, true)
end
addMegalomaniacCompareToTooltipIfApplicable(tooltip, selected_result_index)
end
end
Expand Down
99 changes: 94 additions & 5 deletions src/Classes/TradeQueryGenerator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ local tradeStatCategoryIndices = {
["Exarch"] = 3,
["Synthesis"] = 3,
["PassiveNode"] = 2,
["WatchersEye"] = 2,
}

local influenceSuffixes = { "_shaper", "_elder", "_adjudicator", "_basilisk", "_crusader", "_eyrie"}
Expand Down Expand Up @@ -406,6 +407,7 @@ function TradeQueryGeneratorClass:InitMods()
["Exarch"] = { },
["Synthesis"] = { },
["PassiveNode"] = { },
["WatchersEye"] = { },
}

-- originates from: https://www.pathofexile.com/api/trade/data/stats
Expand Down Expand Up @@ -464,6 +466,17 @@ function TradeQueryGeneratorClass:InitMods()
end
self:GenerateModData(clusterNotableMods, tradeQueryStatsParsed)

-- Watcher's Eye
local watchersEyeMods = {}
for _,v in pairs(data.uniqueMods["Watcher's Eye"]) do
if v.Id:find("SublimeVision") or v.Id:find("SummonArbalist") then
goto continue
end
watchersEyeMods[v.Id] = v.mod
watchersEyeMods[v.Id].type = "WatchersEye"
::continue::
end
self:GenerateModData(watchersEyeMods,tradeQueryStatsParsed,{ ["BaseJewel"] = true, ["AnyJewel"] = true },{["AnyJewel"]="AnyJewel"})
-- Base item implicit mods. A lot of this code is duplicated from generateModData(), but with important small logical flow changes to handle the format differences
local subTypeState = { }
local function updateRangeSubType(range, entry)
Expand Down Expand Up @@ -727,6 +740,28 @@ function TradeQueryGeneratorClass:StartQuery(slot, options)
calcNodesInsteadOfMods = true,
}
end
if options.special.itemName == "Watcher's Eye" then
special={
queryExtra = {
name = "Watcher's Eye"
},
queryFilters = {
type_filters = {
filters = {
category = {
option = "jewel"
},
rarity = {
option = "unique"
}
}
}
},
watchersEye = true
}
itemCategory = "AnyJewel"
itemCategoryQueryStr = "jewel"
end
elseif slot.slotName:find("^Weapon %d") then
if existingItem then
if existingItem.type == "Shield" then
Expand Down Expand Up @@ -874,6 +909,13 @@ function TradeQueryGeneratorClass:ExecuteQuery()
self:GeneratePassiveNodeWeights(self.modData.PassiveNode)
return
end
if self.calcContext.special.watchersEye then
self:GenerateModWeights(self.modData.WatchersEye)
if self.calcContext.options.includeCorrupted then
self:GenerateModWeights(self.modData["Corrupted"])
end
return
end
self:GenerateModWeights(self.modData["Explicit"])
self:GenerateModWeights(self.modData["Implicit"])
if self.calcContext.options.includeCorrupted then
Expand All @@ -891,6 +933,36 @@ function TradeQueryGeneratorClass:ExecuteQuery()
end
end

function TradeQueryGeneratorClass:addMoreWEMods()
local function getTableOfTradeModIds(tbl)
local tmpTable={}
for _,val in ipairs(tbl) do
table.insert(tmpTable,val.tradeModId)
end
return tmpTable
end
for _,skillGroup in ipairs(self.itemsTab.build.skillsTab.socketGroupList) do
for _,gem in ipairs(skillGroup.gemList) do
local tmpAura=""
if not gem.enabled then
goto continue
elseif gem.nameSpec:find("Vaal") and gem.enableGlobal2 then
tmpAura=gem.nameSpec:gsub("Vaal ",""):gsub("Impurity","Purity"):gsub("of","Of"):gsub(" ","")
elseif gem.gemData and gem.gemData.tags.aura or gem.fromItem then
tmpAura=gem.nameSpec:gsub("of","Of"):gsub(" ","")
else
goto continue
end
for id,mod in pairs(self.modData.WatchersEye) do
if id:find(tmpAura) and not isValueInTable(getTableOfTradeModIds(self.modWeights),mod.tradeMod.id) then
table.insert(self.modWeights,{invert=false,meanStatDiff=0,weight=0,tradeModId=mod.tradeMod.id})
end
end
::continue::
end
end
end

function TradeQueryGeneratorClass:FinishQuery()
-- Calc original item Stats without anoint or enchant, and use that diff as a basis for default min sum.
local originalItem = self.calcContext.slot and self.itemsTab.items[self.calcContext.slot.selItemId]
Expand All @@ -914,6 +986,10 @@ function TradeQueryGeneratorClass:FinishQuery()
local originalOutput = originalItem and self.calcContext.calcFunc({ repSlotName = self.calcContext.slot.slotName, repItem = self.calcContext.testItem }) or self.calcContext.baseOutput
local currentStatDiff = TradeQueryGeneratorClass.WeightedRatioOutputs(self.calcContext.baseOutput, originalOutput, self.calcContext.options.statWeights) * 1000 - (self.calcContext.baseStatValue or 0)

if self.calcContext.options.includeAllWEMods then
self:addMoreWEMods()
end

-- Sort by mean Stat diff rather than weight to more accurately prioritize stats that can contribute more
table.sort(self.modWeights, function(a, b)
if a.meanStatDiff == b.meanStatDiff then
Expand Down Expand Up @@ -1116,9 +1192,12 @@ function TradeQueryGeneratorClass:RequestQuery(slot, context, statWeights, callb
options.special = { itemName = context.slotTbl.slotName }
end

controls.includeMirrored = new("CheckBoxControl", {"TOPRIGHT",lastItemAnchor,"BOTTOMRIGHT"}, {0, 5, 18}, "Mirrored items:", function(state) end)
controls.includeMirrored.state = (self.lastIncludeMirrored == nil or self.lastIncludeMirrored == true)
updateLastAnchor(controls.includeMirrored)
-- these unique items cannot be mirrored
if not context.slotTbl.unique then
controls.includeMirrored = new("CheckBoxControl", {"TOPRIGHT",lastItemAnchor,"BOTTOMRIGHT"}, {0, 5, 18}, "Mirrored items:", function(state) end)
controls.includeMirrored.state = (self.lastIncludeMirrored == nil or self.lastIncludeMirrored == true)
updateLastAnchor(controls.includeMirrored)
end

if not isJewelSlot and not isAbyssalJewelSlot and includeScourge then
controls.includeScourge = new("CheckBoxControl", {"TOPRIGHT",lastItemAnchor,"BOTTOMRIGHT"}, {0, 5, 18}, "Scourge Mods:", function(state) end)
Expand All @@ -1138,12 +1217,12 @@ function TradeQueryGeneratorClass:RequestQuery(slot, context, statWeights, callb
updateLastAnchor(controls.includeEldritch)
end

if isJewelSlot then
if isJewelSlot and context.slotTbl.slotName ~= "Watcher's Eye" then
controls.jewelType = new("DropDownControl", {"TOPLEFT",lastItemAnchor,"BOTTOMLEFT"}, {0, 5, 100, 18}, { "Any", "Base", "Abyss" }, function(index, value) end)
controls.jewelType.selIndex = self.lastJewelType or 1
controls.jewelTypeLabel = new("LabelControl", {"RIGHT",controls.jewelType,"LEFT"}, {-5, 0, 0, 16}, "Jewel Type:")
updateLastAnchor(controls.jewelType)
elseif slot and not isAbyssalJewelSlot then
elseif slot and not isAbyssalJewelSlot and context.slotTbl.slotName ~= "Watcher's Eye" then
controls.influence1 = new("DropDownControl", {"TOPLEFT",lastItemAnchor,"BOTTOMLEFT"}, {0, 5, 100, 18}, influenceDropdownNames, function(index, value) end)
controls.influence1.selIndex = self.lastInfluence1 or 1
controls.influence1Label = new("LabelControl", {"RIGHT",controls.influence1,"LEFT"}, {-5, 0, 0, 16}, "Influence 1:")
Expand Down Expand Up @@ -1213,6 +1292,13 @@ function TradeQueryGeneratorClass:RequestQuery(slot, context, statWeights, callb
end
popupHeight = popupHeight + 4

if context.slotTbl.slotName == "Watcher's Eye" then
controls.includeAllWEMods = new("CheckBoxControl", {"TOPRIGHT",lastItemAnchor,"BOTTOMRIGHT"}, {0, 5, 18}, "Include all Watcher's Eye mods:", function(state) end)
controls.includeAllWEMods.tooltipText = "Include mods that could not have a weight calculated for them at weight 0."
lastItemAnchor = controls.includeAllWEMods
popupHeight = popupHeight + 23
end

controls.generateQuery = new("ButtonControl", { "BOTTOM", nil, "BOTTOM" }, {-45, -10, 80, 20}, "Execute", function()
main:ClosePopup()

Expand Down Expand Up @@ -1265,6 +1351,9 @@ function TradeQueryGeneratorClass:RequestQuery(slot, context, statWeights, callb
if controls.links and controls.links.buf then
options.links = tonumber(controls.links.buf)
end
if controls.includeAllWEMods then
options.includeAllWEMods = controls.includeAllWEMods.state
end
options.statWeights = statWeights

self:StartQuery(slot, options)
Expand Down
Loading