Skip to content

Commit b080452

Browse files
LocalIdentityLocalIdentity
andauthored
Fix power report and trade search not working with Minions (#2219)
When using the Power Report of a weighted sum trade search, it would not work with minions unless you included them in FullDPS The power report logic was broken due to the invalid lua logic of using "and not selection.stat ==" For the trade search I used the same logic we have in the items tab for using combined DPS as a fallback incase someone selects fullDPS but doesn't add the minion to it Co-authored-by: LocalIdentity <localidentity2@gmail.com>
1 parent d0e2edd commit b080452

6 files changed

Lines changed: 102 additions & 6 deletions

File tree

spec/System/TestTradeQueryCurrency_spec.lua

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,24 @@ describe("TradeQuery Currency Conversion", function()
2323
end)
2424
end)
2525

26+
describe("ReduceOutput", function()
27+
it("uses selected minion stats for weighted result comparison", function()
28+
mock_tradeQuery.statSortSelectionList = { { stat = "AverageDamage" } }
29+
30+
local result = mock_tradeQuery:ReduceOutput({
31+
AverageDamage = 10,
32+
Life = 100,
33+
Minion = {
34+
AverageDamage = 250,
35+
Life = 200,
36+
},
37+
})
38+
39+
assert.are.equals(250, result.AverageDamage)
40+
assert.is_nil(result.Life)
41+
end)
42+
end)
43+
2644
describe("PriceBuilderProcessPoENinjaResponse", function()
2745
-- Pass: Processes without error, restoring map while adding a notice
2846
-- Fail: Corrupts map or crashes, indicating fragile API response handling, breaking future conversions

spec/System/TestTradeQueryGenerator_spec.lua

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,50 @@ describe("TradeQueryGenerator", function()
3434
local result = mock_queryGen.WeightedRatioOutputs(baseOutput, newOutput, statWeights)
3535
assert.are.equal(result, 100)
3636
end)
37+
38+
it("uses minion output for non-FullDPS stats when minion output is available", function()
39+
local baseOutput = { AverageDamage = 10, Minion = { AverageDamage = 100 } }
40+
local newOutput = { AverageDamage = 10, Minion = { AverageDamage = 250 } }
41+
local statWeights = { { stat = "AverageDamage", weightMult = 1 } }
42+
data.misc.maxStatIncrease = 1000
43+
44+
local result = mock_queryGen.WeightedRatioOutputs(baseOutput, newOutput, statWeights)
45+
46+
assert.are.equal(result, 2.5)
47+
end)
48+
49+
it("uses player output for FullDPS even when minion output is available", function()
50+
local baseOutput = { FullDPS = 100, Minion = { FullDPS = 100 } }
51+
local newOutput = { FullDPS = 250, Minion = { FullDPS = 1000 } }
52+
local statWeights = { { stat = "FullDPS", weightMult = 1 } }
53+
data.misc.maxStatIncrease = 1000
54+
55+
local result = mock_queryGen.WeightedRatioOutputs(baseOutput, newOutput, statWeights)
56+
57+
assert.are.equal(result, 2.5)
58+
end)
59+
60+
it("uses the fallback DPS ratio once when FullDPS is unavailable", function()
61+
local baseOutput = { Minion = { TotalDPS = 10, TotalDotDPS = 0, CombinedDPS = 10 } }
62+
local newOutput = { Minion = { TotalDPS = 25, TotalDotDPS = 0, CombinedDPS = 25 } }
63+
local statWeights = { { stat = "FullDPS", weightMult = 1 } }
64+
data.misc.maxStatIncrease = 1000
65+
66+
local result = mock_queryGen.WeightedRatioOutputs(baseOutput, newOutput, statWeights)
67+
68+
assert.are.equal(result, 2.5)
69+
end)
70+
71+
it("falls back to player output when the selected stat is not on minion output", function()
72+
local baseOutput = { Spirit = 100, Minion = { AverageDamage = 100 } }
73+
local newOutput = { Spirit = 120, Minion = { AverageDamage = 100 } }
74+
local statWeights = { { stat = "Spirit", weightMult = 1 } }
75+
data.misc.maxStatIncrease = 1000
76+
77+
local result = mock_queryGen.WeightedRatioOutputs(baseOutput, newOutput, statWeights)
78+
79+
assert.are.equal(result, 1.2)
80+
end)
3781
end)
3882

