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
47 changes: 47 additions & 0 deletions spec/System/TestItemMods_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,53 @@ describe("TetsItemMods", function()
assert.are.equals(-math.huge, itemDB.list[#itemDB.list].measuredPower)
end)

it("sorts crafted modifier replacements without retaining the selected modifier", function()
local item = new("Item"):Item([[
Rarity: RARE
Armour Chest
Champion Cuirass
Armour: 526
Crafted: true
Prefix: {range:1}IncreasedLife1
Prefix: None
Prefix: None
Suffix: None
Suffix: None
Suffix: None
Quality: 18
Item Level: 100
LevelReq: 65
Implicits: 0
+19 to maximum Life
]])
local calcCount = 0
local retainedCount = 0
assert.are.equals("+19 to maximum Life", item.explicitModLines[1].line)
build.itemsTab.displayItem = item
build.itemsTab.controls.craftingSorting:SelByValue("Life", "stat")
build.calcsTab.GetMiscCalculator = function()
return function(args)
calcCount += 1
local life = 0
for _, modLine in ipairs(args.repItem.explicitModLines) do
if modLine.line == "+19 to maximum Life" then
retainedCount += 1
end
life += tonumber(modLine.line:match("%+(%d+) to maximum Life")) or 0
end
return { Life = life }
end
end

local control = build.itemsTab.controls.displayItemAffix1
build.itemsTab:UpdateAffixControl(control, item, "Prefix", "prefixes", 1, { })

assert.is_true(calcCount > 1)
assert.are.equals(0, retainedCount)
assert.is_truthy(control.list[2].label:find("maximum Life", 1, true))
assert.is_truthy(isValueInArray(control.list[control.selIndex].modList, "IncreasedLife1"))
end)

it("Both slots mod (evasion and es mastery)", function()

build.configTab.input.customMods = "\z
Expand Down
125 changes: 76 additions & 49 deletions src/Classes/ItemsTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -74,32 +74,12 @@ end

local function buildModSortList()
local sortList = { { label = "Default", stat = nil } }
local sortTransforms = { }
for _, entry in ipairs(data.powerStatList) do
if entry.stat and not entry.ignoreForNodes then
t_insert(sortList, { label = entry.label, stat = entry.stat })
sortTransforms[entry.stat] = entry.transform
if entry.stat and not entry.ignoreForItems then
t_insert(sortList, entry)
end
end
return sortList, sortTransforms
end

local function getOutputStatValue(output, stat)
if stat == "FullDPS" then
if output[stat] ~= nil then
return output[stat]
end
if output.Minion and output.Minion.CombinedDPS ~= nil then
return output.Minion.CombinedDPS
end
end
if output.Minion and output.Minion[stat] ~= nil then
return output.Minion[stat]
end
if output[stat] ~= nil then
return output[stat]
end
return 0
return sortList
end

local function setDefaultSortOrder(modList)
Expand All @@ -110,7 +90,8 @@ local function setDefaultSortOrder(modList)
end
end

local function getSortedModValue(item, listMod, stat, sortTransforms, calcFunc, slotName, useFullDPS, addModToItem)
local function getSortedModValue(item, listMod, sortOption, calcFunc, slotName, addModToItem)
local stat = sortOption.stat
listMod.sortValues = listMod.sortValues or { }
if listMod.sortValues[stat] ~= nil then
return listMod.sortValues[stat]
Expand All @@ -119,11 +100,8 @@ local function getSortedModValue(item, listMod, stat, sortTransforms, calcFunc,
testItem.id = item.id
addModToItem(testItem, listMod)
testItem:BuildAndParseRaw()
local output = calcFunc({ repSlotName = slotName, repItem = testItem }, useFullDPS)
local value = getOutputStatValue(output, stat)
if sortTransforms[stat] then
value = sortTransforms[stat](value)
end
local output = calcFunc({ repSlotName = slotName, repItem = testItem }, stat == "FullDPS")
local value = data.powerStatList.GetFromOutput(output, sortOption)
listMod.sortValues[stat] = value
return value
end
Expand Down Expand Up @@ -730,9 +708,24 @@ holding Shift will put it in the second.]])
self.controls["displayItemRuneLabel" .. i] = new("LabelControl"):LabelControl({ "RIGHT", drop, "LEFT" }, { -4, 0, 0, 14 }, "^7Rune #" .. i)
end

-- Section: Crafting modifier sorting
local sortList = buildModSortList()
local function craftingSortingShown()
return self.displayItem and self.displayItem.crafted and not self.displayItem.clusterJewel
end
self.controls.displayItemSectionCraftingSort = new("Control"):Control({ "TOPLEFT", self.controls.displayItemSectionRune, "BOTTOMLEFT" }, { 0, 0, 0, function()
return craftingSortingShown() and 28 or 0
end })
self.controls.craftingSortingLabel = new("LabelControl"):LabelControl({ "TOPLEFT", self.controls.displayItemSectionCraftingSort, "TOPLEFT" }, { 0, 6, 0, 16 }, "^7Modifier sorting:")
self.controls.craftingSortingLabel.shown = craftingSortingShown
self.controls.craftingSorting = new("DropDownControl"):DropDownControl({ "LEFT", self.controls.craftingSortingLabel, "RIGHT" }, { 4, 0, 200, 20 }, sortList, function()
self:UpdateAffixControls()
end)
self.controls.craftingSorting.shown = craftingSortingShown

-- Section: Affix Selection
local maxModCount = 9
self.controls.displayItemSectionAffix = new("Control"):Control({ "TOPLEFT", self.controls.displayItemSectionRune, "BOTTOMLEFT" }, { 0, 0, 0, function()
self.controls.displayItemSectionAffix = new("Control"):Control({ "TOPLEFT", self.controls.displayItemSectionCraftingSort, "BOTTOMLEFT" }, { 0, 0, 0, function()
if not self.displayItem or not self.displayItem.crafted then
return 0
end
Expand All @@ -747,6 +740,7 @@ holding Shift will put it in the second.]])
end
return h
end})

