Skip to content

Commit 0d2a6a9

Browse files
committed
convert trade tool mod weight generation to use tradeHash
1 parent 52fc62d commit 0d2a6a9

4 files changed

Lines changed: 8619 additions & 14121 deletions

File tree

src/Classes/TradeQueryGenerator.lua

Lines changed: 75 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,6 @@ function TradeQueryGeneratorClass.WeightedRatioOutputs(baseOutput, newOutput, st
183183
end
184184

185185
function TradeQueryGeneratorClass:ProcessMod(mod, tradeQueryStatsParsed, itemCategoriesMask, itemCategoriesOverride)
186-
if mod.statOrder == nil then mod.statOrder = { } end
187-
if mod.group == nil then mod.group = "" end
188186

189187
for index, modLine in ipairs(mod) do
190188
if modLine:find("Grants Level") or modLine:find("inflict Decay") then -- skip mods that grant skills / decay, as they will often be overwhelmingly powerful but don't actually fit into the build
@@ -214,42 +212,41 @@ function TradeQueryGeneratorClass:ProcessMod(mod, tradeQueryStatsParsed, itemCat
214212

215213
-- iterate trade mod category to find mod with matching text.
216214
local function getTradeMod()
217-
-- try matching to global mods.
218-
local matchStr = modLine:gsub("[#()0-9%-%+%.]","")
219-
for _, entry in ipairs(tradeQueryStatsParsed.result[tradeStatCategoryIndices[modType]].entries) do
220-
if entry.text:gsub("[#()0-9%-%+%.]","") == matchStr then
221-
return entry
215+
local entry
216+
local tradeHashStr = tostring(mod.tradeHash)
217+
for _, v in ipairs(tradeQueryStatsParsed.result[tradeStatCategoryIndices[modType]].entries) do
218+
-- prefix removed
219+
local ids = v.id:gsub(".+..stat_", "").."|"
220+
-- split by non-integer
221+
for id in ids:gmatch("%d+") do
222+
if tradeHashStr == id then
223+
entry = v
224+
goto finish
225+
end
222226
end
223227
end
224-
-- check reverse
225-
matchStr = swapInverse(matchStr)
226-
for _, entry in ipairs(tradeQueryStatsParsed.result[tradeStatCategoryIndices[modType]].entries) do
227-
if entry.text:gsub("[#()0-9%-%+%.]","") == matchStr then
228-
return entry, true
229-
end
228+
::finish::
229+
230+
if not entry then
231+
return nil
230232
end
231233

232-
return nil
234+
-- determine if the mod is inversed, i.e. increased here -> reduced on trade
235+
local pattern = "[#()0-9%-%+%.]"
236+
local matchStr = modLine:gsub(pattern,"")
237+
local inverseMatchStr = swapInverse(matchStr)
238+
if entry.text:gsub(pattern, "") == matchStr then
239+
return entry, false
240+
elseif entry.text:gsub(pattern, "") == inverseMatchStr then
241+
return entry, true
242+
end
243+
return entry
233244
end
234245

235246
local tradeMod = nil
236247
local invert
237248

238-
if mod.statOrder[index] == nil then -- if there isn't a mod order we have to use the trade id instead e.g. implicits.
239-
tradeMod, invert = getTradeMod()
240-
if tradeMod == nil then
241-
logToFile("Unable to match %s mod: %s", modType, modLine)
242-
goto nextModLine
243-
end
244-
mod.statOrder[index] = tradeMod.id
245-
end
246-
247-
local statOrder = modLine:find("Nearby Enemies have %-") ~= nil and mod.statOrder[index + 1] or mod.statOrder[index] -- hack to get minus res mods associated with the correct statOrder
248-
local uniqueIndex = mod.group ~= "" and tostring(statOrder).."_"..mod.group or tostring(statOrder)
249-
-- ensure that regular jewel and radius jewel mods don't get the same index
250-
if mod.nodeType then
251-
uniqueIndex = uniqueIndex.."Radius"
252-
end
249+
local uniqueIndex = tostring(mod.tradeHash)
253250

254251
if self.modData[modType][uniqueIndex] == nil then
255252
if tradeMod == nil then
@@ -364,7 +361,8 @@ function TradeQueryGeneratorClass:InitMods()
364361

365362
-- originates from: https://www.pathofexile.com/api/trade2/data/stats
366363
local tradeStats = fetchStats()
367-
tradeStats:gsub("\n", " ")
364+
-- stop modifier texts from breaking the lua formatting
365+
tradeStats = tradeStats:gsub("\\n", "")
368366
local tradeQueryStatsParsed = dkjson.decode(tradeStats)
369367
for _, modDomain in ipairs(tradeQueryStatsParsed.result) do
370368
for _, mod in ipairs(modDomain.entries) do
@@ -394,12 +392,30 @@ function TradeQueryGeneratorClass:InitMods()
394392

395393
-- implicit mods
396394
for baseName, entry in pairsSortByKey(data.itemBases) do
397-
if entry.implicit ~= nil then
395+
if entry.implicit ~= nil and entry.type ~= "Transcendent Limb" then
398396
local mod = { type = "Implicit" }
399397
for modLine in string.gmatch(entry.implicit, "([^".."\n".."]+)") do
400398
t_insert(mod, modLine)
401399
end
402400

401+
local found = false
402+
for _, modLine in ipairs(mod) do
403+
if modLine:find("Grants Skill:") then
404+
goto continue
405+
end
406+
for _, v in pairs(data.itemMods.Exclusive) do
407+
if v[1] == modLine then
408+
found = true
409+
mod = v
410+
mod.type = "Implicit"
411+
end
412+
end
413+
end
414+
if not found then
415+
ConPrintf("unknown implicit mod: %s", mod[1])
416+
goto continue
417+
end
418+
403419
-- create trade type mask for base type
404420
local maskOverride = {}
405421
for tradeName, typeNames in pairs(tradeCategoryNames) do
@@ -420,38 +436,42 @@ function TradeQueryGeneratorClass:InitMods()
420436
self:ProcessMod(mod, tradeQueryStatsParsed, regularItemMask, maskOverride)
421437
end
422438
end
439+
::continue::
423440
end
424441

425-
-- rune mods
442+
-- -- rune mods
426443
for name, runeMods in pairsSortByKey(data.itemMods.Runes) do
427444
for slotType, mods in pairs(runeMods) do
428-
if slotType == "weapon" then
429-
self:ProcessMod(mods, tradeQueryStatsParsed, regularItemMask, { ["1HWeapon"] = true, ["2HWeapon"] = true, ["1HMace"] = true, ["Claw"] = true, ["Quarterstaff"] = true, ["Bow"] = true, ["2HMace"] = true, ["Crossbow"] = true, ["Spear"] = true, ["Flail"] = true, ["Talisman"] = true })
430-
elseif slotType == "armour" then
431-
self:ProcessMod(mods, tradeQueryStatsParsed, regularItemMask, { ["Shield"] = true, ["Chest"] = true, ["Helmet"] = true, ["Gloves"] = true, ["Boots"] = true, ["Focus"] = true })
432-
elseif slotType == "caster" then
433-
self:ProcessMod(mods, tradeQueryStatsParsed, regularItemMask, { ["Wand"] = true, ["Staff"] = true })
434-
else
435-
-- Mod is slot specific, try to match against a value in tradeCategoryNames
436-
local matchedCategory = nil
437-
for category, categoryOptions in pairs(tradeCategoryNames) do
438-
for i, opt in pairs(categoryOptions) do
439-
if opt:lower():match(slotType) then
440-
matchedCategory = category
445+
for i, modLine in ipairs(mods) do
446+
local mod = {modLine, tradeHash = mods.tradeHashes[i], type = "Rune"}
447+
if slotType == "weapon" then
448+
self:ProcessMod(mod, tradeQueryStatsParsed, regularItemMask, { ["1HWeapon"] = true, ["2HWeapon"] = true, ["1HMace"] = true, ["Claw"] = true, ["Quarterstaff"] = true, ["Bow"] = true, ["2HMace"] = true, ["Crossbow"] = true, ["Spear"] = true, ["Flail"] = true, ["Talisman"] = true })
449+
elseif slotType == "armour" then
450+
self:ProcessMod(mod, tradeQueryStatsParsed, regularItemMask, { ["Shield"] = true, ["Chest"] = true, ["Helmet"] = true, ["Gloves"] = true, ["Boots"] = true, ["Focus"] = true })
451+
elseif slotType == "caster" then
452+
self:ProcessMod(mod, tradeQueryStatsParsed, regularItemMask, { ["Wand"] = true, ["Staff"] = true })
453+
else
454+
-- Mod is slot specific, try to match against a value in tradeCategoryNames
455+
local matchedCategory = nil
456+
for category, categoryOptions in pairs(tradeCategoryNames) do
457+
for i, opt in pairs(categoryOptions) do
458+
if opt:lower():match(slotType) then
459+
matchedCategory = category
460+
break
461+
end
462+
end
463+
if matchedCategory then
441464
break
442465
end
443466
end
444467
if matchedCategory then
445-
break
468+
self:ProcessMod(mod, tradeQueryStatsParsed, regularItemMask, { [matchedCategory] = true })
469+
else
470+
ConPrintf("TradeQuery: Unmatched category for modifier. Slot type: %s Modifier: %s", mods.slotType, mods.name)
446471
end
447472
end
448-
if matchedCategory then
449-
self:ProcessMod(mods, tradeQueryStatsParsed, regularItemMask, { [matchedCategory] = true })
450-
else
451-
ConPrintf("TradeQuery: Unmatched category for modifier. Slot type: %s Modifier: %s", mods.slotType, mods.name)
452-
end
453473
end
454-
end
474+
end
455475
end
456476

457477
local queryModsFile = io.open(queryModFilePath, 'w')
@@ -499,6 +519,9 @@ function TradeQueryGeneratorClass:GenerateModWeights(modsToTest)
499519
end
500520
end
501521

522+
-- remove (Local) suffix so pob parses the mod correctly
523+
modLine = modLine:gsub("%(Local%)", "")
524+
502525
self.calcContext.testItem.explicitModLines[1] = { line = modLine, custom = true }
503526
self.calcContext.testItem:BuildAndParseRaw()
504527

0 commit comments

Comments
 (0)