Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 10 additions & 1 deletion src/Classes/Item.lua
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,18 @@ function ItemClass:ParseRaw(raw, rarity, highQuality)
end
end
if self.rawLines[l] then
self.name = self.rawLines[l]
-- Determine if "Unidentified" item
local unidentified = false
local unidentifiedBase = data.itemBases[self.rawLines[l]]
local identifiedBase = data.itemBases[self.rawLines[l+1]]
if unidentifiedBase and not identifiedBase then
unidentified = true
self.name = "Unidentified item"
self.baseName = self.rawLines[l]
self.base = unidentifiedBase
else
self.name = self.rawLines[l]
end
for _, line in ipairs(self.rawLines) do
if line == "Unidentified" then
unidentified = true
Expand Down
98 changes: 35 additions & 63 deletions src/Classes/TradeQuery.lua
Original file line number Diff line number Diff line change
Expand Up @@ -673,46 +673,35 @@ function TradeQueryClass:ReduceOutput(output)
end

-- Method to evaluate a result by getting it's output and weight
function TradeQueryClass:GetResultEvaluation(row_idx, result_index, calcFunc, baseOutput)
function TradeQueryClass:GetResultEvaluation(row_idx, result_index)
local result = self.resultTbl[row_idx][result_index]
if not calcFunc then -- Always evaluate when calcFunc is given
calcFunc, baseOutput = self.itemsTab.build.calcsTab:GetMiscCalculator()
local onlyWeightedBaseOutput = self:ReduceOutput(baseOutput)
if not self.onlyWeightedBaseOutput[row_idx] then
self.onlyWeightedBaseOutput[row_idx] = { }
end
if not self.lastComparedWeightList[row_idx] then
self.lastComparedWeightList[row_idx] = { }
end
-- If the interesting stats are the same (the build hasn't changed) and result has already been evaluated, then just return that
if result.evaluation and tableDeepEquals(onlyWeightedBaseOutput, self.onlyWeightedBaseOutput[row_idx][result_index]) and tableDeepEquals(self.statSortSelectionList, self.lastComparedWeightList[row_idx][result_index]) then
return result.evaluation
end
self.onlyWeightedBaseOutput[row_idx][result_index] = onlyWeightedBaseOutput
self.lastComparedWeightList[row_idx][result_index] = self.statSortSelectionList
local calcFunc, baseOutput = self.itemsTab.build.calcsTab:GetMiscCalculator()
local onlyWeightedBaseOutput = self:ReduceOutput(baseOutput)
if not self.onlyWeightedBaseOutput[row_idx] then
self.onlyWeightedBaseOutput[row_idx] = { }
end
if not self.lastComparedWeightList[row_idx] then
self.lastComparedWeightList[row_idx] = { }
end
-- If the interesting stats are the same (the build hasn't changed) and result has already been evaluated, then just return that
if result.evaluation and tableDeepEquals(onlyWeightedBaseOutput, self.onlyWeightedBaseOutput[row_idx][result_index]) and tableDeepEquals(self.statSortSelectionList, self.lastComparedWeightList[row_idx][result_index]) then
return result.evaluation
end
self.fullBaseOutput = baseOutput
self.onlyWeightedBaseOutput[row_idx][result_index] = onlyWeightedBaseOutput
self.lastComparedWeightList[row_idx][result_index] = self.statSortSelectionList

local slotName = self.slotTables[row_idx].nodeId and "Jewel " .. tostring(self.slotTables[row_idx].nodeId) or self.slotTables[row_idx].slotName
if slotName == "Megalomaniac" then
local addedNodes = {}
for nodeName in (result.item_string.."\r\n"):gmatch("1 Added Passive Skill is (.-)\r?\n") do
t_insert(addedNodes, self.itemsTab.build.spec.tree.clusterNodeMap[nodeName])
for nodeName in (result.item_string.."\r\n"):gmatch("Allocates (.-)\r?\n") do
local node = self.itemsTab.build.spec.tree.notableMap[nodeName:lower()]
addedNodes[node] = true
end
local output12 = self:ReduceOutput(calcFunc({ addNodes = { [addedNodes[1]] = true, [addedNodes[2]] = true } }))
local output13 = self:ReduceOutput(calcFunc({ addNodes = { [addedNodes[1]] = true, [addedNodes[3]] = true } }))
local output23 = self:ReduceOutput(calcFunc({ addNodes = { [addedNodes[2]] = true, [addedNodes[3]] = true } }))
local output123 = self:ReduceOutput(calcFunc({ addNodes = { [addedNodes[1]] = true, [addedNodes[2]] = true, [addedNodes[3]] = true } }))
-- Sometimes the third node is as powerful as a wet noodle, so use weight per point spent, including the jewel socket
local weight12 = self.tradeQueryGenerator.WeightedRatioOutputs(baseOutput, output12, self.statSortSelectionList) / 4
local weight13 = self.tradeQueryGenerator.WeightedRatioOutputs(baseOutput, output13, self.statSortSelectionList) / 4
local weight23 = self.tradeQueryGenerator.WeightedRatioOutputs(baseOutput, output23, self.statSortSelectionList) / 4
local weight123 = self.tradeQueryGenerator.WeightedRatioOutputs(baseOutput, output123, self.statSortSelectionList) / 5
result.evaluation = {
{ output = output12, weight = weight12, DNs = { addedNodes[1].dn, addedNodes[2].dn } },
{ output = output13, weight = weight13, DNs = { addedNodes[1].dn, addedNodes[3].dn } },
{ output = output23, weight = weight23, DNs = { addedNodes[2].dn, addedNodes[3].dn } },
{ output = output123, weight = weight123, DNs = { addedNodes[1].dn, addedNodes[2].dn, addedNodes[3].dn } },
}
table.sort(result.evaluation, function(a, b) return a.weight > b.weight end)

local output = self:ReduceOutput(calcFunc({ addNodes = addedNodes }))
local weight = self.tradeQueryGenerator.WeightedRatioOutputs(baseOutput, output, self.statSortSelectionList)
result.evaluation = {{ output = output, weight = weight }}
else
local item = new("Item", result.item_string)
if not self.enchantInSort then -- Calc item DPS without anoint or enchant as these can generally be added after.
Expand Down Expand Up @@ -773,11 +762,7 @@ end

-- Method to sort the fetched results
function TradeQueryClass:SortFetchResults(row_idx, mode)
local calcFunc, baseOutput
local function getResultWeight(result_index)
if not calcFunc then
calcFunc, baseOutput = self.itemsTab.build.calcsTab:GetMiscCalculator()
end
local sum = 0
for _, eval in ipairs(self:GetResultEvaluation(row_idx, result_index)) do
sum = sum + eval.weight
Expand Down Expand Up @@ -969,27 +954,20 @@ function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, ro
self.itemIndexTbl[row_idx] = self.sortedResultTbl[row_idx][index].index
self:SetFetchResultReturn(row_idx, self.itemIndexTbl[row_idx])
end)
local function addMegalomaniacCompareToTooltipIfApplicable(tooltip, result_index)
if slotTbl.slotName ~= "Megalomaniac" then
return
end
for _, evaluationEntry in ipairs(self:GetResultEvaluation(row_idx, result_index)) do
tooltip:AddSeparator(10)
local nodeDNs = evaluationEntry.DNs
local nodeCombo = nodeDNs[1]
for i = 2, #nodeDNs do
nodeCombo = nodeCombo .. " ^8+^7 " .. nodeDNs[i]
end
self.itemsTab.build:AddStatComparesToTooltip(tooltip, self.onlyWeightedBaseOutput[row_idx][result_index], evaluationEntry.output, "^8Allocating ^7"..nodeCombo.."^8 will give You:", #nodeDNs + 2)
local function addCompareTooltip(tooltip, result_index, dbMode)
local result = self.resultTbl[row_idx][result_index]
local item = new("Item", result.item_string)
self.itemsTab:AddItemTooltip(tooltip, item, slotTbl, dbMode)
if main.slotOnlyTooltips and slotTbl.slotName == "Megalomaniac" then
local evaluation = self.resultTbl[row_idx][result_index].evaluation
self.itemsTab.build:AddStatComparesToTooltip(tooltip, self.onlyWeightedBaseOutput[row_idx][result_index], evaluation[1].output, "^7Equipping this item will give you:")
end
end
controls["resultDropdown"..row_idx].tooltipFunc = function(tooltip, dropdown_mode, dropdown_index, dropdown_display_string)
local pb_index = self.sortedResultTbl[row_idx][dropdown_index].index
local result = self.resultTbl[row_idx][pb_index]
local item = new("Item", result.item_string)
tooltip:Clear()
self.itemsTab:AddItemTooltip(tooltip, item, slotTbl)
addMegalomaniacCompareToTooltipIfApplicable(tooltip, pb_index)
local result_index = self.sortedResultTbl[row_idx][dropdown_index].index
local result = self.resultTbl[row_idx][result_index]
addCompareTooltip(tooltip, result_index)
tooltip:AddSeparator(10)
tooltip:AddLine(16, string.format("^7Price: %s %s", result.amount, result.currency))
end
Expand All @@ -1010,14 +988,8 @@ function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, ro
controls["importButton"..row_idx].tooltipFunc = function(tooltip)
tooltip:Clear()
local selected_result_index = self.itemIndexTbl[row_idx]
local item_string = self.resultTbl[row_idx][selected_result_index].item_string
if selected_result_index and item_string then
-- TODO: item parsing bug caught here.
-- 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)
addMegalomaniacCompareToTooltipIfApplicable(tooltip, selected_result_index)
if selected_result_index then
addCompareTooltip(tooltip, selected_result_index, true)
end
end
controls["importButton"..row_idx].enabled = function()
Expand Down
54 changes: 30 additions & 24 deletions src/Classes/TradeQueryGenerator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ local tradeCategoryNames = {
["Ring"] = { "Ring" },
["Amulet"] = { "Amulet" },
["Belt"] = { "Belt" },
["Chest"] = { "Body Armour" },
["Helmet"] = { "Helmet" },
["Gloves"] = { "Gloves" },
["Boots"] = { "Boots" },
["Chest"] = { "Body Armour", "Body Armour: Armour", "Body Armour: Armour/Energy Shield", "Body Armour: Armour/Evasion", "Body Armour: Armour/Evasion/Energy Shield", "Body Armour: Energy Shield", "Body Armour: Evasion", "Body Armour: Evasion/Energy Shield" },
["Helmet"] = { "Helmet", "Helmet: Armour", "Helmet: Armour/Energy Shield", "Helmet: Armour/Evasion", "Helmet: Armour/Evasion/Energy Shield", "Helmet: Energy Shield", "Helmet: Evasion", "Helmet: Evasion/Energy Shield" },
["Gloves"] = { "Gloves: Armour", "Gloves: Armour/Energy Shield", "Gloves: Armour/Evasion", "Gloves: Armour/Evasion/Energy Shield", "Gloves: Energy Shield", "Gloves: Evasion", "Gloves: Evasion/Energy Shield" },
["Boots"] = { "Boots", "Boots: Armour", "Boots: Armour/Energy Shield", "Boots: Armour/Evasion", "Boots: Armour/Evasion/Energy Shield", "Boots: Energy Shield", "Boots: Evasion", "Boots: Evasion/Energy Shield" },
["Quiver"] = { "Quiver" },
["Shield"] = { "Shield" },
["Shield"] = { "Shield", "Shield: Armour", "Shield: Armour/Energy Shield", "Shield: Armour/Evasion", "Shield: Evasion" },
["Focus"] = { "Focus" },
["1HWeapon"] = { "One Handed Mace", "Wand", "Sceptre", "Flail", "Spear" },
["2HWeapon"] = { "Staff", "Staff: Warstaff", "Two Handed Mace", "Crossbow", "Bow" },
Expand Down Expand Up @@ -48,8 +48,8 @@ local tradeCategoryNames = {
-- ["RadiusJewel"] = { "Jewel: Radius" },
-- not in the game yet.
-- ["TrapTool"] = { "TrapTool"}, Unsure if correct
["Flail"] = { "Flail" },
["Spear"] = { "Spear" }
["Flail"] = { "Flail" },
["Spear"] = { "Spear" }
}

-- Build lists of tags present on a given item category
Expand Down Expand Up @@ -83,6 +83,7 @@ local tradeStatCategoryIndices = {
["Explicit"] = 1,
["Implicit"] = 2,
["Corrupted"] = 3,
["AllocatesXEnchant"] = 3,
["Rune"] = 4,
}

Expand Down Expand Up @@ -349,6 +350,7 @@ function TradeQueryGeneratorClass:InitMods()
["Explicit"] = { },
["Implicit"] = { },
["Enchant"] = { },
["AllocatesXEnchant"] = { },
["Corrupted"] = { },
["Rune"] = { },
}
Expand All @@ -375,14 +377,13 @@ function TradeQueryGeneratorClass:InitMods()
self:GenerateModData(data.itemMods.Flask, tradeQueryStatsParsed, { ["LifeFlask"] = true, ["ManaFlask"] = true })
self:GenerateModData(data.itemMods.Charm, tradeQueryStatsParsed, { ["Charm"] = true })

-- megalomaniac tbd
-- local clusterNotableMods = {}
-- for k, v in pairs(data.itemMods.JewelCluster) do
-- if k:find("AfflictionNotable") then
-- clusterNotableMods[k] = v
-- end
-- end
-- self:GenerateModData(clusterNotableMods, tradeQueryStatsParsed)
for _, entry in ipairs(tradeQueryStatsParsed.result[tradeStatCategoryIndices.AllocatesXEnchant].entries) do
if entry.text:sub(1, 10) == "Allocates " then
-- The trade id for allocatesX enchants end with "|[nodeID]" for the allocated node.
local nodeId = entry.id:sub(entry.id:find("|") + 1)
self.modData.AllocatesXEnchant[nodeId] = { tradeMod = entry, specialCaseData = { } }
end
end

-- implicit mods
for baseName, entry in pairs(data.itemBases) do
Expand Down Expand Up @@ -492,16 +493,21 @@ end

function TradeQueryGeneratorClass:GeneratePassiveNodeWeights(nodesToTest)
local start = GetTime()
for _, entry in pairs(nodesToTest) do
for nodeId, entry in pairs(nodesToTest) do
if self.alreadyWeightedMods[entry.tradeMod.id] ~= nil then
ConPrintf("Node %s already evaluated", nodeId)
goto continue
end

local nodeName = entry.tradeMod.text:match("1 Added Passive Skill is (.*)") or entry.tradeMod.text:match("Allocates (.*)")
if not nodeName then
goto continue

local node = self.itemsTab.build.spec.nodes[tonumber(nodeId)]
if not node then
local nodeName = entry.tradeMod.text:match("1 Added Passive Skill is (.*)") or entry.tradeMod.text:match("Allocates (.*)")
node = nodeName and self.itemsTab.build.spec.tree.notableMap[nodeName:lower()]
if not node then
ConPrintf("Failed to find node %s", nodeId)
goto continue
end
end
local node = self.itemsTab.build.spec.tree.clusterNodeMap[nodeName] or self.itemsTab.build.spec.tree.notableMap[nodeName]

local baseOutput = self.calcContext.baseOutput
local output = self.calcContext.calcFunc({ addNodes = { [node] = true } })
Expand Down Expand Up @@ -549,7 +555,7 @@ function TradeQueryGeneratorClass:StartQuery(slot, options)
queryFilters = {},
queryExtra = {
name = "Megalomaniac",
type = "Medium Cluster Jewel"
type = "Diamond"
},
calcNodesInsteadOfMods = true,
}
Expand Down Expand Up @@ -718,7 +724,7 @@ end

