Add OEVG nameplate appearance options

Match ShaguTweaks border themes, add modern health and cast textures, and make the level number adjustable. Keep target color on the border and use a dark masked level inset.
This commit is contained in:
2026-11-08 23:05:57 -04:00
parent 69a39b5709
commit 2f671797f1
21 changed files with 470 additions and 40 deletions
+1
View File
@@ -0,0 +1 @@
* text=auto eol=lf
+2 -1
View File
@@ -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
+35
View File
@@ -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.
+12 -2
View File
@@ -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
+8
View File
@@ -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.
+194
View File
@@ -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
+4
View File
@@ -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
+57 -30
View File
@@ -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)
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+3
View File
@@ -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
+14 -2
View File
@@ -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)
+4
View File
@@ -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
+2
View File
@@ -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
+7 -1
View File
@@ -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
+1 -1
View File
@@ -12,7 +12,7 @@ local pending = {}
local function ShaguDarkModeActive()
return ShaguTweaks
and ShaguTweaks.DarkMode
and (ShaguTweaks.DarkMode or ShaguTweaks.GoldMode)
and ShaguTweaks.DarkenFrame
end
+7 -3
View File
@@ -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
+119
View File
@@ -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")