Skip to content

Commit 11a47ee

Browse files
Update trader to support PoE2 Megalomaniac (#977)
1 parent 3fbc6b5 commit 11a47ee

File tree

5 files changed

+5223
-83
lines changed

5 files changed

+5223
-83
lines changed

src/Classes/Item.lua

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,18 @@ function ItemClass:ParseRaw(raw, rarity, highQuality)
315315
end
316316
end
317317
if self.rawLines[l] then
318-
self.name = self.rawLines[l]
319318
-- Determine if "Unidentified" item
320319
local unidentified = false
320+
local unidentifiedBase = data.itemBases[self.rawLines[l]]
321+
local identifiedBase = data.itemBases[self.rawLines[l+1]]
322+
if unidentifiedBase and not identifiedBase then
323+
unidentified = true
324+
self.name = "Unidentified item"
325+
self.baseName = self.rawLines[l]
326+
self.base = unidentifiedBase
327+
else
328+
self.name = self.rawLines[l]
329+
end
321330
for _, line in ipairs(self.rawLines) do
322331
if line == "Unidentified" then
323332
unidentified = true

src/Classes/TradeQuery.lua

Lines changed: 35 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -675,46 +675,35 @@ function TradeQueryClass:ReduceOutput(output)
675675
end
676676

677677
-- Method to evaluate a result by getting it's output and weight
678-
function TradeQueryClass:GetResultEvaluation(row_idx, result_index, calcFunc, baseOutput)
678+
function TradeQueryClass:GetResultEvaluation(row_idx, result_index)
679679
local result = self.resultTbl[row_idx][result_index]
680-
if not calcFunc then -- Always evaluate when calcFunc is given
681-
calcFunc, baseOutput = self.itemsTab.build.calcsTab:GetMiscCalculator()
682-
local onlyWeightedBaseOutput = self:ReduceOutput(baseOutput)
683-
if not self.onlyWeightedBaseOutput[row_idx] then
684-
self.onlyWeightedBaseOutput[row_idx] = { }
685-
end
686-
if not self.lastComparedWeightList[row_idx] then
687-
self.lastComparedWeightList[row_idx] = { }
688-
end
689-
-- If the interesting stats are the same (the build hasn't changed) and result has already been evaluated, then just return that
690-
if result.evaluation and tableDeepEquals(onlyWeightedBaseOutput, self.onlyWeightedBaseOutput[row_idx][result_index]) and tableDeepEquals(self.statSortSelectionList, self.lastComparedWeightList[row_idx][result_index]) then
691-
return result.evaluation
692-
end
693-
self.onlyWeightedBaseOutput[row_idx][result_index] = onlyWeightedBaseOutput
694-
self.lastComparedWeightList[row_idx][result_index] = self.statSortSelectionList
680+
local calcFunc, baseOutput = self.itemsTab.build.calcsTab:GetMiscCalculator()
681+
local onlyWeightedBaseOutput = self:ReduceOutput(baseOutput)
682+
if not self.onlyWeightedBaseOutput[row_idx] then
683+
self.onlyWeightedBaseOutput[row_idx] = { }
684+
end
685+
if not self.lastComparedWeightList[row_idx] then
686+
self.lastComparedWeightList[row_idx] = { }
695687
end
688+
-- If the interesting stats are the same (the build hasn't changed) and result has already been evaluated, then just return that
689+
if result.evaluation and tableDeepEquals(onlyWeightedBaseOutput, self.onlyWeightedBaseOutput[row_idx][result_index]) and tableDeepEquals(self.statSortSelectionList, self.lastComparedWeightList[row_idx][result_index]) then
690+
return result.evaluation
691+
end
692+
self.fullBaseOutput = baseOutput
693+
self.onlyWeightedBaseOutput[row_idx][result_index] = onlyWeightedBaseOutput
694+
self.lastComparedWeightList[row_idx][result_index] = self.statSortSelectionList
695+
696696
local slotName = self.slotTables[row_idx].nodeId and "Jewel " .. tostring(self.slotTables[row_idx].nodeId) or self.slotTables[row_idx].slotName
697697
if slotName == "Megalomaniac" then
698698
local addedNodes = {}
699-
for nodeName in (result.item_string.."\r\n"):gmatch("1 Added Passive Skill is (.-)\r?\n") do
700-
t_insert(addedNodes, self.itemsTab.build.spec.tree.clusterNodeMap[nodeName])
699+
for nodeName in (result.item_string.."\r\n"):gmatch("Allocates (.-)\r?\n") do
700+
local node = self.itemsTab.build.spec.tree.notableMap[nodeName:lower()]
701+
addedNodes[node] = true
701702
end
702-
local output12 = self:ReduceOutput(calcFunc({ addNodes = { [addedNodes[1]] = true, [addedNodes[2]] = true } }))
703-
local output13 = self:ReduceOutput(calcFunc({ addNodes = { [addedNodes[1]] = true, [addedNodes[3]] = true } }))
704-
local output23 = self:ReduceOutput(calcFunc({ addNodes = { [addedNodes[2]] = true, [addedNodes[3]] = true } }))
705-
local output123 = self:ReduceOutput(calcFunc({ addNodes = { [addedNodes[1]] = true, [addedNodes[2]] = true, [addedNodes[3]] = true } }))
706-
-- Sometimes the third node is as powerful as a wet noodle, so use weight per point spent, including the jewel socket
707-
local weight12 = self.tradeQueryGenerator.WeightedRatioOutputs(baseOutput, output12, self.statSortSelectionList) / 4
708-
local weight13 = self.tradeQueryGenerator.WeightedRatioOutputs(baseOutput, output13, self.statSortSelectionList) / 4
709-
local weight23 = self.tradeQueryGenerator.WeightedRatioOutputs(baseOutput, output23, self.statSortSelectionList) / 4
710-
local weight123 = self.tradeQueryGenerator.WeightedRatioOutputs(baseOutput, output123, self.statSortSelectionList) / 5
711-
result.evaluation = {
712-
{ output = output12, weight = weight12, DNs = { addedNodes[1].dn, addedNodes[2].dn } },
713-
{ output = output13, weight = weight13, DNs = { addedNodes[1].dn, addedNodes[3].dn } },
714-
{ output = output23, weight = weight23, DNs = { addedNodes[2].dn, addedNodes[3].dn } },
715-
{ output = output123, weight = weight123, DNs = { addedNodes[1].dn, addedNodes[2].dn, addedNodes[3].dn } },
716-
}
717-
table.sort(result.evaluation, function(a, b) return a.weight > b.weight end)
703+
704+
local output = self:ReduceOutput(calcFunc({ addNodes = addedNodes }))
705+
local weight = self.tradeQueryGenerator.WeightedRatioOutputs(baseOutput, output, self.statSortSelectionList)
706+
result.evaluation = {{ output = output, weight = weight }}
718707
else
719708
local item = new("Item", result.item_string)
720709
if not self.enchantInSort then -- Calc item DPS without anoint or enchant as these can generally be added after.
@@ -775,11 +764,7 @@ end
775764

776765
-- Method to sort the fetched results
777766
function TradeQueryClass:SortFetchResults(row_idx, mode)
778-
local calcFunc, baseOutput
779767
local function getResultWeight(result_index)
780-
if not calcFunc then
781-
calcFunc, baseOutput = self.itemsTab.build.calcsTab:GetMiscCalculator()
782-
end
783768
local sum = 0
784769
for _, eval in ipairs(self:GetResultEvaluation(row_idx, result_index)) do
785770
sum = sum + eval.weight
@@ -971,27 +956,20 @@ function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, ro
971956
self.itemIndexTbl[row_idx] = self.sortedResultTbl[row_idx][index].index
972957
self:SetFetchResultReturn(row_idx, self.itemIndexTbl[row_idx])
973958
end)
974-
local function addMegalomaniacCompareToTooltipIfApplicable(tooltip, result_index)
975-
if slotTbl.slotName ~= "Megalomaniac" then
976-
return
977-
end
978-
for _, evaluationEntry in ipairs(self:GetResultEvaluation(row_idx, result_index)) do
979-
tooltip:AddSeparator(10)
980-
local nodeDNs = evaluationEntry.DNs
981-
local nodeCombo = nodeDNs[1]
982-
for i = 2, #nodeDNs do
983-
nodeCombo = nodeCombo .. " ^8+^7 " .. nodeDNs[i]
984-
end
985-
self.itemsTab.build:AddStatComparesToTooltip(tooltip, self.onlyWeightedBaseOutput[row_idx][result_index], evaluationEntry.output, "^8Allocating ^7"..nodeCombo.."^8 will give You:", #nodeDNs + 2)
959+
local function addCompareTooltip(tooltip, result_index, dbMode)
960+
local result = self.resultTbl[row_idx][result_index]
961+
local item = new("Item", result.item_string)
962+
self.itemsTab:AddItemTooltip(tooltip, item, slotTbl, dbMode)
963+
if main.slotOnlyTooltips and slotTbl.slotName == "Megalomaniac" then
964+
local evaluation = self.resultTbl[row_idx][result_index].evaluation
965+
self.itemsTab.build:AddStatComparesToTooltip(tooltip, self.onlyWeightedBaseOutput[row_idx][result_index], evaluation[1].output, "^7Equipping this item will give you:")
986966
end
987967
end
988968
controls["resultDropdown"..row_idx].tooltipFunc = function(tooltip, dropdown_mode, dropdown_index, dropdown_display_string)
989-
local pb_index = self.sortedResultTbl[row_idx][dropdown_index].index
990-
local result = self.resultTbl[row_idx][pb_index]
991-
local item = new("Item", result.item_string)
992969
tooltip:Clear()
993-
self.itemsTab:AddItemTooltip(tooltip, item, slotTbl)
994-
addMegalomaniacCompareToTooltipIfApplicable(tooltip, pb_index)
970+
local result_index = self.sortedResultTbl[row_idx][dropdown_index].index
971+
local result = self.resultTbl[row_idx][result_index]
972+
addCompareTooltip(tooltip, result_index)
995973
tooltip:AddSeparator(10)
996974
tooltip:AddLine(16, string.format("^7Price: %s %s", result.amount, result.currency))
997975
end
@@ -1012,14 +990,8 @@ function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, ro
1012990
controls["importButton"..row_idx].tooltipFunc = function(tooltip)
1013991
tooltip:Clear()
1014992
local selected_result_index = self.itemIndexTbl[row_idx]
1015-
local item_string = self.resultTbl[row_idx][selected_result_index].item_string
1016-
if selected_result_index and item_string then
1017-
-- TODO: item parsing bug caught here.
1018-
-- item.baseName is nil and throws error in the following AddItemTooltip func
1019-
-- if the item is unidentified
1020-
local item = new("Item", item_string)
1021-
self.itemsTab:AddItemTooltip(tooltip, item, slotTbl, true)
1022-
addMegalomaniacCompareToTooltipIfApplicable(tooltip, selected_result_index)
993+
if selected_result_index then
994+
addCompareTooltip(tooltip, selected_result_index, true)
1023995
end
1024996
end
1025997
controls["importButton"..row_idx].enabled = function()

src/Classes/TradeQueryGenerator.lua

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ local tradeCategoryNames = {
4848
-- ["RadiusJewel"] = { "Jewel: Radius" },
4949
-- not in the game yet.
5050
-- ["TrapTool"] = { "TrapTool"}, Unsure if correct
51-
["Flail"] = { "Flail" },
52-
["Spear"] = { "Spear" }
51+
["Flail"] = { "Flail" },
52+
["Spear"] = { "Spear" }
5353
}
5454

5555
-- Build lists of tags present on a given item category
@@ -83,6 +83,7 @@ local tradeStatCategoryIndices = {
8383
["Explicit"] = 1,
8484
["Implicit"] = 2,
8585
["Corrupted"] = 3,
86+
["AllocatesXEnchant"] = 3,
8687
["Rune"] = 4,
8788
}
8889

@@ -349,6 +350,7 @@ function TradeQueryGeneratorClass:InitMods()
349350
["Explicit"] = { },
350351
["Implicit"] = { },
351352
["Enchant"] = { },
353+
["AllocatesXEnchant"] = { },
352354
["Corrupted"] = { },
353355
["Rune"] = { },
354356
}
@@ -375,14 +377,13 @@ function TradeQueryGeneratorClass:InitMods()
375377
self:GenerateModData(data.itemMods.Flask, tradeQueryStatsParsed, { ["LifeFlask"] = true, ["ManaFlask"] = true })
376378
self:GenerateModData(data.itemMods.Charm, tradeQueryStatsParsed, { ["Charm"] = true })
377379

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

387388
-- implicit mods
388389
for baseName, entry in pairs(data.itemBases) do
@@ -492,16 +493,21 @@ end
492493

493494
function TradeQueryGeneratorClass:GeneratePassiveNodeWeights(nodesToTest)
494495
local start = GetTime()
495-
for _, entry in pairs(nodesToTest) do
496+
for nodeId, entry in pairs(nodesToTest) do
496497
if self.alreadyWeightedMods[entry.tradeMod.id] ~= nil then
498+
ConPrintf("Node %s already evaluated", nodeId)
497499
goto continue
498500
end
499-
500-
local nodeName = entry.tradeMod.text:match("1 Added Passive Skill is (.*)") or entry.tradeMod.text:match("Allocates (.*)")
501-
if not nodeName then
502-
goto continue
501+
502+
local node = self.itemsTab.build.spec.nodes[tonumber(nodeId)]
503+
if not node then
504+
local nodeName = entry.tradeMod.text:match("1 Added Passive Skill is (.*)") or entry.tradeMod.text:match("Allocates (.*)")
505+
node = nodeName and self.itemsTab.build.spec.tree.notableMap[nodeName:lower()]
506+
if not node then
507+
ConPrintf("Failed to find node %s", nodeId)
508+
goto continue
509+
end
503510
end
504-
local node = self.itemsTab.build.spec.tree.clusterNodeMap[nodeName] or self.itemsTab.build.spec.tree.notableMap[nodeName]
505511

506512
local baseOutput = self.calcContext.baseOutput
507513
local output = self.calcContext.calcFunc({ addNodes = { [node] = true } })
@@ -549,7 +555,7 @@ function TradeQueryGeneratorClass:StartQuery(slot, options)
549555
queryFilters = {},
550556
queryExtra = {
551557
name = "Megalomaniac",
552-
type = "Medium Cluster Jewel"
558+
type = "Diamond"
553559
},
554560
calcNodesInsteadOfMods = true,
555561
}
@@ -718,7 +724,7 @@ end
718724

719725
function TradeQueryGeneratorClass:ExecuteQuery()
720726
if self.calcContext.special.calcNodesInsteadOfMods then
721-
self:GeneratePassiveNodeWeights(self.modData.PassiveNode)
727+
self:GeneratePassiveNodeWeights(self.modData.AllocatesXEnchant)
722728
return
723729
end
724730
self:GenerateModWeights(self.modData["Explicit"])
@@ -866,7 +872,7 @@ function TradeQueryGeneratorClass:RequestQuery(slot, context, statWeights, callb
866872
controls.includeCorrupted.state = not context.slotTbl.alreadyCorrupted and (self.lastIncludeCorrupted == nil or self.lastIncludeCorrupted == true)
867873
controls.includeCorrupted.enabled = not context.slotTbl.alreadyCorrupted
868874

869-
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")
875+
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"))
870876
controls.includeRunes = new("CheckBoxControl", {"TOPRIGHT",controls.includeCorrupted,"BOTTOMRIGHT"}, {0, 5, 18}, "Rune Mods:", function(state) end)
871877
controls.includeRunes.state = canHaveRunes and (self.lastIncludeRunes == nil or self.lastIncludeRunes == true)
872878
controls.includeRunes.enabled = canHaveRunes

0 commit comments

Comments
 (0)