Skip to content

Cull Item Variants on save, export and item copy #5662

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: dev
Choose a base branch
from
Draft
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
205 changes: 166 additions & 39 deletions src/Classes/Item.lua
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ function ItemClass:ParseRaw(raw)
local deferJewelRadiusIndexAssignment
local gameModeStage = "FINDIMPLICIT"
local foundExplicit, foundImplicit
local culledVariantsTemplate = nil

local function processInfluenceLine(line)
for i, curInfluenceInfo in ipairs(influenceInfo) do
Expand Down Expand Up @@ -245,12 +246,17 @@ function ItemClass:ParseRaw(raw)
if not self.variantList then
self.variantList = { }
end
-- This has to be kept for backwards compatibility
local ver, name = specVal:match("{([%w_]+)}(.+)")
if ver then
t_insert(self.variantList, name)
if specVal == "RebuildCulledVariants" and main.uniqueDB.list[self.name..", "..self.baseName] then
culledVariantsTemplate = main.uniqueDB.list[self.name..", "..self.baseName]
self.variantList = copyTable(culledVariantsTemplate.variantList)
else
t_insert(self.variantList, specVal)
-- This has to be kept for backwards compatibility
local ver, name = specVal:match("{([%w_]+)}(.+)")
if ver then
t_insert(self.variantList, name)
else
t_insert(self.variantList, specVal)
end
end
elseif specName == "Talisman Tier" then
self.talismanTier = tonumber(specVal)
Expand Down Expand Up @@ -295,16 +301,47 @@ function ItemClass:ParseRaw(raw)
self.hasAltVariant5 = true
elseif specName == "Selected Variant" then
self.variant = tonumber(specVal)
elseif specName == "Selected Alt Variant" then
self.variantAlt = tonumber(specVal)
elseif specName == "Selected Alt Variant Two" then
self.variantAlt2 = tonumber(specVal)
elseif specName == "Selected Alt Variant Three" then
self.variantAlt3 = tonumber(specVal)
elseif specName == "Selected Alt Variant Four" then
self.variantAlt4 = tonumber(specVal)
elseif specName == "Selected Alt Variant Five" then
self.variantAlt5 = tonumber(specVal)
elseif specName == "Selected Variant Name" then
-- item variants have changed, find same variant
if self.variantList[self.variant] ~= specVal then
for i, variantName in ipairs(self.variantList) do
if variantName == specVal then
self.variant = i
break
end
end
end
elseif specName == "Selected Variant Last Legacy Variant" then
local curVariantName = self.variantList[self.variant]
while self.variant ~= 1 and self.variantList[self.variant - 1] ~= specVal and self.variantList[self.variant - 1]:match(curVariantName) do
self.variant = self.variant - 1
end
elseif specName:match("Selected Alt Variant") then
local altVariantNumber = ""
for _, AltVariant in ipairs({{"2", " Two"}, {"3", " Three"}, {"4", " Four"}, {"5", " Five"}}) do
if specName:match(AltVariant[2]) then
altVariantNumber = AltVariant[1]
break
end
end
if specName:match("Name") then
-- item variants have changed, find same variant
if self.variantList[self["variantAlt"..altVariantNumber]] ~= specVal then
for i, variantName in ipairs(self.variantList) do
if variantName == specVal then
self["variantAlt"..altVariantNumber] = i
break
end
end
end
elseif specName:match("Last Legacy Variant") then
local curVariantName = self.variantList[self["variantAlt"..altVariantNumber]]
while self["variantAlt"..altVariantNumber] ~= 1 and self.variantList[self["variantAlt"..altVariantNumber] - 1] ~= specVal and self.variantList[self["variantAlt"..altVariantNumber] - 1]:match(curVariantName) do
self["variantAlt"..altVariantNumber] = self["variantAlt"..altVariantNumber] - 1
end
else
self["variantAlt"..altVariantNumber] = tonumber(specVal)
end
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
Expand Down Expand Up @@ -589,6 +626,49 @@ function ItemClass:ParseRaw(raw)
self.requirements.level = self.base.req.level
end
end
-- rebuild mods list from template item
if culledVariantsTemplate then
if #self.implicitModLines > 0 then
local replacerModLine = self.implicitModLines
self.implicitModLines = copyTable(culledVariantsTemplate.implicitModLines)
for _, modLine in ipairs(replacerModLine) do
local modLineFound = false
for _, modLine2 in ipairs(self.implicitModLines) do
if modLine.line == modLine2.line then
modLine2.range = modLine.range
modLine2.valueScalar = modLine.valueScalar
modLineFound = true
break
end
end
if not modLineFound then
t_insert(self.implicitModLines, modLine)
end
end
else
self.implicitModLines = copyTable(culledVariantsTemplate.implicitModLines)
end
if #self.explicitModLines > 0 then
local replacerModLine = self.explicitModLines
self.explicitModLines = copyTable(culledVariantsTemplate.explicitModLines)
for _, modLine in ipairs(replacerModLine) do
local modLineFound = false
for _, modLine2 in ipairs(self.explicitModLines) do
if modLine.line == modLine2.line then
modLine2.range = modLine.range
modLine2.valueScalar = modLine.valueScalar
modLineFound = true
break
end
end
if not modLineFound then
t_insert(self.explicitModLines, modLine)
end
end
else
self.explicitModLines = copyTable(culledVariantsTemplate.explicitModLines)
end
end
self.affixLimit = 0
if self.crafted then
if not self.affixes then
Expand Down Expand Up @@ -711,8 +791,9 @@ function ItemClass:CheckIfModIsDelve(mod)
end


