diff --git a/spec/System/TestItemMods_spec.lua b/spec/System/TestItemMods_spec.lua index cc435f3b7c..517c3d65c8 100644 --- a/spec/System/TestItemMods_spec.lua +++ b/spec/System/TestItemMods_spec.lua @@ -7,6 +7,32 @@ describe("TetsItemMods", function() -- newBuild() takes care of resetting everything in setup() end) + it("shows duplicate selected variants in item tooltips when enabled", function() + local item = new("Item", [[ + Rarity: Unique + Mageblood + Utility Belt + Has Alt Variant: true + Selected Variant: 1 + Selected Alt Variant: 1 + Allow Duplicate Variants: true + Variant: Legacy of Amethyst + Implicits: 0 + {variant:1}Legacy of Amethyst + ]]) + local tooltip = new("Tooltip") + + build.itemsTab:AddItemTooltip(tooltip, item) + + local legacyLines = 0 + for _, line in ipairs(tooltip.lines) do + if line.text and line.text:find("Legacy of Amethyst", 1, true) then + legacyLines = legacyLines + 1 + end + end + assert.are.equals(2, legacyLines) + end) + it("aggregates matching ring item rarity lines before applying ring bonus effect", function() build.configTab.input.customMods = "30% increased bonuses gained from left Equipped Ring" build.configTab:BuildModList() diff --git a/spec/System/TestItemParse_spec.lua b/spec/System/TestItemParse_spec.lua index aa281d26b5..fe48536c59 100644 --- a/spec/System/TestItemParse_spec.lua +++ b/spec/System/TestItemParse_spec.lua @@ -85,8 +85,45 @@ describe("TestItemParse", function() --it("Variant name", function() --end) - --it("variant", function() - --end) + it("allows duplicate selected variants when enabled", function() + local item = new("Item", [[ + Rarity: Unique + Mageblood + Utility Belt + Has Alt Variant: true + Has Alt Variant Two: true + Has Alt Variant Three: true + Selected Variant: 1 + Selected Alt Variant: 1 + Selected Alt Variant Two: 2 + Selected Alt Variant Three: 2 + Allow Duplicate Variants: true + Variant: Legacy of Amethyst + Variant: Legacy of Basalt + Implicits: 0 + {variant:1}Legacy of Amethyst + {variant:2}Legacy of Basalt + ]]) + + assert.are.equals(2, item.baseModList:Sum("BASE", nil, "LegacyOfAmethyst")) + assert.are.equals(2, item.baseModList:Sum("BASE", nil, "LegacyOfBasalt")) + end) + + it("does not duplicate selected variants by default", function() + local item = new("Item", [[ + Rarity: Unique + Mageblood + Utility Belt + Has Alt Variant: true + Selected Variant: 1 + Selected Alt Variant: 1 + Variant: Legacy of Amethyst + Implicits: 0 + {variant:1}Legacy of Amethyst + ]]) + + assert.are.equals(1, item.baseModList:Sum("BASE", nil, "LegacyOfAmethyst")) + end) --TODO: Alt variants for POB2 --it("Alt Variant", function() diff --git a/src/Classes/Item.lua b/src/Classes/Item.lua index 7cad4063a6..423f4769a3 100644 --- a/src/Classes/Item.lua +++ b/src/Classes/Item.lua @@ -630,6 +630,8 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.variantAlt4 = specToNumber(specVal) elseif specName == "Selected Alt Variant Five" then self.variantAlt5 = specToNumber(specVal) + elseif specName == "Allow Duplicate Variants" then + self.allowDuplicateVariants = specVal == "true" elseif specName == "Has Variants" or specName == "Selected Variants" then -- Need to skip this line for backwards compatibility -- with builds that used an old Watcher's Eye implementation @@ -1462,6 +1464,9 @@ function ItemClass:BuildRaw() t_insert(rawLines, "Has Alt Variant Five: true") t_insert(rawLines, "Selected Alt Variant Five: " .. self.variantAlt5) end + if self.allowDuplicateVariants then + t_insert(rawLines, "Allow Duplicate Variants: true") + end end if self.quality then t_insert(rawLines, "Quality: " .. self.quality) @@ -1683,6 +1688,24 @@ function ItemClass:CheckModLineVariant(modLine) or (self.hasAltVariant5 and modLine.variantList[self.variantAlt5]) end +function ItemClass:GetModLineVariantCount(modLine) + if not self.allowDuplicateVariants or not modLine.variantList then + return self:CheckModLineVariant(modLine) and 1 or 0 + end + + -- Mageblood can intentionally select the same variant more than once. + local variantList = modLine.variantList + local count = variantList[self.variant] and 1 or 0 + for i = 1, 5 do + local suffix = i == 1 and "" or i + local variant = self["variantAlt" .. suffix] + if self["hasAltVariant" .. suffix] and variant and variantList[variant] then + count = count + 1 + end + end + return count +end + -- Return the name of the slot this item is equipped in function ItemClass:GetPrimarySlot() if self.base.weapon or self.base.type == "Wand" or self.base.type == "Sceptre" or self.base.type == "Staff" then @@ -2027,7 +2050,8 @@ function ItemClass:BuildModList() end end local function processModLine(modLine) - if self:CheckModLineVariant(modLine) then + local variantCount = self:GetModLineVariantCount(modLine) + if variantCount > 0 then -- special section for variant over-ride of pre-modifier item parameters if modLine.line:find("Requires Class") then self.classRestriction = modLine.line:gsub("{variant:([%d,]+)}", ""):match("Requires Class (.+)") @@ -2054,8 +2078,9 @@ function ItemClass:BuildModList() end end for _, mod in ipairs(modLine.modList) do - mod = modLib.setSource(mod, self.modSource) - baseList:AddMod(mod) + for _ = 1, variantCount do + baseList:AddMod(modLib.setSource(mod, self.modSource)) + end end if modLine.modTags and #modLine.modTags > 0 then self.hasModTags = true diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index 3bd2d79867..d3ffb571c6 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -3534,8 +3534,10 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode, maxWidth) for _, modList in ipairs{item.enchantModLines, item.runeModLines, item.implicitModLines, item.explicitModLines} do if modList[1] then for _, modLine in ipairs(modList) do - if item:CheckModLineVariant(modLine) then + local variantCount = item:GetModLineVariantCount(modLine) + if variantCount > 0 then local bg = modLine.desecrated and "HoverModBgAbyss" or nil + local formattedModLine if scale ~= 1 then local copyModLine = copyTable(modLine) local modsList = copyTable(modLine.modList) @@ -3556,9 +3558,12 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode, maxWidth) copyModLine.line = copyModLine.line:gsub("%d*%.?%d+", math.abs(newValue), 1) -- Only scale first number in line end end - tooltip:AddLine(fontSizeBig, itemLib.formatModLine(copyModLine, dbMode), "FONTIN SC", bg) + formattedModLine = itemLib.formatModLine(copyModLine, dbMode) else - tooltip:AddLine(fontSizeBig, itemLib.formatModLine(modLine, dbMode), "FONTIN SC", bg) + formattedModLine = itemLib.formatModLine(modLine, dbMode) + end + for _ = 1, variantCount do + tooltip:AddLine(fontSizeBig, formattedModLine, "FONTIN SC", bg) end -- Show mods from granted Notables diff --git a/src/Data/Uniques/belt.lua b/src/Data/Uniques/belt.lua index 3cf73e6e0b..cb7b88f03d 100644 --- a/src/Data/Uniques/belt.lua +++ b/src/Data/Uniques/belt.lua @@ -169,6 +169,7 @@ Selected Variant: 1 Selected Alt Variant: 2 Selected Alt Variant Two: 3 Selected Alt Variant Three: 4 +Allow Duplicate Variants: true Variant: Legacy of Amethyst Variant: Legacy of Basalt Variant: Legacy of Bismuth diff --git a/src/Export/Uniques/belt.lua b/src/Export/Uniques/belt.lua index ce91dac0a9..d443ad8b62 100644 --- a/src/Export/Uniques/belt.lua +++ b/src/Export/Uniques/belt.lua @@ -169,6 +169,7 @@ Selected Variant: 1 Selected Alt Variant: 2 Selected Alt Variant Two: 3 Selected Alt Variant Three: 4 +Allow Duplicate Variants: true Variant: Legacy of Amethyst Variant: Legacy of Basalt Variant: Legacy of Bismuth