diff --git a/src/Assets/itemsheaderfoilleft.png b/src/Assets/itemsheaderfoilleft.png new file mode 100644 index 0000000000..4c301f1a02 Binary files /dev/null and b/src/Assets/itemsheaderfoilleft.png differ diff --git a/src/Assets/itemsheaderfoilmiddle.png b/src/Assets/itemsheaderfoilmiddle.png new file mode 100644 index 0000000000..5eff33af3a Binary files /dev/null and b/src/Assets/itemsheaderfoilmiddle.png differ diff --git a/src/Assets/itemsheaderfoilright.png b/src/Assets/itemsheaderfoilright.png new file mode 100644 index 0000000000..9348815614 Binary files /dev/null and b/src/Assets/itemsheaderfoilright.png differ diff --git a/src/Assets/itemsheadergemleft.png b/src/Assets/itemsheadergemleft.png new file mode 100644 index 0000000000..c2f2d2f0f9 Binary files /dev/null and b/src/Assets/itemsheadergemleft.png differ diff --git a/src/Assets/itemsheadergemmiddle.png b/src/Assets/itemsheadergemmiddle.png new file mode 100644 index 0000000000..21cc4ac934 Binary files /dev/null and b/src/Assets/itemsheadergemmiddle.png differ diff --git a/src/Assets/itemsheadergemright.png b/src/Assets/itemsheadergemright.png new file mode 100644 index 0000000000..bf437767dd Binary files /dev/null and b/src/Assets/itemsheadergemright.png differ diff --git a/src/Assets/itemsheadermagicleft.png b/src/Assets/itemsheadermagicleft.png new file mode 100644 index 0000000000..f9edec8aaf Binary files /dev/null and b/src/Assets/itemsheadermagicleft.png differ diff --git a/src/Assets/itemsheadermagicmiddle.png b/src/Assets/itemsheadermagicmiddle.png new file mode 100644 index 0000000000..dba6451a55 Binary files /dev/null and b/src/Assets/itemsheadermagicmiddle.png differ diff --git a/src/Assets/itemsheadermagicright.png b/src/Assets/itemsheadermagicright.png new file mode 100644 index 0000000000..e87f78c786 Binary files /dev/null and b/src/Assets/itemsheadermagicright.png differ diff --git a/src/Assets/itemsheaderrareleft.png b/src/Assets/itemsheaderrareleft.png new file mode 100644 index 0000000000..d304c1a26e Binary files /dev/null and b/src/Assets/itemsheaderrareleft.png differ diff --git a/src/Assets/itemsheaderraremiddle.png b/src/Assets/itemsheaderraremiddle.png new file mode 100644 index 0000000000..2e8dc11c01 Binary files /dev/null and b/src/Assets/itemsheaderraremiddle.png differ diff --git a/src/Assets/itemsheaderrareright.png b/src/Assets/itemsheaderrareright.png new file mode 100644 index 0000000000..0d33af1f14 Binary files /dev/null and b/src/Assets/itemsheaderrareright.png differ diff --git a/src/Assets/itemsheaderuniqueleft.png b/src/Assets/itemsheaderuniqueleft.png new file mode 100644 index 0000000000..292ff4049a Binary files /dev/null and b/src/Assets/itemsheaderuniqueleft.png differ diff --git a/src/Assets/itemsheaderuniquemiddle.png b/src/Assets/itemsheaderuniquemiddle.png new file mode 100644 index 0000000000..b455f9336f Binary files /dev/null and b/src/Assets/itemsheaderuniquemiddle.png differ diff --git a/src/Assets/itemsheaderuniqueright.png b/src/Assets/itemsheaderuniqueright.png new file mode 100644 index 0000000000..902846c843 Binary files /dev/null and b/src/Assets/itemsheaderuniqueright.png differ diff --git a/src/Assets/itemsheaderwhiteleft.png b/src/Assets/itemsheaderwhiteleft.png new file mode 100644 index 0000000000..c69df9a19f Binary files /dev/null and b/src/Assets/itemsheaderwhiteleft.png differ diff --git a/src/Assets/itemsheaderwhitemiddle.png b/src/Assets/itemsheaderwhitemiddle.png new file mode 100644 index 0000000000..62a663ce68 Binary files /dev/null and b/src/Assets/itemsheaderwhitemiddle.png differ diff --git a/src/Assets/itemsheaderwhiteright.png b/src/Assets/itemsheaderwhiteright.png new file mode 100644 index 0000000000..048e6d0cf8 Binary files /dev/null and b/src/Assets/itemsheaderwhiteright.png differ diff --git a/src/Assets/itemsseparatorfoil.png b/src/Assets/itemsseparatorfoil.png new file mode 100644 index 0000000000..59c2a19b8d Binary files /dev/null and b/src/Assets/itemsseparatorfoil.png differ diff --git a/src/Assets/itemsseparatorgem.png b/src/Assets/itemsseparatorgem.png new file mode 100644 index 0000000000..ff1dff7541 Binary files /dev/null and b/src/Assets/itemsseparatorgem.png differ diff --git a/src/Assets/itemsseparatormagic.png b/src/Assets/itemsseparatormagic.png new file mode 100644 index 0000000000..b9365d1dad Binary files /dev/null and b/src/Assets/itemsseparatormagic.png differ diff --git a/src/Assets/itemsseparatorrare.png b/src/Assets/itemsseparatorrare.png new file mode 100644 index 0000000000..6798acd436 Binary files /dev/null and b/src/Assets/itemsseparatorrare.png differ diff --git a/src/Assets/itemsseparatorunique.png b/src/Assets/itemsseparatorunique.png new file mode 100644 index 0000000000..310eae2796 Binary files /dev/null and b/src/Assets/itemsseparatorunique.png differ diff --git a/src/Assets/itemsseparatorwhite.png b/src/Assets/itemsseparatorwhite.png new file mode 100644 index 0000000000..343ae939eb Binary files /dev/null and b/src/Assets/itemsseparatorwhite.png differ diff --git a/src/Assets/jewelpassiveheaderleft.png b/src/Assets/jewelpassiveheaderleft.png new file mode 100644 index 0000000000..dfef35824b Binary files /dev/null and b/src/Assets/jewelpassiveheaderleft.png differ diff --git a/src/Assets/jewelpassiveheadermiddle.png b/src/Assets/jewelpassiveheadermiddle.png new file mode 100644 index 0000000000..1360f65b69 Binary files /dev/null and b/src/Assets/jewelpassiveheadermiddle.png differ diff --git a/src/Assets/jewelpassiveheaderright.png b/src/Assets/jewelpassiveheaderright.png new file mode 100644 index 0000000000..1a561e6461 Binary files /dev/null and b/src/Assets/jewelpassiveheaderright.png differ diff --git a/src/Assets/keystonepassiveheaderleft.png b/src/Assets/keystonepassiveheaderleft.png new file mode 100644 index 0000000000..be62fada01 Binary files /dev/null and b/src/Assets/keystonepassiveheaderleft.png differ diff --git a/src/Assets/keystonepassiveheadermiddle.png b/src/Assets/keystonepassiveheadermiddle.png new file mode 100644 index 0000000000..01df3bfaba Binary files /dev/null and b/src/Assets/keystonepassiveheadermiddle.png differ diff --git a/src/Assets/keystonepassiveheaderright.png b/src/Assets/keystonepassiveheaderright.png new file mode 100644 index 0000000000..6e89a80f97 Binary files /dev/null and b/src/Assets/keystonepassiveheaderright.png differ diff --git a/src/Assets/normalpassiveheaderleft.png b/src/Assets/normalpassiveheaderleft.png new file mode 100644 index 0000000000..40663a209c Binary files /dev/null and b/src/Assets/normalpassiveheaderleft.png differ diff --git a/src/Assets/normalpassiveheadermiddle.png b/src/Assets/normalpassiveheadermiddle.png new file mode 100644 index 0000000000..efcef439ab Binary files /dev/null and b/src/Assets/normalpassiveheadermiddle.png differ diff --git a/src/Assets/normalpassiveheaderright.png b/src/Assets/normalpassiveheaderright.png new file mode 100644 index 0000000000..4f75bfd5de Binary files /dev/null and b/src/Assets/normalpassiveheaderright.png differ diff --git a/src/Assets/notablepassiveheaderleft.png b/src/Assets/notablepassiveheaderleft.png new file mode 100644 index 0000000000..8ec1339f80 Binary files /dev/null and b/src/Assets/notablepassiveheaderleft.png differ diff --git a/src/Assets/notablepassiveheadermiddle.png b/src/Assets/notablepassiveheadermiddle.png new file mode 100644 index 0000000000..dbd40a45a5 Binary files /dev/null and b/src/Assets/notablepassiveheadermiddle.png differ diff --git a/src/Assets/notablepassiveheaderright.png b/src/Assets/notablepassiveheaderright.png new file mode 100644 index 0000000000..c065946e05 Binary files /dev/null and b/src/Assets/notablepassiveheaderright.png differ diff --git a/src/Classes/GemSelectControl.lua b/src/Classes/GemSelectControl.lua index 42595188e7..a01ab02ad8 100644 --- a/src/Classes/GemSelectControl.lua +++ b/src/Classes/GemSelectControl.lua @@ -477,6 +477,7 @@ function GemSelectClass:Draw(viewPort, noTooltip) if gemInstance and gemInstance.gemData then self:AddGemTooltip(gemInstance) else + self.tooltip.itemTooltip = false self.tooltip:AddLine(16, toolTipText) end @@ -528,7 +529,7 @@ function GemSelectClass:AddGemTooltip(gemInstance) self.tooltip.color = colorCodes.GEM local grantedEffect = gemInstance.gemData.grantedEffect local additionalEffects = gemInstance.gemData.additionalGrantedEffects - + self.tooltip.itemTooltip = "GEM" self.tooltip:AddLine(20, colorCodes.GEM .. grantedEffect.name) self.tooltip:AddSeparator(10) self.tooltip:AddLine(18, colorCodes.NORMAL .. gemInstance.gemData.gemType) diff --git a/src/Classes/ItemsTab.lua b/src/Classes/ItemsTab.lua index cc200e275e..446dd74596 100644 --- a/src/Classes/ItemsTab.lua +++ b/src/Classes/ItemsTab.lua @@ -44,6 +44,16 @@ local catalystQualityFormat = { "^x7F7F7FQuality (Attribute Modifiers): "..colorCodes.MAGIC.."+%d%% (augmented)", } +local flavourLookup = {} + +for _, entry in pairs(data.flavourText) do + if entry.name and entry.id and entry.text then + flavourLookup[entry.name] = flavourLookup[entry.name] or {} + flavourLookup[entry.name][entry.id] = entry.text + end +end + + local ItemsTabClass = newClass("ItemsTab", "UndoHandler", "ControlHost", "Control", function(self, build) self.UndoHandler() self.ControlHost() @@ -2565,6 +2575,8 @@ end function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode) -- Item name local rarityCode = colorCodes[item.rarity] + tooltip.maxWidth = 600 -- Should instead get the longest mod and set the width to that. Some flavour text is way too long so we need a cap of sorts. + tooltip.itemTooltip = item.rarity tooltip.center = true tooltip.color = rarityCode if item.title then @@ -2869,8 +2881,63 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode) if item.corrupted then tooltip:AddLine(16, colorCodes.NEGATIVE.."Corrupted") end + tooltip:AddSeparator(14) + end + + -- Show flavour text: + if item.rarity == "UNIQUE" and main.showFlavourText == true then + local flavourTable = flavourLookup[item.title] + if flavourTable then + local flavour = nil + + if item.title == "Sekhema's Resolve" then + local selectedFlavourId = nil + for _, lineEntry in ipairs(tooltip.lines or {}) do + local lineText = lineEntry.text or "" + if lineText:find("Emerald") then + selectedFlavourId = "FourUniqueSanctum4a" + break + elseif lineText:find("Sapphire") then + selectedFlavourId = "FourUniqueSanctum4b" + break + elseif lineText:find("Ruby") then + selectedFlavourId = "FourUniqueSanctum4c" + break + end + end + if selectedFlavourId then + flavour = flavourTable[selectedFlavourId] + end + + elseif item.title == "Grand Spectrum" then + local selectedFlavourId = nil + local baseName = item.baseName + if baseName == "Ruby" then + selectedFlavourId = "FourUniqueJewel1" + elseif baseName == "Emerald" then + selectedFlavourId = "FourUniqueJewel2" + elseif baseName == "Sapphire" then + selectedFlavourId = "FourUniqueJewel3" + end + if selectedFlavourId then + flavour = flavourTable[selectedFlavourId] + end + + else + for _, text in pairs(flavourTable) do + flavour = text + break + end + end + + if flavour then + for _, line in ipairs(flavour) do + tooltip:AddLine(16, colorCodes.UNIQUE .. line) + end + tooltip:AddSeparator(14) + end + end end - tooltip:AddSeparator(14) -- Stat differences if not self.showStatDifferences then diff --git a/src/Classes/PassiveTreeView.lua b/src/Classes/PassiveTreeView.lua index 1c673d31ab..11c6befd3c 100644 --- a/src/Classes/PassiveTreeView.lua +++ b/src/Classes/PassiveTreeView.lua @@ -1073,6 +1073,15 @@ end function PassiveTreeViewClass:AddNodeName(tooltip, node, build) tooltip:SetRecipe(node.infoRecipe) + if node.type == "Normal" then + tooltip.itemTooltip = "PASSIVE" + elseif node.type == "Notable" then + tooltip.itemTooltip = "NOTABLE" + elseif node.type == "Socket" then + tooltip.itemTooltip = "JEWEL" + elseif node.type == "Keystone" then -- keystone runs but still prints default header + tooltip.itemTooltip = "KEYSTONE" + end tooltip:AddLine(24, "^7"..node.dn..(launch.devModeAlt and " ["..node.id.."]" or "")) if launch.devModeAlt and node.id > 65535 then -- Decompose cluster node Id diff --git a/src/Classes/Tooltip.lua b/src/Classes/Tooltip.lua index 7a07f9eded..dbc9ba8e4b 100644 --- a/src/Classes/Tooltip.lua +++ b/src/Classes/Tooltip.lua @@ -77,9 +77,46 @@ function TooltipClass:SetRecipe(recipe) end function TooltipClass:AddSeparator(size) - t_insert(self.lines, { size = size }) + size = size or 10 + + local lastLine = self.lines[#self.lines] + if lastLine and lastLine.separatorImage then + -- Prevent back-to-back separator lines + return + end + + local separatorImage = nil + + if self.itemTooltip then + local rarity = tostring(self.itemTooltip):upper() + local separatorConfigs = { + RELIC = "Assets/ItemsSeparatorFoil.png", + UNIQUE = "Assets/ItemsSeparatorUnique.png", + RARE = "Assets/ItemsSeparatorRare.png", + MAGIC = "Assets/ItemsSeparatorMagic.png", + NORMAL = "Assets/ItemsSeparatorWhite.png", + GEM = "Assets/ItemsSeparatorGem.png", + } + local separatorPath = separatorConfigs[rarity] or separatorConfigs.NORMAL + + if not self.separatorImage or self.separatorImagePath ~= separatorPath then + self.separatorImage = NewImageHandle() + self.separatorImage:Load(separatorPath) + self.separatorImagePath = separatorPath + end + + separatorImage = self.separatorImage + end + + local lastBlock = lastLine and lastLine.block or 1 + t_insert(self.lines, { + separatorImage = separatorImage, + size = size, + block = lastBlock, + }) end + function TooltipClass:GetSize() local ttW, ttH = 0, 0 for i, data in ipairs(self.lines) do @@ -128,6 +165,7 @@ function TooltipClass:CalculateColumns(ttY, ttX, ttH, ttW, viewPort) local drawStack = {} for i, data in ipairs(self.lines) do + -- Draw recipe oils on first line if self.recipe and i == 1 then local title = self.lines[1] local imageX = DrawStringWidth(title.size, "VAR", title.text) + title.size @@ -140,31 +178,55 @@ function TooltipClass:CalculateColumns(ttY, ttX, ttH, ttW, viewPort) recipeNameShort = recipeNameShort:sub(1, #recipeNameShort - 3) end -- Draw the name of the recipe component (oil) - t_insert(drawStack, {ttX + imageX, y + (title.size - recipeTextSize)/2, "LEFT", recipeTextSize, "VAR", recipeNameShort}) + t_insert(drawStack, {ttX + imageX, y + (title.size - recipeTextSize) / 2, "LEFT", recipeTextSize, "VAR", recipeNameShort}) imageX = imageX + DrawStringWidth(recipeTextSize, "VAR", recipeNameShort) -- Draw the image of the recipe component (oil) t_insert(drawStack, {recipeInfo.sprite, ttX + imageX, y, title.size, title.size}) imageX = imageX + title.size * 1.25 end end + + local margin = 80 + local maxHeight = math.min(ttH, viewPort.height - margin) + + -- Wrapping logic for text lines if data.text then - -- if data + borders is going to go outside of the viewPort - if currentBlock ~= data.block and self.blocks[data.block].height + y > ttY + math.min(ttH, viewPort.height) then + if currentBlock ~= data.block and (y + data.size > ttY + maxHeight) then y = ttY + 2 * BORDER_WIDTH x = ttX + ttW * columns columns = columns + 1 end currentBlock = data.block + + local yOffset = (i == 1 and self.titleYOffset) or 0 + local drawY = y + yOffset + if self.center then - t_insert(drawStack, {x + ttW/2, y, "CENTER_X", data.size, "VAR", data.text}) + t_insert(drawStack, {x + ttW / 2, drawY, "CENTER_X", data.size, "VAR", data.text}) else - t_insert(drawStack, {x + 6, y, "LEFT", data.size, "VAR", data.text}) + t_insert(drawStack, {x + 6, drawY, "LEFT", data.size, "VAR", data.text}) end y = y + data.size + 2 + + -- Wrapping logic for separator images (counts as a "text" line for wrap height) + elseif data.separatorImage and main.showFlavourText then + local sepSize = data.size or 10 + if currentBlock ~= data.block and (y + sepSize > ttY + maxHeight) then + y = ttY + 2 * BORDER_WIDTH + x = ttX + ttW * columns + columns = columns + 1 + end + currentBlock = data.block + + t_insert(drawStack, {{ handle = data.separatorImage, isSeparator = true },x + 6, y, ttW - 12, sepSize}) + y = y + sepSize + 2 + + -- Horizontal line, if surrounded by text lines elseif self.lines[i + 1] and self.lines[i - 1] and self.lines[i + 1].text then t_insert(drawStack, {nil, x, y - 1 + data.size / 2, ttW - BORDER_WIDTH, 2}) y = y + data.size + 2 end + maxColumnHeight = m_max(y - ttY + 2 * BORDER_WIDTH, maxColumnHeight) end @@ -190,9 +252,9 @@ function TooltipClass:Draw(x, y, w, h, viewPort) ttY = m_max(viewPort.y, y + h - ttH) end elseif self.center then - ttX = m_floor(x - ttW/2) + ttX = m_floor(x - ttW / 2) end - + SetDrawColor(1, 1, 1) local columns, maxColumnHeight, drawStack = self:CalculateColumns(ttY, ttX, ttH, ttW, viewPort) @@ -203,44 +265,110 @@ function TooltipClass:Draw(x, y, w, h, viewPort) DrawImage(nil, ttX, ttY + BORDER_WIDTH, ttW * columns - BORDER_WIDTH, maxColumnHeight - 2 * BORDER_WIDTH) --SetDrawLayer(nil, GetDrawLayer()) SetDrawColor(1, 1, 1) - for i, lines in ipairs(drawStack) do - if #lines < 6 then - if(type(self.color) == "string") then + + -- Item header (drawn within borders) + if self.itemTooltip and main.showFlavourText and self.lines[1] and self.lines[1].text then + local rarity = tostring(self.itemTooltip):upper() + local headerConfigs = { + RELIC = {left="Assets/ItemsHeaderFoilLeft.png",middle="Assets/ItemsHeaderFoilMiddle.png",right="Assets/ItemsHeaderFoilRight.png",height=53,sideWidth=43,middleWidth=43,textYOffset=2}, + UNIQUE = {left="Assets/ItemsHeaderUniqueLeft.png",middle="Assets/ItemsHeaderUniqueMiddle.png",right="Assets/ItemsHeaderUniqueRight.png",height=53,sideWidth=43,middleWidth=43,textYOffset=2}, + RARE = {left="Assets/ItemsHeaderRareLeft.png",middle="Assets/ItemsHeaderRareMiddle.png",right="Assets/ItemsHeaderRareRight.png",height=53,sideWidth=43,middleWidth=43,textYOffset=2}, + MAGIC = {left="Assets/ItemsHeaderMagicLeft.png",middle="Assets/ItemsHeaderMagicMiddle.png",right="Assets/ItemsHeaderMagicRight.png",height=38,sideWidth=32,middleWidth=32,textYOffset=4}, + NORMAL = {left="Assets/ItemsHeaderWhiteLeft.png",middle="Assets/ItemsHeaderWhiteMiddle.png",right="Assets/ItemsHeaderWhiteRight.png",height=38,sideWidth=32,middleWidth=32,textYOffset=4}, + GEM = {left="Assets/ItemsHeaderGemLeft.png",middle="Assets/ItemsHeaderGemMiddle.png",right="Assets/ItemsHeaderGemRight.png",height=38,sideWidth=32,middleWidth=32,textYOffset=4}, + JEWEL = {left="Assets/JewelPassiveHeaderLeft.png",middle="Assets/JewelPassiveHeaderMiddle.png",right="Assets/JewelPassiveHeaderRight.png",height=38,sideWidth=32,middleWidth=32,textYOffset=2}, + NOTABLE = {left="Assets/NotablePassiveHeaderLeft.png",middle="Assets/NotablePassiveHeaderMiddle.png",right="Assets/NotablePassiveHeaderRight.png",height=38,sideWidth=38,middleWidth=32,textYOffset=2}, + PASSIVE = {left="Assets/NormalPassiveHeaderLeft.png",middle="Assets/NormalPassiveHeaderMiddle.png",right="Assets/NormalPassiveHeaderRight.png",height=38,sideWidth=32,middleWidth=32,textYOffset=2}, + KEYSTONE = {left="Assets/KeystonePassiveHeaderLeft.png",middle="Assets/KeystonePassiveHeaderMiddle.png",right="Assets/KeystonePassiveHeaderRight.png",height=38,sideWidth=32,middleWidth=32,textYOffset=2}, + } + local config = headerConfigs[rarity] or headerConfigs.NORMAL + + self.titleYOffset = config.textYOffset or 0 + + if not self.headerLeft or self.headerLeftPath ~= config.left then + self.headerLeft = NewImageHandle() + self.headerLeft:Load(config.left) + self.headerLeftPath = config.left + end + if not self.headerMiddle or self.headerMiddlePath ~= config.middle then + self.headerMiddle = NewImageHandle() + self.headerMiddle:Load(config.middle) + self.headerMiddlePath = config.middle + end + if not self.headerRight or self.headerRightPath ~= config.right then + self.headerRight = NewImageHandle() + self.headerRight:Load(config.right) + self.headerRightPath = config.right + end + + local headerHeight = config.height + local headerSideWidth = config.sideWidth + local headerMiddleWidth = config.middleWidth + + local headerX = ttX + BORDER_WIDTH + local headerY = ttY + BORDER_WIDTH + local headerTotalWidth = ttW - 2 * BORDER_WIDTH + local headerMiddleAreaWidth = m_max(0, headerTotalWidth - 2 * headerSideWidth) + + -- Draw left cap + DrawImage(self.headerLeft, headerX, headerY, headerSideWidth, headerHeight) + + -- Draw middle fill + if headerMiddleAreaWidth > 0 then + local drawX = headerX + headerSideWidth + local endX = headerX + headerTotalWidth - headerSideWidth + while drawX + headerMiddleWidth <= endX do + DrawImage(self.headerMiddle, drawX, headerY, headerMiddleWidth, headerHeight) + drawX = drawX + headerMiddleWidth + end + local remainingWidth = endX - drawX + if remainingWidth > 0 then + DrawImage(self.headerMiddle, drawX, headerY, remainingWidth, headerHeight) + end + end + + -- Draw right cap + DrawImage(self.headerRight, headerX + headerTotalWidth - headerSideWidth, headerY, headerSideWidth, headerHeight) + end + + -- Draw lines and images + for _, line in ipairs(drawStack) do + if #line < 6 then + if line[1] and type(line[1]) == "table" and line[1].isSeparator then + SetDrawColor(1, 1, 1) + elseif type(self.color) == "string" then SetDrawColor(self.color) - elseif lines[1] then -- Don't color images - SetDrawColor(1,1,1) else SetDrawColor(unpack(self.color)) end - if lines[1] and lines[1].handle then - local arguments = { - lines[1].handle, - lines[2], - lines[3], - lines[4], - lines[5] + if line[1] and line[1].handle then + local args = { + line[1].handle, line[2], line[3], line[4], line[5] } - for _, v in ipairs(lines[1]) do - t_insert(arguments, v) + for _, v in ipairs(line[1]) do + t_insert(args, v) end - DrawImage(unpack(arguments)) + SetDrawColor(1,1,1) + DrawImage(unpack(args)) else - DrawImage(unpack(lines)) + DrawImage(unpack(line)) end else - DrawString(unpack(lines)) + DrawString(unpack(line)) end end + + -- Draw borders if type(self.color) == "string" then SetDrawColor(self.color) else SetDrawColor(unpack(self.color)) end - for i=0,columns do - DrawImage(nil, ttX + ttW * i - BORDER_WIDTH * math.ceil(i^2 / (i^2 + 1)), ttY, BORDER_WIDTH, maxColumnHeight) -- borders + for i = 0, columns do + DrawImage(nil, ttX + ttW * i - BORDER_WIDTH * math.ceil(i^2 / (i^2 + 1)), ttY, BORDER_WIDTH, maxColumnHeight) end - DrawImage(nil, ttX, ttY, ttW * columns, BORDER_WIDTH) -- top border - DrawImage(nil, ttX, ttY + maxColumnHeight - BORDER_WIDTH, ttW * columns, BORDER_WIDTH) -- bottom border + DrawImage(nil, ttX, ttY, ttW * columns, BORDER_WIDTH) -- top + DrawImage(nil, ttX, ttY + maxColumnHeight - BORDER_WIDTH, ttW * columns, BORDER_WIDTH) -- bottom return ttW, ttH -end \ No newline at end of file +end diff --git a/src/Data/FlavourText.lua b/src/Data/FlavourText.lua new file mode 100644 index 0000000000..53b0e89514 --- /dev/null +++ b/src/Data/FlavourText.lua @@ -0,0 +1,3002 @@ +-- This file is automatically generated, do not edit! +-- Flavour text data (c) Grinding Gear Games + +return { + [1] = { + id = "FourUniqueBodyStr1", + name = "Bramblejack", + text = { + "It is safer to be feared than to be loved.", + }, + }, + [2] = { + id = "FourUniqueBodyStr2", + name = "Blackbraid", + text = { + "An Ezomyte endures.", + }, + }, + [3] = { + id = "FourUniqueBodyStr3", + name = "Edyrn's Tusks", + text = { + "In death, the legendary boar's tusks were turned", + "to the slaying of Phaaryl's Eternal oppressors.", + }, + }, + [4] = { + id = "FourUniqueBodyStr4", + name = "The Road Warrior", + text = { + "That most legendary caravan bandit had", + "one rule: never let them see you flinch.", + }, + }, + [5] = { + id = "FourUniqueBodyStr5", + name = "Titanrot Cataphract", + text = { + "Not the sound of thunder on the wind, but the", + "rhoaback riders—death charging from the sands.", + }, + }, + [6] = { + id = "FourUniqueBodyStr6", + name = "Wandering Reliquary", + text = { + "Knowing she could outlast any opponent,", + "Wrashmin fought not to win, but to delay.", + }, + }, + [7] = { + id = "FourUniqueBodyStr7", + name = "Kingsguard", + text = { + "The toughest armour is the trust of your people.", + }, + }, + [8] = { + id = "FourUniqueBodyStr8", + name = "Greed's Embrace", + text = { + "Some would question if the risk was worth it.", + "The rest were already dead.", + }, + }, + [9] = { + id = "FourUniqueBodyStr12_", + name = "The Brass Dome", + text = { + "The turtle's shell one day becomes its tomb.", + }, + }, + [10] = { + id = "FourUniqueBodyStr14", + name = "Kaom's Heart", + text = { + "The warrior who fears will fall.", + }, + }, + [11] = { + id = "FourUniqueBodyDex1", + name = "Bristleboar", + text = { + "When cornered and desperate, look within for the rage to break loose.", + }, + }, + [12] = { + id = "FourUniqueBodyDex2", + name = "Foxshade", + text = { + "To catch an animal, think like an animal.", + }, + }, + [13] = { + id = "FourUniqueBodyDex3", + name = "Ashrend", + text = { + "The blasted oak stands forever.", + }, + }, + [14] = { + id = "FourUniqueBodyDex4", + name = "Sands of Silk", + text = { + "The desert is ever flowing.", + }, + }, + [15] = { + id = "FourUniqueBodyDex5", + name = "Briskwrap", + text = { + "\"I carry neither food nor drink. I rely on the charity", + "of my fellow wayfarers. Dead men are generous men.\"", + "- Taruk of the Wildmen", + }, + }, + [16] = { + id = "FourUniqueBodyDex6", + name = "Dustbloom", + text = { + "Wraeclast has suffered many great disasters,", + "but life always springs back anew.", + }, + }, + [17] = { + id = "FourUniqueBodyDex7", + name = "The Rat Cage", + text = { + "The truth lies inside every man, if you dig around.", + "Many a confession was found in the bowels of Axiom.", + }, + }, + [18] = { + id = "FourUniqueBodyDex8", + name = "Quatl's Molt", + text = { + "As the serpent wills.", + }, + }, + [19] = { + id = "FourUniqueBodyDex10", + name = "Queen of the Forest", + text = { + "Shedding away her regal past,", + "she forged a new destiny.", + "Sacrificing the ephemeral joys of man,", + "she embraced the eternal grasp of nature.", + "Seizing her one true wish,", + "she found peace at last.", + }, + }, + [20] = { + id = "FourUniqueBodyDex11", + name = "Yriel's Fostering", + text = { + "Feed a beast and it will not hunt.", + "Protect it and it will not fight.", + "Ferocity must be learned, not taught.", + "It is suffering that forges the greatest warriors.", + }, + }, + [21] = { + id = "FourUniqueBodyDex15", + name = "Hyrri's Ire", + text = { + "Hyrri loosed a barrage of arrows,", + "tipped with a poisoned hatred", + "only oppression can ferment.", + }, + }, + [22] = { + id = "FourUniqueBodyInt1", + name = "Ghostwrithe", + text = { + "Faith springs abundant at the edge of death.", + }, + }, + [23] = { + id = "FourUniqueBodyInt2", + name = "Bitterbloom", + text = { + "The soul cannot flourish in a doubting mind.", + }, + }, + [24] = { + id = "FourUniqueBodyInt3", + name = "The Black Doubt", + text = { + "Suspicion is a sinister shadow slithering in the soul.", + }, + }, + [25] = { + id = "FourUniqueBodyInt4", + name = "Necromantle", + text = { + "Fueled by the blackness in the hearts of men,", + "the armies of Saresh were just as relentless.", + }, + }, + [26] = { + id = "FourUniqueBodyInt5", + name = "Cloak of Flame", + text = { + "He who sows an ember shall reap an inferno.", + }, + }, + [27] = { + id = "FourUniqueBodyInt6", + name = "Prayers for Rain", + text = { + "In its final era, the roofs of Keth were rife with", + "anything and everything that could hold water...", + "should the opportunity arise.", + }, + }, + [28] = { + id = "FourUniqueBodyInt7", + name = "Tetzlapokal's Desire", + text = { + "A faith born of flesh.", + }, + }, + [29] = { + id = "FourUniqueBodyInt8", + name = "The Covenant", + text = { + "My Soul is your Strength", + "My Price is your Blood", + }, + }, + [30] = { + id = "FourUniqueBodyInt9", + name = "Gloamgown", + text = { + "The tale-women of old knew how to build anticipation.", + }, + }, + [31] = { + id = "FourUniqueBodyInt12", + name = "Vis Mortis", + text = { + "Reap what others have sown", + "Muster them from their graves", + "Parade them for your pleasure", + "Zealots in mortis enslaved", + }, + }, + [32] = { + id = "FourUniqueBodyInt13", + name = "Cloak of Defiance", + text = { + "When the throat roars,", + "As eyes weep,", + "When the hand grips hard", + "With trembling fingers,", + "When belly twists", + "Yet legs stand strong,", + "That is the work", + "Of the Defiant Heart.", + }, + }, + [33] = { + id = "FourUniqueBodyInt14", + name = "Silks of Veneration", + text = { + "Hallowed Dordalus was cast into the pit as a heretic,", + "but his piety was so great, he would not burn.", + "He rose again, lauded, his faith forever changed...", + "but not the way the Templar believed.", + }, + }, + [34] = { + id = "FourUniqueBodyStrDex1", + name = "Coat of Red", + text = { + "For those noble families obsessed", + "with keeping their bloodline pure,", + "there was a price to pay...", + }, + }, + [35] = { + id = "FourUniqueBodyStrDex2", + name = "The Barrow Dweller", + text = { + "In the mists they dwell,", + "forever hungry,", + "forever cold.", + }, + }, + [36] = { + id = "FourUniqueBodyStrDex3", + name = "Irongrasp", + text = { + "A power unknown aids your own.", + }, + }, + [37] = { + id = "FourUniqueBodyStrDex4", + name = "Pariah's Embrace", + text = { + "His isolation caused him to treasure", + "their companionship all the more.", + }, + }, + [38] = { + id = "FourUniqueBodyStrDex5", + name = "Belly of the Beast", + text = { + "There is no safer place", + "Than the Belly of the Beast", + }, + }, + [39] = { + id = "FourUniqueBodyStrDex6", + name = "Doryani's Prototype", + text = { + "\"This was the first step in some grand design,", + "lost to the ages, now ours to decipher.\"", + "- Dominus, High Templar", + }, + }, + [40] = { + id = "FourUniqueBodyStrDex7", + name = "Widow's Reign", + text = { + "That day, both the Unblinking Eye and", + "their enemies stood in silence. That day,", + "the sky was clear, but it was raining.", + }, + }, + [41] = { + id = "FourUniqueBodyStrDex9", + name = "The Fallen Formation", + text = { + "\"I will never forget. I will carry your memory", + "forward, all of you, from this ghastly Vale.\"", + "- Artair, last survivor of the Ogham rebellion", + }, + }, + [42] = { + id = "FourUniqueBodyStrDex11", + name = "The Coming Calamity", + text = { + "Whiff of cold, tiny spark, faintest flicker in the dark.", + "Embers swirl, ice takes form, sky exposed - Death's perfect storm.", + "Frost and thunder, flames shine bright, ruin walks the land tonight.", + "By your hand they dance and bend, wield them and brook no end.", + }, + }, + [43] = { + id = "FourUniqueBodyStrInt1_", + name = "Enfolding Dawn", + text = { + "The gleam of the night and howling teeth alike could not abate the rising of the sun.", + }, + }, + [44] = { + id = "FourUniqueBodyStrInt3", + name = "Icetomb", + text = { + "When Solaris closes her burning eye", + "At the end of time,", + "the world will perish in ice.", + }, + }, + [45] = { + id = "FourUniqueBodyStrInt4", + name = "Husk of Dreams", + text = { + "Yes... but what if?", + }, + }, + [46] = { + id = "FourUniqueBodyStrInt5", + name = "Voll's Protector", + text = { + "Although a great leader during the war,", + "Voll proved disastrous in times of peace.", + }, + }, + [47] = { + id = "FourUniqueBodyStrInt6", + name = "Soul Mantle", + text = { + "The greatest mistakes cause suffering", + "long after they have been made", + }, + }, + [48] = { + id = "FourUniqueBodyStrInt7", + name = "The Mutable Star", + text = { + "Through every great purge, and every fiery inquisition,", + "the Twilight Order endured in secret.", + }, + }, + [49] = { + id = "FourUniqueBodyStrInt8", + name = "Waveshaper", + text = { + "\"Move in ways your enemy does not expect.", + "Confuse them with elegance and grace.", + "They'll never see the axe coming.\"", + "- Rakiata, Chieftain of the Tasalio Tribe", + }, + }, + [50] = { + id = "FourUniqueBodyStrInt9", + name = "Couture of Crimson", + text = { + "It is often said of nobles that they live off their", + "peasants... sometimes, it's truer than any suspect.", + }, + }, + [51] = { + id = "FourUniqueBodyStrInt12", + name = "Sacrosanctum", + text = { + "The Twilight Order rejected the gods, choosing", + "instead to put their faith in each other.", + }, + }, + [52] = { + id = "FourUniqueBodyDexInt1", + name = "Apron of Emiran", + text = { + "\"Prepare the rack, boy. And be careful with those hooks!\"", + "- the Master Torturer's last words", + }, + }, + [53] = { + id = "FourUniqueBodyDexInt2", + name = "Gloomform", + text = { + "It was in this forsaken land, where mists shroud the world in mystery,", + "that thieves, murderers, and outcasts, sought refuge.", + }, + }, + [54] = { + id = "FourUniqueBodyDexInt3", + name = "Sierran Inheritance", + text = { + "Born among the high peaks, many Mutewind", + "live their entire lives in snow and ice.", + }, + }, + [55] = { + id = "FourUniqueBodyDexInt4", + name = "The Dancing Mirage", + text = { + "Be not where death falls.", + }, + }, + [56] = { + id = "FourUniqueBodyDexInt5", + name = "Redflare Conduit", + text = { + "In all things, control.", + }, + }, + [57] = { + id = "FourUniqueBodyDexInt6", + name = "Zerphi's Serape", + text = { + "Mortality is a curse.", + "The cure is simple.", + }, + }, + [58] = { + id = "FourUniqueBodyStrDexInt1", + name = "Tabula Rasa", + text = { + }, + }, + [59] = { + id = "FourUniqueHelmetStr1a", + name = "Horns of Bynden", + text = { + "The younger brother waded into battle, shrugging off blows.", + }, + }, + [60] = { + id = "FourUniqueHelmetStr1b", + name = "Wings of Caelyn", + text = { + "The older brother retained calm in the midst of fury.", + }, + }, + [61] = { + id = "FourUniqueHelmetStr2", + name = "Ezomyte Peak", + text = { + "Centuries of servitude, a day", + "of glory, an eternity of death.", + }, + }, + [62] = { + id = "FourUniqueHelmetStr3", + name = "Black Sun Crest", + text = { + "The beasts we fear the most", + "are the ones who dwell in total darkness.", + }, + }, + [63] = { + id = "FourUniqueHelmetStr4", + name = "Thrillsteel", + text = { + "We may fight, and we may die, but in these", + "moments of blood and battle, we truly live.", + }, + }, + [64] = { + id = "FourUniqueHelmetStr5", + name = "Deidbell", + text = { + "May you never hear it toll.", + }, + }, + [65] = { + id = "FourUniqueHelmetStr6", + name = "Corona of the Red Sun", + text = { + "Only the High Priests could enact the sacrifices,", + "but all who witnessed shared in exultation.", + }, + }, + [66] = { + id = "FourUniqueHelmetStr8", + name = "Blood Price", + text = { + "An eye for an eye makes the whole world dead.", + }, + }, + [67] = { + id = "FourUniqueHelmetDex1", + name = "Innsmouth", + text = { + "Beyond madness lies inspiration.", + }, + }, + [68] = { + id = "FourUniqueHelmetDex2", + name = "Goldrim", + text = { + "No metal slips as easily through the fingers as gold.", + }, + }, + [69] = { + id = "FourUniqueHelmetDex3", + name = "Radiant Grief", + text = { + "No man burns alone.", + }, + }, + [70] = { + id = "FourUniqueHelmetDex5", + name = "Elevore", + text = { + "Ancient worshippers of the Greatwolf were overtaken", + "by a ravenous hunger for all things mystical.", + }, + }, + [71] = { + id = "FourUniqueHelmetDex6", + name = "Constricting Command", + text = { + "\"Be vigilant, Nezahul! When the serpent is cornered, does it give up?", + "No... It waits. Then it bites the first hand it finds.", + "The danger of numbers is all in your mind!\"", + "- Viper Napuatzi, instructing Royal Commander Nezahul", + }, + }, + [72] = { + id = "FourUniqueHelmetDex7", + name = "The Black Insignia", + text = { + "Brinerot pirates live in a perpetual blaze of glory,", + "pushing their luck right to the end.", + }, + }, + [73] = { + id = "FourUniqueHelmetDex8", + name = "Starkonja's Head", + text = { + "There was no hero made out of Starkonja's death,", + "but merely a long sleep made eternal.", + }, + }, + [74] = { + id = "FourUniqueHelmetDex9", + name = "Heatshiver", + text = { + "Give of your heated passions.", + "Give of your cold resolve.", + "You will be repaid.", + }, + }, + [75] = { + id = "FourUniqueHelmetDex10", + name = "Myris Uxor", + text = { + "The end always comes sooner than we think.", + }, + }, + [76] = { + id = "FourUniqueHelmetDex11", + name = "Alpha's Howl", + text = { + "Nature respects the strong", + "And paints the snow red", + "With the blood of the weak", + }, + }, + [77] = { + id = "FourUniqueHelmetInt1", + name = "Crown of Thorns", + text = { + "Lift it lightly, don it slow.", + "The spikes point out and in, you know.", + }, + }, + [78] = { + id = "FourUniqueHelmetInt2", + name = "The Devouring Diadem", + text = { + "The spirit hungers for the flesh.", + }, + }, + [79] = { + id = "FourUniqueHelmetInt3", + name = "Visage of Ayah", + text = { + "Tale-women do not fight as dekharas.", + "They command a power all their own.", + }, + }, + [80] = { + id = "FourUniqueHelmetInt4", + name = "Forbidden Gaze", + text = { + "Keep your heart as ice,", + "lest your passions stir.", + }, + }, + [81] = { + id = "FourUniqueHelmetInt5", + name = "Mask of the Stitched Demon", + text = { + "From the flesh of the gods, Xibaqua was born.", + "From the carnage of Xibaqua, we were born.", + "It is our duty to return to the gods what was once theirs.", + }, + }, + [82] = { + id = "FourUniqueHelmetInt6", + name = "Atziri's Disdain", + text = { + "They screamed her name in adulation as they gave", + "their very lives. She looked on with impatience.", + }, + }, + [83] = { + id = "FourUniqueHelmetInt7", + name = "Crown of Eyes", + text = { + "Turning, gazing, blinking,", + "behold the eyes of void.", + "Burning, razing, drinking,", + "your mind is destroyed.", + }, + }, + [84] = { + id = "FourUniqueHelmetInt8", + name = "Scold's Bridle", + text = { + "\"The sharper the pain, the sharper the mind.", + "A curious paradox.\"", + "- Shavronne of Umbra", + }, + }, + [85] = { + id = "FourUniqueHelmetInt11", + name = "Indigon", + text = { + "Where the body's limits begin,", + "the mind's limits end.", + }, + }, + [86] = { + id = "FourUniqueHelmetStrDex1", + name = "Greymake", + text = { + "In the end, even heroes fade away.", + }, + }, + [87] = { + id = "FourUniqueHelmetStrDex2", + name = "Erian's Cobble", + text = { + "Sometimes patching up your", + "equipment gets out of hand.", + }, + }, + [88] = { + id = "FourUniqueHelmetStrDex3", + name = "Ironride", + text = { + "Let the rider's aim be true.", + }, + }, + [89] = { + id = "FourUniqueHelmetStrDex4", + name = "The Smiling Knight", + text = { + "He never spoke a word. His opponents imagined", + "their own personal mockeries, most cruel.", + }, + }, + [90] = { + id = "FourUniqueHelmetStrDex5", + name = "The Vile Knight", + text = { + "Familiarity breeds contempt.", + }, + }, + [91] = { + id = "FourUniqueHelmetStrDex7", + name = "The Bringer of Rain", + text = { + "\"What lies beneath your feet?!\"", + "\"Sacred ground, watered with tears of blood!\"", + }, + }, + [92] = { + id = "FourUniqueHelmetStrInt1", + name = "Crown of the Victor", + text = { + "An endless river of bodies lie in the wake of ambition.", + }, + }, + [93] = { + id = "FourUniqueHelmetStrInt2", + name = "Bronzebeard", + text = { + "Heavy is the head.", + }, + }, + [94] = { + id = "FourUniqueHelmetStrInt3", + name = "Crown of the Pale King", + text = { + "A lightless world", + "a silent reign", + "two sightless eyes", + "feed on your pain.", + }, + }, + [95] = { + id = "FourUniqueHelmetStrInt4", + name = "Veil of the Night", + text = { + "The seeds of greatness are planted in darkness,", + "Watered by suffering,", + "Tended by desperation,", + "And bloom steel flowers of victory.", + }, + }, + [96] = { + id = "FourUniqueHelmetStrInt5", + name = "Cornathaum", + text = { + "Pain brings clarity.", + }, + }, + [97] = { + id = "FourUniqueHelmetStrInt6", + name = "The Deepest Tower", + text = { + "Death crawls in darkness, closer than we think.", + }, + }, + [98] = { + id = "FourUniqueHelmetDexInt1", + name = "The Hollow Mask", + text = { + "The roots take hold within...", + }, + }, + [99] = { + id = "FourUniqueHelmetDexInt2", + name = "Mask of the Sanguimancer", + text = { + "A terror of ancient times, his identity", + "remains lost... but his power does not.", + }, + }, + [100] = { + id = "FourUniqueHelmetDexInt3", + name = "Leer Cast", + text = { + "For none of us are as cruel as all of us.", + }, + }, + [101] = { + id = "FourUniqueHelmetDexInt4", + name = "Atsak's Sight", + text = { + "Remaining unseen, the Dishonoured Assassin struck", + "only in the depths of the harshest sandstorms.", + }, + }, + [102] = { + id = "FourUniqueHelmetDexInt5", + name = "The Vertex", + text = { + "\"A queen should be seen, admired, but never touched.\"", + "- Atziri, Queen of the Vaal", + }, + }, + [103] = { + id = "FourUniqueHelmetDexInt6", + name = "The Three Dragons", + text = { + "\"The ice seared his naked feet", + "As the lightning stilled his heart,", + "But it was the flames upon his lover's face", + "That roused him to vengeance.\"", + "- From 'The Three Dragons' by Victario of Sarn", + }, + }, + [104] = { + id = "FourUniqueHelmetDexInt8", + name = "Mind of the Council", + text = { + "The sky tore asunder, black cleaving upon blue", + "The end of life, of Time, with no escape", + "But they found a fragment, a void, a haven", + "And there they waited, as it all began again", + "Dark will, dark knowledge, enemies of Fate", + "They know your mind, because they remember", + }, + }, + [105] = { + id = "FourUniqueGlovesStr2", + name = "Treefingers", + text = { + "The largest beings on Wraeclast", + "are not flesh and blood.", + }, + }, + [106] = { + id = "FourUniqueGlovesStr3", + name = "Lochtonial Caress", + text = { + "Why cling to your sanity? It offers you nothing.", + "Surrender to me, and I will grant you everything.", + }, + }, + [107] = { + id = "FourUniqueGlovesStr4", + name = "Dreadfist", + text = { + "What is worse, the sting of the past, the pain of the present, or the fear of the future?", + }, + }, + [108] = { + id = "FourUniqueGlovesStr5", + name = "Atziri's Acuity", + text = { + "\"The heart is the herald.", + "It will tell me when it is best to strike.\"", + "- Atziri, Queen of the Vaal", + }, + }, + [109] = { + id = "FourUniqueGlovesStr7", + name = "Empire's Grasp", + text = { + "\"I like my vassals at sword point,", + "but my enemies as close as the hilt.\"", + "- Emperor Chitus", + }, + }, + [110] = { + id = "FourUniqueGlovesDex1_", + name = "Northpaw", + text = { + "Fight with the ferocity of the First Ones.", + }, + }, + [111] = { + id = "FourUniqueGlovesDex2", + name = "Grip of Winter", + text = { + "After the eruption, the skies turned grey,", + "ash began to fall, and a chill set in...", + }, + }, + [112] = { + id = "FourUniqueGlovesDex4", + name = "Idle Hands", + text = { + "The devil finds work for idle hands.", + }, + }, + [113] = { + id = "FourUniqueGlovesDex5", + name = "Snakebite", + text = { + "As the serpent shuns thought,", + "It shuns fear.", + "It strikes with the speed of wrath", + "And the skill of compulsion.", + }, + }, + [114] = { + id = "FourUniqueGlovesDex6", + name = "Maligaro's Virtuosity", + text = { + "Maligaro operated effortlessly,", + "with great speed and terrible consequences.", + }, + }, + [115] = { + id = "FourUniqueGlovesInt1", + name = "Painter's Servant", + text = { + "Bloodshed on the crimson shores,", + "longing for the endless sea.", + "Treasures, life, I'd give it all", + "just to capture thee.", + }, + }, + [116] = { + id = "FourUniqueGlovesInt2", + name = "Candlemaker", + text = { + "You can be the wick or the wax. Either way, your light goes out and mine goes on.", + }, + }, + [117] = { + id = "FourUniqueGlovesInt3", + name = "Doedre's Tenure", + text = { + "While Doedre lacked Maligaro's sense of style,", + "she surpassed her master in pure malevolence.", + }, + }, + [118] = { + id = "FourUniqueGlovesInt4", + name = "Kitoko's Current", + text = { + "Reality is a puzzle. Ingenuity is power.", + }, + }, + [119] = { + id = "FourUniqueGlovesInt5", + name = "Demon Stitcher", + text = { + "Xibaqua's treachery was met with divine fury.", + "One by one, the gods reclaimed their flesh,", + "until all that remained was a droplet of pure light:", + "The first Vaal.", + }, + }, + [120] = { + id = "FourUniqueGlovesInt6", + name = "Nightscale", + text = { + "Diamora sings not for hunger, but for longing.", + }, + }, + [121] = { + id = "FourUniqueGlovesInt7", + name = "Leopold's Applause", + text = { + "\"Keep smiling. The deepest cut comes not from insults, but from false praise.\"", + }, + }, + [122] = { + id = "FourUniqueGlovesStrDex1", + name = "Jarngreipr", + text = { + "The whispers of the old gods hum through the iron. They demand a hero.", + }, + }, + [123] = { + id = "FourUniqueGlovesStrDex2", + name = "Aurseize", + text = { + "Wealth is not to be borne lightly.", + }, + }, + [124] = { + id = "FourUniqueGlovesStrDex3", + name = "Deathblow", + text = { + "Anticipation is a gift.", + }, + }, + [125] = { + id = "FourUniqueGlovesStrDex4", + name = "Valako's Vice", + text = { + "Unlike the other gods, when he was born from the volcano,", + "Valako rode the clouds of ash into the thundering sky.", + }, + }, + [126] = { + id = "FourUniqueGlovesStrDex5", + name = "Aerisvane's Wings", + text = { + "The strongest souls are forged through struggle and defeat.", + }, + }, + [127] = { + id = "FourUniqueGlovesStrInt1", + name = "Gravebind", + text = { + "Try as you like to hide the", + "blood on your hands.", + "You'll still know the truth.", + }, + }, + [128] = { + id = "FourUniqueGlovesStrInt2", + name = "Shackles of the Wretched", + text = { + "Captivity breeds creativity.", + }, + }, + [129] = { + id = "FourUniqueGlovesStrInt3", + name = "Blueflame Bracers", + text = { + "The secret was lost with its maker.", + }, + }, + [130] = { + id = "FourUniqueGlovesStrInt4", + name = "The Prisoner's Manacles", + text = { + "Only once did Maligaro wonder if he'd gone too far.", + "His greatest success took three entire legions to capture.", + }, + }, + [131] = { + id = "FourUniqueGlovesDexInt1", + name = "Plaguefinger", + text = { + "Ulcers, scabs, and pocks, the third army makes its claim.", + }, + }, + [132] = { + id = "FourUniqueGlovesDexInt2", + name = "Killjoy", + text = { + "\"Stitches? Wouldn't that defeat the purpose?\"", + "- Jeffry, Torturer's Apprentice", + }, + }, + [133] = { + id = "FourUniqueGlovesDexInt5", + name = "Essentia Sanguis", + text = { + "The darkest clouds clashed and coupled,", + "giving birth to four lightning children of hate.", + }, + }, + [134] = { + id = "FourUniqueBootsStr1", + name = "Legionstride", + text = { + "A wall of steel and muscle.", + }, + }, + [135] = { + id = "FourUniqueBootsStr2", + name = "Corpsewade", + text = { + "Natural decay can be twisted to dark ends.", + }, + }, + [136] = { + id = "FourUniqueBootsStr3", + name = "The Infinite Pursuit", + text = { + "We move to be closer to her, but the distance yet grows.", + }, + }, + [137] = { + id = "FourUniqueBootsStr4", + name = "Trampletoe", + text = { + "The truly mighty are never outnumbered.", + }, + }, + [138] = { + id = "FourUniqueBootsStr5", + name = "Birth of Fury", + text = { + "As the sun rises and the light approaches,", + "so too shall your enemies fear you.", + }, + }, + [139] = { + id = "FourUniqueBootsDex2", + name = "Briarpatch", + text = { + "The druids walk the Grelwood without fear.", + }, + }, + [140] = { + id = "FourUniqueBootsDex3", + name = "Gamblesprint", + text = { + "All your tomorrows lie ahead of you,", + "unknown and snarled to the very last.", + }, + }, + [141] = { + id = "FourUniqueBootsDex4", + name = "Thunderstep", + text = { + "Where legends tread,", + "the world hearkens.", + }, + }, + [142] = { + id = "FourUniqueBootsDex5", + name = "Bushwhack", + text = { + "Banished for his tragic failure,", + "Erian learned to hunt to survive.", + }, + }, + [143] = { + id = "FourUniqueBootsInt1", + name = "Luminous Pace", + text = { + "Blessed are those who tend the Grove.", + }, + }, + [144] = { + id = "FourUniqueBootsInt2", + name = "Wanderlust", + text = { + "All the world is my home.", + }, + }, + [145] = { + id = "FourUniqueBootsInt3", + name = "Bones of Ullr", + text = { + "The dead man walks where", + "the living fear to tread.", + }, + }, + [146] = { + id = "FourUniqueBootsInt4", + name = "Wondertrap", + text = { + "Wonders abound at death's door.", + }, + }, + [147] = { + id = "FourUniqueBootsInt5", + name = "Windscream", + text = { + "The mocking wind, a shielding spell,", + "The haunting screams, a maddening hell", + }, + }, + [148] = { + id = "FourUniqueBootsStrDex1", + name = "The Knight-errant", + text = { + "Some search forever for their path.", + }, + }, + [149] = { + id = "FourUniqueBootsStrDex2", + name = "Darkray Vectors", + text = { + "\"Sirrius flew on wings of light, faster than wind, faster", + "than thought. But try as he might to outrun the darkness,", + "it was there, at every turn, waiting for him.\"", + "- Azmerian legend", + }, + }, + [150] = { + id = "FourUniqueBootsStrDex3", + name = "Obern's Bastion", + text = { + "The storm cannot sway those of sure footing.", + }, + }, + [151] = { + id = "FourUniqueBootsStrInt2", + name = "Wake of Destruction", + text = { + "Tempest's power given form,", + "Flee before the walking storm.", + }, + }, + [152] = { + id = "FourUniqueBootsDexInt2", + name = "Ghostmarch", + text = { + "The cursed ones march forever,", + "On their hopeless, last endeavour.", + }, + }, + [153] = { + id = "FourUniqueBootsDexInt3", + name = "Powertread", + text = { + "The combat stance used by Vaal nobles", + "was as elegant as it was deadly.", + }, + }, + [154] = { + id = "FourUniqueShieldStr1", + name = "Dionadair", + text = { + "Praetor Draven knew his only chance to subjugate", + "the Ezomytes was to catch them unaware.", + }, + }, + [155] = { + id = "FourUniqueShieldStr2", + name = "Wulfsbane", + text = { + "The Counts of Ogham share a", + "legacy of cunning and power.", + }, + }, + [156] = { + id = "FourUniqueShieldStr3", + name = "Doomgate", + text = { + "Welcome to Wraeclast.", + }, + }, + [157] = { + id = "FourUniqueShieldStr4", + name = "Window to Paradise", + text = { + "\"Beyond fire, blood, and nightmare,", + "the Savior will build utopia.\"", + }, + }, + [158] = { + id = "FourUniqueShieldStr5", + name = "The Wailing Wall", + text = { + "Some stories are never told.", + }, + }, + [159] = { + id = "FourUniqueShieldStr6", + name = "Lycosidae", + text = { + "A true predator does not chase; It waits.", + }, + }, + [160] = { + id = "FourUniqueShieldStr7", + name = "Redblade Banner", + text = { + "Blood shed is blood shared.", + }, + }, + [161] = { + id = "FourUniqueShieldStr8", + name = "The Surrender", + text = { + "Our hearts cry out", + "but are silenced by our flesh", + "and so we give up our flesh.", + }, + }, + [162] = { + id = "FourUniqueShieldStr13", + name = "Chernobog's Pillar", + text = { + "Fire dances with those who doubt", + "Licks the skin and flesh from the fearful", + "Where there is no fear", + "There is no flame", + }, + }, + [163] = { + id = "FourUniqueShieldStrDex1", + name = "Arvil's Wheel", + text = { + "The unending carnage of war", + "mercilessly grinds away", + "at body and mind.", + }, + }, + [164] = { + id = "FourUniqueShieldStrDex2", + name = "Merit of Service", + text = { + "Lead by example, and you shall never be alone.", + }, + }, + [165] = { + id = "FourUniqueShieldStrDex4", + name = "Feathered Fortress", + text = { + "Ride the western wind, and take flight.", + }, + }, + [166] = { + id = "FourUniqueShieldStrInt1", + name = "Alkem Eira", + text = { + "May your resolve never waver.", + }, + }, + [167] = { + id = "FourUniqueShieldStrInt2", + name = "Oaksworn", + text = { + "The druids swore to protect the Grelwood with their very lives.", + }, + }, + [168] = { + id = "FourUniqueShieldStrInt3", + name = "Saffell's Frame", + text = { + "A swift mind solves problems before they occur.", + }, + }, + [169] = { + id = "FourUniqueShieldStrInt4", + name = "Crest of Ardura", + text = { + "When the Red Sekhema called,", + "the Ardura were the first to answer.", + }, + }, + [170] = { + id = "FourUniqueShieldStrInt5", + name = "Prism Guardian", + text = { + "When blood is paid, the weak think twice.", + }, + }, + [171] = { + id = "FourUniqueShieldStrInt6", + name = "Rise of the Phoenix", + text = { + "My bearer shall be guarded by flame,", + "for I am the phoenix, forever radiant in glory.", + }, + }, + [172] = { + id = "FourUniqueShieldDex1", + name = "Dunkelhalt", + text = { + "\"A thief in the night, Draven did creep,", + "families asleep, taken, held on high.", + "Clever, he thought, 'til his children paid.", + "Nay, villain, a man never bleeds alone.\"", + }, + }, + [173] = { + id = "FourUniqueShieldDex2", + name = "Nocturne", + text = { + "Light and shadow chase eternal,", + "but neither knows the other exists...", + }, + }, + [174] = { + id = "FourUniqueShieldDex3", + name = "Rondel de Ezo", + text = { + "\"Resist for long enough, and your oppressor", + "will lose his will. Then, you've won.\"", + }, + }, + [175] = { + id = "FourUniqueShieldDex4", + name = "Bloodbarrier", + text = { + "A window onto a realm of red,", + "where countless voices scream...", + }, + }, + [176] = { + id = "FourUniqueShieldDex6", + name = "Silverthorne", + text = { + "As a boy, in the arena, Daresso learned to", + "feign weakness to open up a lethal blow.", + }, + }, + [177] = { + id = "FourUniqueShieldDex11_", + name = "Calgyra's Arc", + text = { + "\"There is nowhere my vengeance cannot find you.\"", + }, + }, + [178] = { + id = "FourUniqueShieldDex12", + name = "Sunsplinter", + text = { + "\"Lundara held back the hordes, while Solerai rose to split the sky.", + "With a single stroke, she ended the Winter of the World.\"", + "- Wranga, tale-woman of the Wahida akhara", + }, + }, + [179] = { + id = "FourUniqueFocus1", + name = "Deathrattle", + text = { + "The cry of death whispers in the wind.", + }, + }, + [180] = { + id = "FourUniqueFocus2", + name = "Threaded Light", + text = { + "A gift, a braid, of golden hair.", + "The war, forgotten.", + "The reason, remembered.", + }, + }, + [181] = { + id = "FourUniqueFocus3", + name = "Effigy of Cruelty", + text = { + "The horrors we imagined as children", + "still exist somewhere in the dark...", + }, + }, + [182] = { + id = "FourUniqueFocus4", + name = "Carrion Call", + text = { + "Obedience stretches beyond the grave.", + }, + }, + [183] = { + id = "FourUniqueFocus5", + name = "Serpent's Lesson", + text = { + "Sinuous, entwined... inextricable.", + }, + }, + [184] = { + id = "FourUniqueFocus6", + name = "The Eternal Spark", + text = { + "A flash of blue, a stormcloud's kiss,", + "her motionless dance the pulse of bliss", + }, + }, + [185] = { + id = "FourUniqueFocus7", + name = "Apep's Supremacy", + text = { + "Give him your body, and your burdens will follow.", + }, + }, + [186] = { + id = "FourUniqueFocus8", + name = "Rathpith Globe", + text = { + "The Vaal emptied their slaves of beating hearts,", + "and left a mountain of twitching dead.", + }, + }, + [187] = { + id = "FourUniqueQuiver1", + name = "Asphyxia's Wrath", + text = { + "Mist of breath", + "Icing to lips and throat", + "As the warm ones choke and fall", + "Upon the frozen wasteland.", + }, + }, + [188] = { + id = "FourUniqueQuiver2_", + name = "Blackgleam", + text = { + "Molten feathers, veiled spark,", + "Hissing arrows from the dark.", + }, + }, + [189] = { + id = "FourUniqueQuiver3", + name = "The Lethal Draw", + text = { + "Life and death ooze from the same sap.", + }, + }, + [190] = { + id = "FourUniqueQuiver5", + name = "Rearguard", + text = { + "\"It's a rare man that has eyes in the back of his head.\"", + "- Kiravi, Vaal Archer", + }, + }, + [191] = { + id = "FourUniqueQuiver6", + name = "Murkshaft", + text = { + "\"Boiling frogs isn't for spells, dear. That's a disgusting", + "rumour. They're actually for brewing poisons.\"", + "- Selassie of the Black Fen", + }, + }, + [192] = { + id = "FourUniqueQuiver8", + name = "Cadiro's Gambit", + text = { + "\"One can never fully eliminate Chance, but with the right", + "machinations, all the outcomes may be turned in your favour...\"", + "- Cadiro Perandus", + }, + }, + [193] = { + id = "FourUniqueAmulet1", + name = "Igniferis", + text = { + "A hearth unyielding, ever warm,", + "A light unbroken, endlessly reborn.", + }, + }, + [194] = { + id = "FourUniqueAmulet2", + name = "Idol of Uldurn", + text = { + "Worship of house gods was tolerated", + "in Oriath, so long as it remained private.", + }, + }, + [195] = { + id = "FourUniqueAmulet3", + name = "The Everlasting Gaze", + text = { + "What they saw was what they believed, and", + "they believed Lunaris had not abandoned them.", + }, + }, + [196] = { + id = "FourUniqueAmulet4", + name = "Ungil's Harmony", + text = { + "Gentle anger, raging calm.", + }, + }, + [197] = { + id = "FourUniqueAmulet5", + name = "Revered Resin", + text = { + "The sacred sap flows slowly, but surely.", + }, + }, + [198] = { + id = "FourUniqueAmulet6", + name = "Carnage Heart", + text = { + "Forged from the blood of countless wars,", + "its thirst has only begun.", + }, + }, + [199] = { + id = "FourUniqueAmulet7", + name = "Surefooted Sigil", + text = { + "Natural grace is born, not earned.", + }, + }, + [200] = { + id = "FourUniqueAmulet8", + name = "Defiance of Destiny", + text = { + "The respect of Karui warriors is hard to earn,", + "but lasts a lifetime... and beyond.", + }, + }, + [201] = { + id = "FourUniqueAmulet9", + name = "Stone of Lazhwar", + text = { + "You are slow, foolish and ignorant.", + "I am not.", + }, + }, + [202] = { + id = "FourUniqueAmulet10_", + name = "Ligurium Talisman", + text = { + "Healing the soul requires sacrifice.", + }, + }, + [203] = { + id = "FourUniqueAmulet12", + name = "Rondel of Fragility", + text = { + "Fanatics are the most dangerous enemy,", + "for they care not for their own survival.", + }, + }, + [204] = { + id = "FourUniqueAmulet13", + name = "The Anvil", + text = { + "Forge your Perseverance on the Anvil of Faith.", + }, + }, + [205] = { + id = "FourUniqueAmulet14", + name = "Yoke of Suffering", + text = { + "Let the unrepentant be dragged ever downwards by the weight of their sins.", + }, + }, + [206] = { + id = "FourUniqueAmulet15_", + name = "Astramentis", + text = { + "Mindless rage will shake the world,", + "Cunning lies will bend it.", + "Reckless haste will break the world,", + "And into darkness send it.", + }, + }, + [207] = { + id = "FourUniqueAmulet16", + name = "Fixation of Yix", + text = { + "He knew not why he was changing, only", + "that he wanted to hold his family close...", + }, + }, + [208] = { + id = "FourUniqueAmulet17", + name = "Beacon of Azis", + text = { + "The homeguard signalled for aid against a surprise attack,", + "but it was not their dekharas that responded.", + "It was Solerai herself.", + }, + }, + [209] = { + id = "FourUniqueAmulet18", + name = "Fireflower", + text = { + "Tale-women in training drink of a painful desert fruit.", + "Fire, they learn, springs from agony.", + }, + }, + [210] = { + id = "FourUniqueAmulet19_", + name = "Eye of Chayula", + text = { + "Never blinking, always watching.", + }, + }, + [211] = { + id = "FourUniqueAmulet20", + name = "Serpent's Egg", + text = { + "When Kabala the Serpent Queen was banished from Keth,", + "the Sekhemas took a single hostage as punishment.", + }, + }, + [212] = { + id = "FourUniqueRing1", + name = "Blackheart", + text = { + "Fear is highly infectious.", + }, + }, + [213] = { + id = "FourUniqueRing2a", + name = "Icefang Orbit", + text = { + "Those members of the Brotherhood who employ the venom of", + "Trarthan ice snakes must take great care with the volatile substance.", + }, + }, + [214] = { + id = "FourUniqueRing2b", + name = "Venopuncture", + text = { + "There is a way to survive the bite of an ice snake,", + "but few have the resolve to attempt it.", + }, + }, + [215] = { + id = "FourUniqueRing3", + name = "Prized Pain", + text = { + "Agony brings clarity to those of pure mind.", + }, + }, + [216] = { + id = "FourUniqueRing4", + name = "Glowswarm", + text = { + "As their eyes adjusted, they became aware of a strange", + "blue light. Countless glowing worms crawled above,", + "blissfully unaware of their flight from the sirens.", + }, + }, + [217] = { + id = "FourUniqueRing5", + name = "Doedre's Damning", + text = { + "Where her mouth should have been there was only a whirling, black void.", + }, + }, + [218] = { + id = "FourUniqueRing6", + name = "Seed of Cataclysm", + text = { + "The dawn of a new era is set into motion", + }, + }, + [219] = { + id = "FourUniqueRing7", + name = "Cracklecreep", + text = { + "Fear the fire that spreads like a plague.", + }, + }, + [220] = { + id = "FourUniqueRing8", + name = "Blistering Bond", + text = { + "\"The Brotherhood of Silence does not set out to torture our targets.", + "Excruciating pain is simply a byproduct of certain... necessary methods.\"", + }, + }, + [221] = { + id = "FourUniqueRing10", + name = "Polcirkeln", + text = { + "I rule the north", + "A legacy earned", + "Time and time again", + "Sing Meginord's song!", + }, + }, + [222] = { + id = "FourUniqueRing11", + name = "Dream Fragments", + text = { + "Doryani stumbled into a realm of madness", + "And awoke its Master.", + }, + }, + [223] = { + id = "FourUniqueRing12", + name = "Whisper of the Brotherhood", + text = { + "Forged by the last remaining brother", + "to return all that was once given.", + }, + }, + [224] = { + id = "FourUniqueRing13", + name = "Levinstone", + text = { + "Highgate held other secrets.", + }, + }, + [225] = { + id = "FourUniqueRing14", + name = "The Burrower", + text = { + "It coils deeper and deeper", + "It slithers between thoughts", + "It lies beneath the valley", + "It lies in our minds", + }, + }, + [226] = { + id = "FourUniqueRing15", + name = "Call of the Brotherhood", + text = { + "Forged by three brothers", + "so that they may recognize each other", + "across any distance of time or travel.", + }, + }, + [227] = { + id = "FourUniqueRing16", + name = "Ming's Heart", + text = { + "Ming slew Tranquillity", + "Took Chaos for his wife", + "And on Her immortal finger", + "He placed his Heart", + }, + }, + [228] = { + id = "FourUniqueRing17", + name = "Blackflame", + text = { + "Beyond the veil of death, there burns a fire", + "by whose light night is borne.", + }, + }, + [229] = { + id = "FourUniqueRing18", + name = "Original Sin", + text = { + "Innocence rose to godhood not on inspired faith,", + "but on the vilification and hatred of another.", + }, + }, + [230] = { + id = "FourUniqueRing19", + name = "Vigilant View", + text = { + "The warriors of the Unblinking Eye moved", + "together as one, shoulder to shoulder.", + }, + }, + [231] = { + id = "FourUniqueRing20", + name = "Death Rush", + text = { + "To truly appreciate life you must be there when it ends", + }, + }, + [232] = { + id = "FourUniqueRing21", + name = "Thief's Torment", + text = { + "The ring I stole,", + "My finger they took,", + "A shrouded mind,", + "Cut their curses short,", + "As I drained their spirit", + "And stole their soul.", + "A blessing is often a curse.", + }, + }, + [233] = { + id = "FourUniqueRing22", + name = "Evergrasping Ring", + text = { + "Power comes to those who seek", + "Death comes to those who reach", + }, + }, + [234] = { + id = "FourUniqueRing23", + name = "Heartbound Loop", + text = { + "When the axe finally fell, Seryl shared his pain,", + "and the last thought that flickered through his", + "fading mind was her broken, shattered scream.", + }, + }, + [235] = { + id = "FourUniqueRing24", + name = "Snakepit", + text = { + "They wrap around you until your blood turns as cold as theirs.", + }, + }, + [236] = { + id = "FourUniqueRing25", + name = "Gifts from Above", + text = { + "God blesses those who bless themselves.", + }, + }, + [237] = { + id = "FourUniqueRing28", + name = "Perandus Seal", + text = { + "A pact with Prospero always comes at a price.", + }, + }, + [238] = { + id = "FourUniqueRing29", + name = "Andvarius", + text = { + "Danger is the price of wealth.", + }, + }, + [239] = { + id = "FourUniqueRing30", + name = "Ventor's Gamble", + text = { + "In a blaze of glory,", + "An anomaly defying all odds", + "The \"unkillable\" beast met the divine", + "And Ventor met his latest trophy.", + }, + }, + [240] = { + id = "FourUniqueRing32", + name = "Kalandra's Touch", + text = { + "Power is a matter of perspective.", + }, + }, + [241] = { + id = "FourUniqueBelt1", + name = "Meginord's Girdle", + text = { + "Kaom's strength was rivaled only by", + "the great Meginord of the north.", + }, + }, + [242] = { + id = "FourUniqueBelt2", + name = "Midnight Braid", + text = { + "Adversity is the soil in", + "which persistence grows.", + }, + }, + [243] = { + id = "FourUniqueBelt3", + name = "Keelhaul", + text = { + "Below all living things,", + "there exists a flow...", + }, + }, + [244] = { + id = "FourUniqueBelt5", + name = "Birthright Buckle", + text = { + "Some families have peculiar gifts...", + }, + }, + [245] = { + id = "FourUniqueBelt6", + name = "Brynabas", + text = { + "The Brinerot sail without fear of storms.", + }, + }, + [246] = { + id = "FourUniqueBelt8", + name = "Soul Tether", + text = { + "Vaal bloodpriests were among the earliest intellectuals on record.", + "It was they who found that a newly freed soul would", + "desperately cling to any other source of life.", + }, + }, + [247] = { + id = "FourUniqueBelt9", + name = "Infernoclasp", + text = { + "Tempered by the forbidden flame.", + }, + }, + [248] = { + id = "FourUniqueBelt10", + name = "Goregirdle", + text = { + "Bleeding just means you're still alive.", + }, + }, + [249] = { + id = "FourUniqueBelt12", + name = "Ryslatha's Coil", + text = { + "All creatures have the potential for greatness or unequivocal failure.", + }, + }, + [250] = { + id = "FourUniqueBelt13", + name = "Coward's Legacy", + text = { + "Death is your most important duty.", + "Face it, or curse your bloodline for all eternity.", + }, + }, + [251] = { + id = "FourUniqueBelt15", + name = "Bijouborne", + text = { + "Trifle not with the trinket mage.", + }, + }, + [252] = { + id = "FourUniqueBelt16_", + name = "Silverpoint", + text = { + "Asinia promised vengeance beyond death,", + "and she found a way to keep that promise.", + }, + }, + [253] = { + id = "FourUniqueBelt17", + name = "Waistgate", + text = { + "Clever artifice is not always complex.", + }, + }, + [254] = { + id = "FourUniqueBelt18_", + name = "Headhunter", + text = { + "\"A man's soul rules from a cavern of bone, learns and", + "judges through flesh-born windows. The heart is meat.", + "The head is where the Man is.\"", + "- Lavianga, Advisor to Kaom", + }, + }, + [255] = { + id = "FourUniqueBelt21", + name = "Shavronne's Satchel", + text = { + "Bring mystery to life. Again and again.", + }, + }, + [256] = { + id = "FourUniqueOneHandMace1", + name = "Brynhand's Mark", + text = { + "The mark of the smith was widely known.", + }, + }, + [257] = { + id = "FourUniqueOneHandMace2", + name = "Wylund's Stake", + text = { + "Shaped metal never forgets the forge.", + }, + }, + [258] = { + id = "FourUniqueOneHandMace3", + name = "Frostbreath", + text = { + "A merciful murderer swept through the streets of Sarn", + "Robbing breath from the weak and worthless.", + }, + }, + [259] = { + id = "FourUniqueOneHandMace4", + name = "Trenchtimbre", + text = { + "Ezomyte loyalty was not given to distant leaders.", + "It was earned by comrades in arms.", + }, + }, + [260] = { + id = "FourUniqueOneHandMace5", + name = "Sculpted Suffering", + text = { + "The Abyssals were created, not born,", + "and every moment in the light was agony.", + }, + }, + [261] = { + id = "FourUniqueOneHandMace6", + name = "Seeing Stars", + text = { + "Within lies a window.", + }, + }, + [262] = { + id = "FourUniqueOneHandMace7", + name = "Nebuloch", + text = { + "They hoped that, trapped in its prison,", + "the creature would age and perish.", + "But time would not touch the fiend.", + }, + }, + [263] = { + id = "FourUniqueOneHandMace13", + name = "Mjölner", + text = { + "Look the storm in the eye and you will have its respect.", + }, + }, + [264] = { + id = "FourUniqueTwoHandMace1", + name = "Hoghunt", + text = { + "There was a very clear and delicious", + "reason why the Ezomytes chose to", + "stop their flight and settle in Phaaryl.", + }, + }, + [265] = { + id = "FourUniqueTwoHandMace2", + name = "Hrimnor's Hymn", + text = { + "\"The crack of bone, the spray of blood.", + "Is there sweeter music?\"", + "- Hrimnor of the Ezomytes.", + }, + }, + [266] = { + id = "FourUniqueTwoHandMace3", + name = "Trephina", + text = { + "The art of surgery advances one mistake at a time.", + }, + }, + [267] = { + id = "FourUniqueTwoHandMace4", + name = "Brain Rattler", + text = { + "The mind may have no limits, but the skull sure does.", + }, + }, + [268] = { + id = "FourUniqueTwoHandMace5", + name = "The Empty Roar", + text = { + "Secrecy and silence are powers all their own.", + }, + }, + [269] = { + id = "FourUniqueTwoHandMace6", + name = "Shyaba", + text = { + "Be not deceived by the treachery of men.", + }, + }, + [270] = { + id = "FourUniqueTwoHandMace7", + name = "Chober Chaber", + text = { + "The faithful may continue to serve, even after death.", + }, + }, + [271] = { + id = "FourUniqueTwoHandMace8", + name = "Quecholli", + text = { + "\"The finest prosperity grows from the direst", + "carnage. Such is the nature of progress.\"", + "- Doryani of the Vaal", + }, + }, + [272] = { + id = "FourUniqueTwoHandMace9", + name = "Tidebreaker", + text = { + "The sea strikes the rock relentlessly.", + "Whether in one day or in ten thousand years,", + "eventually the rock will crumble,", + "and the Brine King's domain will grow.", + }, + }, + [273] = { + id = "FourUniqueTwoHandMace13", + name = "The Hammer of Faith", + text = { + "The secret Order endured by publicly", + "praying however the Templars demanded.", + "One day, justice would fall upon them...", + }, + }, + [274] = { + id = "FourUniqueSpear1", + name = "Splinter of Loratta", + text = { + "The Baleful Gem's corruption lingers still...", + }, + }, + [275] = { + id = "FourUniqueSpear2", + name = "Tyranny's Grip", + text = { + "The might of the Eternal Empire was formidable,", + "but rebels of every culture stood together as one.", + }, + }, + [276] = { + id = "FourUniqueSpear3", + name = "Chainsting", + text = { + "The Sacred Hunt ends with mercy.", + }, + }, + [277] = { + id = "FourUniqueSpear4", + name = "Skysliver", + text = { + "Heads fall to the sand, just as the star fell from the sky", + }, + }, + [278] = { + id = "FourUniqueSpear5", + name = "Daevata's Wind", + text = { + "\"You killed their Golden Sekhema. The Maraketh will think of nothing", + "but vengeance now.\" - Dimos, Advisor to General Titucius", + }, + }, + [279] = { + id = "FourUniqueSpear6", + name = "Tangletongue", + text = { + "\"In the hands of Orbala, it made a god bleed.\"", + "- Wranga, tale-woman of the Wahida akhara", + }, + }, + [280] = { + id = "FourUniqueSpear7", + name = "Saitha's Spear", + text = { + "Born in a star of man's own make,", + "fused to her hand by her last mistake.", + }, + }, + [281] = { + id = "FourUniqueSpear13", + name = "Spire of Ire", + text = { + "The spear was specially forged to assassinate Voll,", + "but Maligaro never got a chance to use it...", + }, + }, + [282] = { + id = "FourUniqueQuarterstaff1", + name = "The Blood Thorn", + text = { + "Touch not the thorn, for only blood and pain await.", + }, + }, + [283] = { + id = "FourUniqueQuarterstaff2", + name = "Pillar of the Caged God", + text = { + "Forged to rule the waves and tide", + "Destined to serve the monkey's paw", + "Strong as a tower of iron", + "Deft as the needle doubt", + }, + }, + [284] = { + id = "FourUniqueQuarterstaff3", + name = "The Sentry", + text = { + "The night Draven attacked,", + "Erian was asleep at his post.", + }, + }, + [285] = { + id = "FourUniqueQuarterstaff5", + name = "Matsya", + text = { + "In our tales, and in our hearts, the rivers still flow.", + }, + }, + [286] = { + id = "FourUniqueQuarterstaff6", + name = "Nazir's Judgement", + text = { + "The first witch hunter knew one critical tactic:", + "never let your enemy have a clear moment.", + }, + }, + [287] = { + id = "FourUniqueWand1", + name = "The Wicked Quill", + text = { + "With a flick of the finger, their fates are written,", + "the pages torn to a million pieces.", + }, + }, + [288] = { + id = "FourUniqueWand2", + name = "Sanguine Diviner", + text = { + "One way or another, it will find what it seeks.", + }, + }, + [289] = { + id = "FourUniqueWand3", + name = "Lifesprig", + text = { + "From the smallest seeds", + "To the tallest redwoods,", + "Life endures in Wraeclast.", + }, + }, + [290] = { + id = "FourUniqueWand4", + name = "Adonia's Ego", + text = { + "Adonia rose with eyes afire, emanating a ghastly aura, and", + "broke off a carving from the wall of the Throne Room.", + "\"You think me powerless without my wand? Insult me again!\"", + }, + }, + [291] = { + id = "FourUniqueWand5", + name = "Enezun's Charge", + text = { + "He alone was welcome in the sacred spaces of the Titans.", + }, + }, + [292] = { + id = "FourUniqueWand7", + name = "Cursecarver", + text = { + "Lost in the Black Fen, Erian hoped that dawn would save him. He had no idea how far away the light truly was.", + }, + }, + [293] = { + id = "FourUniqueStaff1", + name = "Dusk Vigil", + text = { + "The candlemass tradition was born in a time of darkness and fear.", + }, + }, + [294] = { + id = "FourUniqueStaff2", + name = "Taryn's Shiver", + text = { + "Shed by the winged beast of night,", + "A scaly frost-encrusted thorn.", + "All who feel its wintry light", + "Shiver in pain at the frozen dawn.", + }, + }, + [295] = { + id = "FourUniqueStaff3", + name = "Earthbound", + text = { + "An ancient Azmeri staff, overgrown by roots...", + }, + }, + [296] = { + id = "FourUniqueStaff5", + name = "The Searing Touch", + text = { + "Burn to cinders, scar and maim,", + "Rule a world, bathed in flame.", + }, + }, + [297] = { + id = "FourUniqueStaff6", + name = "Sire of Shards", + text = { + "That which was broken may yet break.", + }, + }, + [298] = { + id = "FourUniqueStaff14", + name = "The Whispering Ice", + text = { + "\"From what beast you derived, we can only fathom.", + "Aye, you of living ice, rotting gill, and untold nightmare!", + "We Brinerot return ye to the sea.\"", + "- Weylam Roth", + }, + }, + [299] = { + id = "FourUniqueBow1", + name = "Widowhail", + text = { + "\"I loosed a volley of arrows into the heart of the man", + "who slew my beloved. There was no satisfaction, no", + "healing, no revenge. There was only... emptiness.\"", + }, + }, + [300] = { + id = "FourUniqueBow2", + name = "Quill Rain", + text = { + "\"The rain of a thousand quills that whittle", + "present into past, life into death.\"", + "- Rigwald of the Ezomytes", + }, + }, + [301] = { + id = "FourUniqueBow4", + name = "Splinterheart", + text = { + "The forests of the Vastiri held many secrets", + "mystical and dark. Men learned not to wander,", + "lest they return with a strange new purpose.", + }, + }, + [302] = { + id = "FourUniqueBow5", + name = "Doomfletch", + text = { + "\"Toasted or frozen", + "Or twitching in the light", + "I'm not fussy", + "And neither is Death.\"", + "- Koralus Doomfletch", + }, + }, + [303] = { + id = "FourUniqueBow6", + name = "Death's Harp", + text = { + "The mournful music of the strings,", + "The creaking arch, the arrow sings.", + "A choking cry, a rattled breath,", + "The Reaper's Song, the Harp of Death.", + }, + }, + [304] = { + id = "FourUniqueBow7", + name = "Voltaxic Rift", + text = { + "The eldritch storm descended upon us, and bruised lightning", + "rained down. Metal withered and flesh melted before its", + "arcane power. There was no escape, no shelter. Only despair.", + }, + }, + [305] = { + id = "FourUniqueBow8", + name = "Slivertongue", + text = { + "A hundred blind heads, each seeking the taste of prey on the air.", + }, + }, + [306] = { + id = "FourUniqueBow13_", + name = "Lioneye's Glare", + text = { + "\"Kinslayer, you dishonour your own traditions to turn the tide of battle!", + "Let us see which is stronger... Karui savagery or the might of the Empire!\"", + "- General Marceus Lioneye", + }, + }, + [307] = { + id = "FourUniqueCrossbow1", + name = "Mist Whisper", + text = { + "Sibilant promises surrounded them in the night.", + "All the travelers had to give him was their devotion...", + }, + }, + [308] = { + id = "FourUniqueCrossbow2", + name = "Rampart Raptor", + text = { + "\"His approach to the gate was met with sounding trumpets", + "and an unfurling of banners. He never saw it coming.\"", + "- anonymous Brotherhood of Silence report", + }, + }, + [309] = { + id = "FourUniqueCrossbow13", + name = "The Last Lament", + text = { + "\"And here we shall remain...", + "trapped in our symphony of eternal anguish.", + "Artist and Composer, their fates entwined for all of time.\"", + "- Adamantia Brektov, the Composer", + }, + }, + [310] = { + id = "FourUniqueSceptre1", + name = "The Dark Defiler", + text = { + "Rare is the Necromancer who leads", + "his undead armies from the front.", + }, + }, + [311] = { + id = "FourUniqueSceptre4", + name = "Font of Power", + text = { + "Tale-women may not fight directly,", + "for they have a much higher purpose.", + }, + }, + [312] = { + id = "FourUniqueSceptre6", + name = "Guiding Palm", + text = { + "\"When the Third Pact was written in stone, the Dreamer gave the alliance of men and", + "beasts knowledge. In return, they gave him a drop of blood; one from each of the", + "races of Wraeclast. In the centuries that followed, his Will began to subtly change.\"", + "- Book of the Benevolent Dreamer, Histories 220:5", + }, + }, + [313] = { + id = "FourUniqueSceptre6a", + name = "Guiding Palm of the Heart", + text = { + "\"Power of the Red Pyre! Flaming Heart of the Hive!", + "I release your burning message to rest here, forevermore.\"", + "The Dreamer declared, casting out the lingering dark embers within him.", + }, + }, + [314] = { + id = "FourUniqueSceptre6b", + name = "Guiding Palm of the Eye", + text = { + "\"With piercing eyes, you saw through the Stillness.", + "Undulating as one, you gloriously covered all in white.", + "But... I can bear you no longer.\"", + "The Dreamer whispered with fogging breath, ice creeping down his hand.", + }, + }, + [315] = { + id = "FourUniqueSceptre6c", + name = "Guiding Palm of the Mind", + text = { + "\"Deep in thought, you would tremble the very air before you.", + "Wreathed in light, you nurtured them all.", + "And yet... Your nature became you.\"", + "The Dreamer mused with aching heart, as remnants of forking tendrils burst forth.", + }, + }, + [316] = { + id = "FourUniqueSceptre6d", + name = "Palm of the Dreamer", + text = { + "\"We sometimes fail. We sometimes succeed. Who determines one from the other?", + "I now know we can never be made One, if we are bore of differing desires.", + "And yet, I have hope for a new truth. And I will see it... made real.\"", + "- The Benevolent Dreamer", + }, + }, + [317] = { + id = "FourUniqueCharm1", + name = "Nascent Hope", + text = { + "\"Even in the face of the Winter of the World,", + "life found a way. The Spirit always provides.\"", + }, + }, + [318] = { + id = "FourUniqueCharm2", + name = "Sanguis Heroum", + text = { + "Wraeclast has known too few true heroes.", + "It remembers those that stood in defiance.", + }, + }, + [319] = { + id = "FourUniqueCharm3", + name = "Arakaali's Gift", + text = { + "Devotees of the Goddess of Lust", + "needed never fear her sting.", + }, + }, + [320] = { + id = "FourUniqueCharm4", + name = "Beira's Anguish", + text = { + "They found a crying child tied to a frozen pyre.", + "She was clad in ice, but the village was ash.", + }, + }, + [321] = { + id = "FourUniqueCharm5", + name = "The Black Cat", + text = { + "The most beloved member of every Brinerot crew", + "is the one that refuses to do any actual work.", + }, + }, + [322] = { + id = "FourUniqueCharm6", + name = "For Utopia", + text = { + "\"It may be centuries hence, but I still hold utmost faith.", + "The Savior will rise, and mankind will be free.\"", + }, + }, + [323] = { + id = "FourUniqueCharm7", + name = "The Fall of the Axe", + text = { + "\"When the headsman's blade swings,", + "your last moments stretch to eternity.\"", + "- Vorm, the Twice-Pardoned", + }, + }, + [324] = { + id = "FourUniqueCharm8", + name = "Ngamahu's Chosen", + text = { + "Kaom was not known for his restraint.", + }, + }, + [325] = { + id = "FourUniqueCharm9", + name = "Breath of the Mountains", + text = { + "\"To scrape the sky,", + "to touch the clouds themselves,", + "is to know true freedom.\"", + "- Mutewind saying", + }, + }, + [326] = { + id = "FourUniqueCharm10", + name = "Valako's Roar", + text = { + "The sea swells, the sky thunders; two ships tilt at odds.", + "Flashes of light show only swinging axes... and a grin.", + }, + }, + [327] = { + id = "FourUniqueCharm11", + name = "Forsaken Bangle", + text = { + "Among the Templars, a secret few ate the sins of others.", + "They bore this burden to empower their hidden Order.", + }, + }, + [328] = { + id = "FourUniquePinnacle1", + name = "Morior Invictus", + text = { + "The Unblinking Eye did not cower and wail.", + "They stood against the end.", + }, + }, + [329] = { + id = "FourUniquePinnacle2", + name = "Solus Ipse", + text = { + "One warrior alone survived to face the Arbiter.", + }, + }, + [330] = { + id = "FourUniquePinnacle3", + name = "Sine Aequo", + text = { + "The greatest warrior of his era fought with honour.", + }, + }, + [331] = { + id = "FourUniquePinnacle4", + name = "Ab Aeterno", + text = { + "His enemy was for endurance forged. His own waned.", + }, + }, + [332] = { + id = "FourUniquePinnacle5", + name = "Sacred Flame", + text = { + "Fire destroys, but fire also purifies.", + "Life always springs anew.", + }, + }, + [333] = { + id = "FourUniqueSanctum1", + name = "Temporalis", + text = { + "The final element the tale-women", + "mastered was Time itself.", + }, + }, + [334] = { + id = "FourUniqueSanctum2", + name = "Sandstorm Visage", + text = { + "A fell wind brings death.", + }, + }, + [335] = { + id = "FourUniqueSanctum3", + name = "Blessed Bonds", + text = { + "\"We survived the endless winter.", + "We endure the long summer.", + "One day, spring will return the rains.\"", + }, + }, + [336] = { + id = "FourUniqueSanctum4a", + name = "Sekhema's Resolve", + text = { + "Though the summer of centuries burns the", + "Vastiri to dust, we remain, unchanged.", + }, + }, + [337] = { + id = "FourUniqueSanctum4b", + name = "Sekhema's Resolve", + text = { + "Though the Winter of the World shrouded the", + "Vastiri in ice, we remained, unchanged.", + }, + }, + [338] = { + id = "FourUniqueSanctum4c", + name = "Sekhema's Resolve", + text = { + "Though the rains refuse to return to a dry", + "Vastiri, we shall remain, unchanged.", + }, + }, + [339] = { + id = "FourUniqueUltimatum1", + name = "Glimpse of Chaos", + text = { + "Man retains sanity and strives toward civilisation", + "only under the blessed veil of ignorance.", + }, + }, + [340] = { + id = "FourUniqueUltimatum2", + name = "Zerphi's Genesis", + text = { + "The most horrifying ideas often begin with a simple innovation.", + }, + }, + [341] = { + id = "FourUniqueUltimatum3", + name = "Mahuxotl's Machination", + text = { + "The Banished Architect sought to employ the darkest secrets of the Vaal.", + }, + }, + [342] = { + id = "FourUniqueUltimatum4", + name = "Hateforge", + text = { + "The first Karui born on the fringes of the Vaal empire developed a blood fever born of corruption.", + }, + }, + [343] = { + id = "FourUniqueExpedition1", + name = "Svalinn", + text = { + "The priests found the Great Shield the night it fell to Middengard,", + "but it was the smiths who delved into the secrets it held.", + }, + }, + [344] = { + id = "FourUniqueExpedition2", + name = "Keeper of the Arc", + text = { + "The priests of the Kalguur keep faith through numbers", + "and calculation, not unprovable promises.", + }, + }, + [345] = { + id = "FourUniqueExpedition3_", + name = "Olroth's Resolve", + text = { + "Olroth the Gallant,", + "tireless and true,", + "he fights for me,", + "he fights for you!", + }, + }, + [346] = { + id = "FourUniqueExpedition4", + name = "Olrovasara", + text = { + "\"True heroes grow stronger in the face of adversity.\"", + "- Fourth Tenet of the Knights of the Sun", + }, + }, + [347] = { + id = "FourUniqueDelirium1", + name = "Assailum", + text = { + "A moment of calm before the battle can end the war.", + }, + }, + [348] = { + id = "FourUniqueDelirium2", + name = "Perfidy", + text = { + "The Trickster God turned the very Day and Night against each other.", + "What hope have you?", + }, + }, + [349] = { + id = "FourUniqueDelirium3", + name = "Melting Maelstrom", + text = { + "What is life, but a dreamlike spiral of panic?", + }, + }, + [350] = { + id = "FourUniqueDelirium4", + name = "Collapsing Horizon", + text = { + "The edges bend, the world flexes, the infinite spills into view.", + }, + }, + [351] = { + id = "FourUniqueDelirium5", + name = "Strugglescream", + text = { + "There is no light at the end of this inner strife,", + "but the shadows eventually become home.", + }, + }, + [352] = { + id = "FourUniqueRitual1", + name = "The Burden of Shadows", + text = { + "Nothingness is loathe to relinquish its grip.", + "Every moment is a struggle to exist.", + }, + }, + [353] = { + id = "FourUniqueRitual2", + name = "Beetlebite", + text = { + "They crawl and chitter and swarm", + "in the shadow of his presence.", + }, + }, + [354] = { + id = "FourUniqueRitual3", + name = "Ingenuity", + text = { + "Experiments with geomancy taught", + "the Maji more than they ever expected.", + }, + }, + [355] = { + id = "FourUniqueRitual4", + name = "Pragmatism", + text = { + "In an endless war against darkness,", + "one must be ever vigilant.", + }, + }, + [356] = { + id = "FourUniqueBreach1_", + name = "Skin of the Loyal", + text = { + "We happily give our limbs.", + "A net woven to keep safe the bones of the Lords.", + }, + }, + [357] = { + id = "FourUniqueBreach2", + name = "Hand of Wisdom and Action", + text = { + "She thinks and we act.", + "She acts and we think.", + "Fragments of the whole that washes clean the skies.", + }, + }, + [358] = { + id = "FourUniqueBreach3", + name = "Beyond Reach", + text = { + "The limit of our knowledge is a barrier", + "that protects us from ourselves.", + }, + }, + [359] = { + id = "FourUniqueBreach4a", + name = "Xoph's Blood", + text = { + "We are his blood.", + "Through us he carries his burning message.", + }, + }, + [360] = { + id = "FourUniqueBreach4b", + name = "Choir of the Storm", + text = { + "But the fool did not bow.", + "The fool stood and questioned.", + "And the fool was unwritten.", + }, + }, + [361] = { + id = "FourUniqueBreach4c", + name = "The Pandemonius", + text = { + "A single moment sets in motion an eternal fall,", + "beneath which all are buried.", + }, + }, + [362] = { + id = "FourUniqueSpirit1", + name = "Rite of Passage", + text = { + "To become a warrior and a hunter, each young", + "Azmeri must prove themselves before the Spirit.", + }, + }, + [363] = { + id = "FourUniqueCorruption1", + name = "The Gnashing Sash", + text = { + "\"Ghorr knows only hunger, only ravenous feasting.", + "It will consume all that lives, and more!\"", + "- Rantings of a Templar prisoner, page fourteen", + }, + }, + [364] = { + id = "FourUniqueCorruption2", + name = "Bursting Decay", + text = { + "\"All Beidat desires is a foothold, a grip on your flesh,", + "on the world... he will offer you anything to get it...\"", + "- Rantings of a Templar prisoner, page thirty", + }, + }, + [365] = { + id = "FourUniqueCorruption3", + name = "Death Articulated", + text = { + "\"The mind at the center of the swarm... K'Tash does", + "the thinking... but it has only one thought... hate.\"", + "- Rantings of a Templar prisoner, page ninety-four", + }, + }, + [366] = { + id = "FourUniqueJewel1", + name = "Grand Spectrum", + text = { + "A wellspring of vitality bubbling from within.", + }, + }, + [367] = { + id = "FourUniqueJewel2", + name = "Grand Spectrum", + text = { + "An indomitable force of control.", + }, + }, + [368] = { + id = "FourUniqueJewel3", + name = "Grand Spectrum", + text = { + "Skin like steel tempered by bright flames.", + }, + }, + [369] = { + id = "FourUniqueJewel4", + name = "Megalomaniac", + text = { + "If you're going to act like you're better", + "than everyone else, make sure you are.", + }, + }, + [370] = { + id = "FourUniqueJewel5", + name = "Heroic Tragedy", + text = { + "They believed themselves courageous and selfless,", + "but that bravery became the doom at their door.", + }, + }, + [371] = { + id = "FourUniqueJewel6", + name = "From Nothing", + text = { + "They clawed their way up from the agonising depths of nonexistence,", + "breathing deep with joy the exquisite light of meaning.", + }, + }, + [372] = { + id = "FourUniqueJewel7", + name = "Controlled Metamorphosis", + text = { + "Our world was dying, but we chose to survive.", + "We broke free from the chains within.", + }, + }, + [373] = { + id = "FourUniqueJewel8", + name = "Prism of Belief", + text = { + "Entropy can be reversed.", + }, + }, + [374] = { + id = "FourUniqueJewel9", + name = "The Adorned", + text = { + "At their height, the Vaal glittered under the sun.", + "A decade, a century, an aeon of prosperity...", + "now nothing more than a passing wonder.", + }, + }, + [375] = { + id = "FourUniqueJewel10", + name = "Against the Darkness", + text = { + "After the fires, in the depths of the Winter of the World, all life in the Vastiri banded together. Whether serpent, hyena, human, or golem, hated enemies clasped hand to claw, built refuge, and fought side by side against the Abyssals. Thus, the Third Pact was born.", + }, + }, +} diff --git a/src/Data/Uniques/ring.lua b/src/Data/Uniques/ring.lua index 75185bfc65..be48e00980 100644 --- a/src/Data/Uniques/ring.lua +++ b/src/Data/Uniques/ring.lua @@ -238,9 +238,9 @@ Variant: Sapphire Requires Level 40 (10-20)% increased Rarity of Items found {tags:attribute}+(10-20) to all Attributes -{variant:2}Cold Resistance is unaffected by Area Penalties +{variant:3}Cold Resistance is unaffected by Area Penalties {variant:1}Fire Resistance is unaffected by Area Penalties -{variant:3}Lightning Resistance is unaffected by Area Penalties +{variant:2}Lightning Resistance is unaffected by Area Penalties {variant:2}You can only Socket Emerald Jewels in this item {variant:1}You can only Socket Ruby Jewels in this item {variant:3}You can only Socket Sapphire Jewels in this item diff --git a/src/Export/Scripts/flavourText.lua b/src/Export/Scripts/flavourText.lua new file mode 100644 index 0000000000..7fa0cf26bd --- /dev/null +++ b/src/Export/Scripts/flavourText.lua @@ -0,0 +1,79 @@ +-- +-- export flavour text data +-- +local function normalizeId(id) + id = tostring(id) + -- remove trailing underscores only. We can't match Hash sadly. + return id:gsub("_+$", "") +end + +local function cleanAndSplit(str) + -- Normalize newlines + str = str:gsub("\r\n", "\n") + + local lines = {} + for line in str:gmatch("[^\n]+") do + line = line:match("^%s*(.-)%s*$") -- trim each line + if line ~= "" then + -- Escape quotes + line = line:gsub('"', '\\"') + table.insert(lines, line) + end + end + + return lines +end + +local uniqueNameLookup = {} +local unmatchedIds = {} +local forcedNameMap = { + ["FourUniqueSceptre6"] = "Guiding Palm", + ["FourUniqueSceptre6a"] = "Guiding Palm of the Heart", + ["FourUniqueSceptre6b"] = "Guiding Palm of the Eye", + ["FourUniqueSceptre6c"] = "Guiding Palm of the Mind", +} + +for row in dat("UniqueStashLayout"):Rows() do + -- We use Text2 because Words.Text has "The Immortan" instead of "The Road Warrior". Everything else so far matches up. + local name = row.WordsKey.Text2 + local id = normalizeId(row.ItemVisualIdentity.Id) + uniqueNameLookup[id] = name + unmatchedIds[id] = name +end + +local out = io.open("../Data/FlavourText.lua", "w") +out:write('-- This file is automatically generated, do not edit!\n') +out:write('-- Flavour text data (c) Grinding Gear Games\n\n') +out:write('return {\n') + +local index = 1 +for c in dat("FlavourText"):Rows() do + local id = normalizeId(c.Id) + local name = forcedNameMap[id] or uniqueNameLookup[id] + + if name then + local lines = cleanAndSplit(tostring(c.Text)) + out:write('\t[', index, '] = {\n') + out:write('\t\tid = "', tostring(c.Id), '",\n') + out:write('\t\tname = "', name, '",\n') + out:write('\t\ttext = {\n') + for _, line in ipairs(lines) do + out:write('\t\t\t"', line, '",\n') + end + out:write('\t\t},\n') + out:write('\t},\n') + index = index + 1 + unmatchedIds[id] = nil + end +end + +out:write('}\n') +out:close() + +print("Flavour Texts exported.") + +-- Print unmatched +print("Unique items from UniqueStashLayout without flavour text:") +for id, name in pairs(unmatchedIds) do + print(string.format("Id: %s, Name: %s", id, name)) +end diff --git a/src/Export/Uniques/ring.lua b/src/Export/Uniques/ring.lua index 0d502986e7..9ec3c6c732 100644 --- a/src/Export/Uniques/ring.lua +++ b/src/Export/Uniques/ring.lua @@ -239,8 +239,8 @@ Requires Level 40 UniqueItemFoundRarityIncrease20 UniqueAllAttributes1 {variant:1}UniqueFireResistanceNoPenalty1 -{variant:2}UniqueColdResistanceNoPenalty1 -{variant:3}UniqueLightningResistanceNoPenalty1 +{variant:2}UniqueLightningResistanceNoPenalty1 +{variant:3}UniqueColdResistanceNoPenalty1 {variant:1}UniqueOnlySocketRubyJewel1 {variant:2}UniqueOnlySocketEmeraldJewel1 {variant:3}UniqueOnlySocketSapphireJewel1 diff --git a/src/Export/spec.lua b/src/Export/spec.lua index 945780aae3..ebc88e042e 100644 --- a/src/Export/spec.lua +++ b/src/Export/spec.lua @@ -15445,6 +15445,8 @@ return { }, strongboxes={ }, + strongboxpacks={ + }, suicideexplosion={ [1]={ list=false, @@ -16310,7 +16312,7 @@ return { [1]={ list=false, name="WordsKey", - refTo="Word", + refTo="Words", type="Key", width=150 }, @@ -16914,7 +16916,7 @@ return { }, [6]={ list=false, - name="", + name="Text2", refTo="", type="String", width=150 diff --git a/src/Modules/Data.lua b/src/Modules/Data.lua index 1037549331..894283ebd0 100644 --- a/src/Modules/Data.lua +++ b/src/Modules/Data.lua @@ -962,3 +962,5 @@ LoadModule("Data/Uniques/Special/Generated") LoadModule("Data/Uniques/Special/New") data.questRewards = LoadModule("Data/QuestRewards") + +data.flavourText = LoadModule("Data/FlavourText") diff --git a/src/Modules/Main.lua b/src/Modules/Main.lua index 4a09970fb0..b16a471737 100644 --- a/src/Modules/Main.lua +++ b/src/Modules/Main.lua @@ -102,6 +102,7 @@ function main:Init() self.slotOnlyTooltips = true self.POESESSID = "" self.showPublicBuilds = true + self.showFlavourText = false if self.userPath then self:ChangeUserPath(self.userPath, ignoreBuild) @@ -619,6 +620,9 @@ function main:LoadSettings(ignoreBuild) if node.attrib.showPublicBuilds then self.showPublicBuilds = node.attrib.showPublicBuilds == "true" end + if node.attrib.showFlavourText then + self.showFlavourText = node.attrib.showFlavourText == "true" + end end end end @@ -729,7 +733,8 @@ function main:SaveSettings() POESESSID = self.POESESSID, invertSliderScrollDirection = tostring(self.invertSliderScrollDirection), disableDevAutoSave = tostring(self.disableDevAutoSave), - showPublicBuilds = tostring(self.showPublicBuilds) + showPublicBuilds = tostring(self.showPublicBuilds), + showFlavourText = tostring(self.showFlavourText) } }) local res, errMsg = common.xml.SaveXMLFile(setXML, self.userPath.."Settings.xml") if not res then @@ -909,6 +914,11 @@ function main:OpenOptionsPopup() self.showPublicBuilds = state end) + nextRow() + controls.showFlavourText = new("CheckBoxControl", { "TOPLEFT", nil, "TOPLEFT" }, { defaultLabelPlacementX, currentY, 20 }, "^7Styled Tooltips with Flavour Text:", function(state) + self.showFlavourText = state + end) + nextRow() drawSectionHeader("build", "Build-related options") @@ -990,6 +1000,7 @@ function main:OpenOptionsPopup() controls.edgeSearchHighlight.state = self.edgeSearchHighlight controls.titlebarName.state = self.showTitlebarName controls.showPublicBuilds.state = self.showPublicBuilds + controls.showFlavourText.state = self.showFlavourText local initialNodePowerTheme = self.nodePowerTheme local initialColorPositive = self.colorPositive local initialColorNegative = self.colorNegative @@ -1008,6 +1019,7 @@ function main:OpenOptionsPopup() local initialInvertSliderScrollDirection = self.invertSliderScrollDirection local initialDisableDevAutoSave = self.disableDevAutoSave local initialShowPublicBuilds = self.showPublicBuilds + local initialShowFlavourText = self.showFlavourText -- last line with buttons has more spacing nextRow(1.5) @@ -1058,6 +1070,7 @@ function main:OpenOptionsPopup() self.invertSliderScrollDirection = initialInvertSliderScrollDirection self.disableDevAutoSave = initialDisableDevAutoSave self.showPublicBuilds = initialShowPublicBuilds + self.showFlavourText = initialShowFlavourText main:ClosePopup() end) nextRow(1.5)