diff --git a/mods/xpbar-text.lua b/mods/xpbar-text.lua index 7f9aef5..4bb4d15 100644 --- a/mods/xpbar-text.lua +++ b/mods/xpbar-text.lua @@ -1,4 +1,3 @@ -local _G = ShaguTweaks.GetGlobalEnv() local T = ShaguTweaks.T local module = ShaguTweaks:register({ @@ -11,57 +10,69 @@ local module = ShaguTweaks:register({ }) module.enable = function(self) - -- Create a separate overlay frame anchored to the XP bar, - -- same approach as actionbar-improved-expbar to avoid touching bar internals - local exp = CreateFrame("Frame", nil, UIParent) - exp:SetAllPoints(MainMenuExpBar) - exp:SetFrameStrata("HIGH") + -- Reuse the overlay if enable() is called again instead of stacking another + -- frame and another event handler on top of the experience bar. + if not self.exp then + self.exp = CreateFrame("Frame", nil, UIParent) + self.exp:SetAllPoints(MainMenuExpBar) + self.exp:SetFrameStrata("HIGH") - exp.text = exp:CreateFontString(nil, "OVERLAY", "GameFontWhite") - exp.text:SetFont("Fonts\\ARIALN.TTF", 14, "OUTLINE") - exp.text:SetPoint("CENTER", MainMenuExpBar, "CENTER", 0, 1) - exp.text:SetJustifyH("CENTER") - exp.text:SetTextColor(1, 1, 1) + self.exp.text = self.exp:CreateFontString(nil, "OVERLAY", "GameFontWhite") + self.exp.text:SetFont("Fonts\\ARIALN.TTF", 14, "OUTLINE") + self.exp.text:SetPoint("CENTER", MainMenuExpBar, "CENTER", 0, 1) + self.exp.text:SetJustifyH("CENTER") + self.exp.text:SetTextColor(1, 1, 1) + end + + local exp = self.exp local function UpdateXPText() local curr = UnitXP("player") - local max = UnitXPMax("player") + local max = UnitXPMax("player") if not max or max == 0 then - exp.text:Hide() + if exp.text:IsShown() then exp.text:Hide() end + self.lastText = nil return end - local rest = GetXPExhaustion() or 0 - local xpPct = math.floor(curr / max * 100) + local rest = GetXPExhaustion() or 0 + local xpPct = math.floor(curr / max * 100) local text if rest > 0 then - -- Rested XP pool is 150% of max XP, not 100% (mécanique post-patch) + -- Preserve the existing Turtle/Vanilla rested display calculation. local restPct = math.floor(math.min(rest / (max * 1.5) * 100, 100)) text = "|cffffffff" .. xpPct .. "%|r |cffaaaaaa(|cffa78aca" .. restPct .. "%|cffaaaaaa)|r" else text = "|cffffffff" .. xpPct .. "%|r" end - exp.text:SetText(text) - exp.text:Show() + if self.lastText ~= text then + exp.text:SetText(text) + self.lastText = text + end + + if not exp.text:IsShown() then exp.text:Show() end end - local events = CreateFrame("Frame", nil, UIParent) - events:RegisterEvent("PLAYER_ENTERING_WORLD") - events:RegisterEvent("PLAYER_XP_UPDATE") - events:RegisterEvent("UPDATE_EXHAUSTION") - events:RegisterEvent("PLAYER_LEVEL_UP") - events:SetScript("OnEvent", function() + if not self.events then + self.events = CreateFrame("Frame", nil, UIParent) + self.events:RegisterEvent("PLAYER_ENTERING_WORLD") + self.events:RegisterEvent("PLAYER_XP_UPDATE") + self.events:RegisterEvent("UPDATE_EXHAUSTION") + self.events:RegisterEvent("PLAYER_LEVEL_UP") + end + + self.events:SetScript("OnEvent", function() if event == "PLAYER_ENTERING_WORLD" then - if not this.loaded then - this.loaded = true - -- hide blizzard's default overlay that renders the original xp text - MainMenuBarOverlayFrame:Hide() - UpdateXPText() - end - else - UpdateXPText() + -- Hide Blizzard's default overlay that renders the original XP text. + MainMenuBarOverlayFrame:Hide() end + + UpdateXPText() end) + + -- Refresh immediately in case the module is enabled after entering the world. + MainMenuBarOverlayFrame:Hide() + UpdateXPText() end