forked from Dusk/ShaguTweaks-ClassicAPI
241 lines
8.9 KiB
Lua
241 lines
8.9 KiB
Lua
local _G = ShaguTweaks.GetGlobalEnv()
|
|
local T = ShaguTweaks.T
|
|
local hooksecurefunc = hooksecurefunc or ShaguTweaks.hooksecurefunc
|
|
|
|
local FALLBACK_CLASS_COLOR = { r = .5, g = .5, b = .5, a = 1 }
|
|
|
|
local module = ShaguTweaks:register({
|
|
title = T["Unit Frame Class Colors"],
|
|
description = T["Adds class colors to the player, target and party unit frames."],
|
|
expansions = { ["vanilla"] = true },
|
|
category = T["Unit Frames"],
|
|
enabled = nil,
|
|
})
|
|
|
|
local function GetUnitClassColor(unit)
|
|
local _, class = UnitClass(unit)
|
|
local palette = ShaguTweaks.ModernClassColors or RAID_CLASS_COLORS
|
|
return palette[class] or FALLBACK_CLASS_COLOR
|
|
end
|
|
|
|
local function SetTextColorIfChanged(fontString, r, g, b, a)
|
|
local cr, cg, cb, ca = fontString:GetTextColor()
|
|
if cr ~= r or cg ~= g or cb ~= b or ca ~= a then
|
|
fontString:SetTextColor(r, g, b, a)
|
|
end
|
|
end
|
|
|
|
local function SetVertexColorIfChanged(texture, r, g, b, a)
|
|
local cr, cg, cb, ca = texture:GetVertexColor()
|
|
if cr ~= r or cg ~= g or cb ~= b or ca ~= a then
|
|
texture:SetVertexColor(r, g, b, a)
|
|
end
|
|
end
|
|
|
|
local function UpdatePartyColors()
|
|
for id = 1, MAX_PARTY_MEMBERS do
|
|
local name = _G["PartyMemberFrame" .. id .. "Name"]
|
|
if name then
|
|
local color = GetUnitClassColor("party" .. id)
|
|
SetTextColorIfChanged(name, color.r, color.g, color.b, 1)
|
|
end
|
|
end
|
|
end
|
|
|
|
module.enable = function(self)
|
|
local function UpdateTargetClassColor()
|
|
if not TargetFrameNameBackground then return end
|
|
|
|
local reaction = UnitReaction("target", "player")
|
|
if UnitIsPlayer("target") then
|
|
local color = GetUnitClassColor("target")
|
|
SetVertexColorIfChanged(TargetFrameNameBackground,
|
|
color.r, color.g, color.b, 1)
|
|
TargetFrameNameBackground:Show()
|
|
elseif reaction and reaction > 4 then
|
|
TargetFrameNameBackground:Hide()
|
|
else
|
|
TargetFrameNameBackground:Show()
|
|
end
|
|
end
|
|
|
|
-- Let Blizzard and other addons finish their target-faction handling first,
|
|
-- then apply the class-color background instead of replacing the global.
|
|
hooksecurefunc("TargetFrame_CheckFaction", UpdateTargetClassColor)
|
|
|
|
local playerColor = GetUnitClassColor("player")
|
|
|
|
-- add name background to player frame
|
|
PlayerFrameNameBackground = PlayerFrame:CreateTexture(nil, "BACKGROUND")
|
|
PlayerFrameNameBackground:SetTexture("Interface\\TargetingFrame\\UI-TargetingFrame-LevelBackground")
|
|
PlayerFrameNameBackground:SetWidth(119)
|
|
PlayerFrameNameBackground:SetHeight(19)
|
|
PlayerFrameNameBackground:SetPoint("TOPLEFT", 106, -22)
|
|
PlayerFrameNameBackground:SetVertexColor(playerColor.r, playerColor.g, playerColor.b, 1)
|
|
|
|
local wait = CreateFrame("Frame")
|
|
wait:RegisterEvent("PLAYER_ENTERING_WORLD")
|
|
wait:SetScript("OnEvent", function()
|
|
local color = GetUnitClassColor("player")
|
|
SetVertexColorIfChanged(PlayerFrameNameBackground,
|
|
color.r, color.g, color.b, 1)
|
|
this:UnregisterAllEvents()
|
|
|
|
-- make sure to keep name background above frame shadow
|
|
PlayerFrameNameBackground:SetDrawLayer("BORDER")
|
|
TargetFrameNameBackground:SetDrawLayer("BORDER")
|
|
end)
|
|
|
|
-- add font outline
|
|
local font, size = PlayerFrame.name:GetFont()
|
|
PlayerFrame.name:SetFont(font, size, "NONE")
|
|
TargetFrame.name:SetFont(font, size, "NONE")
|
|
|
|
-- Update party name colors after the stock member refresh instead of
|
|
-- replacing PartyMemberFrame_UpdateMember. Cached color writes avoid doing
|
|
-- extra rendering work when the class did not change.
|
|
hooksecurefunc("PartyMemberFrame_UpdateMember", UpdatePartyColors)
|
|
|
|
UpdateTargetClassColor()
|
|
UpdatePartyColors()
|
|
end
|
|
|
|
|
|
-- Retail resource artwork contains its own colors, including light-blue mana.
|
|
-- A white tint preserves those native colors and gradients.
|
|
local MODERN_POWER_TEXTURES = {
|
|
[0] = "Interface\\AddOns\\ShaguTweaks\\img\\ModernPowerMana",
|
|
[1] = "Interface\\AddOns\\ShaguTweaks\\img\\ModernPowerRage",
|
|
[2] = "Interface\\AddOns\\ShaguTweaks\\img\\ModernPowerFocus",
|
|
[3] = "Interface\\AddOns\\ShaguTweaks\\img\\ModernPowerEnergy",
|
|
}
|
|
local DEFAULT_BAR_TEXTURE = "Interface\\TargetingFrame\\UI-StatusBar"
|
|
|
|
local function SetupModernPowerBars()
|
|
local bars = {}
|
|
|
|
local function ApplyPowerStyle(bar)
|
|
local state = bars[bar]
|
|
if not state then return end
|
|
local unit = bar.unit or state.unit
|
|
if not ShaguTweaks.ModernClassColors or not UnitExists(unit) then
|
|
state.background:Hide()
|
|
return
|
|
end
|
|
-- The druid's secondary bar stays mana while the primary bar is rage/energy.
|
|
local powerType = state.powerType
|
|
if powerType == nil then powerType = UnitPowerType(unit) end
|
|
local texture = MODERN_POWER_TEXTURES[powerType]
|
|
if texture then
|
|
local suffix = state.family
|
|
if suffix == "Player" then
|
|
suffix = ""
|
|
local _, class = UnitClass(unit)
|
|
-- Keep the retail energy variant for combo-point users.
|
|
if powerType == 3 and (class == "ROGUE" or class == "DRUID") then
|
|
suffix = "Class"
|
|
end
|
|
end
|
|
-- Vanilla mana slots are rectangular. Retail target/small-frame fills
|
|
-- have cut-out corners that leave a visible wedge inside those slots.
|
|
-- Use the native rectangular mana artwork for every mana frame.
|
|
if powerType == 0 then suffix = "Class" end
|
|
bar:SetStatusBarTexture(texture .. suffix)
|
|
state.background:Show()
|
|
-- Call the method captured before our hook to avoid recursive updates.
|
|
state.setColor(bar, 1, 1, 1, 1)
|
|
else
|
|
-- Unknown/custom power types retain their original texture and tint.
|
|
bar:SetStatusBarTexture(state.originalTexture)
|
|
state.background:Hide()
|
|
end
|
|
end
|
|
|
|
local definitions = {
|
|
{"PlayerFrameManaBar", "player", "Player"},
|
|
{"PlayerFrameAlternatePowerBar", "player", "Player", 0},
|
|
{"TargetFrameManaBar", "target", "Target"},
|
|
{"PetFrameManaBar", "pet", "Small"},
|
|
{"TargetofTargetManaBar", "targettarget", "Small"},
|
|
}
|
|
for id = 1, MAX_PARTY_MEMBERS do
|
|
table.insert(definitions, {"PartyMemberFrame" .. id .. "ManaBar", "party" .. id, "Party"})
|
|
end
|
|
for _, definition in ipairs(definitions) do
|
|
local bar = _G[definition[1]]
|
|
if bar then
|
|
local texture = bar:GetStatusBarTexture()
|
|
-- Opaque black behind the native alpha edges prevents the old frame's
|
|
-- colored backing from changing the retail gradient's apparent color.
|
|
local background = bar:CreateTexture(nil, "BACKGROUND")
|
|
background:SetAllPoints(bar)
|
|
background:SetTexture(0, 0, 0)
|
|
background:Hide()
|
|
bars[bar] = {
|
|
unit = definition[2],
|
|
family = definition[3],
|
|
powerType = definition[4],
|
|
background = background,
|
|
setColor = bar.SetStatusBarColor,
|
|
originalTexture = (texture and texture:GetTexture()) or DEFAULT_BAR_TEXTURE,
|
|
}
|
|
hooksecurefunc(bar, "SetStatusBarColor", function() ApplyPowerStyle(bar) end)
|
|
end
|
|
end
|
|
|
|
local function RefreshPowerBars()
|
|
for bar in pairs(bars) do ApplyPowerStyle(bar) end
|
|
end
|
|
-- Vanilla refreshes power type here. Appending preserves the normal frame
|
|
-- updates, including shapeshifts and targets with a different power type.
|
|
hooksecurefunc("UnitFrame_UpdateManaType", RefreshPowerBars)
|
|
RefreshPowerBars()
|
|
return RefreshPowerBars
|
|
end
|
|
|
|
local modern = ShaguTweaks:register({
|
|
title = "Modern Class Colors",
|
|
description = "Use modern class colors and retail health/power textures. Enable Unit Frame Class Colors for class-colored unit frames.",
|
|
expansions = { ["vanilla"] = true },
|
|
category = T["Unit Frames"],
|
|
enabled = nil,
|
|
})
|
|
|
|
modern.enable = function(self)
|
|
if self.installed then return end
|
|
self.installed = true
|
|
ShaguTweaks.ModernClassColors = {
|
|
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},
|
|
}
|
|
local RefreshPowerBars = SetupModernPowerBars()
|
|
-- Refresh after every module has initialized, regardless of enable order.
|
|
local deferred = CreateFrame("Frame")
|
|
deferred:SetScript("OnUpdate", function()
|
|
this:SetScript("OnUpdate", nil)
|
|
this:Hide()
|
|
RefreshPowerBars()
|
|
for _, prefix in ipairs({"PlayerFrame", "TargetFrame", "PetFrame", "TargetofTarget", "PartyMemberFrame1", "PartyMemberFrame2", "PartyMemberFrame3", "PartyMemberFrame4"}) do
|
|
local bar = _G[prefix .. "HealthBar"]
|
|
if bar then bar:SetStatusBarTexture("Interface\\AddOns\\ShaguTweaks\\img\\BlizzardRetailBar") end
|
|
end
|
|
if not PlayerFrameNameBackground then return end
|
|
local color = GetUnitClassColor("player")
|
|
PlayerFrameNameBackground:SetVertexColor(color.r, color.g, color.b, 1)
|
|
if TargetFrame_CheckFaction then TargetFrame_CheckFaction() end
|
|
UpdatePartyColors()
|
|
-- Big Health reads its tint from the name background.
|
|
if PlayerFrameHealthBar then
|
|
local r, g, b, a = PlayerFrameHealthBar:GetStatusBarColor()
|
|
PlayerFrameHealthBar:SetStatusBarColor(r, g, b, a)
|
|
end
|
|
end)
|
|
end
|