function ItemClass:BuildRaw()
function ItemClass:BuildRaw(cullVariants)
local rawLines = { }
local cullVariantsTemplate = nil
t_insert(rawLines, "Rarity: " .. self.rarity)
if self.title then
t_insert(rawLines, self.title)
Expand Down Expand Up @@ -773,6 +854,41 @@ function ItemClass:BuildRaw()
if self.itemLevel then
t_insert(rawLines, "Item Level: " .. self.itemLevel)
end
local function templateItemMatchesCurrent()
if not main.uniqueDB.list[self.title..", "..self.baseName] or (#self.variantList ~= #main.uniqueDB.list[self.title..", "..self.baseName].variantList) then
return false
end
local templateItem = main.uniqueDB.list[self.title..", "..self.baseName]
for _, modLineType in ipairs({"enchant", "scourge", "classRequirement", "implicit", "explicit"}) do
if #self[modLineType.."ModLines"] ~= #templateItem[modLineType.."ModLines"] then
return false
end
for i, modLine in ipairs(self[modLineType.."ModLines"]) do
if templateItem[modLineType.."ModLines"][i].line ~= modLine.line then
return false
end
end
end
cullVariantsTemplate = templateItem
return true
end
local function variantValid(variantList)
for varId in pairs(variantList) do
if self.variant == varId then
return true
end
for _, AltVariant in ipairs({"", "2", "3", "4", "5"}) do
if self["hasAltVariant"..AltVariant] then
if self["variantAlt"..AltVariant] == varId then
return true
end
else
break
end
end
end
return false
end
local function writeModLine(modLine)
local line = modLine.line
if modLine.range and line:match("%(%-?[%d%.]+%-%-?[%d%.]+%)") then
Expand Down Expand Up @@ -804,6 +920,11 @@ function ItemClass:BuildRaw()
for varId in pairs(modLine.variantList) do
varSpec = (varSpec and varSpec .. "," or "") .. varId
end
if cullVariantsTemplate then
if not variantValid(modLine.variantList) and ((not modLine.range) or modLine.range == main.defaultItemAffixQuality) then
return
end
end
line = "{variant:" .. varSpec .. "}" .. line
end
if modLine.modTags and #modLine.modTags > 0 then
Expand All @@ -812,33 +933,39 @@ function ItemClass:BuildRaw()
t_insert(rawLines, line)
end
if self.variantList then
for _, variantName in ipairs(self.variantList) do
t_insert(rawLines, "Variant: " .. variantName)
if cullVariants and templateItemMatchesCurrent() then
t_insert(rawLines, "Variant: " .. "RebuildCulledVariants")
else
for _, variantName in ipairs(self.variantList) do
t_insert(rawLines, "Variant: " .. variantName)
end
end
t_insert(rawLines, "Selected Variant: " .. self.variant)
if cullVariantsTemplate and self.variantList[#self.variantList] ~= "Current" then
t_insert(rawLines, "Selected Variant Name: " .. self.variantList[self.variant])
if not self.variantList[self.variant]:match(" %(Pre ") then
local lastVariant = self.variant ~= 1 and (self.variantList[self.variant - 1]:match(self.variantList[self.variant]) and self.variantList[self.variant - 1] or self.variantList[self.variant]) or self.variantList[self.variant]
t_insert(rawLines, "Selected Variant Last Legacy Variant: " .. lastVariant)
end
end

for _, baseLine in pairs(self.baseLines) do
writeModLine(baseLine)
end
if self.hasAltVariant then
t_insert(rawLines, "Has Alt Variant: true")
t_insert(rawLines, "Selected Alt Variant: " .. self.variantAlt)
end
if self.hasAltVariant2 then
t_insert(rawLines, "Has Alt Variant Two: true")
t_insert(rawLines, "Selected Alt Variant Two: " .. self.variantAlt2)
end
if self.hasAltVariant3 then
t_insert(rawLines, "Has Alt Variant Three: true")
t_insert(rawLines, "Selected Alt Variant Three: " .. self.variantAlt3)
end
if self.hasAltVariant4 then
t_insert(rawLines, "Has Alt Variant Four: true")
t_insert(rawLines, "Selected Alt Variant Four: " .. self.variantAlt4)
end
if self.hasAltVariant5 then
t_insert(rawLines, "Has Alt Variant Five: true")
t_insert(rawLines, "Selected Alt Variant Five: " .. self.variantAlt5)
for _, AltVariant in ipairs({{"", ""}, {"2", " Two"}, {"3", " Three"}, {"4", " Four"}, {"5", " Five"}}) do
if self["hasAltVariant" .. AltVariant[1]] then
t_insert(rawLines, "Has Alt Variant" .. AltVariant[2] .. ": true")
t_insert(rawLines, "Selected Alt Variant" .. AltVariant[2] .. ": " .. self["variantAlt" .. AltVariant[1]])
if cullVariantsTemplate and self.variantList[#self.variantList] ~= "Current" then
t_insert(rawLines, "Selected Alt Variant" .. AltVariant[2] .. " Name: " .. self.variantList[self["variantAlt" .. AltVariant[1]]])
if not self.variantList[self["variantAlt" .. AltVariant[1]]]:match(" %(Pre ") then
local lastVariant = self["variantAlt" .. AltVariant[1]] ~= 1 and (self.variantList[self["variantAlt" .. AltVariant[1]] - 1]:match(self.variantList[self["variantAlt" .. AltVariant[1]]]) and self.variantList[self["variantAlt" .. AltVariant[1]] - 1] or self.variantList[self["variantAlt" .. AltVariant[1]]]) or self.variantList[self["variantAlt" .. AltVariant[1]]]
t_insert(rawLines, "Selected Alt Variant" .. AltVariant[2] .. " Last Legacy Variant: " .. lastVariant)
end
end
else
break
end
end
end
if self.quality then
Expand Down Expand Up @@ -894,8 +1021,8 @@ function ItemClass:BuildRaw()
return table.concat(rawLines, "\n")
end

function ItemClass:BuildAndParseRaw()
local raw = self:BuildRaw()
function ItemClass:BuildAndParseRaw(cullVariants)
local raw = self:BuildRaw(cullVariants)
self:ParseRaw(raw)
end

Expand Down
2 changes: 1 addition & 1 deletion src/Classes/ItemListControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ end

function ItemListClass:OnSelCopy(index, itemId)
local item = self.itemsTab.items[itemId]
Copy(item:BuildRaw():gsub("\n", "\r\n"))
Copy(item:BuildRaw(true):gsub("\n", "\r\n"))
end

function ItemListClass:OnSelDelete(index, itemId)
Expand Down
27 changes: 1 addition & 26 deletions src/Classes/ItemsTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -969,33 +969,8 @@ function ItemsTabClass:Save(xml)
variantAlt5 = item.variantAlt5 and tostring(item.variantAlt5)
}
}
item:BuildAndParseRaw()
item:BuildAndParseRaw(true)
t_insert(child, item.raw)
local id = #item.buffModLines + 1
for _, modLine in ipairs(item.enchantModLines) do
if modLine.range then
t_insert(child, { elem = "ModRange", attrib = { id = tostring(id), range = tostring(modLine.range) } })
end
id = id + 1
end
for _, modLine in ipairs(item.scourgeModLines) do
if modLine.range then
t_insert(child, { elem = "ModRange", attrib = { id = tostring(id), range = tostring(modLine.range) } })
end
id = id + 1
end
for _, modLine in ipairs(item.implicitModLines) do
if modLine.range then
t_insert(child, { elem = "ModRange", attrib = { id = tostring(id), range = tostring(modLine.range) } })
end
id = id + 1
end
for _, modLine in ipairs(item.explicitModLines) do
if modLine.range then
t_insert(child, { elem = "ModRange", attrib = { id = tostring(id), range = tostring(modLine.range) } })
end
id = id + 1
end
t_insert(xml, child)
end
for _, itemSetId in ipairs(self.itemSetOrderList) do
Expand Down