Thread Tools Display Modes
08-23-16, 07:38 AM   #1
Aftermathhqt
A Molten Giant
 
Aftermathhqt's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 784
Buff Timer to be Statusbar instead of text

Hi, anyone know how to do this?



My Code:

http://hastebin.com/iteweyohun.lua
  Reply With Quote
08-23-16, 08:20 AM   #2
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
https://www.wowinterface.com/downloa...hinyBuffs.html
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
08-23-16, 10:54 AM   #3
Aftermathhqt
A Molten Giant
 
Aftermathhqt's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 784
Thanks, im just not quite sure how to go forward, i looked at ShinyBuffs before, but i dont know how to get it working.. some dry code would be awesome to explain what needs to be done or how to get forward.
  Reply With Quote
08-23-16, 12:06 PM   #4
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
Look at the SkinningMachine and SkinBuffs functions.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
08-23-16, 01:37 PM   #5
Aftermathhqt
A Molten Giant
 
Aftermathhqt's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 784
Originally Posted by Seerah View Post
Look at the SkinningMachine and SkinBuffs functions.
Thank you, got it working although they are jumping back and forth whenever a buff/debuff are refreshed/gained/lost
  Reply With Quote
08-23-16, 02:21 PM   #6
Aftermathhqt
A Molten Giant
 
Aftermathhqt's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 784
Forgot to post the code

Lua Code:
  1. hooksecurefunc("AuraButton_Update", function(self, index)
  2.     local ABuffFrame = _G[self..index]
  3.     if ABuffFrame then
  4.         ABuffFrame:SetSize(33, 33)
  5.         A.CreateBorder(ABuffFrame, true, 33, 33)
  6.     end
  7.        
  8.     local ABuffFrameIcon = _G[self..index.."Icon"]
  9.     if ABuffFrameIcon then
  10.         ABuffFrameIcon:SetTexCoord(0.03, 0.97, 0.03, 0.97)
  11.     end
  12.    
  13.     local ABuffFrameDuration = _G[self..index.."Duration"]
  14.     if ABuffFrameDuration then
  15.         --ABuffFrameDuration:SetDrawLayer("OVERLAY")
  16.         --ABuffFrameDuration:ClearAllPoints()
  17.         --ABuffFrameDuration:SetPoint("BOTTOM", ABuffFrame, "BOTTOM", 1, -15.5)
  18.         --ABuffFrameDuration:SetFont(C.Media.Font, 12, "THINOUTLINE")
  19.         --ABuffFrameDuration:SetShadowOffset(1, -1)
  20.         --ABuffFrameDuration:SetShadowColor(0, 0, 0)
  21.         ABuffFrameDuration:SetAlpha(0)
  22.     end
  23.    
  24.     local ABuffFrameCount = _G[self..index.."Count"]
  25.     if ABuffFrameCount then
  26.         ABuffFrameCount:SetDrawLayer("OVERLAY")
  27.         ABuffFrameCount:ClearAllPoints()
  28.         ABuffFrameCount:SetPoint("BOTTOMRIGHT", ABuffFrame, 1, 1)
  29.         ABuffFrameCount:SetFont(C.Media.Font, 12.5, "THINOUTLINE")
  30.         ABuffFrameCount:SetShadowOffset(1, -1)
  31.         ABuffFrameCount:SetShadowColor(0, 0, 0)
  32.     end
  33.    
  34.     local ABuffFrameBorder = _G[self..index.."Border"]
  35.  
  36.     local R, G, B = ABuffFrameBorder:GetVertexColor()
  37.     ABuffFrameBorder:Hide()
  38.     ABuffFrameBorder.Show = function() end
  39.     ABuffFrameBorder:SetTexture(nil)
  40.     A.ColorBorder(ABuffFrame, R, G, B)     
  41.  
  42.    
  43.  
  44.    
  45.     local BuffStatusBar = CreateFrame("StatusBar", nil, ABuffFrame)
  46.     BuffStatusBar:SetFrameStrata("HIGH")
  47.     BuffStatusBar:SetSize(33, 6)
  48.     BuffStatusBar:SetPoint("BOTTOM", ABuffFrameIcon, 0, -8)
  49.     BuffStatusBar:SetMinMaxValues(0, 1)
  50.     BuffStatusBar:SetStatusBarTexture(C.Media.Texture)
  51.     BuffStatusBar:SetStatusBarColor(A.ClassColor.r, A.ClassColor.g, A.ClassColor.b)
  52.     A.Skin(BuffStatusBar)
  53.    
  54.     local Timer = 0
  55.     local ABuffFrameDuration, Exps, _, Exps
  56.     BuffStatusBar:SetScript("OnUpdate", function(self, Elapsed)
  57.         Timer = Timer + Elapsed
  58.         if Timer >= .1 then
  59.             _,_,_,_,_, ABuffFrameDuration, Exps = UnitBuff("player", index)
  60.             if ABuffFrameDuration == 0 then
  61.                 self:SetValue(1)
  62.             else
  63.                 if Exps then
  64.                     Val = Exps-GetTime()
  65.                     self:SetValue(Val/ABuffFrameDuration)
  66.                 end
  67.             end
  68.             Timer = 0
  69.         end
  70.     end)
  71.    
  72. end)
  Reply With Quote
