diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/BlizzNameplatesPlus.toc b/BlizzNameplatesPlus.toc index 030a253..0c938b0 100644 --- a/BlizzNameplatesPlus.toc +++ b/BlizzNameplatesPlus.toc @@ -3,11 +3,12 @@ ## Notes: Lightweight personal debuffs and class colors for Blizzard nameplates. Requires SuperWoW and ClassicAPI. ## Author: Wurmschwanz; nameplate discovery inspired by Shagu's Vanilla projects ## OptionalDeps: ShaguTweaks -## Version: 2.0.2 +## Version: 2.0.2-oevg.7 ## SavedVariablesPerCharacter: BNP_DB core\core.lua core\compat_shagutweaks.lua +core\appearance.lua core\ui.lua core\config.lua core\bridge.lua diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..e3857fe --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,35 @@ +# Changelog + +## 2.0.2-oevg.7 +- Apply the retail texture to nameplate castbars when Modern Class Colors is enabled. Existing castbars update immediately and keep their cast colors. + +## 2.0.2-oevg.6 +- Add Level Number Scale under Nameplates > Names & Level: 50–150% in 5% steps, default 100%. Applies immediately and to newly shown/recycled plates, preserving font and outline. Independent of nameplate scale and name font size. +- Local Lua 5.0 parse and scale/restoration checks pass; in-game testing remains required. + +## 2.0.2-oevg.5 +- Replace the rectangular level fill with an alpha-masked 128x32 atlas sharing the exact bounds and all eight UV coordinates of the nameplate border. Pixels outside the level inset are transparent. +- Use a fixed dark olive-black level background inspired by the supplied WoW Forever reference, replacing health-texture/color matching at OEVG's request. +- Local Lua and atlas-mask checks pass; in-game visual confirmation required. + +## 2.0.2-oevg.4 +- Fix level-fill placement to account for the native border texture's cropped UV coordinates. The previous geometry incorrectly assumed the whole 128x32 atlas was displayed, causing misplaced fills and spill outside the level inset. +- Recompute geometry when the border crop or size changes. Add Lua 5.0 regression checks for cropped and resized borders. +- Local checks pass; corrected placement still needs in-game visual confirmation. + +## 2.0.2-oevg.3 +- Level backgrounds now use the health bar texture and current color on target and non-target nameplates, including modern textures, player class colors, NPC reaction colors and BNP color overrides. Border tint remains independent. +- Reuse the existing visual guard and cache texture, color and geometry writes. Original personal-plate artwork remains intact. +- Local Lua 5.0 checks only; requires in-game testing. + +## 2.0.2-oevg.2 +- Recolored Border also themes the baked-in rims of debuff and crowd-control icons. Darkened UI and Golden UI use ShaguTweaks' configured colors; spell artwork and timer/stack text retain their colors. +- Refresh pooled icons when their spell or size changes, and restore their original rims immediately when Recolored Border is disabled. No additional update loop. +- Lua 5.0 parse and mocked appearance checks pass; in-game visual testing remains required. + +## 2.0.2-oevg.1 +- Rename Dark Border to Recolored Border; follow the active ShaguTweaks Darkened UI or Golden UI texture tint, including configured colors. +- Keep the level-number background neutral when target border color is enabled, including bold borders. +- Add an independent Modern Class Colors toggle: retail health textures for all nameplates, modern colors for every player class, and native NPC reaction colors. Personal health bars follow the same toggle. +- Retain existing saved border settings and BNP class-color, tank-mode, and foreign-tag controls. +- Local Lua 5.0 checks only; requires in-game visual testing. diff --git a/README.md b/README.md index 72a1828..09b5ccc 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,19 @@ # ⚔️ Blizz Nameplates+ +[![ClassicAPI](https://img.shields.io/badge/ClassicAPI-Required-purple.svg)](https://github.com/brues-code/ClassicAPI) +[![SuperWoW](https://img.shields.io/badge/SuperWoW-Required-purple.svg)](https://github.com/balakethelock/SuperWoW) + +Local OEVG appearance build. In **Nameplates**, enable **Recolored Border** to follow your ShaguTweaks UI theme. **Modern Class Colors** independently enables the retail health texture and modern player class palette (off by default); keep **Class Colors** enabled for player class tinting. NPCs retain their native red/yellow/green reaction colors. Tank Mode and foreign-tag grey retain priority. + +Recolored Border also themes debuff and crowd-control icon rims, preserving the spell artwork and timer text. The level-number background uses a fixed dark olive-black inspired by WoW Forever, independent of health and border colors. Test both normal and bold target borders, changing targets and toggling both new appearance settings in game. Local checks do not validate in-game rendering. + **Blizz Nameplates+** enhances the original Blizzard nameplates for **Vanilla WoW / WoW 1.12** while preserving their classic look and feel. It adds reliable multi-target aura tracking, Crowd Control, PvP immunities, castbars, Combo Points, Personal Nameplates, quest indicators, totem icons, Raid Marks and extensive customization — without replacing the original Blizzard nameplate system. -**Current version:** `v2.0.1` +**Current version:** `v2.0.2-oevg.7` + +**Names & Level → Level Number Scale:** resize the level number from 50% to 150% (default 100%), independently of the rest of the nameplate. Changes apply immediately. **Required:** `SuperWoW.dll` + `ClassicAPI.dll` --- @@ -17,7 +26,8 @@ It adds reliable multi-target aura tracking, Crowd Control, PvP immunities, cast - Enemy **Class Colors** - **Tank Mode** with custom Aggro / No Aggro colors - Optional **Hide Player Names**, **NPC Names**, **Level** and **Border** -- Optional **Dark Border** +- Optional **Recolored Border**: follows ShaguTweaks Darkened UI / Golden UI; dark grey fallback. +- Optional **Modern Class Colors**: retail texture on health bars and castbars, modern player class colors, native NPC reaction colors. Castbars retain their usual cast colors. Toggle independently in BNP Nameplates settings (off by default). - Adjustable name font size and position - **Black Health Background** - Neutral grey healthbar for foreign-tagged mobs diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md new file mode 100644 index 0000000..02e792b --- /dev/null +++ b/THIRD_PARTY_NOTICES.md @@ -0,0 +1,8 @@ +# Local customization credits + +BlizzNameplatesPlus is by Wurmschwanz: https://github.com/Wurmschwanz/BlizzNameplatesPlus +Local OEVG appearance changes do not imply upstream authorship. + +`media/BlizzardRetailBar.tga` is copied unchanged from OEVG's ShaguTweaks-ClassicAPI `img/BlizzardRetailBar.tga`, retail World of Warcraft health-bar artwork. World of Warcraft artwork belongs to Blizzard Entertainment. The modern class palette matches that fork's Modern Class Colors module. + +`media/level_fill_dark.tga` uses the native nameplate level inset as an alpha mask. diff --git a/core/appearance.lua b/core/appearance.lua new file mode 100644 index 0000000..52a0eda --- /dev/null +++ b/core/appearance.lua @@ -0,0 +1,194 @@ +BNP = BNP or {} + +function BNP:GetLevelNumberScale() + local scale = tonumber(BNP_DB and BNP_DB.levelNumberScale) or 1 + return math.max(0.5, math.min(1.5, scale)) +end + +function BNP:ApplyLevelNumberScale(plate) + local level = plate and plate.level + if not level or not level.GetFont or not level.SetFont then return end + local font, size, flags = level:GetFont() + if not font or not size then return end + if not plate.BNPLevelBaseSize then plate.BNPLevelBaseSize = size end + local wanted = plate.BNPLevelBaseSize * self:GetLevelNumberScale() + if math.abs(size - wanted) > 0.01 then level:SetFont(font, wanted, flags) end +end + +function BNP:RefreshLevelNumberScale() + local plate + for plate in pairs(self.plates or {}) do self:ApplyLevelNumberScale(plate) end +end + +local modernColors = { + DRUID = {r=1, g=0.49, b=0.04}, HUNTER = {r=0.67, g=0.83, b=0.45}, + MAGE = {r=0.25, g=0.78, b=0.92}, PALADIN = {r=0.96, g=0.55, b=0.73}, + PRIEST = {r=1, g=1, b=1}, ROGUE = {r=1, g=0.96, b=0.41}, + SHAMAN = {r=0, g=0.44, b=0.87}, WARLOCK = {r=0.53, g=0.53, b=0.93}, + WARRIOR = {r=0.78, g=0.61, b=0.43}, +} + +function BNP:GetModernClassColor(class) + local palette = ShaguTweaks and ShaguTweaks.ModernClassColors or modernColors + return class and palette[class] +end + +function BNP:GetRecoloredBorderColor() + local shagu = ShaguTweaks + local key + if shagu and shagu.DarkMode then key = "darkmode.color" + elseif shagu and shagu.GoldMode then key = "goldmode.color" end + local color = key and shagu.overwrites and shagu.overwrites[key] + if type(color) == "table" then return color.r, color.g, color.b, color.a or 1 end + if key == "goldmode.color" then return 1, 0.78, 0.4, 1 end + return 0.3, 0.3, 0.3, 0.9 +end + +-- Spell icons include their silver rim in the artwork. Copy only the outer +-- four pixels of a 64px icon, preserving the untinted spell image underneath. +function BNP:ApplyAuraBorderColor(icon) + local strips = icon.BNPRecoloredEdges + if not (self.IsDarkNameplateBorderEnabled and self:IsDarkNameplateBorderEnabled()) then + if strips then + local i + for i = 1, 4 do strips[i]:Hide() end + end + return + end + local path = icon.texture and icon.texture:GetTexture() + if not path then return end + if not strips then + strips = {} + icon.BNPRecoloredEdges = strips + local parent = icon.BNPTextOverlay or icon + local i + for i = 1, 4 do strips[i] = parent:CreateTexture(nil, "BORDER") end + strips[1]:SetPoint("TOPLEFT", icon, "TOPLEFT", 0, 0) + strips[1]:SetPoint("TOPRIGHT", icon, "TOPRIGHT", 0, 0) + strips[2]:SetPoint("BOTTOMLEFT", icon, "BOTTOMLEFT", 0, 0) + strips[2]:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", 0, 0) + strips[3]:SetPoint("TOPLEFT", icon, "TOPLEFT", 0, 0) + strips[3]:SetPoint("BOTTOMLEFT", icon, "BOTTOMLEFT", 0, 0) + strips[4]:SetPoint("TOPRIGHT", icon, "TOPRIGHT", 0, 0) + strips[4]:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", 0, 0) + strips[1]:SetTexCoord(0, 1, 0, 0.0625) + strips[2]:SetTexCoord(0, 1, 0.9375, 1) + strips[3]:SetTexCoord(0, 0.0625, 0, 1) + strips[4]:SetTexCoord(0.9375, 1, 0, 1) + end + local r, g, b, a = self:GetRecoloredBorderColor() + local shagu = ShaguTweaks + if shagu and shagu.GoldMode and not shagu.DarkMode then + local edge = shagu.overwrites and shagu.overwrites["goldmode.border"] + r, g, b, a = 0.8, 0.62, 0.32, 1 + if type(edge) == "table" then r, g, b, a = edge.r, edge.g, edge.b, edge.a or 1 end + end + local width, height = icon:GetWidth(), icon:GetHeight() + local i + for i = 1, 4 do + local strip = strips[i] + if i <= 2 then strip:SetHeight(height * 0.0625) + else strip:SetWidth(width * 0.0625) end + strip:SetTexture(path) + strip:SetVertexColor(r, g, b, a) + strip:Show() + end +end + +function BNP:RefreshAuraBorderColors() + local plate, i + for plate in pairs(self.plates or {}) do + local container = plate.BNPAuraContainer + if container then + for i = 1, table.getn(container.icons or {}) do self:ApplyAuraBorderColor(container.icons[i]) end + end + container = plate.BNPCCContainer + if container then + for i = 1, table.getn(container.icons or {}) do self:ApplyAuraBorderColor(container.icons[i]) end + end + end +end + +local modernTexture = "Interface\\AddOns\\BlizzNameplatesPlus\\media\\BlizzardRetailBar" + +function BNP:GetCastbarFillTexture() + if BNP_DB and BNP_DB.modernClassColors then return modernTexture end + return "Interface\\TargetingFrame\\UI-StatusBar" +end + +function BNP:ApplyModernHealthTexture(plate) + local bar = plate and plate.healthbar + if not bar or not bar.SetStatusBarTexture then return end + if BNP_DB and BNP_DB.modernClassColors then + if not plate.BNPModernHealthActive then + local original = bar.GetStatusBarTexture and bar:GetStatusBarTexture() + if type(original) == "string" then plate.BNPOldHealthTexture = original + elseif original and original.GetTexture then plate.BNPOldHealthTexture = original:GetTexture() end + plate.BNPModernHealthActive = true + end + bar:SetStatusBarTexture(modernTexture) + elseif plate.BNPModernHealthActive then + bar:SetStatusBarTexture(plate.BNPOldHealthTexture or "Interface\\TargetingFrame\\UI-StatusBar") + plate.BNPModernHealthActive = nil + plate.BNPOldHealthTexture = nil + end +end + +function BNP:RefreshModernNameplates() + local plate + for plate in pairs(self.plates or {}) do self:ApplyModernHealthTexture(plate) end + if self.RefreshClassColors then self:RefreshClassColors() end + if self.UpdateTankMode then self:UpdateTankMode() end + if self.RefreshPersonalNameplateStyle then self:RefreshPersonalNameplateStyle() end + if self.RefreshCastbarStyle then self:RefreshCastbarStyle() end +end + +-- The level well is a small health-texture fill underneath the native rim. +-- Cache values so the existing visual guard performs no unchanged writes. +function BNP:UpdateLevelBackground(plate) + local border, bar = plate.border, plate.healthbar + if not border or not bar then return end + local background = plate.BNPNeutralLevelBackground + local hidden = self.IsNameplateBorderHidden and self:IsNameplateBorderHidden() + if hidden or plate.BNPTotemLastKey then + if background then background:Hide() end + return + end + if not background then + background = border:GetParent():CreateTexture(nil, "BACKGROUND") + plate.BNPNeutralLevelBackground = background + end + if background:GetParent() ~= border:GetParent() then + background:SetParent(border:GetParent()) + end + -- Match the entire border region. The alpha-masked fill uses the same + -- 128x32 atlas, eliminating separate inset position/size calculations. + if not background.BNPAnchored then + background:ClearAllPoints() + background:SetAllPoints(border) + background.BNPAnchored = true + end + local ulx, uly, llx, lly, urx, ury, lrx, lry = border:GetTexCoord() + if background.BNPULX ~= ulx or background.BNPULY ~= uly + or background.BNPLLX ~= llx or background.BNPLLY ~= lly + or background.BNPURX ~= urx or background.BNPURY ~= ury + or background.BNPLRX ~= lrx or background.BNPLRY ~= lry then + background:SetTexCoord(ulx, uly, llx, lly, urx, ury, lrx, lry) + background.BNPULX, background.BNPULY = ulx, uly + background.BNPLLX, background.BNPLLY = llx, lly + background.BNPURX, background.BNPURY = urx, ury + background.BNPLRX, background.BNPLRY = lrx, lry + end + local style = "dark" + if background.BNPStyle ~= style then + background:SetTexture("Interface\\AddOns\\BlizzNameplatesPlus\\media\\level_fill_" .. style .. ".tga") + background.BNPStyle = style + end + -- WoW Forever-style dark olive well, independent of health and border tint. + local r, g, b, a = 0.055, 0.065, 0.025, 1 + if background.BNPR ~= r or background.BNPG ~= g or background.BNPB ~= b or background.BNPA ~= a then + background:SetVertexColor(r, g, b, a) + background.BNPR, background.BNPG, background.BNPB, background.BNPA = r, g, b, a + end + if not background:IsShown() then background:Show() end +end diff --git a/core/config.lua b/core/config.lua index b27c804..a4cdb6a 100644 --- a/core/config.lua +++ b/core/config.lua @@ -5,6 +5,7 @@ BNP.defaults = BNP.defaults or { nameplateYOffset = 0, comboPointsYOffset = 0, nameFontSize = 12, + levelNumberScale = 1, nameFontYOffset = 0, customNameColor = false, nameColor = { r = 1.00, g = 1.00, b = 1.00 }, @@ -24,6 +25,7 @@ BNP.defaults = BNP.defaults or { invertTankAggroColor = { r = 1.00, g = 0.00, b = 0.00 }, invertTankNoAggroColor = { r = 0.00, g = 1.00, b = 0.00 }, classColors = true, + modernClassColors = false, darkNameplateBorder = false, hideNameplateBorder = false, hideNameplateLevel = false, @@ -145,6 +147,8 @@ function BNP:InitConfig() InitTankColor("invertTankNoAggroColor", self.defaults.invertTankNoAggroColor) if BNP_DB.classColors == nil then BNP_DB.classColors = self.defaults.classColors end + if BNP_DB.levelNumberScale == nil then BNP_DB.levelNumberScale = self.defaults.levelNumberScale end + if BNP_DB.modernClassColors == nil then BNP_DB.modernClassColors = self.defaults.modernClassColors end if BNP_DB.darkNameplateBorder == nil then BNP_DB.darkNameplateBorder = self.defaults.darkNameplateBorder end if BNP_DB.hideNameplateBorder == nil then BNP_DB.hideNameplateBorder = self.defaults.hideNameplateBorder end if BNP_DB.hideNameplateLevel == nil then BNP_DB.hideNameplateLevel = self.defaults.hideNameplateLevel end diff --git a/core/options.lua b/core/options.lua index 1021da5..74b54a8 100644 --- a/core/options.lua +++ b/core/options.lua @@ -1228,7 +1228,7 @@ function BNP:CreateOptions() end frame.pages = { - nameplates = CreatePage(542), + nameplates = CreatePage(606), personal = CreatePage(345), auras = CreatePage(520), totems = CreatePage(610), @@ -1465,15 +1465,22 @@ function BNP:CreateOptions() if BNP.RefreshClassColors then BNP:RefreshClassColors() end end, 214) frame.classColorsCheck = classColors + do + local modern = CreateCheck(nameplatesPage, "Modern Class Colors", -116, function() + BNP_DB.modernClassColors = this:GetChecked() and true or false + BNP:RefreshModernNameplates() + end, 214) + frame.modernClassColorsCheck = modern + end - local darkNameplateBorder = CreateCheck(nameplatesPage, "Dark Border", -88, function() + local darkNameplateBorder = CreateCheck(nameplatesPage, "Recolored Border", -88, function() BNP_DB.darkNameplateBorder = this:GetChecked() and true or false if BNP.RefreshNameplateBorderStyle then BNP:RefreshNameplateBorderStyle() end end, 22) darkNameplateBorder:SetScript("OnEnter", function() GameTooltip:SetOwner(this, "ANCHOR_RIGHT") - GameTooltip:SetText("Dark Nameplate Border", 1, 0.82, 0) - GameTooltip:AddLine("Darkens only the classic Blizzard nameplate border using the ShaguTweaks Darkened UI color.", 1, 1, 1, true) + GameTooltip:SetText("Recolored Nameplate Border", 1, 0.82, 0) + GameTooltip:AddLine("Matches the active ShaguTweaks Darkened UI or Golden UI border tint. Falls back to dark grey without an active UI recolor.", 1, 1, 1, true) GameTooltip:AddLine("When disabled, the original gold border is restored, including with ShaguTweaks. Other elements remain unchanged.", 0.8, 0.8, 0.8, true) GameTooltip:Show() end) @@ -1495,9 +1502,9 @@ function BNP:CreateOptions() frame.hideNameplateBorderCheck = hideNameplateBorder -- TANK MODE ------------------------------------------------------------- - CreateSection(nameplatesPage, "Tank Mode", -118) + CreateSection(nameplatesPage, "Tank Mode", -146) - local tank = CreateCheck(nameplatesPage, "Tank Mode", -142, function() + local tank = CreateCheck(nameplatesPage, "Tank Mode", -170, function() BNP_DB.tankMode = this:GetChecked() and true or false if BNP.UpdateTankMode then BNP:UpdateTankMode() end if frame.UpdateDependentControls then frame:UpdateDependentControls() end @@ -1511,7 +1518,7 @@ function BNP:CreateOptions() tank:SetScript("OnLeave", function() GameTooltip:Hide() end) frame.tankCheck = tank - local invertTankColors = CreateCheck(nameplatesPage, "Invert Tank Colors", -142, function() + local invertTankColors = CreateCheck(nameplatesPage, "Invert Tank Colors", -170, function() BNP_DB.invertTankColors = this:GetChecked() and true or false if BNP.UpdateTankMode then BNP:UpdateTankMode() end if frame.UpdateDependentControls then frame:UpdateDependentControls() end @@ -1525,13 +1532,13 @@ function BNP:CreateOptions() invertTankColors:SetScript("OnLeave", function() GameTooltip:Hide() end) frame.invertTankColorsCheck = invertTankColors - local invertAggroColor = CreateColorSwatch(nameplatesPage, "Aggro Color", -170, 22, + local invertAggroColor = CreateColorSwatch(nameplatesPage, "Aggro Color", -198, 22, function() return BNP:GetInvertTankAggroColor() end, function(r, g, b) BNP:SetInvertTankAggroColor(r, g, b) end, 1.00, 0.00, 0.00) frame.invertAggroColorSwatch = invertAggroColor - local invertNoAggroColor = CreateColorSwatch(nameplatesPage, "No Aggro Color", -170, 214, + local invertNoAggroColor = CreateColorSwatch(nameplatesPage, "No Aggro Color", -198, 214, function() return BNP:GetInvertTankNoAggroColor() end, function(r, g, b) BNP:SetInvertTankNoAggroColor(r, g, b) end, 0.00, 1.00, 0.00) @@ -1539,7 +1546,7 @@ function BNP:CreateOptions() -- Separate scope keeps the large options builder below Lua 5.0's local limit. do - local noTarget = CreateCheck(nameplatesPage, "Inactive Combat", -198, function() + local noTarget = CreateCheck(nameplatesPage, "Inactive Combat", -226, function() BNP_DB.tankNoTarget = this:GetChecked() and true or false if BNP.UpdateTankMode then BNP:UpdateTankMode() end if frame.UpdateDependentControls then frame:UpdateDependentControls() end @@ -1553,7 +1560,7 @@ function BNP:CreateOptions() end) noTarget:SetScript("OnLeave", function() GameTooltip:Hide() end) frame.tankNoTargetCheck = noTarget - frame.tankNoTargetColorSwatch = CreateColorSwatch(nameplatesPage, "Inactive Color", -198, 214, + frame.tankNoTargetColorSwatch = CreateColorSwatch(nameplatesPage, "Inactive Color", -226, 214, function() return BNP:GetTankNoTargetColor() end, function(r, g, b) BNP:SetTankNoTargetColor(r, g, b) end, 0.00, 0.45, 1.00, @@ -1575,21 +1582,21 @@ function BNP:CreateOptions() end -- NAMES & LEVEL --------------------------------------------------------- - CreateSection(nameplatesPage, "Names & Level", -234) + CreateSection(nameplatesPage, "Names & Level", -262) - local hidePlayerNames = CreateCheck(nameplatesPage, "Hide Player Names", -258, function() + local hidePlayerNames = CreateCheck(nameplatesPage, "Hide Player Names", -286, function() BNP_DB.hidePlayerNames = this:GetChecked() and true or false if BNP.RefreshNameVisibility then BNP:RefreshNameVisibility() end end, 22) frame.hidePlayerNamesCheck = hidePlayerNames - local hideNPCNames = CreateCheck(nameplatesPage, "Hide NPC Names", -258, function() + local hideNPCNames = CreateCheck(nameplatesPage, "Hide NPC Names", -286, function() BNP_DB.hideNPCNames = this:GetChecked() and true or false if BNP.RefreshNameVisibility then BNP:RefreshNameVisibility() end end, 214) frame.hideNPCNamesCheck = hideNPCNames - local hideNameplateLevel = CreateCheck(nameplatesPage, "Hide Level", -282, function() + local hideNameplateLevel = CreateCheck(nameplatesPage, "Hide Level", -310, function() BNP_DB.hideNameplateLevel = this:GetChecked() and true or false if BNP.RefreshNameplateLevelVisibility then BNP:RefreshNameplateLevelVisibility() end if BNP.RefreshCastbarLayout then BNP:RefreshCastbarLayout() end @@ -1603,7 +1610,7 @@ function BNP:CreateOptions() hideNameplateLevel:SetScript("OnLeave", function() GameTooltip:Hide() end) frame.hideNameplateLevelCheck = hideNameplateLevel - local customNameColor = CreateCheck(nameplatesPage, "Custom Name Color", -282, function() + local customNameColor = CreateCheck(nameplatesPage, "Custom Name Color", -310, function() BNP_DB.customNameColor = this:GetChecked() and true or false if BNP.RefreshNameAppearance then BNP:RefreshNameAppearance() end if frame.UpdateDependentControls then frame:UpdateDependentControls() end @@ -1617,7 +1624,7 @@ function BNP:CreateOptions() customNameColor:SetScript("OnLeave", function() GameTooltip:Hide() end) frame.customNameColorCheck = customNameColor - local nameColorSwatch, nameColorLabel = CreateColorSwatch(nameplatesPage, "Name Color", -308, 214, + local nameColorSwatch, nameColorLabel = CreateColorSwatch(nameplatesPage, "Name Color", -336, 214, function() return BNP:GetNameColor() end, function(r, g, b) BNP:SetNameColor(r, g, b) end, 1.00, 1.00, 1.00, @@ -1634,7 +1641,7 @@ function BNP:CreateOptions() -- Name text controls are independent from Nameplate Scale. The size setting -- only touches the Blizzard name FontString; the Y offset only moves it. - local nameFontSize = CreateSlider(nameplatesPage, "Name Font Size", 8, 24, 1, -338, 28, 150) + local nameFontSize = CreateSlider(nameplatesPage, "Name Font Size", 8, 24, 1, -366, 28, 150) nameFontSize:SetScript("OnValueChanged", function() if not BNP_DB or frame.BNPSyncingNameControls then return end local value = math.floor(this:GetValue() + 0.5) @@ -1644,7 +1651,7 @@ function BNP:CreateOptions() end) frame.nameFontSizeSlider = nameFontSize - local nameFontYOffset = CreateSlider(nameplatesPage, "Name Y Offset", -50, 50, 1, -338, 220, 150) + local nameFontYOffset = CreateSlider(nameplatesPage, "Name Y Offset", -50, 50, 1, -366, 220, 150) nameFontYOffset:SetScript("OnValueChanged", function() if not BNP_DB or frame.BNPSyncingNameControls then return end local value = RoundSignedInteger(this:GetValue()) @@ -1654,16 +1661,28 @@ function BNP:CreateOptions() end) frame.nameFontYOffsetSlider = nameFontYOffset + do + local levelScale = CreateSlider(nameplatesPage, "Level Number Scale", 50, 150, 5, -402, 28, 150) + levelScale:SetScript("OnValueChanged", function() + if not BNP_DB or frame.BNPSyncingNameControls then return end + local percent = math.floor(this:GetValue() / 5 + 0.5) * 5 + BNP_DB.levelNumberScale = percent / 100 + getglobal(this:GetName() .. "Text"):SetText("Level Number Scale: " .. percent .. "%") + BNP:RefreshLevelNumberScale() + end) + frame.levelNumberScaleSlider = levelScale + end + -- HEALTH BAR & TEXT ----------------------------------------------------- - CreateSection(nameplatesPage, "Health Bar & Text", -368) + CreateSection(nameplatesPage, "Health Bar & Text", -432) local healthTextLabel = nameplatesPage:CreateFontString(nil, "OVERLAY", "GameFontNormal") - healthTextLabel:SetPoint("TOPLEFT", nameplatesPage, "TOPLEFT", 28, -390) + healthTextLabel:SetPoint("TOPLEFT", nameplatesPage, "TOPLEFT", 28, -454) healthTextLabel:SetText("Display") healthTextLabel:SetTextColor(1.00, 0.82, 0.00) local healthTextDropdown = CreateFrame("Frame", "BNPHealthTextDropdown", nameplatesPage, "UIDropDownMenuTemplate") - healthTextDropdown:SetPoint("TOPLEFT", nameplatesPage, "TOPLEFT", 10, -402) + healthTextDropdown:SetPoint("TOPLEFT", nameplatesPage, "TOPLEFT", 10, -466) UIDropDownMenu_SetWidth(150, healthTextDropdown) local healthModeLabels = { @@ -1699,12 +1718,12 @@ function BNP:CreateOptions() frame.SetHealthTextMode = SetHealthTextMode local healthOutlineLabel = nameplatesPage:CreateFontString(nil, "OVERLAY", "GameFontNormal") - healthOutlineLabel:SetPoint("TOPLEFT", nameplatesPage, "TOPLEFT", 220, -390) + healthOutlineLabel:SetPoint("TOPLEFT", nameplatesPage, "TOPLEFT", 220, -454) healthOutlineLabel:SetText("Outline") healthOutlineLabel:SetTextColor(1.00, 0.82, 0.00) local healthOutlineDropdown = CreateFrame("Frame", "BNPHealthOutlineDropdown", nameplatesPage, "UIDropDownMenuTemplate") - healthOutlineDropdown:SetPoint("TOPLEFT", nameplatesPage, "TOPLEFT", 200, -402) + healthOutlineDropdown:SetPoint("TOPLEFT", nameplatesPage, "TOPLEFT", 200, -466) UIDropDownMenu_SetWidth(150, healthOutlineDropdown) local healthOutlineLabels = { @@ -1737,7 +1756,7 @@ function BNP:CreateOptions() frame.healthTextOutlineDropdown = healthOutlineDropdown frame.SetHealthTextOutline = SetHealthTextOutline - local healthFontSize = CreateSlider(nameplatesPage, "Health Font Size", 8, 20, 1, -448, 28, 150) + local healthFontSize = CreateSlider(nameplatesPage, "Health Font Size", 8, 20, 1, -512, 28, 150) healthFontSize:SetScript("OnValueChanged", function() if not BNP_DB or frame.BNPSyncingHealthTextControls then return end local value = math.floor(this:GetValue() + 0.5) @@ -1747,7 +1766,7 @@ function BNP:CreateOptions() end) frame.healthTextFontSizeSlider = healthFontSize - local blackHealthbarBackground = CreateCheck(nameplatesPage, "Black Health Background", -444, function() + local blackHealthbarBackground = CreateCheck(nameplatesPage, "Black Health Background", -508, function() BNP_DB.blackHealthbarBackground = this:GetChecked() and true or false if BNP.RefreshHealthbarBackground then BNP:RefreshHealthbarBackground() end end, 214) @@ -1762,9 +1781,9 @@ function BNP:CreateOptions() -- COMBO POINTS (Rogue / Druid only) ------------------------------------ if comboOptionsClass then - CreateSection(nameplatesPage, "Combo Points", -474) + CreateSection(nameplatesPage, "Combo Points", -538) - local comboPoints = CreateCheck(nameplatesPage, "Combo Points", -498, function() + local comboPoints = CreateCheck(nameplatesPage, "Combo Points", -562, function() BNP_DB.comboPoints = this:GetChecked() and true or false if BNP.RefreshComboPoints then BNP:RefreshComboPoints() end if BNP.RefreshAllAuraLayouts then BNP:RefreshAllAuraLayouts() end @@ -1773,7 +1792,7 @@ function BNP:CreateOptions() end, 22) frame.comboPointsCheck = comboPoints - local darkComboPointBorder = CreateCheck(nameplatesPage, "Dark CP Border", -498, function() + local darkComboPointBorder = CreateCheck(nameplatesPage, "Dark CP Border", -562, function() BNP_DB.darkComboPointBorder = this:GetChecked() and true or false if BNP.RefreshComboPointBorderStyle then BNP:RefreshComboPointBorderStyle() end if BNP.RefreshComboPoints then BNP:RefreshComboPoints() end @@ -1788,7 +1807,7 @@ function BNP:CreateOptions() darkComboPointBorder:SetScript("OnLeave", function() GameTooltip:Hide() end) frame.darkComboPointBorderCheck = darkComboPointBorder - local comboYOffset = CreateSlider(nameplatesPage, "Combo Point Y Offset", -50, 50, 1, -498, 278, 105) + local comboYOffset = CreateSlider(nameplatesPage, "Combo Point Y Offset", -50, 50, 1, -562, 278, 105) comboYOffset:SetScript("OnValueChanged", function() if not BNP_DB then return end local value = RoundSignedInteger(this:GetValue()) @@ -3066,6 +3085,11 @@ function BNP:SyncOptions() end if frame.nameFontSizeSlider or frame.nameFontYOffsetSlider then frame.BNPSyncingNameControls = true + if frame.levelNumberScaleSlider then + local percent = math.floor(self:GetLevelNumberScale() * 100 + 0.5) + frame.levelNumberScaleSlider:SetValue(percent) + getglobal(frame.levelNumberScaleSlider:GetName() .. "Text"):SetText("Level Number Scale: " .. percent .. "%") + end if frame.nameFontSizeSlider then local value = self:GetNameFontSize() frame.nameFontSizeSlider:SetValue(value) @@ -3266,6 +3290,9 @@ function BNP:SyncOptions() frame.questPlateYOffsetSlider:SetValue(value) getglobal(frame.questPlateYOffsetSlider:GetName() .. "Text"):SetText("Quest Icon Y Offset: " .. (value > 0 and "+" or "") .. value) end + if frame.modernClassColorsCheck then + frame.modernClassColorsCheck:SetChecked(BNP_DB and BNP_DB.modernClassColors == true) + end frame.castbarsCheck:SetChecked(self:AreCastbarsEnabled()) if frame.castbarTestCheck then frame.castbarTestCheck:SetChecked(self.IsCastbarTestMode and self:IsCastbarTestMode() or false) diff --git a/media/BlizzardRetailBar.tga b/media/BlizzardRetailBar.tga new file mode 100644 index 0000000..18e973c Binary files /dev/null and b/media/BlizzardRetailBar.tga differ diff --git a/media/classic_nameplate_border_bold_tint.tga b/media/classic_nameplate_border_bold_tint.tga index 788d81c..5290b5b 100644 Binary files a/media/classic_nameplate_border_bold_tint.tga and b/media/classic_nameplate_border_bold_tint.tga differ diff --git a/media/classic_nameplate_border_healthlevel.tga b/media/classic_nameplate_border_healthlevel.tga new file mode 100644 index 0000000..7ddcfca Binary files /dev/null and b/media/classic_nameplate_border_healthlevel.tga differ diff --git a/media/classic_nameplate_border_tint.tga b/media/classic_nameplate_border_tint.tga index fedf991..7124bc3 100644 Binary files a/media/classic_nameplate_border_tint.tga and b/media/classic_nameplate_border_tint.tga differ diff --git a/media/level_fill_dark.tga b/media/level_fill_dark.tga new file mode 100644 index 0000000..336eb20 Binary files /dev/null and b/media/level_fill_dark.tga differ diff --git a/modules/auras.lua b/modules/auras.lua index 5bfbe47..7db98f8 100644 --- a/modules/auras.lua +++ b/modules/auras.lua @@ -2823,6 +2823,7 @@ local function ApplyIconDimensions(icon, size) icon:SetWidth(size) icon:SetHeight(size) icon.BNPLayoutSize = size + BNP:ApplyAuraBorderColor(icon) end local auraFontSize = (BNP.GetAuraFontSize and BNP:GetAuraFontSize()) or (UI.TIMER_SIZE or 8) @@ -3250,6 +3251,7 @@ local function UpdateCCRow(plate, guid, cache, now) local entry = active[i] if entry then icon.texture:SetTexture(entry.aura.texture or entry.def.texture) + BNP:ApplyAuraBorderColor(icon) local stackCount = tonumber(entry.aura.stacks) or 0 if icon.stack then if stackCount > 1 then icon.stack:SetText(tostring(stackCount)) else icon.stack:SetText("") end @@ -3818,6 +3820,7 @@ local function UpdatePlate(plate, now) if icon.BNPLastTexture ~= texture then icon.texture:SetTexture(texture) icon.BNPLastTexture = texture + BNP:ApplyAuraBorderColor(icon) end local stackCount = tonumber(entry.aura.stacks) or 0 diff --git a/modules/castbar.lua b/modules/castbar.lua index cf7eda0..0e0ebcc 100644 --- a/modules/castbar.lua +++ b/modules/castbar.lua @@ -322,6 +322,15 @@ end local function ApplyCastbarStyle(bar) if not bar then return end + local texture = BNP:GetCastbarFillTexture() + if bar.BNPCastbarTexture ~= texture then + local r, g, b, a = bar:GetStatusBarColor() + bar:SetStatusBarTexture(texture) + if r then bar:SetStatusBarColor(r, g, b, a or 1) end + bar.background:SetTexture(texture) + bar.BNPCastbarTexture = texture + end + local classic = IsClassicCastbarStyle() if bar.classicBackdrop then @@ -390,7 +399,9 @@ local function CreateCastbar(plate) bar.BNPRenderWidth = initialRenderWidth bar.BNPLayoutHealthWidth = initialHealthWidth bar.BNPLayoutEndExtension = initialEndExtension - bar:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar") + local texture = BNP:GetCastbarFillTexture() + bar:SetStatusBarTexture(texture) + bar.BNPCastbarTexture = texture bar:SetStatusBarColor(1.0, 0.8, 0.0) bar:SetMinMaxValues(0, 1) bar:SetValue(0) @@ -398,9 +409,10 @@ local function CreateCastbar(plate) bar:Hide() local bg = bar:CreateTexture(nil, "BACKGROUND") - bg:SetTexture("Interface\\TargetingFrame\\UI-StatusBar") + bg:SetTexture(texture) bg:SetVertexColor(0.10, 0.10, 0.00, 0.85) bg:SetAllPoints(bar) + bar.background = bg local text = bar:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall") ApplyCastbarFont(text) diff --git a/modules/classcolors.lua b/modules/classcolors.lua index f00b871..77f85f8 100644 --- a/modules/classcolors.lua +++ b/modules/classcolors.lua @@ -13,6 +13,10 @@ local fallbackColors = { } local function GetColor(class) + if BNP_DB and BNP_DB.modernClassColors then + local c = BNP:GetModernClassColor(class) + if c then return c.r, c.g, c.b end + end if RAID_CLASS_COLORS and RAID_CLASS_COLORS[class] then local c = RAID_CLASS_COLORS[class] return c.r, c.g, c.b diff --git a/modules/fullalpha.lua b/modules/fullalpha.lua index 2631d8e..10d9f64 100644 --- a/modules/fullalpha.lua +++ b/modules/fullalpha.lua @@ -651,6 +651,7 @@ local function ApplyTargetBorderColor(plate) border:SetTexture(wantedTexture) end plate.BNPTargetBorderTexture = wantedTexture + BNP:UpdateLevelBackground(plate) local needsColor = true if border.GetVertexColor then @@ -978,6 +979,7 @@ local function InstallAlphaGuard(plate) -- reintroduce a visible grey/red flash on tagged mobs. The expensive owner -- query inside ApplyForeignTagVisual is already cached to 10 Hz. ApplyForeignTagVisual(current) + BNP:UpdateLevelBackground(current) -- Native projection can reset the raid icon anchor on any frame. Correct -- visible marks before rendering; the Y-offset loop leaves their anchors diff --git a/modules/personalnameplate.lua b/modules/personalnameplate.lua index b8c4d44..a60167b 100644 --- a/modules/personalnameplate.lua +++ b/modules/personalnameplate.lua @@ -351,6 +351,10 @@ end local function GetPlayerHealthColor() if BNP.IsPersonalNameplateClassColorEnabled and BNP:IsPersonalNameplateClassColorEnabled() then local _, class = UnitClass("player") + if BNP_DB and BNP_DB.modernClassColors then + local c = BNP:GetModernClassColor(class) + if c then return c.r, c.g, c.b end + end if RAID_CLASS_COLORS and class and RAID_CLASS_COLORS[class] then local c = RAID_CLASS_COLORS[class] return c.r, c.g, c.b @@ -397,6 +401,7 @@ local function UpdateStyle(frame) if not frame then return end ApplyLevelLayout(frame) + BNP:ApplyModernHealthTexture(frame) local dark = BNP.IsDarkNameplateBorderEnabled and BNP:IsDarkNameplateBorderEnabled() local hidden = BNP.IsNameplateBorderHidden and BNP:IsNameplateBorderHidden() @@ -407,7 +412,7 @@ local function UpdateStyle(frame) else frame.border:Show() if dark then - frame.border:SetVertexColor(0.38, 0.38, 0.38, 1) + frame.border:SetVertexColor(BNP:GetRecoloredBorderColor()) else frame.border:SetVertexColor(1, 1, 1, 1) end @@ -416,6 +421,7 @@ local function UpdateStyle(frame) local edge = dark and 0.32 or 0.78 local edgeG = dark and 0.32 or 0.60 local edgeB = dark and 0.32 or 0.08 + if dark then edge, edgeG, edgeB = BNP:GetRecoloredBorderColor() end SetThinBorderColor(frame.powerHolder, edge, edgeG, edgeB, hidden and 0 or 1) if blackBG then diff --git a/modules/shagu_darkmode.lua b/modules/shagu_darkmode.lua index d797a1e..c5c7409 100644 --- a/modules/shagu_darkmode.lua +++ b/modules/shagu_darkmode.lua @@ -12,7 +12,7 @@ local pending = {} local function ShaguDarkModeActive() return ShaguTweaks - and ShaguTweaks.DarkMode + and (ShaguTweaks.DarkMode or ShaguTweaks.GoldMode) and ShaguTweaks.DarkenFrame end diff --git a/modules/visualguard.lua b/modules/visualguard.lua index 952e76f..70621c3 100644 --- a/modules/visualguard.lua +++ b/modules/visualguard.lua @@ -10,9 +10,8 @@ BNP = BNP or {} -- heartbeat and no layout/parent/anchor enforcement here, so BNP never fights -- WorldFrame movement while the player/camera is moving. -local BORDER_TEXTURE = "Interface\\AddOns\\BlizzNameplatesPlus\\media\\classic_nameplate_border.tga" +local BORDER_TEXTURE = "Interface\\AddOns\\BlizzNameplatesPlus\\media\\classic_nameplate_border_healthlevel.tga" local GLOW_TEXTURE = "Interface\\AddOns\\BlizzNameplatesPlus\\media\\classic_nameplate_glow.tga" -local DARK_BORDER_R, DARK_BORDER_G, DARK_BORDER_B, DARK_BORDER_A = 0.3, 0.3, 0.3, 0.9 local function IsTotemIconOnly(plate) return plate and plate.BNPTotemLastKey and @@ -77,7 +76,7 @@ local function ApplyBorderStyle(plate) if BNP.IsDarkNameplateBorderEnabled and BNP:IsDarkNameplateBorderEnabled() then -- Match ShaguTweaks' default Darkened UI color, but touch only the native -- nameplate border. Healthbars, glows, castbars and icons stay unchanged. - SetBorderVertexColor(border, DARK_BORDER_R, DARK_BORDER_G, DARK_BORDER_B, DARK_BORDER_A) + SetBorderVertexColor(border, BNP:GetRecoloredBorderColor()) else -- This option is authoritative for the nameplate border. In particular, -- switching it off must restore the original gold even when ShaguTweaks' @@ -158,9 +157,12 @@ function BNP:RepairNativeNameplateVisuals(plate) RestoreBorder(plate) RestoreGlow(plate) + if self.ApplyModernHealthTexture then self:ApplyModernHealthTexture(plate) end ApplyBorderStyle(plate) ApplyLevelVisibility(plate) ApplyHealthbarBackground(plate) + self:ApplyLevelNumberScale(plate) + self:UpdateLevelBackground(plate) -- Native repair uses the original gold artwork. Reapply a target-specific -- colored border immediately so White/Blue do not flash gold after OnShow, @@ -171,6 +173,7 @@ function BNP:RepairNativeNameplateVisuals(plate) end function BNP:RefreshNameplateBorderStyle() + if self.RefreshAuraBorderColors then self:RefreshAuraBorderColors() end local plate for plate in pairs(BNP.plates or {}) do self:RepairNativeNameplateVisuals(plate) @@ -200,6 +203,7 @@ function BNP:RefreshHealthbarBackground() local plate for plate in pairs(BNP.plates or {}) do ApplyHealthbarBackground(plate) + self:UpdateLevelBackground(plate) end if self.RefreshPersonalNameplateStyle then self:RefreshPersonalNameplateStyle() end end diff --git a/tests/test_appearance.lua b/tests/test_appearance.lua new file mode 100644 index 0000000..7ef7752 --- /dev/null +++ b/tests/test_appearance.lua @@ -0,0 +1,119 @@ +local files = { + "core/appearance.lua", "core/config.lua", "core/options.lua", + "modules/classcolors.lua", "modules/fullalpha.lua", "modules/personalnameplate.lua", + "modules/shagu_darkmode.lua", "modules/visualguard.lua", "modules/auras.lua", "modules/castbar.lua", +} +for _, path in ipairs(files) do assert(loadfile(path)) end +dofile("core/appearance.lua") +local level={size=12} +function level:GetFont()return "font",self.size,"OUTLINE" end +function level:SetFont(font,size,flags)self.size=size;assert(flags=="OUTLINE")end +local levelScalePlate={level=level} +BNP_DB={levelNumberScale=.5} +BNP:ApplyLevelNumberScale(levelScalePlate) +assert(level.size==6) +BNP_DB.levelNumberScale=1.5 +BNP:ApplyLevelNumberScale(levelScalePlate) +BNP:ApplyLevelNumberScale(levelScalePlate) +assert(level.size==18) +BNP_DB.levelNumberScale=1 +BNP:ApplyLevelNumberScale(levelScalePlate) +assert(level.size==12) +local function color(r,g,b,a) + local cr,cg,cb,ca=BNP:GetRecoloredBorderColor() + assert(cr==r and cg==g and cb==b and ca==a) +end +color(.3,.3,.3,.9) +ShaguTweaks={GoldMode=true,overwrites={["goldmode.color"]={r=.9,g=.7,b=.2,a=1}}} +color(.9,.7,.2,1) +ShaguTweaks.DarkMode=true +ShaguTweaks.overwrites["darkmode.color"]={r=.2,g=.2,b=.2,a=.8} +color(.2,.2,.2,.8) +ShaguTweaks=nil +local bar={path="original"} +function bar:GetStatusBarTexture() return self.path end +function bar:SetStatusBarTexture(path) self.path=path end +local plate={healthbar=bar} +BNP_DB={modernClassColors=true} +BNP:ApplyModernHealthTexture(plate) +assert(string.find(bar.path,"BlizzardRetailBar",1,true)) +BNP:ApplyModernHealthTexture(plate) +BNP_DB.modernClassColors=false +BNP:ApplyModernHealthTexture(plate) +assert(bar.path=="original") +for _,class in ipairs({"WARRIOR","MAGE","ROGUE","DRUID","HUNTER","SHAMAN","PRIEST","WARLOCK","PALADIN"}) do + assert(BNP:GetModernClassColor(class)) +end +local function region() + local t={} + function t:SetPoint() end + function t:SetTexCoord(...) self.coords=arg end + function t:SetHeight(n) self.height=n end + function t:SetWidth(n) self.width=n end + function t:SetTexture(path) self.path=path end + function t:SetVertexColor(...) self.color=arg end + function t:Show() self.shown=true end + function t:Hide() self.shown=false end + return t +end +local icon={texture={GetTexture=function()return "spell-one" end},created=0} +function icon:CreateTexture() self.created=self.created+1;return region() end +function icon:GetWidth() return 32 end +function icon:GetHeight() return 16 end +BNP.IsDarkNameplateBorderEnabled=function()return BNP_DB.darkNameplateBorder end +BNP_DB.darkNameplateBorder=true +ShaguTweaks={GoldMode=true,overwrites={["goldmode.border"]={r=.7,g=.5,b=.2,a=1}}} +BNP:ApplyAuraBorderColor(icon) +assert(icon.created==4) +for i=1,4 do + local strip=icon.BNPRecoloredEdges[i] + assert(strip.shown and strip.path=="spell-one" and strip.color[1]==.7 and strip.color[2]==.5) +end +assert(icon.BNPRecoloredEdges[1].height==1 and icon.BNPRecoloredEdges[3].width==2) +icon.texture.GetTexture=function()return "spell-two" end +ShaguTweaks.DarkMode=true +ShaguTweaks.overwrites["darkmode.color"]={r=.1,g=.2,b=.3,a=1} +BNP:ApplyAuraBorderColor(icon) +assert(icon.created==4 and icon.BNPRecoloredEdges[1].path=="spell-two") +assert(icon.BNPRecoloredEdges[1].color[1]==.1) +BNP_DB.darkNameplateBorder=false +BNP:ApplyAuraBorderColor(icon) +for i=1,4 do assert(not icon.BNPRecoloredEdges[i].shown) end +local writes = 0 +local fill = region() +function fill:GetParent() return icon end +function fill:IsShown() return self.shown end +function fill:ClearAllPoints() end +function fill:SetAllPoints(relative) self.anchor=relative end +function fill:SetTexture(path) self.path=path;writes=writes+1 end +function fill:SetVertexColor(...) self.color=arg;writes=writes+1 end +local rim={GetParent=function()return icon end,GetWidth=function()return 128 end,GetHeight=function()return 32 end} +function rim:GetTexCoord() return 0,0,0,1,1,0,1,1 end +function icon:CreateTexture() return fill end +bar.path="modern-health" +BNP_DB.modernClassColors=true +bar.color={1,0,0,1} +function bar:GetStatusBarColor() return unpack(self.color) end +local levelPlate={border=rim,healthbar=bar} +BNP:UpdateLevelBackground(levelPlate) +assert(string.find(fill.path,"level_fill_dark",1,true) and fill.color[1]==.055 and fill.color[2]==.065 and fill.shown) +assert(fill.anchor==rim) +function fill:SetPoint(point,relative,relativePoint,x,y) self.x=x;self.y=y end +function rim:GetTexCoord() return 0,.5,0,1,1, .5,1,1 end +BNP:UpdateLevelBackground(levelPlate) +assert(fill.anchor==rim and fill.coords[2]==.5 and fill.coords[4]==1) +function rim:GetWidth()return 256 end +BNP:UpdateLevelBackground(levelPlate) +assert(fill.anchor==rim) +local before=writes +BNP:UpdateLevelBackground(levelPlate) +assert(writes==before) +bar.color={.96,.55,.73,1} -- paladin +bar.path="classic-health" +BNP_DB.modernClassColors=false +BNP:UpdateLevelBackground(levelPlate) +assert(string.find(fill.path,"level_fill_dark",1,true) and fill.color[1]==.055 and fill.color[2]==.065) +BNP.IsNameplateBorderHidden=function()return true end +BNP:UpdateLevelBackground(levelPlate) +assert(not fill.shown) +print("Lua 5.0: ten Lua files parse; palette, texture restoration, aura rims and masked dark level backgrounds pass")