Thread Tools Display Modes
05-08-14, 10:19 PM   #1
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Count Down Timer

I was wondering if there is a way to add a count down timer to the frame that you click enter dungeon on to show exactly how long you have. Lately ive qued for ramdoms and been in the middle of a quest and would like to lnow how long I have u ntill the window closes.

I am on my phone right now but with /fstack I was able to get the frame name. I would something like
Code:
countdowntimer = CreateFrame ("Frame", nil, (the frames name))
countdowntimer:SetPoint ("BOTTOM", (the frame name), 0, 0)
to create a frame to put the count down in.

Ive seen DBM have a count down stays bar show. But I'm just looking for a numeric count down nothing dance.

Ill look threw DBM maybe I can find how they get the timer info.

Coke
  Reply With Quote
05-08-14, 10:47 PM   #2
10leej
A Molten Giant
 
10leej's Avatar
AddOn Author - Click to view addons
Join Date: Feb 2011
Posts: 583
Originally Posted by cokedrivers View Post
I was wondering if there is a way to add a count down timer to the frame that you click enter dungeon on to show exactly how long you have. Lately ive qued for ramdoms and been in the middle of a quest and would like to lnow how long I have u ntill the window closes.

I am on my phone right now but with /fstack I was able to get the frame name. I would something like
Code:
countdowntimer = CreateFrame ("Frame", nil, (the frames name))
countdowntimer:SetPoint ("BOTTOM", (the frame name), 0, 0)
to create a frame to put the count down in.

Ive seen DBM have a count down stays bar show. But I'm just looking for a numeric count down nothing dance.

Ill look threw DBM maybe I can find how they get the timer info.

Coke
The basic function is simple enough. I use this for a pull timer, though it uses a chat output
Lua Code:
  1. local pull, seconds, onesec
  2. local frame = CreateFrame("Frame")
  3. frame:Hide()
  4. frame:SetScript("OnUpdate", function(self, elapsed)
  5.     --Start DBM pull timer
  6.     onesec = onesec - elapsed
  7.     pull = pull - elapsed
  8.     if pull <= 0 then
  9.         SendChatMessage("Pulling!", cfg.channelannounce)
  10.         self:Hide()
  11.     elseif onesec <= 0 then
  12.         SendChatMessage(seconds, cfg.channelannounce)
  13.         seconds = seconds - 1
  14.         onesec = 1
  15.     end
  16. end)
  17. SlashCmdList["COUNTDOWN"] = function(t)
  18.     t = tonumber(t) or 6
  19.     pull = t + 1
  20.     seconds = t
  21.     onesec = 1
  22.     frame:Show()
  23. end
  24. SLASH_COUNTDOWN1 = "/inc"

just replace SendChatMessage and a few other things with a status bar fill I imagine.
__________________
Tweets YouTube Website
  Reply With Quote
05-08-14, 11:55 PM   #3
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by cokedrivers View Post
Ive seen DBM have a count down stays bar show. But I'm just looking for a numeric count down nothing dance.

Ill look threw DBM maybe I can find how they get the timer info.
DBM just hardcodes it at 40 seconds; AFAIK there is no API function to get the remaining time.

Code:
local PROPOSAL_DURATION = 40

local frame = CreateFrame("Frame", nil, LFGDungeonReadyPopup)
frame:SetPoint("TOP", LFGDungeonReadyPopup, "BOTTOM", 0, -5)
frame:SetSize(20, 20) -- doesn't actually matter, just needs nonzero dimensions

local text = frame:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
text:SetPoint("TOP")

local t = PROPOSAL_DURATION
frame:SetScript("OnUpdate", function(self, elapsed)
     t = t - elapsed
     text:SetText(floor(t + 0.5))
end)

frame:RegisterEvent("LFG_PROPOSAL_SHOW")
frame:SetScript("OnEvent", function(self, event)
     if event == "LFG_PROPOSAL_SHOW" then
          t = PROPOSAL_DURATION
          self:Show()
     else
          self:Hide()
     end
end)
If you wanted a status bar (complete with gradient coloring) instead:

Code:
local PROPOSAL_DURATION = 40

local bar = CreateFrame("StatusBar", nil, LFGDungeonReadyPopup)
bar:SetPoint("TOPLEFT", LFGDungeonReadyPopup, "BOTTOMLEFT", 0, -5)
bar:SetPoint("TOPRIGHT", LFGDungeonReadyPopup, "BOTTOMRIGHT", 0, -5)
bar:SetHeight(5)
bar:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
bar:SetMinMaxValues(0, PROPOSAL_DURATION)

local spark = bar:CreateTexture(nil, "OVERLAY")
spark:SetPoint("CENTER", bar:GetStatusBarTexture(), "LEFT")
spark:SetSize(5, 8) -- height should be about 2.5x width
spark:SetAlpha(0.5)
spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
spark:SetBlendMode("ADD")

local t = PROPOSAL_DURATION
local HALF_POINT = PROPOSAL_DURATION / 2
bar:SetScript("OnUpdate", function(self, elapsed)
     t = t - elapsed
     self:SetValue(t)
     if t > HALF_POINT then
          self:SetStatusBarColor(1, t / PROPOSAL_DURATION, 0)
     else
          self:SetStatusBarColor(1 - (t / PROPOSAL_DURATION), 1, 0)
     end
end)

frame:RegisterEvent("LFG_PROPOSAL_SHOW")
frame:SetScript("OnEvent", function(self, event)
     if event == "LFG_PROPOSAL_SHOW" then
          t = PROPOSAL_DURATION
          self:Show()
     else
          self:Hide()
     end
end)
__________________
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.

Last edited by Phanx : 05-09-14 at 12:03 AM.
  Reply With Quote
05-09-14, 07:34 AM   #4
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Thank you for both versions, ill test it tonight. Now if the 40 seconds is to long all ill need to change is the 40 at the top correct?

Coke

EDIT: Will this also work for PvP, or is that a different frame?

Last edited by cokedrivers : 05-09-14 at 02:51 PM.
  Reply With Quote
05-09-14, 07:25 PM   #5
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
PvP is a different frame, a different event, and possibly a different duration, but the general idea should be the same.
__________________
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
05-09-14, 09:47 PM   #6
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
PvP is a different frame, a different event, and possibly a different duration, but the general idea should be the same.
so for the PvP I was able to create this:
Code:
	local PROPOSAL_DURATION = 90

	local PVPTimerFrame = CreateFrame("Frame", nil, PVPReadyDialog)
	PVPTimerFrame:SetPoint("TOP", PVPReadyDialog, "BOTTOM", -1, 20)
	PVPTimerFrame:SetWidth(300)
	PVPTimerFrame:SetHeight(35)
	PVPTimerFrame:SetBackdrop({ 
		bgFile = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]], 
		edgeFile = [[Interface\AddOns\nExtras\Media\UI-DialogBox-Border.blp]], 
		edgeSize = 25, insets = { left = 5, right = 5, top = 5, bottom = 5 } 
	})
	PVPTimerFrame:SetBackdropColor(0, 0, 0, 1)
	
	local text = PVPTimerFrame:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
	text:SetPoint("CENTER")

	local t = PROPOSAL_DURATION
	PVPTimerFrame:SetScript("OnUpdate", function(self, elapsed)
		 t = t - elapsed
		 text:SetText(floor(t + 0.5).."s left to Enter Battleground.")
	end)

	PVPTimerFrame:RegisterEvent("UPDATE_BATTLEFIELD_STATUS")
	PVPTimerFrame:SetScript("OnEvent", function(self, event)
		 if event == "UPDATE_BATTLEFIELD_STATUS" then
			  t = PROPOSAL_DURATION
			  self:Show()
		 else
			  self:Hide()
		 end
	end)
Which inturn gave me this:


But the time keeps reseting, I don't think I have the correct event. There are like 6 of them but in the event doc page the other ones are for like World PvP not battlegrounds.

Thanks for any help.

Coke
  Reply With Quote