for i = 1, maxModCount do
local prev = self.controls["displayItemAffix"..(i-1)] or self.controls.displayItemSectionAffix
local drop, slider
Expand Down Expand Up @@ -1939,11 +1933,12 @@ end
function ItemsTabClass:UpdateAffixControls()
local item = self.displayItem
local prefixLimit = item.prefixes.limit or (item.affixLimit / 2)
local powerCache = { }
for i = 1, item.affixLimit do
if i <= prefixLimit then
self:UpdateAffixControl(self.controls["displayItemAffix"..i], item, "Prefix", "prefixes", i)
self:UpdateAffixControl(self.controls["displayItemAffix"..i], item, "Prefix", "prefixes", i, powerCache)
else
self:UpdateAffixControl(self.controls["displayItemAffix"..i], item, "Suffix", "suffixes", i - prefixLimit)
self:UpdateAffixControl(self.controls["displayItemAffix"..i], item, "Suffix", "suffixes", i - prefixLimit, powerCache)
end
end
-- The custom affixes may have had their indexes changed, so the custom control UI is also rebuilt so that it will
Expand Down Expand Up @@ -2043,7 +2038,7 @@ function ItemsTabClass:UpdateRuneControls()
end
end

function ItemsTabClass:UpdateAffixControl(control, item, type, outputTable, outputIndex)
function ItemsTabClass:UpdateAffixControl(control, item, type, outputTable, outputIndex, powerCache)
local extraTags = { }
local excludeGroups = { }
for _, table in ipairs({"prefixes","suffixes"}) do
Expand Down Expand Up @@ -2142,6 +2137,40 @@ function ItemsTabClass:UpdateAffixControl(control, item, type, outputTable, outp
end
end
end
local sortOption = self.controls.craftingSorting:GetSelValue()
if sortOption.stat and self.controls.craftingSorting:IsShown() then
local modList = { }
for index = 2, #control.list do
t_insert(modList, control.list[index])
end
setDefaultSortOrder(modList)
local calcFunc = self.build.calcsTab:GetMiscCalculator()
local slotName = self:GetComparisonSlotNameForItem(item)
local controlPowerCache = selAffix ~= "None" and { } or powerCache or { }
sortModList(modList, sortOption.stat, function(listMod)
local modId = listMod.modList[1 + round((#listMod.modList - 1) * main.defaultItemAffixQuality)]
local cacheEntry = controlPowerCache[modId]
if not cacheEntry then
cacheEntry = { modId = modId }
controlPowerCache[modId] = cacheEntry
end
return getSortedModValue(item, cacheEntry, sortOption, calcFunc, slotName, function(testItem, sortedMod)
testItem[outputTable][outputIndex] = { modId = sortedMod.modId, range = main.defaultItemAffixQuality }
testItem:Craft()
end)
end)
wipeTable(control.list)
t_insert(control.list, "None")
for _, listMod in ipairs(modList) do
t_insert(control.list, listMod)
end
for index, listMod in ipairs(control.list) do
if listMod.modList and isValueInArray(listMod.modList, selAffix) then
control.selIndex = index
break
end
end
end
if control.list[control.selIndex].haveRange then
control.slider.divCount = #control.list[control.selIndex].modList
local index = isValueInArray(control.list[control.selIndex].modList, selAffix)
Expand Down Expand Up @@ -2706,7 +2735,7 @@ function ItemsTabClass:CorruptDisplayItem() -- todo implement vaal orb new outco
local corruptedRanges = {}
local currentModType = "Corrupted"
local sourceList = { "Corrupted" }
local sortList, sortTransforms = buildModSortList()
local sortList = buildModSortList()

if self.displayItem.base.type == "Helmet" then
t_insert(sourceList, "Glimpse of Chaos")
Expand Down Expand Up @@ -2789,13 +2818,12 @@ function ItemsTabClass:CorruptDisplayItem() -- todo implement vaal orb new outco
end
end
end
local function sortEnchantList(stat)
if stat then
local function sortEnchantList(sortOption)
if sortOption.stat then
local slotName = self:GetComparisonSlotNameForItem(self.displayItem)
local calcFunc = self.build.calcsTab:GetMiscCalculator()
local useFullDPS = stat == "FullDPS"
sortModList(enchantList[currentModType], stat, function(listMod)
return getSortedModValue(self.displayItem, listMod, stat, sortTransforms, calcFunc, slotName, useFullDPS, function(item, sortedMod)
sortModList(enchantList[currentModType], sortOption.stat, function(listMod)
return getSortedModValue(self.displayItem, listMod, sortOption, calcFunc, slotName, function(item, sortedMod)
applyCorruptionMods(item, { sortedMod.mod })
end)
end)
Expand Down Expand Up @@ -2956,7 +2984,7 @@ function ItemsTabClass:CorruptDisplayItem() -- todo implement vaal orb new outco
end
end
if controls.sort then
sortEnchantList(controls.sort.list[controls.sort.selIndex].stat)
sortEnchantList(controls.sort:GetSelValue())
end
rebuildEnchantControls(true)
main.popups[1].height = 103 + 20 * enchantNum
Expand All @@ -2966,7 +2994,7 @@ function ItemsTabClass:CorruptDisplayItem() -- todo implement vaal orb new outco
controls.source:SelByValue(currentModType == "SpecialCorrupted" and "Glimpse of Chaos" or "Corrupted")
controls.sortLabel = new("LabelControl"):LabelControl({ "TOPRIGHT", nil, "TOPLEFT" }, { 350, 30, 0, 16 }, "^7Sort by:")
controls.sort = new("DropDownControl"):DropDownControl({ "TOPLEFT", nil, "TOPLEFT" }, { 355, 30, 240, 18 }, sortList, function(index, value)
sortEnchantList(value.stat)
sortEnchantList(value)
rebuildEnchantControls()
end)
for i = 1, 8 do
Expand Down Expand Up @@ -3014,18 +3042,17 @@ function ItemsTabClass:AddCustomModifierToDisplayItem()
local controls = { }
local sourceList = { }
local modList = { }
local sortList, sortTransforms = buildModSortList()
local function applySort(stat, selectFirst)
local sortList = buildModSortList()
local function applySort(sortOption, selectFirst)
if not controls.modSelect or not controls.modSelect:IsShown() then
return
end
local selected = not selectFirst and modList[controls.modSelect.selIndex] or nil
if stat then
if sortOption.stat then
local slotName = self:GetComparisonSlotNameForItem(self.displayItem)
local calcFunc = self.build.calcsTab:GetMiscCalculator()
local useFullDPS = stat == "FullDPS"
sortModList(modList, stat, function(listMod)
return getSortedModValue(self.displayItem, listMod, stat, sortTransforms, calcFunc, slotName, useFullDPS, function(item, sortedMod)
sortModList(modList, sortOption.stat, function(listMod)
return getSortedModValue(self.displayItem, listMod, sortOption, calcFunc, slotName, function(item, sortedMod)
for _, line in ipairs(sortedMod.mod) do
t_insert(item.explicitModLines, { line = checkLineForAllocates(line, self.build.spec.nodes), modTags = sortedMod.mod.modTags, [sortedMod.type] = true })
end
Expand Down Expand Up @@ -3233,7 +3260,7 @@ function ItemsTabClass:AddCustomModifierToDisplayItem()
buildMods(value.sourceId)
controls.modSelect:SetSel(1)
if controls.sort then
applySort(controls.sort.list[controls.sort.selIndex].stat, true)
applySort(controls.sort:GetSelValue(), true)
end
end)
controls.source.enabled = #sourceList > 1
Expand All @@ -3242,7 +3269,7 @@ function ItemsTabClass:AddCustomModifierToDisplayItem()
return sourceList[controls.source.selIndex].sourceId ~= "CUSTOM"
end
controls.sort = new("DropDownControl"):DropDownControl({ "TOPLEFT", nil, "TOPLEFT" }, { 355, 20, 240, 18 }, sortList, function(index, value)
applySort(value.stat, true)
applySort(value, true)
end)
controls.sort.shown = function()
return sourceList[controls.source.selIndex].sourceId ~= "CUSTOM"
Expand Down
Loading