function TradeQueryGeneratorClass:ExecuteQuery()
if self.calcContext.special.calcNodesInsteadOfMods then
self:GeneratePassiveNodeWeights(self.modData.PassiveNode)
self:GeneratePassiveNodeWeights(self.modData.AllocatesXEnchant)
return
end
self:GenerateModWeights(self.modData["Explicit"])
Expand Down Expand Up @@ -866,7 +872,7 @@ function TradeQueryGeneratorClass:RequestQuery(slot, context, statWeights, callb
controls.includeCorrupted.state = not context.slotTbl.alreadyCorrupted and (self.lastIncludeCorrupted == nil or self.lastIncludeCorrupted == true)
controls.includeCorrupted.enabled = not context.slotTbl.alreadyCorrupted

local canHaveRunes = slot.slotName:find("Weapon 1") or slot.slotName:find("Weapon 2") or slot.slotName:find("Helmet") or slot.slotName:find("Body Armour") or slot.slotName:find("Gloves") or slot.slotName:find("Boots")
local canHaveRunes = slot and (slot.slotName:find("Weapon 1") or slot.slotName:find("Weapon 2") or slot.slotName:find("Helmet") or slot.slotName:find("Body Armour") or slot.slotName:find("Gloves") or slot.slotName:find("Boots"))
controls.includeRunes = new("CheckBoxControl", {"TOPRIGHT",controls.includeCorrupted,"BOTTOMRIGHT"}, {0, 5, 18}, "Rune Mods:", function(state) end)
controls.includeRunes.state = canHaveRunes and (self.lastIncludeRunes == nil or self.lastIncludeRunes == true)
controls.includeRunes.enabled = canHaveRunes
Expand Down
Loading