05-10-14, 03:27 AM   #7
Resike
A Pyroguard Emberseer
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,290
I don't think the event is the issue here, more like the timer onupdate. Elapsed is a time in miliseconds, and the 90 sec timer is a decimal. I can make an example tonight how do it, if noone will do it faster, but i have to leave now.
  Reply With Quote
05-10-14, 03:54 AM   #8
Lombra
A Molten Giant
 
Lombra's Avatar
AddOn Author - Click to view addons
Join Date: Nov 2006
Posts: 554
No, elapsed is in seconds.

You could try the BATTLEFIELD_MGR_ENTRY_INVITE event.
__________________
Grab your sword and fight the Horde!
  Reply With Quote
05-10-14, 05:23 AM   #9
karmamuscle
A Cobalt Mageweaver
 
karmamuscle's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2008
Posts: 205
Originally Posted by cokedrivers View Post
That looks really useful for dungeon/lfr/pvp queues!
Is it something that you plan to release as a standalone addon?
__________________
55 89 144 233 377 610 987 1597 2584 4181 6765
  Reply With Quote
05-10-14, 07:32 AM   #10
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by ckramme View Post
That looks really useful for dungeon/lfr/pvp queues!
Is it something that you plan to release as a standalone addon?
Its just my idea as far as a stand alone addon that would be up to Phanx she wrote the code all I did was add the border and background.

Personally I still need to test the LFG and LFR to see if the time matches. When I'm done ill post the code here if Phanx chooses not to make a stand alone.

Coke
  Reply With Quote
05-10-14, 09:15 AM   #11
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Based on a quick glance at the code in FrameXML\PVPHelper.lua, I'd guess you want BATTLEFIELD_MGR_ENTRY_INVITE as Lombra suggested.

Also, be careful with your global names. "PVPTimerFrame" is already used by a default UI frame, so overwriting it with your own frame is likely to cause some issues.
__________________
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
05-10-14, 10:47 AM   #12
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
Based on a quick glance at the code in FrameXML\PVPHelper.lua, I'd guess you want BATTLEFIELD_MGR_ENTRY_INVITE as Lombra suggested.

Also, be careful with your global names. "PVPTimerFrame" is already used by a default UI frame, so overwriting it with your own frame is likely to cause some issues.
Will try the new event this evening when I get home. As for the frame name do you think "LFGQueueCountdown" and "PVPQueueCountdown" would work for names cause i remember you saying i need to make them different so other addons or the main ui dont cross.
  Reply With Quote
05-10-14, 11:52 AM   #13
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by cokedrivers View Post
Will try the new event this evening when I get home. As for the frame name do you think "LFGQueueCountdown" and "PVPQueueCountdown" would work for names cause i remember you saying i need to make them different so other addons or the main ui dont cross.
Log into the game and type "/dump LFGQueueCountdown" -- if you see anything other than "empty result" then that name is already taken.

However, in addition to your globals being unique, you should also make them identifiable as belonging to your addon -- this way you don't have to check if they're already used by some other addon, and other authors following the same best practice also don't have to check other addons to see if the name is in use.

However #2, there's no reason to give these things you're creating global names at all, since you're not using Blizzard templates that require them.
__________________
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
05-10-14, 07:20 PM   #14
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
BATTLEFIELD_MGR_ENTRY_INVITE doesn't seem to work. If I select "Leave Queue" then sign up again it continues to count down from were it left off.

Will look go hunting around the interweb to see if I can find a solution.

Coke
  Reply With Quote
05-11-14, 12:30 AM   #15
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Upon further reading in the default UI code, you probably want UPDATE_BATTLEFIELD_STATUS after all, but you need to do an additional check to see whether the event is relevant:

Code:
f:RegisterEvent("UPDATE_BATTLEFIELD_STATUS")
f:SetScript("OnEvent", function(self, event, index)
	 if GetBattlefieldStatus(index) == "confirm" then
		  t = PROPOSAL_DURATION
		  self:Show()
	 else
		  self:Hide()
	 end
end)
__________________
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
05-11-14, 08:28 AM   #16
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
Upon further reading in the default UI code, you probably want UPDATE_BATTLEFIELD_STATUS after all, but you need to do an additional check to see whether the event is relevant:

Code:
f:RegisterEvent("UPDATE_BATTLEFIELD_STATUS")
f:SetScript("OnEvent", function(self, event, index)
	 if GetBattlefieldStatus(index) == "confirm" then
		  t = PROPOSAL_DURATION
		  self:Show()
	 else
		  self:Hide()
	 end
end)
Well this did work either, I did figure it out tho thanks to an addon close to the results I was looking for.

This addon is called SafeQueue.

Here is the new code im using.
Code:
-- Provided by Phanx from WoWInterface
	
	local f = CreateFrame("Frame", nil, PVPReadyDialog)
	f:SetPoint("TOP", PVPReadyDialog, "BOTTOM", 0, 15)
	f:SetWidth(PVPReadyDialog:GetWidth() - 4)
	f:SetHeight(36)
	f:SetBackdrop({ 
		bgFile = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]], 
		edgeFile = [[Interface\DialogFrame\UI-DialogBox-Border.blp]], 
		edgeSize = 25, insets = { left = 5, right = 5, top = 5, bottom = 5 } 
	})
	f:SetBackdropColor(0, 0, 0, 1)
	
	local text = f:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
	text:SetPoint("CENTER", f, "CENTER", 0, 0)

	-- Borrowed from SafeQueue by Jordon
	------------------------------------------------------------------------------------
	local queueTime
	local queue = 0
	local remaining = 0
	
	f:SetScript("OnUpdate", function(self)
		local secs = GetBattlefieldPortExpiration(queue)
		if secs and secs > 0 and remaining ~= secs then
			remaining = secs
			local color = secs > 20 and "f20ff20" or secs > 10 and "fffff00" or "fff0000"
			text:SetText("Queue Expires in |cf"..color.. SecondsToTime(secs) .. "|r")
		end
	end)
	
	function f:UPDATE_BATTLEFIELD_STATUS()
		local queued
		for i=1, GetMaxBattlefieldID() do
			local status = GetBattlefieldStatus(i)
			if status == "queued" then
				queued = true
				if not queueTime then queueTime = GetTime() end
			elseif status == "confirm" then
				if queueTime then
					queueTime = nil
					remaining = 0
					queue = i
				end					
			end
			break
		end
		if not queued and queueTime then queueTime = nil end
	end	
	
	f:RegisterEvent("UPDATE_BATTLEFIELD_STATUS")
	f:SetScript("OnEvent", function(self, event, ...) self[event](self, ...) end)
	------------------------------------------------------------------------------------
Here is a screen shot:


Now just if I can figure out where wow pulls the time to close the LFG popup like they do for the Battleground.

Thanks
Coke

Last edited by cokedrivers : 05-11-14 at 08:41 AM.
  Reply With Quote
05-11-14, 05:29 PM   #17
Clamsoda
A Frostmaul Preserver
Join Date: Nov 2011
Posts: 269
I believe Phanx mentioned at the start of the thread that there is no API to derive the timeout for LFR/LFD. You can surely adapt the code you borrowed from SafeQueue to use the 40 second time-frame (also mentioned by Phanx) instead of a time returned by a function call.
  Reply With Quote
05-11-14, 08:44 PM   #18
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
The popup is closed in response to other events. There is no timer.
__________________
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
05-11-14, 09:15 PM   #19
cokedrivers
A Rage Talon Dragon Guard
 
cokedrivers's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2009
Posts: 325
Originally Posted by Phanx View Post
The popup is closed in response to other events. There is no timer.
From what I can find seems to be the normal staic popup timer to close the window.

Sources are:
http://wowprogramming.com/utils/xmlb...L/LFGFrame.lua