08-23-16, 05:19 PM   #7
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
Every time your function gets called you are setting a new OnUpdate for that buff slot.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
08-23-16, 07:27 PM   #8
Aftermathhqt
A Molten Giant
 
Aftermathhqt's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 784
Originally Posted by Seerah View Post
Every time your function gets called you are setting a new OnUpdate for that buff slot.
So how do i fix it?
  Reply With Quote
08-23-16, 08:33 PM   #9
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
In ShinyBuffs you should see how I saved whether a buff slot was skinned/handled yet or not.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
08-24-16, 04:02 AM   #10
Aftermathhqt
A Molten Giant
 
Aftermathhqt's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 784
Originally Posted by Seerah View Post
In ShinyBuffs you should see how I saved whether a buff slot was skinned/handled yet or not.
Not sure how to do it
  Reply With Quote
08-24-16, 12:49 PM   #11
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
Look for where it says "firstTime" and then check the event handler that actually calls the functions and sets that argument.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
08-25-16, 03:11 AM   #12
Aftermathhqt
A Molten Giant
 
Aftermathhqt's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 784
Originally Posted by Seerah View Post
Look for where it says "firstTime" and then check the event handler that actually calls the functions and sets that argument.
No luck here
  Reply With Quote
08-25-16, 12:00 PM   #13
Seerah
Fishing Trainer
 
Seerah's Avatar
WoWInterface Super Mod
Featured
Join Date: Oct 2006
Posts: 10,860
When you skin/handle a buff frame, store a value in that frame's table. Check to see if it's been handled already before trying to skin/handle it again.
__________________
"You'd be surprised how many people violate this simple principle every day of their lives and try to fit square pegs into round holes, ignoring the clear reality that Things Are As They Are." -Benjamin Hoff, The Tao of Pooh

  Reply With Quote
08-26-16, 08:07 AM   #14
Aftermathhqt
A Molten Giant
 
Aftermathhqt's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 784
Originally Posted by Seerah View Post
When you skin/handle a buff frame, store a value in that frame's table. Check to see if it's been handled already before trying to skin/handle it again.
Doesn't work :/

http://hastebin.com/olisukoyeb.coffee
  Reply With Quote
08-26-16, 09:01 AM   #15
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
What doesn't work? You've commented out the whole status bar section, so no wonder! What did you do to prevent it from getting created multiple times?
__________________
Grab your sword and fight the Horde!
  Reply With Quote
08-26-16, 10:26 AM   #16
Aftermathhqt
A Molten Giant
 
Aftermathhqt's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 784
Originally Posted by Lombra View Post
What doesn't work? You've commented out the whole status bar section, so no wonder! What did you do to prevent it from getting created multiple times?
I know i've done that, it was on purpose cause its not working as intended, the thing that doesn't work is the stautusbars are jumping back and forth whenever a buff/debuff are refreshed/gained/lost
  Reply With Quote
08-27-16, 12:27 AM   #17
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
There are several problems with your code. Let's start with this one:

Code:
hooksecurefunc("AuraButton_Update", function(self, index)
	...
end)
Everything inside that function gets re-run every time an aura button is updated. That includes this:

Code:
local BuffStatusBar = CreateFrame("StatusBar", nil, ABuffFrame)
Your statusbars aren't "jumping around" -- they're being covered up by new statusbars every time the button is updated. Eventually you'll end up with thousands of statusbars on every aura button, which will use up a lot of memory and impact your game's performance.

It also includes this:

Code:
BuffStatusBar:SetScript("OnUpdate", function(self, Elapsed)
	...
end)
When each of those thousands of statusbars per button has its own OnUpdate script running, that uses a lot of CPU time, which will impact your game's performance even more. Creating thousands of copies of the same function also uses lots of memory.

Fortunately these are easy problems to solve.

================================

First, stop creating a new copy of that OnUpdate function every time a button is update. Create one copy of the function, outside of your AuraButton_Update hook:

Code:
local function AuraButtonStatusBar_OnUpdate(self, Elapsed)
	...
end
Then inside your hook, instead of passing a new (unnamed) function to SetScript, just pass the name of the function you already have:

Code:
BuffStatusBar:SetScript("OnUpdate", AuraButtonStatusBar_OnUpdate)
Now you need to make a few minor adjustments. Your original OnUpdate function refers to local variables that only exist in the scope of the AuraButton_Update hook. Since you moved it outside of that scope, those references are now looking for and/or writing to global variables by those names. The ones it looks for (eg. "index") don't exist, so your code will fail with an error. The ones it reads will be created, and creating global variables with names like "Val" is just asking for trouble.

Code:
_,_,_,_,_, ABuffFrameDuration, Exps = UnitBuff("player", index)
1. Your underscore, "ABuffFrameDuration", and "Exps" are now being written into the global scope. This is bad. Don't do it. Add a "local" keyword at the beginning of the line.

2. There is no variable "index" in this scope. Instead of looking for one, look for a value stored on the statusbar itself under the key name "index".

3. You're always specifying "player" -- this will fail when you're using a vehicle. Instead of "player", look at PlayerFrame.unit, which will usually be "player", but gets swapped with "vehicle" automatically when you enter or leave a vehicle.

4. You're using UnitBuff, but AuraButton_Update also runs for debuffs, so you should use UnitAura here instead, and store the filter value that's passed to AuraButton_Update.

Fixed version:

Code:
local _,_,_,_,_, ABuffFrameDuration, Exps = UnitAura(PlayerFrame.unit, self.index, self.filter)
You need a "local" keyword here, too:

Code:
local Val = Exps-GetTime()
Correspondingly, in your AuraButton_Update hook, store the necessary values under the "index" and "filter" keys on the statusbar:

Code:
BuffStatusBar.index = index
BuffStatusBar.filter = filter
(This doesn't go in the one-time chunk, since it needs to happen every time the button is updated.)

You also need to update your hook function definition so it actually receives the "filter" argument:

Code:
hooksecurefunc("AuraButton_Update", function(self, index, filter)
Okay, now you're no longer creating thousands of functions!

================================

Let's move on to the "creating thousands of statusbars" problem. Instead of indiscriminately creating a new statusbar every time an aura button updates, check to see if one already exists. If it does, use it. If it doesn't, then and only then should you create a new one:

Code:
local BuffStatusBar = ABuffFrame.StatusBar
if not BuffStatusBar then
	-- It doesn't exist yet. Create it:
	BuffStatusBar = CreateFrame("StatusBar", nil, ABuffFrame)
	-- and store a reference to it so you can easily find it next time:
	ABuffFrame.StatusBar = BuffStatusBar
end
Now you have a chunk of code that's only running the first time a particular aura button is updated. Every time after that, the button will already have a statusbar, so that chunk of code gets skipped.

From here, the logical next step is to move other things that only need to happen once into that chunk of code, so they don't keep getting run over and over for no reason. Since the statusbar is something you are creating, the default UI will never touch it, so all of the lines of code that place and style the statusbar only need to happen once. Move them into that block. The only thing you need to do with your statusbar after it's created is set the "index" value.

================================

Now your code should work, but there are a few simple optimizations I'd recommend doing. Since your code is going to be running very frequently, you should do everything you can (within reason) to make it as fast as possible.

The first optimization is similar to what we did for the statusbar. The default UI isn't moving and styling icons and font strings on every button update, so you don't need to do that either -- you only need to do that once, on the first update for each button. Conveniently, you already have a way to tell if this is the first update for a given button -- if it doesn't have a statusbar yet, it's the first update. Just move all of your other one-time styling code into the same chunk of code where you create a statusbar.

================================

The second optimization would be to use just one OnUpdate function to update all the statusbars, instead of a separate OnUpdate function for each statusbar, and to use GetTime() directly as the statusbar value instead of doing math calculations. The parent frame for buffs and debuffs already has an OnUpdate function, so just piggyback on that:

Code:
BuffFrame:HookScript("OnUpdate", function()
	-- Store the current time:
	local now = GetTime()

	-- Update all the buffs:
	for i = 1, BUFF_ACTUAL_DISPLAY do
		local button = _G["BuffButton"..i]
		if button.timeLeft then
			button.StatusBar:SetValue(now)
		end
	end

	-- Update all the debuffs:
	for i = 1, DEBUFF_ACTUAL_DISPLAY do
		local button = _G["DebuffButton"..i]
		if button.timeLeft then
			button.StatusBar:SetValue(now)
		end
	end
end)
Again, this should be outside of your AuraButton_Update hook.

You don't need to worry about whether or not the statusbar exists here, because BUFF_ACTUAL_DISPLAY is a count of how many buttons have already been updated, so your AuraButton_Update hook will already have been run for every button this loop catches.

However, you need to make another adjustment inside your AuraButton_Update hook to support using times directly as statusbar values:

Code:
-- Remove these two lines; we don't need them anymore:
BuffStatusBar.index = index
BuffStatusBar.filter = filter

-- Add these ones instead:
local _, _, _, _, _, duration, expirationTime = UnitAura(PlayerFrame.unit, index, filter)
BuffStatusBar:SetMinMaxValues(expirationTime - duration, expirationTime)
Now the bar's min value is the aura's start time, and it's max value is the aura's end time, so you can just set "now" as the current value in the OnUpdate script. You've also avoided calling UnitAura inside the OnUpdate script, which adds another performance boost.

(Note that I didn't actually test any of this code in-game, so there may be typos. If you get an error and can't figure it out, post your complete updated code and the actual error message.)
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
08-27-16, 01:17 AM   #18
Aftermathhqt
A Molten Giant
 
Aftermathhqt's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 784
Originally Posted by Phanx View Post
There are several problems with your code. Let's start with this one:

Code:
hooksecurefunc("AuraButton_Update", function(self, index)
	...
end)
Everything inside that function gets re-run every time an aura button is updated. That includes this:

Code:
local BuffStatusBar = CreateFrame("StatusBar", nil, ABuffFrame)
Your statusbars aren't "jumping around" -- they're being covered up by new statusbars every time the button is updated. Eventually you'll end up with thousands of statusbars on every aura button, which will use up a lot of memory and impact your game's performance.

It also includes this:

Code:
BuffStatusBar:SetScript("OnUpdate", function(self, Elapsed)
	...
end)
When each of those thousands of statusbars per button has its own OnUpdate script running, that uses a lot of CPU time, which will impact your game's performance even more. Creating thousands of copies of the same function also uses lots of memory.

Fortunately these are easy problems to solve.

================================

First, stop creating a new copy of that OnUpdate function every time a button is update. Create one copy of the function, outside of your AuraButton_Update hook:

Code:
local function AuraButtonStatusBar_OnUpdate(self, Elapsed)
	...
end
Then inside your hook, instead of passing a new (unnamed) function to SetScript, just pass the name of the function you already have:

Code:
BuffStatusBar:SetScript("OnUpdate", AuraButtonStatusBar_OnUpdate)
Now you need to make a few minor adjustments. Your original OnUpdate function refers to local variables that only exist in the scope of the AuraButton_Update hook. Since you moved it outside of that scope, those references are now looking for and/or writing to global variables by those names. The ones it looks for (eg. "index") don't exist, so your code will fail with an error. The ones it reads will be created, and creating global variables with names like "Val" is just asking for trouble.

Code:
_,_,_,_,_, ABuffFrameDuration, Exps = UnitBuff("player", index)
1. Your underscore, "ABuffFrameDuration", and "Exps" are now being written into the global scope. This is bad. Don't do it. Add a "local" keyword at the beginning of the line.

2. There is no variable "index" in this scope. Instead of looking for one, look for a value stored on the statusbar itself under the key name "index".

3. You're always specifying "player" -- this will fail when you're using a vehicle. Instead of "player", look at PlayerFrame.unit, which will usually be "player", but gets swapped with "vehicle" automatically when you enter or leave a vehicle.

4. You're using UnitBuff, but AuraButton_Update also runs for debuffs, so you should use UnitAura here instead, and store the filter value that's passed to AuraButton_Update.

Fixed version:

Code:
local _,_,_,_,_, ABuffFrameDuration, Exps = UnitAura(PlayerFrame.unit, self.index, self.filter)
You need a "local" keyword here, too:

Code:
local Val = Exps-GetTime()
Correspondingly, in your AuraButton_Update hook, store the necessary values under the "index" and "filter" keys on the statusbar:

Code:
BuffStatusBar.index = index
BuffStatusBar.filter = filter
(This doesn't go in the one-time chunk, since it needs to happen every time the button is updated.)

You also need to update your hook function definition so it actually receives the "filter" argument:

Code:
hooksecurefunc("AuraButton_Update", function(self, index, filter)
Okay, now you're no longer creating thousands of functions!

================================

Let's move on to the "creating thousands of statusbars" problem. Instead of indiscriminately creating a new statusbar every time an aura button updates, check to see if one already exists. If it does, use it. If it doesn't, then and only then should you create a new one:

Code:
local BuffStatusBar = ABuffFrame.StatusBar
if not BuffStatusBar then
	-- It doesn't exist yet. Create it:
	BuffStatusBar = CreateFrame("StatusBar", nil, ABuffFrame)
	-- and store a reference to it so you can easily find it next time:
	ABuffFrame.StatusBar = BuffStatusBar
end
Now you have a chunk of code that's only running the first time a particular aura button is updated. Every time after that, the button will already have a statusbar, so that chunk of code gets skipped.

From here, the logical next step is to move other things that only need to happen once into that chunk of code, so they don't keep getting run over and over for no reason. Since the statusbar is something you are creating, the default UI will never touch it, so all of the lines of code that place and style the statusbar only need to happen once. Move them into that block. The only thing you need to do with your statusbar after it's created is set the "index" value.

================================

Now your code should work, but there are a few simple optimizations I'd recommend doing. Since your code is going to be running very frequently, you should do everything you can (within reason) to make it as fast as possible.

The first optimization is similar to what we did for the statusbar. The default UI isn't moving and styling icons and font strings on every button update, so you don't need to do that either -- you only need to do that once, on the first update for each button. Conveniently, you already have a way to tell if this is the first update for a given button -- if it doesn't have a statusbar yet, it's the first update. Just move all of your other one-time styling code into the same chunk of code where you create a statusbar.

================================

The second optimization would be to use just one OnUpdate function to update all the statusbars, instead of a separate OnUpdate function for each statusbar, and to use GetTime() directly as the statusbar value instead of doing math calculations. The parent frame for buffs and debuffs already has an OnUpdate function, so just piggyback on that:

Code:
BuffFrame:HookScript("OnUpdate", function()
	-- Store the current time:
	local now = GetTime()

	-- Update all the buffs:
	for i = 1, BUFF_ACTUAL_DISPLAY do
		local button = _G["BuffButton"..i]
		if button.timeLeft then
			button.StatusBar:SetValue(now)
		end
	end

	-- Update all the debuffs:
	for i = 1, DEBUFF_ACTUAL_DISPLAY do
		local button = _G["DebuffButton"..i]
		if button.timeLeft then
			button.StatusBar:SetValue(now)
		end
	end
end)
Again, this should be outside of your AuraButton_Update hook.

You don't need to worry about whether or not the statusbar exists here, because BUFF_ACTUAL_DISPLAY is a count of how many buttons have already been updated, so your AuraButton_Update hook will already have been run for every button this loop catches.

However, you need to make another adjustment inside your AuraButton_Update hook to support using times directly as statusbar values:

Code:
-- Remove these two lines; we don't need them anymore:
BuffStatusBar.index = index
BuffStatusBar.filter = filter

-- Add these ones instead:
local _, _, _, _, _, duration, expirationTime = UnitAura(PlayerFrame.unit, index, filter)
BuffStatusBar:SetMinMaxValues(expirationTime - duration, expirationTime)
Now the bar's min value is the aura's start time, and it's max value is the aura's end time, so you can just set "now" as the current value in the OnUpdate script. You've also avoided calling UnitAura inside the OnUpdate script, which adds another performance boost.

(Note that I didn't actually test any of this code in-game, so there may be typos. If you get an error and can't figure it out, post your complete updated code and the actual error message.)
Thank you again Phanx, you're a life saver!

This makes everything much more easier, when explained like this

It works, but its behaving strange, the bars fills up instead of down, and sometime it doesn't really even do anything.

Lua Code:
  1. local Timer = 0
  2. local NumBuffsSkinned = 0
  3.  
  4. local function AuraButtonStatusBar_OnUpdate(self, Elapsed)
  5.    
  6.     local _,_,_,_,_, ABuffFrameDuration, Exps = UnitAura(PlayerFrame.unit, self.index, self.filter)
  7.     local Val = Exps-GetTime()
  8.    
  9.     BuffStatusBar:SetScript("OnUpdate", function(self, Elapsed)
  10.         Timer = Timer + Elapsed
  11.         if Timer >= .1 then
  12.             if ABuffFrameDuration == 0 then
  13.                 self:SetValue(1)
  14.             else
  15.                 if Exps then
  16.                     self:SetValue(Val/ABuffFrameDuration)
  17.                 end
  18.             end
  19.            
  20.             Timer = 0
  21.         end
  22.        
  23.         NumBuffsSkinned = self.index
  24.     end)
  25. end
  26.  
  27. hooksecurefunc("AuraButton_Update", function(self, index, filter)
  28.     local ABuffFrame = _G[self..index]
  29.     if ABuffFrame then
  30.         ABuffFrame:SetSize(BuffSize, BuffSize)
  31.         A.CreateBorder(ABuffFrame, true, BuffSize, BuffSize)
  32.  
  33.         local BuffStatusBar = ABuffFrame.StatusBar
  34.         if not BuffStatusBar then
  35.             local _, _, _, _, _, duration, expirationTime = UnitAura(PlayerFrame.unit, index, filter)
  36.             BuffStatusBar = CreateFrame("StatusBar", nil, ABuffFrame)
  37.             BuffStatusBar:SetFrameStrata("HIGH")
  38.             BuffStatusBar:SetSize(32, 6)
  39.             BuffStatusBar:SetPoint("BOTTOM", ABuffFrame, 0, -8)
  40.             BuffStatusBar:SetMinMaxValues(expirationTime - duration, expirationTime)
  41.             BuffStatusBar:SetStatusBarTexture(C.Media.Texture)
  42.             BuffStatusBar:SetStatusBarColor(A.ClassColor.r, A.ClassColor.g, A.ClassColor.b)
  43.             A.Skin(BuffStatusBar)
  44.    
  45.             ABuffFrame.StatusBar = BuffStatusBar           
  46.         end
  47.     end
  48.    
  49.     local ABuffFrameIcon = _G[self..index.."Icon"]
  50.     if ABuffFrameIcon then
  51.         ABuffFrameIcon:SetTexCoord(0.03, 0.97, 0.03, 0.97)
  52.     end
  53.    
  54.     local ABuffFrameDuration = _G[self..index.."Duration"]
  55.     if ABuffFrameDuration then
  56.         ABuffFrameDuration:SetDrawLayer("OVERLAY")
  57.         ABuffFrameDuration:ClearAllPoints()
  58.         ABuffFrameDuration:SetPoint("BOTTOM", ABuffFrame, "BOTTOM", 1, -15.5)
  59.         ABuffFrameDuration:SetFont(C.Media.Font, 12, "THINOUTLINE")
  60.         ABuffFrameDuration:SetShadowOffset(1, -1)
  61.         ABuffFrameDuration:SetShadowColor(0, 0, 0)
  62.         ABuffFrameDuration:SetAlpha(0)
  63.     end
  64.    
  65.     local ABuffFrameCount = _G[self..index.."Count"]
  66.     if ABuffFrameCount then
  67.         ABuffFrameCount:SetDrawLayer("OVERLAY")
  68.         ABuffFrameCount:ClearAllPoints()
  69.         ABuffFrameCount:SetPoint("BOTTOMRIGHT", ABuffFrame, 1, 1)
  70.         ABuffFrameCount:SetFont(C.Media.Font, 12.5, "THINOUTLINE")
  71.         ABuffFrameCount:SetShadowOffset(1, -1)
  72.         ABuffFrameCount:SetShadowColor(0, 0, 0)
  73.     end
  74.    
  75.     local ABuffFrameBorder = _G[self..index.."Border"]
  76.     if ABuffFrameBorder then
  77.         local R, G, B = ABuffFrameBorder:GetVertexColor()
  78.         ABuffFrameBorder:Hide()
  79.         ABuffFrameBorder:SetTexture(nil)
  80.         A.ColorBorder(ABuffFrame, R, G, B)     
  81.     end
  82. end)
  83.  
  84. BuffFrame:HookScript("OnUpdate", function()
  85.     -- Store the current time:
  86.     local now = GetTime()
  87.  
  88.     -- Update all the buffs:
  89.     for i = 1, BUFF_ACTUAL_DISPLAY do
  90.         local button = _G["BuffButton"..i]
  91.         if button.timeLeft then
  92.             button.StatusBar:SetValue(now)
  93.         end
  94.     end
  95.  
  96.     -- Update all the debuffs:
  97.     for i = 1, DEBUFF_ACTUAL_DISPLAY do
  98.         local button = _G["DebuffButton"..i]
  99.         if button.timeLeft then
  100.             button.StatusBar:SetValue(now)
  101.         end
  102.     end
  103. end)

Last edited by Aftermathhqt : 08-27-16 at 01:41 AM.
  Reply With Quote
08-27-16, 03:58 AM   #19
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
In the future, please don't quote the entire 1500 lines of a post. If you're replying the post directly before yours in the thread, there's no need for a quote at all. If you're replying to something further back, just quote the 1-3 lines that are most relevant to what you're replying. Scrolling past the whole thing quoted is annoying.

The first 26 lines of your current code don't need to exist. Delete everything up to (but not including) line 27:

Code:
hooksecurefunc("AuraButton_Update", function(self, index, filter)
You should re-read the part of my last post explaining about one-time vs every-time parts of the code. You currently have these in the "only run one time" section:

Code:
            local _, _, _, _, _, duration, expirationTime = UnitAura(PlayerFrame.unit, index, filter)
            BuffStatusBar:SetMinMaxValues(expirationTime - duration, expirationTime)
... but those need to be run every time AuraButton_Update happens, not just the first time. Since you're only setting the bar's min/max values once when you create it, instead of updating them when the button is updated, you should expect bad results (and possibly even errors) later when setting the bar's value to something outside of that original range.

And actually now that I'm looking at it again, the current code doesn't account for buffs that don't have durations. You'll want to do something like this:

Code:
            local _, _, _, _, _, duration, expirationTime = UnitAura(PlayerFrame.unit, index, filter)
            if duration > 0 and expirationTime then
                  -- This aura has a duration:
                  BuffStatusBar:SetMinMaxValues(expirationTime - duration, expirationTime)
            else
                  -- This aura doesn't have a duration:
                  BuffStatusBar:SetMinMaxValues(0, 1)
                  BuffStatusBar:SetValue(1)
            end
This check is pointless:

Code:
    if ABuffFrame then
Remove that, and its corresponding "end". The game doesn't call AuraButton_Update for buttons that don't exist, so this check just clutters up your code.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
08-27-16, 07:51 AM   #20
Aftermathhqt
A Molten Giant
 
Aftermathhqt's Avatar
AddOn Author - Click to view addons
Join Date: Dec 2009
Posts: 784
Originally Posted by Phanx View Post
In the future, please don't quote the entire 1500 lines of a post. If you're replying the post directly before yours in the thread, there's no need for a quote at all. If you're replying to something further back, just quote the 1-3 lines that are most relevant to what you're replying. Scrolling past the whole thing quoted is annoying.
Haha sorry!

That makes much more sense.

When i actually remove the check it give errors for some reason

Lua Code:
  1. ...nterface\AddOns\AftermathhUI\Modules\Auras\Auras.lua:180: attempt to index local 'ABuffFrame' (a nil value)
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Buff Timer to be Statusbar instead of text

Thread Tools
Display Modes

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