Thread Tools Display Modes
10-28-22, 04:16 PM   #1
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
Red face Force show cooldown text

Does anyone know a way to force enable showing of *Blizzard* cooldown text per cooldown frame?

In other words, I want to have the option "Show Numbers for Cooldowns" disabled, but force it to show on specific cooldown frames I have access to.

Currently I'm just creating my own text handler per frame, but it would be much nicer for consistency to use Blizzard's.

Edit:

For some clarity, here's what I mean:

Lua Code:
  1. local f = CreateFrame("Button", nil, UIParent, "CompactAuraTemplate")
  2. f:SetSize(40, 40)
  3. f:SetPoint("CENTER", 0, 0)
  4.  
  5. f.icon:SetTexture("Interface\\Icons\\spell_holy_divineillumination")
  6.  
  7. f.cooldown.text = f.cooldown:CreateFontString(nil, "OVERLAY", "GameFontNormal")
  8. f.cooldown.text:SetFont("Fonts\\FRIZQT__.TTF", 15, "OUTLINE")
  9. f.cooldown.text:SetPoint("CENTER", 0, 0)
  10.  
  11. f.cooldown:SetHideCountdownNumbers(false)
  12.  
  13. f:SetScript("OnClick", function(self)
  14.     CooldownFrame_Set(self.cooldown, GetTime(), 10, 1)
  15. end)

Here's a button with a cooldown that will go on CD when clicked. For reference, I have up potentially hundreds of these.

Currently how I'm handling them is this:

Lua Code:
  1. local timeElapsed = 0
  2. f.cooldown:SetScript("OnUpdate", function(self, elapsed)
  3.     timeElapsed = timeElapsed + elapsed
  4.     if timeElapsed > 0.2 then
  5.         local start, dur = self:GetCooldownTimes()
  6.         local timeLeft = start / 1000 + dur / 1000 - GetTime()
  7.  
  8.         if timeLeft >= 1 then
  9.             self.text:SetText(format("%d", timeLeft))
  10.         else
  11.             self.text:SetText("")
  12.         end
  13.  
  14.         timeElapsed = 0
  15.     end
  16. end)

But I'm wondering if there's a way to force this button to show blizzard text even with the setting disabled.

Last edited by tehmoku : 10-28-22 at 06:08 PM. Reason: Clarity
  Reply With Quote
10-29-22, 05:40 PM   #2
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,330
Taint-free solution:

Lua Code:
  1. local LockShowCountdownNumbers; do
  2.     local function ReshowCountdownNumbers(cooldown)
  3. --      Call the real function still in the frame's metatable
  4.         getmetatable(cooldown).__index.SetHideCountdownNumbers(cooldown, false)
  5.     end
  6.  
  7.     function LockShowCountdownNumbers(cooldown, lock)
  8.         if lock then
  9. --          We use hooksecurefunc() to prevent taint
  10. --          A quirk of this is it copies the original function from the metatable and stores our hooked version in the frame's actual table
  11. --          This still performs what we want and setting the entry to nil will restore the original operation
  12.             hooksecurefunc(cooldown, "SetHideCountdownNumbers", ReshowCountdownNumbers)
  13.         else
  14.             cooldown.SetHideCountdownNumbers = nil;--   Clear table entry, allowing fallback to frame metatable
  15.         end
  16.     end
  17. end

Lua Code:
  1. --  Test setup
  2. local f = CreateFrame("Button", nil, UIParent, "CompactAuraTemplate")
  3. f:SetSize(40, 40)
  4. f:SetPoint("CENTER", 0, 0)
  5.  
  6. f.icon:SetTexture("Interface\\Icons\\spell_holy_divineillumination")
  7.  
  8. LockShowCountdownNumbers(f.cooldown, true)--    Call our function
  9. f.cooldown:SetHideCountdownNumbers(false)-- Test the lock
  10.  
  11. f:SetScript("OnClick", function(self)
  12.     CooldownFrame_Set(self.cooldown, GetTime(), 10, 1)
  13. end)