In this function:
Code:
function LFGInvitePopup_Update(inviter, roleTankAvailable, roleHealerAvailable, roleDamagerAvailable)
there is a line that shows:
Code:
self.timeOut = STATICPOPUP_TIMEOUT;
Then further down in the code it shows:
Code:
function LFGInvitePopup_OnUpdate(self, elapsed)
    self.timeOut = self.timeOut - elapsed;
    if ( self.timeOut <= 0 ) then
        LFGInvitePopupDecline_OnClick();
    end
end
which I'm guessing closes the popup.

Now in this file:http://wowprogramming.com/utils/xmlb...taticPopup.lua

This is at the top of the file:
Code:
STATICPOPUP_TIMEOUT = 60;
So with this information I should set the timeOut to 60 and it should work.

The one thing im not sure of would be the f:SetScript("OnEvent" function(self, event) -- code)
In the Phanx example I got is show a self:Show() and a self.Hide() would that be all that is needed?

Here is my proposed code for the LFG (also while scrolling threw those codes I notice that this was at the top of the code --LFG is used for for generic functions/values that may be used for LFD, LFR, and any other LF_ system we may implement in the future. so it should work on raids as well)
Here is the code:
Code:
	local PROPOSAL_DURATION = 60

	local f = CreateFrame("Frame", nil, LFGDungeonReadyPopup)
	f:SetPoint("TOP", LFGDungeonReadyPopup, "BOTTOM", 0, 15)
	f:SetWidth(LFGDungeonReadyPopup:GetWidth() - 4)
	f:SetHeight(36)
	f:SetBackdrop({ 
		bgFile = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]], 
		edgeFile = [[Interface\DialogFrame\UI-DialogBox-Border.blp]], 
		edgeSize = 25, insets = { left = 5, right = 5, top = 5, bottom = 5 } 
	})
	f:SetBackdropColor(0, 0, 0, 1)
	
	local text = f:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge")
	text:SetPoint("CENTER", f, "CENTER", 0, 0)	

	f:SetScript("OnUpdate", function(self)
		local remaining = 0
		local sec = PROPOSAL_DURATION
		if secs and secs > 0 and remaining ~= secs then
			remaining = secs
			local color = secs > 20 and "f20ff20" or secs > 10 and "fffff00" or "fff0000"
			text:SetText("Queue Expires in |cf"..color.. SecondsToTime(secs) .. "|r")
		end
	end)

	f:RegisterEvent("LFG_PROPOSAL_SHOW")
	f:SetScript("OnEvent", function(self, event)
		 if event == "LFG_PROPOSAL_SHOW" then
			  self:Show()
		 else
			  self:Hide()
		 end
	end)
Thanks Everyone
Coke
  Reply With Quote
05-12-14, 01:08 AM   #20
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
You're not using OnUpdate correctly. You're setting your "remaining" variable to 0 every time your script runs, and setting "sec" to 60, and then checking a variable named "secs" that isn't defined anywhere, and then checking if "remaining" and "secs" are not equal which (assuming the "sec" definition is actually meant to be "sec") will always pass because 0 will never be equal to 60 and those are the only values those variables can ever have, and you're not actually keeping track of how much time has elapsed at all.

Code:
-- This variable needs to be outside of the OnUpdate so it persists between executions:
local remaining = PROPOSAL_DURATION

f:SetScript("OnUpdate", function(self, elapsed) -- You need to know how much time has elapsed
	-- Deduct the elapsed time (since the last OnUpdate) from the total remaining time:
	remaining = remaining - elapsed

	local color = remaining > 20 and "20ff20" or remaining > 10 and "ffff00" or "ff0000"

	-- Use SetFormattedText here, and don't split the color code in the middle of the alpha value.
	text:SetFormattedText("Queue Expires in |cff%s%s|r", color, SecondsToTime(remaining))
end)

f:RegisterEvent("LFG_PROPOSAL_SHOW")
f:SetScript("OnEvent", function(self, event)
	if event == "LFG_PROPOSAL_SHOW" then
		-- Restart the timer:
		remaining = PROPOSAL_DURATION
		self:Show()
	else
		self:Hide()
	end
end)
__________________
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

WoWInterface » Developer Discussions » Lua/XML Help » Count Down Timer

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