From d178bedc6e60dbea6725aa0e5f57ddb39ff92053 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Sun, 26 Jul 2026 23:45:48 +0300 Subject: [PATCH 1/8] Add support for 3.29 vestigial and intangibility parsing --- src/Classes/Item.lua | 11 ++++++++++- src/Classes/ItemsTab.lua | 7 ++++++- src/Data/Global.lua | 4 +++- src/Modules/ItemTools.lua | 2 +- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/Classes/Item.lua b/src/Classes/Item.lua index 67476cf1f8c..41fb24d6805 100644 --- a/src/Classes/Item.lua +++ b/src/Classes/Item.lua @@ -100,6 +100,7 @@ local lineFlags = { -- in poe2. this is currently only added as a hack for cane of kulemak and -- should be added based on mod tags after matching a mod in the future ["unveiled"] = true, + ["vestigial"] = true, } -- Special function to store unique instances of modifier on specific item slots @@ -690,6 +691,8 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) end elseif specName == "CatalystQuality" then self.catalystQuality = specToNumber(specVal) + elseif specName == "Intangibility" then + self.intangibility = specToNumber(specVal) elseif specName == "Note" then self.note = specVal elseif specName == "Str" or specName == "Strength" or specName == "Dex" or specName == "Dexterity" or @@ -791,7 +794,7 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.name = self.name:gsub(" %(.+%)","") end if not baseName then - baseName = line:gsub("^Superior ", ""):gsub("^Synthesised ","") + baseName = line:gsub("^Superior ", ""):gsub("^Synthesised ", ""):gsub("^Vestigial ", "") end if baseName == "Two-Toned Boots" then baseName = "Two-Toned Boots (Armour/Energy Shield)" @@ -1479,6 +1482,9 @@ function ItemClass:BuildRaw() end end end + if self.intangibility then + t_insert(rawLines, string.format("Intangibility: %d%%", self.intangibility)) + end if self.uniqueID then t_insert(rawLines, "Unique ID: " .. self.uniqueID) end @@ -1574,6 +1580,9 @@ function ItemClass:BuildRaw() if modLine.unscalable then line = "{unscalable}" .. line end + if modLine.vestigial then + line = "{vestigial}" .. line + end if modLine.variantList then local varSpec for varId in pairs(modLine.variantList) do diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index 7171ea2db24..634ae3e625d 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -4272,7 +4272,7 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode, maxWidth) end end end - + if item.catalyst and item.catalyst > 0 and item.catalyst <= #catalystQualityFormat and item.catalystQuality and item.catalystQuality > 0 then tooltip:AddLine(fontSizeBig, s_format(catalystQualityFormat[item.catalyst], item.catalystQuality), "FONTIN SC") tooltip:AddSeparator(10) @@ -4314,6 +4314,11 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode, maxWidth) tooltip:AddSeparator(10) end + if item.intangibility then + tooltip:AddLine(fontSizeBig, colorCodes.INTANGIBILITY .. s_format("Intangibility: ^7%d%%", item.intangibility), "FONTIN SC") + tooltip:AddSeparator(10) + end + -- Requirements self.build:AddRequirementsToTooltip(tooltip, item.requirements.level, item.requirements.strMod, item.requirements.dexMod, item.requirements.intMod, diff --git a/src/Data/Global.lua b/src/Data/Global.lua index 7a07f9a8e4a..b33de85d79e 100644 --- a/src/Data/Global.lua +++ b/src/Data/Global.lua @@ -57,7 +57,9 @@ colorCodes = { SAPBG = "^x261500", SCOURGE = "^xFF6E25", CRUCIBLE = "^xFFA500", - SPLITPERSONALITY = "^xFFD62A" + SPLITPERSONALITY = "^xFFD62A", + VESTIGIAL = "^xCBA5F1", + INTANGIBILITY = "^x9BF4BD", } colorCodes.STRENGTH = colorCodes.MARAUDER colorCodes.DEXTERITY = colorCodes.RANGER diff --git a/src/Modules/ItemTools.lua b/src/Modules/ItemTools.lua index 70331dad442..74c996fb9c6 100644 --- a/src/Modules/ItemTools.lua +++ b/src/Modules/ItemTools.lua @@ -362,7 +362,7 @@ function itemLib.formatModLine(modLine, dbMode) line = line .. " ^1'" .. modLine.extra .. "'" end else - colorCode = (modLine.fractured and colorCodes.FRACTURED) or (modLine.crafted and colorCodes.CRAFTED) or (modLine.mutated and colorCodes.MUTATED) or (modLine.scourge and colorCodes.SCOURGE) or (modLine.custom and colorCodes.CUSTOM) or (modLine.crucible and colorCodes.CRUCIBLE) or colorCodes.MAGIC + colorCode = (modLine.fractured and colorCodes.FRACTURED) or (modLine.crafted and colorCodes.CRAFTED) or (modLine.mutated and colorCodes.MUTATED) or (modLine.scourge and colorCodes.SCOURGE) or (modLine.custom and colorCodes.CUSTOM) or (modLine.crucible and colorCodes.CRUCIBLE) or (modLine.vestigial and colorCodes.VESTIGIAL) or colorCodes.MAGIC end return colorCode..line end From 1b484dd3fdfff3e150adf0eb6dc94a723a43f808 Mon Sep 17 00:00:00 2001 From: vaisest <4550061+vaisest@users.noreply.github.com> Date: Wed, 29 Jul 2026 19:23:50 +0300 Subject: [PATCH 2/8] Also remove prefix from import typeline --- src/Classes/ImportTab.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Classes/ImportTab.lua b/src/Classes/ImportTab.lua index 39ffb7d081a..03a2afadc02 100644 --- a/src/Classes/ImportTab.lua +++ b/src/Classes/ImportTab.lua @@ -1460,7 +1460,7 @@ function ImportTabClass:ImportItem(itemData, slotName, ignoreWeaponSwap) item.rarity = rarityMap[itemData.frameType] if #itemData.name > 0 then item.title = sanitiseText(itemData.name) - item.baseName = sanitiseText(itemData.typeLine):gsub("Synthesised ","") + item.baseName = sanitiseText(itemData.typeLine):gsub("Synthesised ", ""):gsub("^Vestigial ", "") item.name = item.title .. ", " .. item.baseName if item.baseName == "Two-Toned Boots" then -- Hack for Two-Toned Boots From 3448b73a4debe748edda3e70eff170e09f3a933c Mon Sep 17 00:00:00 2001 From: Blitz54 Date: Wed, 29 Jul 2026 23:44:45 -0500 Subject: [PATCH 3/8] Vestigial and Memory Icons --- src/Assets/memoryicon.png | Bin 0 -> 7969 bytes src/Assets/vestigialicon.png | Bin 0 -> 7969 bytes src/Classes/Item.lua | 9 +++++++++ src/Classes/ItemsTab.lua | 11 ++++++++++- src/Classes/Tooltip.lua | 2 ++ src/Data/Global.lua | 3 ++- 6 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 src/Assets/memoryicon.png create mode 100644 src/Assets/vestigialicon.png diff --git a/src/Assets/memoryicon.png b/src/Assets/memoryicon.png new file mode 100644 index 0000000000000000000000000000000000000000..bae7de0e5d6322ced2bce9cb6ee0d4b333d56590 GIT binary patch literal 7969 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 oe#w{+kv;sWfNz=jZ@pvhJHOn& Date: Fri, 31 Jul 2026 23:07:57 -0500 Subject: [PATCH 4/8] Import memory and vestigial info --- src/Assets/intangibilitybg.png | Bin 0 -> 79140 bytes src/Assets/memorybg.png | Bin 0 -> 74313 bytes src/Classes/ImportTab.lua | 24 ++++--- src/Classes/Item.lua | 26 +++---- src/Classes/ItemsTab.lua | 125 +++++++++++++++++---------------- src/Classes/Tooltip.lua | 52 +++++++++++--- 6 files changed, 131 insertions(+), 96 deletions(-) create mode 100644 src/Assets/intangibilitybg.png create mode 100644 src/Assets/memorybg.png diff --git a/src/Assets/intangibilitybg.png b/src/Assets/intangibilitybg.png new file mode 100644 index 0000000000000000000000000000000000000000..ced3b1a655acca9c393d00ff5b2e50e8d527eb51 GIT binary patch literal 79140 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 literal 0 HcmV?d00001 diff --git a/src/Assets/memorybg.png b/src/Assets/memorybg.png new file mode 100644 index 0000000000000000000000000000000000000000..deea214c795a1577b6be8c1ad5e0903be15723c8 GIT binary patch literal 74313 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 ZwSWH~{ 5 and self.build.Act < 11 then resistancePenaltyIndex = 2 elseif self.build.Act > 10 then resistancePenaltyIndex = 3 end end end self.build.configTab.varControls["resistancePenalty"]:SetSel(resistancePenaltyIndex) - + local function setSelByVal(dropdown, val) for i, v in ipairs(dropdown.list) do if v.val == val then @@ -1436,7 +1436,7 @@ function ImportTabClass:ImportItemsAndSkills(charData, clearItems, clearSkills, end local rarityMap = { [0] = "NORMAL", "MAGIC", "RARE", "UNIQUE", [9] = "RELIC", [10] = "RELIC" } -local slotMap = { ["Weapon"] = "Weapon 1", ["Offhand"] = "Weapon 2", ["Weapon2"] = "Weapon 1 Swap", ["Offhand2"] = "Weapon 2 Swap", ["Helm"] = "Helmet", ["BodyArmour"] = "Body Armour", ["Gloves"] = "Gloves", ["Boots"] = "Boots", +local slotMap = { ["Weapon"] = "Weapon 1", ["Offhand"] = "Weapon 2", ["Weapon2"] = "Weapon 1 Swap", ["Offhand2"] = "Weapon 2 Swap", ["Helm"] = "Helmet", ["BodyArmour"] = "Body Armour", ["Gloves"] = "Gloves", ["Boots"] = "Boots", ["Amulet"] = "Amulet", ["Ring"] = "Ring 1", ["Ring2"] = "Ring 2", ["Ring3"] = "Ring 3", ["Belt"] = "Belt", ["BrequelGrafts"] = "Graft 1", ["BrequelGrafts2"] = "Graft 2", } function ImportTabClass:ImportItem(itemData, slotName, ignoreWeaponSwap) @@ -1569,6 +1569,10 @@ function ImportTabClass:ImportItem(itemData, slotName, ignoreWeaponSwap) item.baseName = "Two-Toned Boots (Evasion/Energy Shield)" item.base = self.build.data.itemBases[item.baseName] end + elseif property.name:find("Intangibility") then + item.intangibility = tonumber(property.values[1][1]:match("%d+")) + elseif property.name == "Memory Strands" then + item.memoryStrands = tonumber(property.values[1][1]) end if property.name == "Energy Shield" or property.name == "Ward" or property.name == "Armour" or property.name == "Evasion Rating" then item.armourData = item.armourData or { } @@ -1766,7 +1770,7 @@ function ImportTabClass:ImportSocketedItems(item, socketedItems, slotName) local normalizedBasename = sanitiseText(socketedItem.typeLine) local gemId = self.build.data.gemForBaseName[normalizedBasename:lower()] if socketedItem.hybrid then - -- Used by transfigured gems and dual-skill gems (currently just Stormbind) + -- Used by transfigured gems and dual-skill gems (currently just Stormbind) normalizedBasename = sanitiseText(socketedItem.hybrid.baseTypeName) gemId = self.build.data.gemForBaseName[normalizedBasename:lower()] if gemId and socketedItem.hybrid.isVaalGem then diff --git a/src/Classes/Item.lua b/src/Classes/Item.lua index aec43ef6cc5..7f2b91ad8ae 100644 --- a/src/Classes/Item.lua +++ b/src/Classes/Item.lua @@ -66,7 +66,7 @@ local influenceInfo = itemLib.influenceInfo.all local ItemClass = newClass("Item", function(self, raw, rarity, highQuality) if raw then self:ParseRaw(sanitiseText(raw), rarity, highQuality) - end + end end) -- Reset all influence keys to false @@ -414,7 +414,7 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) local linePrefix = "" local linePostfix = "" - while self.rawLines[l] do + while self.rawLines[l] do local line = self.rawLines[l] if line == "Veiled Prefix" or line == "Veiled Suffix" then self.veiled = true @@ -893,7 +893,7 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.pendingAffixList = { pendingAffix } break end - end + end end end -- Use rolling Delta/Range in case one range is 1-3 and another is 1-100 so we get the finest precision possible @@ -918,7 +918,7 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) -- Use rolling Delta/Range in case one range is 1-3 and another is 1-100 so we get the finest precision possible local bestPrecisionDelta = -1 local bestPrecisionRange = -1 - + -- Replace non-number ranges as unsupported line = line:gsub("(%a+)%([%a%s]+%-[%a%s]+%)", "%1") @@ -1185,7 +1185,7 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) end self.affixLimit = 0 if self.crafted then - if not self.affixes then + if not self.affixes then self.crafted = false elseif self.rarity == "MAGIC" then if self.prefixes.limit or self.suffixes.limit then @@ -1388,7 +1388,7 @@ function ItemClass:NormaliseQuality() elseif not self.uniqueID and not self.corrupted and not self.split and not self.mirrored and self.quality < 20 then self.quality = 20 end - end + end end function ItemClass:GetModSpawnWeight(mod, includeTags, excludeTags) @@ -1492,7 +1492,7 @@ function ItemClass:BuildRaw() t_insert(rawLines, string.format("Intangibility: %d%%", self.intangibility)) end if self.memoryStrands then - t_insert(rawLines, string.format("Memory Strands: %d%%", self.memoryStrands)) + t_insert(rawLines, string.format("Memory Strands: %d", self.memoryStrands)) end if self.uniqueID then t_insert(rawLines, "Unique ID: " .. self.uniqueID) @@ -1615,7 +1615,7 @@ function ItemClass:BuildRaw() if baseLine.variantList then writeModLine(baseLine) end - end + end if self.hasAltVariant then t_insert(rawLines, "Has Alt Variant: true") t_insert(rawLines, "Selected Alt Variant: " .. self.variantAlt) @@ -1759,7 +1759,7 @@ function ItemClass:Craft() end end statOrder[order] = modLine - end + end end end end @@ -2116,11 +2116,11 @@ function ItemClass:BuildModListForSlotNum(baseList, slotNum) if jewelData.clusterJewelSkill and not self.clusterJewel.skills[jewelData.clusterJewelSkill] then jewelData.clusterJewelSkill = nil end - jewelData.clusterJewelValid = jewelData.clusterJewelKeystone - or ((jewelData.clusterJewelSkill or jewelData.clusterJewelSmallsAreNothingness) and jewelData.clusterJewelNodeCount) + jewelData.clusterJewelValid = jewelData.clusterJewelKeystone + or ((jewelData.clusterJewelSkill or jewelData.clusterJewelSmallsAreNothingness) and jewelData.clusterJewelNodeCount) or (jewelData.clusterJewelSocketCountOverride and jewelData.clusterJewelNothingnessCount) end - end + end return { unpack(modList) } end @@ -2248,7 +2248,7 @@ function ItemClass:BuildModList() -- Force the socket count to be equal to the stated number self.selectableSocketCount = socketCount local group = 0 - for i = 1, m_max(socketCount, #self.sockets) do + for i = 1, m_max(socketCount, #self.sockets) do if i > socketCount then self.sockets[i] = nil elseif not self.sockets[i] then diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index ed0a73a7d7a..deb77a82a06 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -17,7 +17,7 @@ local m_modf = math.modf local buySimilar = LoadModule("Classes/CompareBuySimilar") local gemTooltip = LoadModule("Classes/GemTooltip") -local rarityDropList = { +local rarityDropList = { { label = colorCodes.NORMAL.."Normal", rarity = "NORMAL" }, { label = colorCodes.MAGIC.."Magic", rarity = "MAGIC" }, { label = colorCodes.RARE.."Rare", rarity = "RARE" }, @@ -83,7 +83,7 @@ local ItemsTabClass = newClass("ItemsTab", "UndoHandler", "ControlHost", "Contro self.Control() self.build = build - + self.socketViewer = new("PassiveTreeView") self.items = { } @@ -153,7 +153,7 @@ local ItemsTabClass = newClass("ItemsTab", "UndoHandler", "ControlHost", "Contro return self.activeItemSet.useSecondWeaponSet end for i = 1, 6 do - local abyssal = new("ItemSlotControl", {"TOPLEFT",prevSlot,"BOTTOMLEFT"}, 0, 2, self, slotName.." Swap Abyssal Socket "..i, "Abyssal #"..i) + local abyssal = new("ItemSlotControl", {"TOPLEFT",prevSlot,"BOTTOMLEFT"}, 0, 2, self, slotName.." Swap Abyssal Socket "..i, "Abyssal #"..i) addSlot(abyssal) abyssal.parentSlot = swapSlot abyssal.weaponSet = 2 @@ -174,7 +174,7 @@ local ItemsTabClass = newClass("ItemsTab", "UndoHandler", "ControlHost", "Contro if slotName == "Weapon 1" or slotName == "Weapon 2" or slotName == "Helmet" or slotName == "Gloves" or slotName == "Body Armour" or slotName == "Boots" or slotName == "Belt" then -- Add Abyssal Socket slots for i = 1, 6 do - local abyssal = new("ItemSlotControl", {"TOPLEFT",prevSlot,"BOTTOMLEFT"}, 0, 2, self, slotName.." Abyssal Socket "..i, "Abyssal #"..i) + local abyssal = new("ItemSlotControl", {"TOPLEFT",prevSlot,"BOTTOMLEFT"}, 0, 2, self, slotName.." Abyssal Socket "..i, "Abyssal #"..i) addSlot(abyssal) abyssal.parentSlot = slot if slotName:match("Weapon") then @@ -298,23 +298,23 @@ local ItemsTabClass = newClass("ItemsTab", "UndoHandler", "ControlHost", "Contro self:CraftItem() end) self.controls.craftDisplayItem.shown = function() - return self.displayItem == nil + return self.displayItem == nil end self.controls.newDisplayItem = new("ButtonControl", {"TOPLEFT",self.controls.craftDisplayItem,"TOPRIGHT"}, {8, 0, 120, 20}, "Create custom...", function() self:EditDisplayItemText() end) - self.controls.displayItemTip = new("LabelControl", {"TOPLEFT",self.controls.craftDisplayItem,"BOTTOMLEFT"}, {0, 8, 100, 16}, + self.controls.displayItemTip = new("LabelControl", {"TOPLEFT",self.controls.craftDisplayItem,"BOTTOMLEFT"}, {0, 8, 100, 16}, [[^7Double-click an item from one of the lists, or copy and paste an item from in game (hover over the item and Ctrl+C) to view or edit -the item and add it to your build. You can -also clone an item within Path of Building by +the item and add it to your build. You can +also clone an item within Path of Building by copying and pasting it with Ctrl+C and Ctrl+V. -You can Control + Click an item to equip it, or -drag it onto the slot. This will also add it to +You can Control + Click an item to equip it, or +drag it onto the slot. This will also add it to your build if it's from the unique/template list. -If there's 2 slots an item can go in, +If there's 2 slots an item can go in, holding Shift will put it in the second.]]) self.controls.sharedItemList = new("SharedItemListControl", {"TOPLEFT",self.controls.craftDisplayItem, "BOTTOMLEFT"}, {0, 232, 340, 308}, self, true) @@ -353,11 +353,11 @@ holding Shift will put it in the second.]]) if not self.controls.displayItemVariant:IsShown() then return 0 end - return (28 + - (self.displayItem.hasAltVariant and 24 or 0) + - (self.displayItem.hasAltVariant2 and 24 or 0) + + return (28 + + (self.displayItem.hasAltVariant and 24 or 0) + + (self.displayItem.hasAltVariant2 and 24 or 0) + (self.displayItem.hasAltVariant3 and 24 or 0) + - (self.displayItem.hasAltVariant4 and 24 or 0) + + (self.displayItem.hasAltVariant4 and 24 or 0) + (self.displayItem.hasAltVariant5 and 24 or 0)) end}) self.controls.displayItemVariant = new("DropDownControl", {"TOPLEFT", self.controls.displayItemSectionVariant,"TOPLEFT"}, {0, 0, 300, 20}, nil, function(index, value) @@ -541,7 +541,7 @@ holding Shift will put it in the second.]]) self.controls.displayItemAddImplicit.shown = function() return self.displayItem and self.displayItem.type ~= "Tincture" and self.displayItem.type ~= "Graft" and (self.displayItem.corruptible or ((self.displayItem.type ~= "Flask" and self.displayItem.type ~= "Jewel") and - (self.displayItem.rarity == "NORMAL" or self.displayItem.rarity == "MAGIC" or self.displayItem.rarity == "RARE"))) and + (self.displayItem.rarity == "NORMAL" or self.displayItem.rarity == "MAGIC" or self.displayItem.rarity == "RARE"))) and not self.displayItem.implicitsCannotBeChanged end @@ -664,7 +664,7 @@ holding Shift will put it in the second.]]) return self.displayItem and self.displayItem.crafted and self.displayItem.clusterJewel end } - + self.controls.displayItemClusterJewelNodeCountLabel = new("LabelControl", {"TOPLEFT",self.controls.displayItemClusterJewelSkill,"BOTTOMLEFT"}, {0, 7, 0, 14}, "^7Added Passives:") self.controls.displayItemClusterJewelNodeCount = new("SliderControl", {"LEFT",self.controls.displayItemClusterJewelNodeCountLabel,"RIGHT"}, {2, 0, 150, 20}, function(val) local divVal = self.controls.displayItemClusterJewelNodeCount:GetDivVal() @@ -721,7 +721,7 @@ holding Shift will put it in the second.]]) end return false end - + if priorMod then if flipRange(priorMod, self.displayItem.affixes[drop.list[drop.selIndex].modList[index]]) then range = 1 - range @@ -859,7 +859,7 @@ holding Shift will put it in the second.]]) else mod = self.displayItem.affixes[modList[1 + round((#modList - 1) * main.defaultItemAffixQuality)]] end - + -- Adding Mod self:AddModComparisonTooltip(tooltip, mod) end @@ -1264,17 +1264,17 @@ function ItemsTabClass:Save(xml) } for _, id in ipairs(self.itemOrderList) do local item = self.items[id] - local child = { - elem = "Item", - attrib = { - id = tostring(id), - variant = item.variant and tostring(item.variant), - variantAlt = item.variantAlt and tostring(item.variantAlt), + local child = { + elem = "Item", + attrib = { + id = tostring(id), + variant = item.variant and tostring(item.variant), + variantAlt = item.variantAlt and tostring(item.variantAlt), variantAlt2 = item.variantAlt2 and tostring(item.variantAlt2), - variantAlt3 = item.variantAlt3 and tostring(item.variantAlt3), - variantAlt4 = item.variantAlt4 and tostring(item.variantAlt4), + variantAlt3 = item.variantAlt3 and tostring(item.variantAlt3), + variantAlt4 = item.variantAlt4 and tostring(item.variantAlt4), variantAlt5 = item.variantAlt5 and tostring(item.variantAlt5) - } + } } item:BuildAndParseRaw() t_insert(child, item.raw) @@ -1385,9 +1385,9 @@ function ItemsTabClass:Draw(viewPort, inputEvents) end self.x = self.x - self.controls.scrollBarH.offset self.y = self.y - self.controls.scrollBarV.offset - + for _, event in ipairs(inputEvents) do - if event.type == "KeyDown" then + if event.type == "KeyDown" then if event.key == "v" and IsKeyDown("CTRL") then local newItem = Paste() if newItem then @@ -1617,12 +1617,12 @@ function ItemsTabClass:AddItem(item, noAutoEquip, index) end end end - + -- Add it to the list local replacing = self.items[item.id] self.items[item.id] = item item:BuildModList() - + if replacing and (replacing.clusterJewel or item.clusterJewel or replacing.baseName == "Timeless Jewel") then -- We're replacing an existing item, and either the new or old one is a cluster jewel if isValueInTable(self.build.spec.jewels, item.id) then @@ -1752,7 +1752,7 @@ function ItemsTabClass:CopyAnointsAndEldritchImplicits(newItem, copyEldritchImpl return end end - + local modifiableItem = not (newItem.corrupted or newItem.mirrored) if copyEldritchImplicits and isValueInTable(eldritchBaseTypes, newItem.base.type) and isValueInTable(eldritchRarities, newItem.rarity) and (#newItem.implicitModLines == 0 or overwrite) and modifiableItem and (currentItem.cleansing or currentItem.tangle) and currentItem.implicitModLines then @@ -1937,7 +1937,7 @@ function ItemsTabClass:UpdateAffixControls() else self:UpdateAffixControl(self.controls["displayItemAffix"..i], item, "Suffix", "suffixes", i - prefixLimit) end - end + end -- The custom affixes may have had their indexes changed, so the custom control UI is also rebuilt so that it will -- reference the correct affix index. self:UpdateCustomControls() @@ -1963,7 +1963,7 @@ function ItemsTabClass:UpdateAffixControl(control, item, type, outputTable, outp end end end - if item.clusterJewel and item.clusterJewelSkill then + if item.clusterJewel and item.clusterJewelSkill then local skill = item.clusterJewel.skills[item.clusterJewelSkill] if skill then extraTags[skill.tag] = true @@ -2103,7 +2103,7 @@ function ItemsTabClass:UpdateCustomControls() local id = item.id self:CreateDisplayItemFromRaw(item:BuildRaw()) self.displayItem.id = id - end + end i = i + 1 end end @@ -2143,7 +2143,7 @@ end function ItemsTabClass:AddModComparisonTooltip(tooltip, mod) local slotName = self.displayItem:GetPrimarySlot() local newItem = new("Item", self.displayItem:BuildRaw()) - + for _, subMod in ipairs(mod) do t_insert(newItem.explicitModLines, { line = checkLineForAllocates(subMod, self.build.spec.nodes), modTags = mod.modTags, [mod.type] = true }) end @@ -2153,7 +2153,7 @@ function ItemsTabClass:AddModComparisonTooltip(tooltip, mod) local calcFunc = self.build.calcsTab:GetMiscCalculator() local outputBase = calcFunc({ repSlotName = slotName, repItem = self.displayItem }) local outputNew = calcFunc({ repSlotName = slotName, repItem = newItem }) - self.build:AddStatComparesToTooltip(tooltip, outputBase, outputNew, "\nAdding this mod will give: ") + self.build:AddStatComparesToTooltip(tooltip, outputBase, outputNew, "\nAdding this mod will give: ") end -- Returns the first slot in which the given item is equipped @@ -2385,7 +2385,7 @@ function ItemsTabClass:EditDisplayItemText(alsoAddItem) tooltip:AddLine(14, "For Normal and Magic items, the base name must be somewhere in the first line. E.g.:") tooltip:AddLine(14, "Scholar's Platinum Kris of Joy") end - end + end controls.cancel = new("ButtonControl", nil, {45, 470, 80, 20}, "Cancel", function() main:ClosePopup() end) @@ -2396,7 +2396,7 @@ end function ItemsTabClass:EnchantDisplayItem(enchantSlot) self.enchantSlot = enchantSlot or 1 - local controls = { } + local controls = { } local enchantments = self.displayItem.enchantments local haveSkills = true for _, source in ipairs(self.build.data.enchantmentSource) do @@ -2410,7 +2410,7 @@ function ItemsTabClass:EnchantDisplayItem(enchantSlot) if haveSkills then for _, socketGroup in ipairs(self.build.skillsTab.socketGroupList) do for _, gemInstance in ipairs(socketGroup.gemList) do - if gemInstance.gemData then + if gemInstance.gemData then for _, grantedEffect in ipairs(gemInstance.gemData.grantedEffectList) do if not grantedEffect.support and enchantments[grantedEffect.name] then skillsUsed[grantedEffect.name] = true @@ -2713,7 +2713,7 @@ end function ItemsTabClass:AnointDisplayItem(enchantSlot) self.anointEnchantSlot = enchantSlot or 1 - local controls = { } + local controls = { } controls.notableDB = new("NotableDBControl", {"TOPLEFT",nil,"TOPLEFT"}, {10, 60, 360, 360}, self, self.build.spec.tree.nodes, "ANOINT") local function saveLabel() @@ -2742,7 +2742,7 @@ function ItemsTabClass:AnointDisplayItem(enchantSlot) controls.save.tooltipFunc = function(tooltip) tooltip:Clear() self:AppendAnointTooltip(tooltip, controls.notableDB.selValue) - end + end controls.close = new("ButtonControl", {"TOPLEFT", controls.save, "TOPRIGHT" }, {10, 0, 80, 20}, "Cancel", function() main:ClosePopup() end) @@ -3078,7 +3078,7 @@ function ItemsTabClass:CorruptDisplayItem(modType) controls.save.tooltipFunc = function(tooltip) tooltip:Clear() self:AddItemTooltip(tooltip, corruptItem(controls.implicit1.shown), nil, false) - end + end controls.close = new("ButtonControl", { "BOTTOM", nil, "BOTTOM" }, { 45, -4, 80, 20 }, "Cancel", function() main:ClosePopup() end) @@ -3382,11 +3382,11 @@ function ItemsTabClass:AddCustomModifierToDisplayItem() controls.save.tooltipFunc = function(tooltip) tooltip:Clear() self:AddItemTooltip(tooltip, addModifier()) - end + end controls.close = new("ButtonControl", nil, {45, 75, 80, 20}, "Cancel", function() main:ClosePopup() end) - main:OpenPopup(710, 105, "Add Modifier to Item", controls, "save", sourceList[controls.source.selIndex].sourceId == "CUSTOM" and "custom") + main:OpenPopup(710, 105, "Add Modifier to Item", controls, "save", sourceList[controls.source.selIndex].sourceId == "CUSTOM" and "custom") end -- Opens the crucible modifier popup @@ -3859,11 +3859,11 @@ function ItemsTabClass:AddImplicitToDisplayItem() controls.save.tooltipFunc = function(tooltip) tooltip:Clear() self:AddItemTooltip(tooltip, addModifier()) - end + end controls.close = new("ButtonControl", nil, {45, 100, 80, 20}, "Cancel", function() main:ClosePopup() end) - main:OpenPopup(710, 130, "Add Implicit to Item", controls, "save", sourceList[controls.source.selIndex].sourceId == "CUSTOM" and "custom") + main:OpenPopup(710, 130, "Add Implicit to Item", controls, "save", sourceList[controls.source.selIndex].sourceId == "CUSTOM" and "custom") end function ItemsTabClass:AddItemSetTooltip(tooltip, itemSet) @@ -4155,7 +4155,7 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode, maxWidth) end tooltip:AddLine(fontSizeBig, elemLine, "FONTIN SC") tooltip:AddLine(fontSizeBig, s_format("^x7F7F7FElemental DPS: "..colorCodes.MAGIC.."%.1f", weaponData.ElementalDPS), "FONTIN SC") - totalDamageTypes = totalDamageTypes + 1 + totalDamageTypes = totalDamageTypes + 1 end if weaponData.ChaosDPS then tooltip:AddLine(fontSizeBig, s_format("^x7F7F7FChaos Damage: "..colorCodes.CHAOS.."%d-%d "..colorCodes.MAGIC.."(%.1f DPS)", weaponData.ChaosMin, weaponData.ChaosMax, weaponData.ChaosDPS), "FONTIN SC") @@ -4237,7 +4237,7 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode, maxWidth) elseif base.tincture then -- Tincture-specific info local tinctureData = item.tinctureData - + if item.quality and item.quality > 0 then tooltip:AddLine(fontSizeBig, s_format("^x7F7F7FQuality: "..colorCodes.MAGIC.."+%d%%", item.quality), "FONTIN SC") end @@ -4313,24 +4313,25 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode, maxWidth) end tooltip:AddLine(fontSizeBig, "^x7F7F7FSockets: "..line, "FONTIN SC") end - tooltip:AddSeparator(10) if item.talismanTier then tooltip:AddLine(fontSizeBig, "^x7F7F7FTalisman Tier ^xFFFFFF"..item.talismanTier, "FONTIN SC") tooltip:AddSeparator(10) end if item.memoryStrands then - tooltip:AddLine(fontSizeBig, colorCodes.MEMORY .. s_format("Memory Strands: ^7%d%%", item.memoryStrands), "FONTIN SC") - tooltip:AddSeparator(10) + tooltip:AddLine(5, "") + tooltip:AddLine(fontSizeBig, colorCodes.MEMORY .. s_format("Memory Strands: ^7%d", item.memoryStrands), "FONTIN SC", "MemoryBG") + tooltip:AddLine(5, "") end if item.intangibility then - tooltip:AddLine(fontSizeBig, colorCodes.INTANGIBILITY .. s_format("Intangibility: ^7%d%%", item.intangibility), "FONTIN SC") - tooltip:AddSeparator(10) + tooltip:AddLine(5, "") + tooltip:AddLine(fontSizeBig, colorCodes.INTANGIBILITY .. s_format("Intangibility: ^7%d%%", item.intangibility), "FONTIN SC", "IntangibilityBG") + tooltip:AddLine(5, "") end - + tooltip:AddSeparator(10) -- Requirements - self.build:AddRequirementsToTooltip(tooltip, item.requirements.level, - item.requirements.strMod, item.requirements.dexMod, item.requirements.intMod, + self.build:AddRequirementsToTooltip(tooltip, item.requirements.level, + item.requirements.strMod, item.requirements.dexMod, item.requirements.intMod, item.requirements.str or 0, item.requirements.dex or 0, item.requirements.int or 0) -- Modifiers @@ -4792,7 +4793,7 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode, maxWidth) return end - + local slots = {} local isUnique = item.rarity == "UNIQUE" or item.rarity == "RELIC" local currentSameUniqueCount = 0 @@ -4816,7 +4817,7 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode, maxWidth) return end - + -- either the same unique or same base type local function similar(compareItem, sameUnique) -- empty slot @@ -4855,11 +4856,11 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode, maxWidth) return false end table.sort(slots, sortFunc) - + for _, slotEntry in ipairs(slots) do addCompareForSlot(slotEntry.compareSlot, slotEntry.selItem, slotEntry.output) end - + end if launch.devModeAlt then diff --git a/src/Classes/Tooltip.lua b/src/Classes/Tooltip.lua index e177c50f2d3..4ff20dcd743 100644 --- a/src/Classes/Tooltip.lua +++ b/src/Classes/Tooltip.lua @@ -84,7 +84,7 @@ function TooltipClass:CheckForUpdate(...) end end -function TooltipClass:AddLine(size, text, font) +function TooltipClass:AddLine(size, text, font, background) if text then local fontToUse if main.showFlavourText then @@ -92,7 +92,7 @@ function TooltipClass:AddLine(size, text, font) else fontToUse = "VAR" end - for line in s_gmatch(text .. "\n", "([^\n]*)\n") do + for line in s_gmatch(text .. "\n", "([^\n]*)\n") do if line:match("^.*(Equipping)") == "Equipping" or line:match("^.*(Removing)") == "Removing" then t_insert(self.blocks, { height = size + 2}) else @@ -100,10 +100,10 @@ function TooltipClass:AddLine(size, text, font) end if self.maxWidth then for _, wrappedLine in ipairs(main:WrapString(line, size, self.maxWidth - H_PAD)) do - t_insert(self.lines, { size = size, text = wrappedLine, block = #self.blocks, font = fontToUse, center = self.center }) + t_insert(self.lines, { size = size, text = wrappedLine, block = #self.blocks, font = fontToUse, center = self.center, background = background }) end else - t_insert(self.lines, { size = size, text = line, block = #self.blocks, font = fontToUse, center = self.center }) + t_insert(self.lines, { size = size, text = line, block = #self.blocks, font = fontToUse, center = self.center, background = background }) end end end @@ -190,7 +190,7 @@ end function TooltipClass:GetDynamicSize(viewPort) local staticttW, staticttH = self:GetSize() local columns, ttH, _, extraColumnWidth = self:CalculateColumns(0, 0, staticttH, staticttW, viewPort) - + -- ensure extra column width has sensible value extraColumnWidth = (columns > 1 and extraColumnWidth > 0) and extraColumnWidth or staticttW local ttW = staticttW + (m_max(columns - 1, 0) * extraColumnWidth) @@ -294,7 +294,7 @@ function TooltipClass:CalculateColumns(ttY, ttX, ttH, ttW, viewPort) local lineX = lineCentered and (x + ttW / 2) or (x + (H_PAD / 2)) local lineAlign = lineCentered and "CENTER_X" or "LEFT" - t_insert(drawStack, {lineX, y, lineAlign, data.size, font, data.text}) + t_insert(drawStack, {lineX, y, lineAlign, data.size, font, data.text, background = data.background}) y = y + data.size + 2 -- track max width for extra columns @@ -331,7 +331,7 @@ function TooltipClass:CalculateColumns(ttY, ttX, ttH, ttW, viewPort) -- calculate column index (origX is at least x * original widths from start) local colIndex = m_floor((origX - ttX) / ttW) + 1 - + if colIndex > 1 then local oldBaseX = ttX + ttW * (colIndex - 1) local newBaseX = ttX + ttW + extraColumnWidth * (colIndex - 2) -- `- 2` because first column is unchanged @@ -447,7 +447,7 @@ function TooltipClass:Draw(x, y, w, h, viewPort) local newX = m_max(viewPort.x, viewPort.x + viewPort.width - totalDrawWidth) local offsetX = newX - ttX ttX = newX - + for _, line in ipairs(drawStack) do if #line < 6 then -- Text element entries have 6 entries and `x` at `[2]` @@ -565,13 +565,13 @@ function TooltipClass:Draw(x, y, w, h, viewPort) -- Draw lines and images local firstSeparatorSkipped = false - for _, line in ipairs(drawStack) do + for _, line in ipairs(drawStack) do if #line < 6 then local skip = false if line[1] and type(line[1]) == "table" and line[1].isSeparator then -- Only skip first separator for items and skill gems local tooltipType = self.tooltipHeader and tostring(self.tooltipHeader):upper() or "" - if main.showFlavourText and not firstSeparatorSkipped and + if main.showFlavourText and not firstSeparatorSkipped and (tooltipType == "RELIC" or tooltipType == "UNIQUE" or tooltipType == "RARE" or tooltipType == "MAGIC" or tooltipType == "GEM") then firstSeparatorSkipped = true skip = true @@ -596,13 +596,43 @@ function TooltipClass:Draw(x, y, w, h, viewPort) end end else + -- Draw background if specified, used for gem mod lines and desecrated mods on items. + local bg = line.background + if bg then + -- Save current draw color BEFORE drawing background image, otherwise wrapped strings print white text for later lines. + local prevR, prevG, prevB, prevA = GetDrawColor() + + if type(bg) == "string" then + if not self._bgHandles then + self._bgHandles = {} + end + if not self._bgHandles[bg] then + local h = NewImageHandle() + h:Load("Assets/" .. bg .. ".png") + self._bgHandles[bg] = h + end + bg = self._bgHandles[bg] + end + + local x = ttX + local y = line[2] - 5 + local width = ttW - 8 + local height = line[4] + 10 + SetDrawColor(1,1,1,1) + DrawImage(bg, x + 4, y, width, height) + + -- Restore color BEFORE DrawString + SetDrawColor(prevR, prevG, prevB, prevA) + end + + -- Draw text line DrawString(unpack(line)) end end -- Draw borders if type(self.color) == "string" then - SetDrawColor(self.color) + SetDrawColor(self.color) else SetDrawColor(unpack(self.color)) end From 0f80029e112103e8a1cb9a70b0820b2e6e6af553 Mon Sep 17 00:00:00 2001 From: Blitz54 Date: Fri, 31 Jul 2026 23:14:26 -0500 Subject: [PATCH 5/8] fix y offset on title text --- src/Classes/Tooltip.lua | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Classes/Tooltip.lua b/src/Classes/Tooltip.lua index 4ff20dcd743..bb2dbc447cd 100644 --- a/src/Classes/Tooltip.lua +++ b/src/Classes/Tooltip.lua @@ -399,19 +399,19 @@ function TooltipClass:Draw(x, y, w, h, viewPort) Vestigial = "Assets/vestigialicon.png", } local headerConfigs = { - RELIC = {left="Assets/itemsheaderfoilleft.png",middle="Assets/itemsheaderfoilmiddle.png",right="Assets/itemsheaderfoilright.png",height=54,sideWidth=47,middleWidth=52,textYOffset=1,allowInfluenceIcon=true}, - UNIQUE = {left="Assets/itemsheaderuniqueleft.png",middle="Assets/itemsheaderuniquemiddle.png",right="Assets/itemsheaderuniqueright.png",height=54,sideWidth=47,middleWidth=52,textYOffset=1,allowInfluenceIcon=true}, - RARE = {left="Assets/itemsheaderrareleft.png",middle="Assets/itemsheaderraremiddle.png",right="Assets/itemsheaderrareright.png",height=54,sideWidth=47,middleWidth=52,textYOffset=1,allowInfluenceIcon=true}, - MAGIC = {left="Assets/itemsheadermagicleft.png",middle="Assets/itemsheadermagicmiddle.png",right="Assets/itemsheadermagicright.png",height=38,sideWidth=32,middleWidth=32,textYOffset=4,allowInfluenceIcon=true}, - NORMAL = {left="Assets/itemsheaderwhiteleft.png",middle="Assets/itemsheaderwhitemiddle.png",right="Assets/itemsheaderwhiteright.png",height=38,sideWidth=32,middleWidth=32,textYOffset=4,allowInfluenceIcon=true}, - GEM = {left="Assets/itemsheadergemleft.png",middle="Assets/itemsheadergemmiddle.png",right="Assets/itemsheadergemright.png",height=38,sideWidth=33,middleWidth=38,textYOffset=3}, - JEWEL = {left="Assets/jewelpassiveheaderleft.png",middle="Assets/jewelpassiveheadermiddle.png",right="Assets/jewelpassiveheaderright.png",height=38,sideWidth=33,middleWidth=38,textYOffset=3}, - NOTABLE = {left="Assets/notablepassiveheaderleft.png",middle="Assets/notablepassiveheadermiddle.png",right="Assets/notablepassiveheaderright.png",height=38,sideWidth=38,middleWidth=38,textYOffset=3}, - PASSIVE = {left="Assets/normalpassiveheaderleft.png",middle="Assets/normalpassiveheadermiddle.png",right="Assets/normalpassiveheaderright.png",height=38,sideWidth=33,middleWidth=38,textYOffset=3}, - KEYSTONE = {left="Assets/keystonepassiveheaderleft.png",middle="Assets/keystonepassiveheadermiddle.png",right="Assets/keystonepassiveheaderright.png",height=38,sideWidth=33,middleWidth=38,textYOffset=3}, - ASCENDANCY = {left="Assets/ascendancypassiveheaderleft.png",middle="Assets/ascendancypassiveheadermiddle.png",right="Assets/ascendancypassiveheaderright.png",height=38,sideWidth=33,middleWidth=38,textYOffset=3}, - MASTERY = {left="Assets/masteryheaderunallocatedleft.png",middle="Assets/masteryheaderunallocatedmiddle.png",right="Assets/masteryheaderunallocatedright.png",height=38,sideWidth=33,middleWidth=38,textYOffset=3}, - MASTERYALLOC = {left="Assets/masteryheaderallocatedleft.png",middle="Assets/masteryheaderallocatedmiddle.png",right="Assets/masteryheaderallocatedright.png",height=38,sideWidth=33,middleWidth=38,textYOffset=3}, + RELIC = {left="Assets/itemsheaderfoilleft.png",middle="Assets/itemsheaderfoilmiddle.png",right="Assets/itemsheaderfoilright.png",height=54,sideWidth=47,middleWidth=52,textYOffset=3,allowInfluenceIcon=true}, + UNIQUE = {left="Assets/itemsheaderuniqueleft.png",middle="Assets/itemsheaderuniquemiddle.png",right="Assets/itemsheaderuniqueright.png",height=54,sideWidth=47,middleWidth=52,textYOffset=3,allowInfluenceIcon=true}, + RARE = {left="Assets/itemsheaderrareleft.png",middle="Assets/itemsheaderraremiddle.png",right="Assets/itemsheaderrareright.png",height=54,sideWidth=47,middleWidth=52,textYOffset=3,allowInfluenceIcon=true}, + MAGIC = {left="Assets/itemsheadermagicleft.png",middle="Assets/itemsheadermagicmiddle.png",right="Assets/itemsheadermagicright.png",height=38,sideWidth=32,middleWidth=32,textYOffset=6,allowInfluenceIcon=true}, + NORMAL = {left="Assets/itemsheaderwhiteleft.png",middle="Assets/itemsheaderwhitemiddle.png",right="Assets/itemsheaderwhiteright.png",height=38,sideWidth=32,middleWidth=32,textYOffset=6,allowInfluenceIcon=true}, + GEM = {left="Assets/itemsheadergemleft.png",middle="Assets/itemsheadergemmiddle.png",right="Assets/itemsheadergemright.png",height=38,sideWidth=33,middleWidth=38,textYOffset=5}, + JEWEL = {left="Assets/jewelpassiveheaderleft.png",middle="Assets/jewelpassiveheadermiddle.png",right="Assets/jewelpassiveheaderright.png",height=38,sideWidth=33,middleWidth=38,textYOffset=6}, + NOTABLE = {left="Assets/notablepassiveheaderleft.png",middle="Assets/notablepassiveheadermiddle.png",right="Assets/notablepassiveheaderright.png",height=38,sideWidth=38,middleWidth=38,textYOffset=6}, + PASSIVE = {left="Assets/normalpassiveheaderleft.png",middle="Assets/normalpassiveheadermiddle.png",right="Assets/normalpassiveheaderright.png",height=38,sideWidth=33,middleWidth=38,textYOffset=6}, + KEYSTONE = {left="Assets/keystonepassiveheaderleft.png",middle="Assets/keystonepassiveheadermiddle.png",right="Assets/keystonepassiveheaderright.png",height=38,sideWidth=33,middleWidth=38,textYOffset=6}, + ASCENDANCY = {left="Assets/ascendancypassiveheaderleft.png",middle="Assets/ascendancypassiveheadermiddle.png",right="Assets/ascendancypassiveheaderright.png",height=38,sideWidth=33,middleWidth=38,textYOffset=6}, + MASTERY = {left="Assets/masteryheaderunallocatedleft.png",middle="Assets/masteryheaderunallocatedmiddle.png",right="Assets/masteryheaderunallocatedright.png",height=38,sideWidth=33,middleWidth=38,textYOffset=6}, + MASTERYALLOC = {left="Assets/masteryheaderallocatedleft.png",middle="Assets/masteryheaderallocatedmiddle.png",right="Assets/masteryheaderallocatedright.png",height=38,sideWidth=33,middleWidth=38,textYOffset=6}, } -- spell-checker: enable local config From 9577344926ee35eab9334f44c4edbe95d8b0ec11 Mon Sep 17 00:00:00 2001 From: Blitz54 Date: Fri, 31 Jul 2026 23:18:35 -0500 Subject: [PATCH 6/8] Add check for options menu --- src/Classes/ItemsTab.lua | 8 ++++---- src/Classes/Tooltip.lua | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index deb77a82a06..835178b1784 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -4319,14 +4319,14 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode, maxWidth) tooltip:AddSeparator(10) end if item.memoryStrands then - tooltip:AddLine(5, "") + if main.showFlavourText then tooltip:AddLine(5, "") end tooltip:AddLine(fontSizeBig, colorCodes.MEMORY .. s_format("Memory Strands: ^7%d", item.memoryStrands), "FONTIN SC", "MemoryBG") - tooltip:AddLine(5, "") + if main.showFlavourText then tooltip:AddLine(5, "") end end if item.intangibility then - tooltip:AddLine(5, "") + if main.showFlavourText then tooltip:AddLine(5, "") end tooltip:AddLine(fontSizeBig, colorCodes.INTANGIBILITY .. s_format("Intangibility: ^7%d%%", item.intangibility), "FONTIN SC", "IntangibilityBG") - tooltip:AddLine(5, "") + if main.showFlavourText then tooltip:AddLine(5, "") end end tooltip:AddSeparator(10) -- Requirements diff --git a/src/Classes/Tooltip.lua b/src/Classes/Tooltip.lua index bb2dbc447cd..d32ed75f996 100644 --- a/src/Classes/Tooltip.lua +++ b/src/Classes/Tooltip.lua @@ -598,7 +598,7 @@ function TooltipClass:Draw(x, y, w, h, viewPort) else -- Draw background if specified, used for gem mod lines and desecrated mods on items. local bg = line.background - if bg then + if bg and main.showFlavourText then -- Save current draw color BEFORE drawing background image, otherwise wrapped strings print white text for later lines. local prevR, prevG, prevB, prevA = GetDrawColor() From 47208edb427d94b6fbb63b974b61025dda91a10b Mon Sep 17 00:00:00 2001 From: Blitz54 Date: Fri, 31 Jul 2026 23:24:50 -0500 Subject: [PATCH 7/8] Increase blank space width on bg images --- src/Assets/intangibilitybg.png | Bin 79140 -> 115612 bytes src/Assets/memorybg.png | Bin 74313 -> 110798 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/src/Assets/intangibilitybg.png b/src/Assets/intangibilitybg.png index ced3b1a655acca9c393d00ff5b2e50e8d527eb51..c682f48c4333addd4b875eb4459fb09e027d608b 100644 GIT binary patch delta 2121 zcmaKue@q)?7{~8zujQz3e=MbLLndJS6&BM5`D0r&qJtu1LPu~6vk64as&2y!F%tz1q(Q^6&h{un1OB&zhMw3sS@L1*SB<94{@ zooB}T+e7;FufSiNLHNucf1lL=z+IBH>H%>!dWQIm?NX3OE^?&I0Uwnmn6xIWDf;9g znN2(-@4kBTpinyx!hPp#__=Nj8ie#gCHh5ym}KjZC|TjL`xlvv=5bn4y4{K#WHjs| z?lyt=_u3%7{(ELZ4rd_Z>2DXv<%g1RvbutaV-rh+Qj*ZTS4s$c_N+~>MYV>DB4Y{?h!_@BQQ+7!$gUSNxn@Mg-0{3X-hRU)x&6qauq!ufB*btwiKnv(KfZlKq1Km*PygMbKoNJJ0BiT!n7SsgIO*yZU{}P+1h9(7 zKK%Su3&~trO{(AH$&qLQ{Ms{bbUBujOp(FechpjJF+8we1LC-BmO~sz7RS6WdGHBi zx=8~9p~JpB7=-qMVOT88Gp?8q!|xL9Gq4tgacZb?PAjkKA*R;lpelRHe>`d-+cI9o zPSjRTxIWaJm#!zq(&c39iSaP=@d^gd9MDhq#;p^7x?dc@V;UI8A<}euCERt=Vyx-1 z2d%mXXX(y^r(|}0s1}B^;t)$zT1i)81uUh`TMT=d>k|d=->DfMALzSWp%K9JmoCdd>T7wh*$!uik z*>a=s=8suJArs~(eD`y{F#`NTg%zjw45YNWq;qaH)Ge_(v6Yr>*7jFko58@17G6CS z7WTQNZ|uk=eQie`{o;_$2?)y_2({+X^H}VJ-m1lj3brIWlR4yq&FCpA?sz^UZ#0jtTiUWD% z(`!(zRkoKSKhu(l66D=?Ad~l5hbGnYjBWt=!o7%nEtzsm$@H+Rv*CA=Urf`lfKAGK hUfNoPJ~bR&G+Wx!5U=w7M86HV`r5{tu}3;y{|^H6Q_cVY delta 2032 zcmZuyYitx%6rMA4XLe?GTDG#Kv=+Ke!64E=vC(R%(q@Y-&qkUQG?E2>044&)KoC(- zObI^}XD>1mtUN@-5RJ=VZbG!I{?ULMs|Ji{EMmY14W(VT-RqQ|O(k|g@Q0Zo;w^jHl9^w`ocLJ;%@ zIZhaxXlG=vJvKI8i2MDrKb5jldTb7!g62)Wok)yM(lmuhc7|f(hP$SPXqxE7V7i;b z^7U8ug?`a162zY{5t4daSwbKW+)3%0dcN(&O17ij2lH zqkbyGmStPsIAw{vwi|alQGDuzIdilg?HG-YjmgHv51<;+3`(SW#%L;Ody%Lgyf%x| zUS&;HwL~(Rzz;W;8y^`U>+uSdNLV*1Y|sX4$a{$H$Or}BHO^%w__<7G*v%Un85u+f zO=!yp61shB_@8V3I-6zxIg zl?N}1I9;XU(4A8$cDsA7%v>7&lM!fV07m9T&~Tt%#&%jZKVEjVh!)-JGqzL#tt}g1SU76|I`kb`74_Z{NR-{M=@W;8l;eD4bfrO~A+nt^_W;Wn|U zZT+cOl`X)fYlnI5X@GKfSmra=w>enr9m_5bj;vh|xyg}pTc8UeQg?k5y^|_J*ZDN#cps_U z0h1*W?0dK$^ka?Wl|5c&xYKz66(YO}7OTI&xoFaTFo(NaN3zo8vDS7(@%mugg1~Tn^C@V~&IR{6V5(>T+&!V~usSxcGm@OKupTW7{ Y$y=ev->kpT#NJUIZOg+Swnkq57ZK%glK=n! diff --git a/src/Assets/memorybg.png b/src/Assets/memorybg.png index deea214c795a1577b6be8c1ad5e0903be15723c8..ae477c71697720ac4f64e3fb95b48eff25022956 100644 GIT binary patch delta 2495 zcma)8SxggA6rI;T+5ukE;uMWok|Kf&Rk3Q+7}JWN5EMz{f=d*ms04pBQHdhr5~JdW z!;3b=t#SKMBjAnc2SFz;F`^j#LF1N+F>wPz;*z)|z8M@+W@tJe)0xhk`|dgC-uq@A z-osDcSu&24mMpL(r6qA3XDceq4{)5Rj9pLSE$sK({!Qb>jLjo>gog`TK6Xv#I5$_6 zKX*wr;z|y*h@k@NuH2~}4b~hQ@i^GQxBTr+P;bj;QOXQPMj=o1J$5}$!ApV-ime~D z0qmJmgI@(ZZ3&j>n{44Bagty%k@niDUX?N2Ni}0l22eSsV+N|>EU!$b^=rW%nlTge#m zxS(Oy_qbAy3zHRmWP2hF`RwePr%l;BZT4bXUQ3k!uC+YfuFhfAY2R}$>%Mf@} zHeFjkop9P4u+lm~u@GEqPom)4QOFJ*<%i=ouk4v5V47QjsiOkJ){2R-(k&-7IWr|y z2~DXyB=Z#|7vsspjVc2?>wE(I-l_xAAv_hO6qr_Bpd}Lnsuc0nQNrdB!-?AQCfZ(C zPwt;M`d;M=OZV+E4>ovoEF-a6O!#teicto+)jW)=pJNaXm7=0;0|}6gohnJy)CTL= zSVCp1TFa6^3eGT?N?D18P$_5u``K0#bcS|ltjLU!4oWW?EdexM$wK7Zl5H1MHE`>y zTQh($n|&m7H5<;96E+HEePMxJZL7`DC7nX#5F}n2V7KQ^p=K0gy72I>(S$Ip-7s|3 z)3{I@x3}Z5s8UwiWZQp&5FuugDCLIk zddUaME$7OI1xxD5QaKTQU z*H?iRTRaT|zM=@EU$-paHK!bIBE0BA*k=;RdK?`nHklMA2_jq2(5A#^+63ay;1T7W zAVy12!$ro}=N52_wM6nydD0?#lQHXf1Z5zzhu#ZVvKX-^GnLZvX(ZB+h%EnRs5}}e zTI23Xt&xd6t~?^1(F!(6rxChCy>c2)C>_%Hv*+#6-O3uW*rno$$5qVEF5yqE6mI~9 znc+*iQ}Eh6B94|N0qa+`;5ubTST^bcHg@YtPg_1B(;YLQp~_^D(eOl$p1keKqJ4ds1Bp*&C?${WYvFE3dRJ0C;^R;!>|N2#?nA;{x8 zILoW123XYrQujJ(mszX!G(&~90vJ4>2FZAO$f(A*LL-v4{#y4(^;+6t9GIu7(g~%a z2$`uLzajO>4JMD&^Z}MZy?h%+!5c_W9V2j!y~=(y=^p$<(${m_nyHfq*{`DVV{iZx X7i_~vvu}=!QinN5MU^~eQ?C98i0Uz@ From bfdd47ee4de4c855ef396fcda1ef4fd401e1df6d Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Wed, 5 Aug 2026 03:19:07 +1000 Subject: [PATCH 8/8] Remove previous intangibility and memory strand code Also fix the asset path for linux users --- spec/System/TestImport_spec.lua | 5 +++++ spec/System/TestItemParse_spec.lua | 2 ++ src/Classes/ImportTab.lua | 8 +++++--- src/Classes/Item.lua | 5 ----- src/Classes/ItemsTab.lua | 9 ++------- src/Classes/Tooltip.lua | 2 +- 6 files changed, 15 insertions(+), 16 deletions(-) diff --git a/spec/System/TestImport_spec.lua b/spec/System/TestImport_spec.lua index 2ea158148ef..3b483f0db46 100644 --- a/spec/System/TestImport_spec.lua +++ b/spec/System/TestImport_spec.lua @@ -78,6 +78,7 @@ describe("TestImport", function() typeLine = "Rawhide Gloves", inventoryId = "Gloves", ilvl = 10, + vestigial = true, properties = { }, implicitMods = { { description = "+20 to maximum Life" }, @@ -86,6 +87,7 @@ describe("TestImport", function() { description = "+10 to maximum Life", flags = { crafted = true } }, { description = "+11 to maximum Mana", flags = { fractured = true } }, { description = "+12 to Strength", flags = { mutated = true } }, + { description = "+13 to Dexterity", flags = { vestigial = true } }, }, }) @@ -100,6 +102,9 @@ describe("TestImport", function() assert.is_true(explicitMods["+10 to maximum Life"].crafted) assert.is_true(explicitMods["+11 to maximum Mana"].fractured) assert.is_true(explicitMods["+12 to Strength"].mutated) + assert.is_true(item.vestigial) + assert.is_true(explicitMods["+13 to Dexterity"].vestigial) + assert.is_truthy(item:BuildRaw():find("{vestigial}", 1, true)) end) function importAndReimportWithOldJewel(shouldDelete) diff --git a/spec/System/TestItemParse_spec.lua b/spec/System/TestItemParse_spec.lua index b221053957e..0654d3c8634 100644 --- a/spec/System/TestItemParse_spec.lua +++ b/spec/System/TestItemParse_spec.lua @@ -981,6 +981,8 @@ describe("TestAdvancedItemParse #item", function() assert.are.equals(70, item.memoryStrands) assert.are.equals(1, #item.explicitModLines) + local _, memoryStrandsCount = item:BuildRaw():gsub("Memory Strands:", "") + assert.are.equals(1, memoryStrandsCount) item:BuildAndParseRaw() assert.are.equals(70, item.memoryStrands) diff --git a/src/Classes/ImportTab.lua b/src/Classes/ImportTab.lua index a21340ca98f..9176c657d5a 100644 --- a/src/Classes/ImportTab.lua +++ b/src/Classes/ImportTab.lua @@ -305,7 +305,6 @@ local function addOAuthControls(self) self.oauthErrCode = "Could not import character" end end - self.oauthLoading = false end) end) @@ -1635,6 +1634,7 @@ function ImportTabClass:ImportItem(itemData, slotName, ignoreWeaponSwap, itemSet item.corrupted = itemData.corrupted item.fractured = itemData.fractured item.synthesised = itemData.synthesised + item.vestigial = itemData.vestigial if itemData.sockets and itemData.sockets[1] then item.sockets = { } for i, socket in pairs(itemData.sockets) do @@ -1686,9 +1686,10 @@ function ImportTabClass:ImportItem(itemData, slotName, ignoreWeaponSwap, itemSet if itemData.implicitMods then for _, itemMod in ipairs(itemData.implicitMods) do local modLine = itemMod.description or itemMod + local flags = itemMod.flags or itemMod for line in modLine:gmatch("[^\n]+") do local modList, extra = modLib.parseMod(line) - t_insert(item.implicitModLines, { line = line, extra = extra, mods = modList or { } }) + t_insert(item.implicitModLines, { line = line, extra = extra, mods = modList or { }, vestigial = flags.vestigial }) end end end @@ -1710,7 +1711,8 @@ function ImportTabClass:ImportItem(itemData, slotName, ignoreWeaponSwap, itemSet t_insert(item.explicitModLines, { line = line, extra = extra, mods = modList or { }, fractured = flags.fractured, crafted = flags.crafted, - mutated = flags.mutated }) + mutated = flags.mutated, + vestigial = flags.vestigial }) end end end diff --git a/src/Classes/Item.lua b/src/Classes/Item.lua index b9a63aef5d4..c0d2e7a7dcd 100644 --- a/src/Classes/Item.lua +++ b/src/Classes/Item.lua @@ -824,8 +824,6 @@ function ItemClass:ParseRaw(raw, rarity, highQuality) self.catalystQuality = specToNumber(specVal) elseif specName == "Intangibility" then self.intangibility = specToNumber(specVal) - elseif specName == "Memory Strands" then - self.memoryStrands = specToNumber(specVal) elseif specName == "Note" then self.note = specVal elseif specName == "Str" or specName == "Strength" or specName == "Dex" or specName == "Dexterity" or @@ -1754,9 +1752,6 @@ function ItemClass:BuildRaw() if self.intangibility then t_insert(rawLines, string.format("Intangibility: %d%%", self.intangibility)) end - if self.memoryStrands then - t_insert(rawLines, string.format("Memory Strands: %d", self.memoryStrands)) - end if self.uniqueID then t_insert(rawLines, "Unique ID: " .. self.uniqueID) end diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index 7c64ef8850a..84938ca9655 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -4478,23 +4478,18 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode, maxWidth) tooltip:AddLine(fontSizeBig, "^x7F7F7FSockets: "..line, "FONTIN SC") end - if item.memoryStrands then - tooltip:AddLine(fontSizeBig, colorCodes.CRAFTED.."Memory Strands: ^7"..item.memoryStrands, "FONTIN SC") - tooltip:AddSeparator(10) - end - if item.talismanTier then tooltip:AddLine(fontSizeBig, "^x7F7F7FTalisman Tier ^xFFFFFF"..item.talismanTier, "FONTIN SC") tooltip:AddSeparator(10) end if item.memoryStrands then if main.showFlavourText then tooltip:AddLine(5, "") end - tooltip:AddLine(fontSizeBig, colorCodes.MEMORY .. s_format("Memory Strands: ^7%d", item.memoryStrands), "FONTIN SC", nil, "MemoryBG") + tooltip:AddLine(fontSizeBig, colorCodes.MEMORY .. s_format("Memory Strands: ^7%d", item.memoryStrands), "FONTIN SC", nil, "Assets/memorybg.png") if main.showFlavourText then tooltip:AddLine(5, "") end end if item.intangibility then if main.showFlavourText then tooltip:AddLine(5, "") end - tooltip:AddLine(fontSizeBig, colorCodes.INTANGIBILITY .. s_format("Intangibility: ^7%d%%", item.intangibility), "FONTIN SC", nil, "IntangibilityBG") + tooltip:AddLine(fontSizeBig, colorCodes.INTANGIBILITY .. s_format("Intangibility: ^7%d%%", item.intangibility), "FONTIN SC", nil, "Assets/intangibilitybg.png") if main.showFlavourText then tooltip:AddLine(5, "") end end tooltip:AddSeparator(10) diff --git a/src/Classes/Tooltip.lua b/src/Classes/Tooltip.lua index 014a680687e..1906629b706 100644 --- a/src/Classes/Tooltip.lua +++ b/src/Classes/Tooltip.lua @@ -614,7 +614,7 @@ function TooltipClass:Draw(x, y, w, h, viewPort) end if not self._bgHandles[bg] then local h = NewImageHandle() - h:Load("Assets/" .. bg .. ".png") + h:Load(bg) self._bgHandles[bg] = h end bg = self._bgHandles[bg]