If you don't care about taint, then you could just set the table entry to nop(), which is an empty function defined in UIParent.lua. Just like the taint-free code, you can set this back to nil to restore operation since the actual function is in the frame's metatable.
Code:
f.coolodown.SetHideCountdownNumbers = nop
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
10-29-22, 10:46 PM   #3
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
It seems this solution isn't working for me.

I may definitely be missing something, or perhaps I misrepresented my problem. It seems that this forces cooldown text to show even when the text is disabled by SetHideCountdownNumbers(true), and for that it works wonderfully. But I'm looking to know if there's a way to show the cooldown text when it is globally disabled by SetCVar("countdownForCooldowns", false)

With that CVar disabled the text still doesn't show using your solution.



  Reply With Quote
10-30-22, 04:06 PM   #4
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,330
Can't really think of any other way besides what you've already done. There could be a little optimization with your math, but that's more nitpicking on trimming the number of operations you're using than anything you'd actually notice.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 10-30-22 at 04:16 PM.
  Reply With Quote
10-30-22, 05:03 PM   #5
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
Yeah, I was worried this is handled entirely on the C side of things. I was hoping that somebody smarter than I had a silver bullet though.

I would like to see your optimizations though. I threw it together pretty quick, and I can already see at least one thing I'd change, but I might as well optimize as much as I can if I'm going to handle the numbers myself (although I don't know if that's specifically worth it...)

Last edited by tehmoku : 10-30-22 at 05:08 PM. Reason: clarity
  Reply With Quote
10-31-22, 04:11 PM   #6
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,330
Originally Posted by tehmoku View Post
I would like to see your optimizations though. I threw it together pretty quick, and I can already see at least one thing I'd change, but I might as well optimize as much as I can if I'm going to handle the numbers myself (although I don't know if that's specifically worth it...)
The first thing that stood out to me was this line.
Code:
local timeLeft = start / 1000 + dur / 1000 - GetTime()
Currently, you're taking one variable, dividing by 1000, then taking another variable and doing the same before adding them together. You can save a divide operation by adding the variables together before dividing by 1000.
Code:
local timeLeft = (start + dur) / 1000 - GetTime()


A second thing I'd note is FontStrings have a built-in format function that works in the same way, you can save a global index and a function call by using it instead. Even if C code does the exact same thing, remember, C code processes much faster natively than Lua code can.
Code:
self.text:SetFormattedText("%d", timeLeft)


Again, and at the scale of once every 200ms, you're not really going to see a difference.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 10-31-22 at 04:22 PM.
  Reply With Quote
11-02-22, 08:58 PM   #7
tehmoku
A Fallenroot Satyr
Join Date: May 2007
Posts: 27
Originally Posted by SDPhantom View Post
Code:
local timeLeft = (start + dur) / 1000 - GetTime()

Yeah, this was the thing that immediately stood out to me when I re-looked it over, haha.



Originally Posted by SDPhantom View Post
A second thing I'd note is FontStrings have a built-in format function that works in the same way, you can save a global index and a function call by using it instead. Even if C code does the exact same thing, remember, C code processes much faster natively than Lua code can.
Code:
self.text:SetFormattedText("%d", timeLeft)

This one I actually didn't know though, so thank you!


Originally Posted by SDPhantom View Post
Again, and at the scale of once every 200ms, you're not really going to see a difference.

What fun is coding if you aren't unnecessarily harsh on yourself about efficiency?
  Reply With Quote
11-03-22, 02:07 PM   #8
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,330
Originally Posted by tehmoku View Post
What fun is coding if you aren't unnecessarily harsh on yourself about efficiency?
I used to get a rush from making an idea work, but the dopamine from that has faded long ago. I still enjoy a good problem to solve for entertainment. At least an effort to keep the old brain working in comparison to the mundacity that is everything else.

Basically the definition of a hobby at this point.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 11-03-22 at 02:09 PM.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Force show cooldown text


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off