3983
describe("Filter prioritization", function()

spec/System/TestTreeTab_spec.lua

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,4 +146,22 @@ describe("TreeTab", function()
146146
assert.is_nil(build.treeTab.specList[1].allocNodes[2])
147147
end)
148148
end)
149+
150+
describe("Power stat calculation", function()
151+
it("uses minion output for non-FullDPS stats when minion output is available", function()
152+
local selection = { stat = "AverageDamage" }
153+
local outputWithNode = { AverageDamage = 10, Minion = { AverageDamage = 250 } }
154+
local baseOutput = { AverageDamage = 10, Minion = { AverageDamage = 100 } }
155+
156+
assert.are.equals(150, build.calcsTab:CalculatePowerStat(selection, outputWithNode, baseOutput))
157+
end)
158+
159+
it("uses player output for FullDPS even when minion output is available", function()
160+
local selection = { stat = "FullDPS" }
161+
local outputWithNode = { FullDPS = 250, Minion = { FullDPS = 1000 } }
162+
local baseOutput = { FullDPS = 100, Minion = { FullDPS = 1000 } }
163+
164+
assert.are.equals(150, build.calcsTab:CalculatePowerStat(selection, outputWithNode, baseOutput))
165+
end)
166+
end)
149167
end)

src/Classes/CalcsTab.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ function CalcsTabClass:PowerBuilder()
672672
end
673673

674674
function CalcsTabClass:CalculatePowerStat(selection, original, modified)
675-
if modified.Minion and not selection.stat == "FullDPS" then
675+
if modified.Minion and selection.stat ~= "FullDPS" then
676676
original = original.Minion
677677
modified = modified.Minion
678678
end

src/Classes/TradeQuery.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ end
770770
function TradeQueryClass:ReduceOutput(output)
771771
local smallOutput = {}
772772
for _, statTable in ipairs(self.statSortSelectionList) do
773-
smallOutput[statTable.stat] = output[statTable.stat]
773+
smallOutput[statTable.stat] = output.Minion and output.Minion[statTable.stat] or output[statTable.stat]
774774
end
775775
return smallOutput
776776
end

src/Classes/TradeQueryGenerator.lua

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,12 +157,26 @@ end
157157

158158
function TradeQueryGeneratorClass.WeightedRatioOutputs(baseOutput, newOutput, statWeights)
159159
local meanStatDiff = 0
160+
local function getOutputStatValue(output, stat)
161+
if stat == "FullDPS" then
162+
if output[stat] ~= nil then
163+
return output[stat]
164+
end
165+
if output.Minion and output.Minion.CombinedDPS ~= nil then
166+
return output.Minion.CombinedDPS
167+
end
168+
end
169+
if output.Minion and output.Minion[stat] ~= nil then
170+
return output.Minion[stat]
171+
end
172+
return output[stat] or 0
173+
end
160174
local function ratioModSums(...)
161175
local baseModSum = 0
162176
local newModSum = 0
163177
for _, mod in ipairs({ ... }) do
164-
baseModSum = baseModSum + (baseOutput[mod] or 0)
165-
newModSum = newModSum + (newOutput[mod] or 0)
178+
baseModSum = baseModSum + getOutputStatValue(baseOutput, mod)
179+
newModSum = newModSum + getOutputStatValue(newOutput, mod)
166180
end
167181

168182
if baseModSum == math.huge then
@@ -176,10 +190,12 @@ function TradeQueryGeneratorClass.WeightedRatioOutputs(baseOutput, newOutput, st
176190
end
177191
end
178192
for _, statTable in ipairs(statWeights) do
193+
local modSumRatio
179194
if statTable.stat == "FullDPS" and not (baseOutput["FullDPS"] and newOutput["FullDPS"]) then
180-
meanStatDiff = meanStatDiff + ratioModSums("TotalDPS", "TotalDotDPS", "CombinedDPS") * statTable.weightMult
195+
modSumRatio = ratioModSums("TotalDPS", "TotalDotDPS", "CombinedDPS")
196+
else
197+
modSumRatio = ratioModSums(statTable.stat)
181198
end
182-
local modSumRatio = ratioModSums(statTable.stat)
183199
-- some weights, such as damage taken from hit need to be negated as lower is better for them
184200
if statTable.transform then
185201
modSumRatio = statTable.transform(modSumRatio)

0 commit comments

Comments
 (0)