Quantcast

Add expiry timers to buffs/debuffs (thanks to rythos42)

James Whitehead II [10-15-10 - 18:33]
Add expiry timers to buffs/debuffs (thanks to rythos42)
Filename
PerfectRaid_Buffs.lua
diff --git a/PerfectRaid_Buffs.lua b/PerfectRaid_Buffs.lua
index 32781c3..c35bad5 100644
--- a/PerfectRaid_Buffs.lua
+++ b/PerfectRaid_Buffs.lua
@@ -32,6 +32,29 @@
 local Buffs = PerfectRaid:NewModule("PerfectRaid-Buffs")
 local L = PerfectRaidLocals
 local utils, frames
+local timerFrame
+
+-- Speed up this module as much as possible
+local genv = _G
+local PerfectRaid = genv.PerfectRaid
+local setmetatable = genv.setmetatable
+local pairs = genv.pairs
+local table = genv.table
+local ipairs = genv.ipairs
+local select = genv.select
+local UnitClass = genv.UnitClass
+local UnitRaid = genv.UnitRace
+local GetNumRaidMembers = genv.GetNumRaidMembers
+local CreateFrame = genv.CreateFrame
+local UIParent = genv.UIParent
+local GetRaidRosterInfo = genv.GetRaidRosterInfo
+local string = genv.string
+local rawset = genv.rawset
+local UnitBuff = genv.UnitBuff
+local UnitDebuff = genv.UnitDebuff
+local unpack = genv.unpack
+local GetTime = genv.GetTime
+local strjoin = genv.strjoin

 function Buffs:Initialize()
 	PerfectRaid.defaults.profile.buffs = {}
@@ -45,6 +68,7 @@ end
 function Buffs:Enable()
 	self:RegisterEvent("UNIT_AURA")
 	self:RegisterEvent("RAID_ROSTER_UPDATE")
+
 	if GetNumRaidMembers() > 0 then
 		self:RAID_ROSTER_UPDATE()
 	end
@@ -54,6 +78,18 @@ function Buffs:Enable()
 	for unit in pairs(frames) do
 		self:UNIT_AURA(nil, unit)
 	end
+
+    -- Create a simple OnUpdate timer that triggers an update every second
+    local updateInterval = 1.0  -- How often the OnUpdate code will run (in seconds)
+    local elapsedCount = 0
+	timerFrame = CreateFrame("Frame", "PraidBuffTimerFrame", UIParent);
+	timerFrame:SetScript("OnUpdate", function(frame, elapsed)
+        elapsedCount = elapsedCount + elapsed
+        if elapsedCount > updateInterval then
+            self:FullUpdate()
+            timerFrame.TimeSinceLastUpdate = elapsedCount - updateInterval;
+        end
+    end)
 end

 function Buffs:FullUpdate()
@@ -119,6 +155,7 @@ local buffs = {}
 local buffcache = {}
 local mybuffs = {}
 local mymask = {}
+local buffexpiry = {}

 local BIT_CURSE = 1
 local BIT_MAGIC = 2
@@ -145,6 +182,7 @@ function Buffs:UNIT_AURA(event, unit)
 		if not name then break end
 		if caster == "player" then
 			mybuffs[name] = true
+			buffexpiry[name] = expires
 		end

 		buffcache[name] = (buffcache[name] or 0) + 1
@@ -156,6 +194,7 @@ function Buffs:UNIT_AURA(event, unit)
 		if not name and not dispelType then break end

 		buffcache[name] = (buffcache[name] or 0) + 1
+		buffexpiry[name] = expires

 		if dispelType and name ~= dispelType then
 			buffcache[dispelType] = (buffcache[dispelType] or 0) + 1
@@ -201,7 +240,6 @@ function Buffs:UNIT_AURA(event, unit)

 	-- Update the status
 	debuffstatus[unit] = status
-
 	for k,v in pairs(work) do work[k] = nil end

 	for i,entry in ipairs(buffs) do
@@ -216,12 +254,11 @@ function Buffs:UNIT_AURA(event, unit)
 		end

 		-- How many stacks are there?
-		local num = buffcache[buffname]
 		local class = select(2, UnitClass(unit))
 		local conds = self.conditions
 		local group = raidLookup[unit]
 		local mine = mybuffs[buffname]
-
+
 		if entry.missing then
 			if not buffname then
 				checkcond = true
@@ -247,43 +284,13 @@ function Buffs:UNIT_AURA(event, unit)
 				end

 				if pass then
-					if num and num > 1 then
-						local num = num
-						if mine and not mymask[buffname] then
-							num = num - 1
-						end
-
-						table.insert(work, entry.colortext .. "(" .. num .. ")")
-					else
-						if (entry.onlymine and not mine) or (not entry.onlymine and mymask[buffname]) then
-							-- Do nothing
-						else
-							table.insert(work, entry.colortext)
-						end
-					end
+					self:CreateBuffEntry(buffname, entry)
 				end
 			else
 				-- Simply iterate each of the conditions, and break when we match
 				for i,name in pairs(entry.cond) do
 					if conds[name] and conds[name](unit, class, group, mine) then
-						if num and num > 1 then
-							local num = num
-							-- If the buff is mine, and it should be masked
-							-- A buff is masked when there is a "mine" filter set for it
-							if mine and not mymask[buffname] then
-								num = num - 1
-							end
-
-							table.insert(work, entry.colortext .. "(" .. num .. ")")
-						else
-						if (entry.onlymine and not mine) or (not entry.onlymine and mymask[buffname]) then
-								-- Don't show
-							else
-								table.insert(work, entry.colortext)
-							end
-						end
-
-						-- Break out
+						self:CreateBuffEntry(buffname, entry)
 						break
 					end
 				end
@@ -296,6 +303,37 @@ function Buffs:UNIT_AURA(event, unit)
 	end
 end

+function Buffs:CreateBuffEntry(buffname, entry)
+	local expires = buffexpiry[buffname]
+	local num = buffcache[buffname]
+	local mine = mybuffs[buffname]
+
+	if num and num > 1 and not entry.onlymine then
+		local num = num
+		-- If the buff is mine, and it should be masked
+		-- A buff is masked when there is a "mine" filter set for it
+		if mine and not mymask[buffname] then
+			num = num - 1
+		end
+
+		if (expires and entry.showexpiry) then
+			work[#work + 1] = string.format("%s(%d)(%d)", entry.colortext, num, -1 * (GetTime() - expires))
+		else
+			work[#work + 1] = string.format("%s(%d)", entry.colortext, num)
+		end
+	else
+		if (entry.onlymine and not mine) or (not entry.onlymine and mymask[buffname]) then
+			-- Don't show
+		else
+			if (expires and entry.showexpiry) then
+				work[#work + 1] = string.format("%s(%d)", entry.colortext, -1 * (GetTime()-expires))
+			else
+				work[#work + 1] = entry.colortext
+			end
+		end
+	end
+end
+
 function Buffs:CreateOptions(opt)
 	self.options = opt
 	local options = CreateFrame("Frame", "PROptions_Buffs", PROptions)
@@ -311,7 +349,7 @@ function Buffs:CreateOptions(opt)
 	end

 	for i=1,num_entries do
-		button = scrollframe.entries[i]
+		local button = scrollframe.entries[i]
 		button:SetScript("OnDoubleClick", OnDoubleClick)
 	end

@@ -323,7 +361,7 @@ function Buffs:CreateOptions(opt)
 		FauxScrollFrame_Update(scrollframe, #list, 15, 20)
 		for i=1,num_entries do
 			idx = offset + i
-			button = scrollframe.entries[i]
+			local button = scrollframe.entries[i]
 			if idx <= #list then
 				local entry = list[idx]
 				local display = entry.buffname
@@ -622,9 +660,15 @@ function Buffs:CreateEditFrame(parent)
 	onlymine:Show()
 	frame.onlymine = onlymine

+	local showexpiry = CreateFrame("CheckButton", "PRBuffs_ShowExpiry", PROptions_Buffs_Edit, "PRCheckTemplate")
+	showexpiry.Label:SetText(L["Show expiry"])
+	showexpiry:SetPoint("TOPLEFT", strict, "TOPRIGHT", 150, 0)
+	showexpiry:Show()
+	frame.showexpiry = showexpiry
+
 	local dropdown = CreateFrame("Frame", "PRBuffs_Dropdown", PROptions_Buffs_Edit, "UIDropDownMenuTemplate")
 	dropdown:SetID(1)
-	dropdown:SetPoint("BOTTOMRIGHT", -115, 30)
+	dropdown:SetPoint("BOTTOMRIGHT", -115, 80)
 	dropdown:SetScript("OnShow", function() self:DropDown_OnShow() end)

 	PRBuffs_DropdownButton:SetScript("OnClick", function() ToggleDropDownMenu(nil, nil, PRBuffs_Dropdown, "cursor") end)
@@ -655,6 +699,7 @@ function Buffs:FillEntry(entry)
 	options.disabled:SetChecked(entry.disabled)
 	options.strict:SetChecked(entry.strict)
 	options.onlymine:SetChecked(entry.onlymine)
+	options.showexpiry:SetChecked(entry.showexpiry)
 end

 function Buffs:EditEntry()
@@ -719,6 +764,7 @@ function Buffs:AddEntry()
 	options.disabled:SetChecked(false)
 	options.strict:SetChecked(false)
 	options.onlymine:SetChecked(false)
+	options.showexpiry:SetChecked(false)
 	options.buffname:SetFocus()
 end

@@ -749,6 +795,7 @@ function Buffs:UpdateBuffTable()
 			tbl.strict = entry.strict
 			tbl.cond = {string.split(",", entry.conds)}
 			tbl.onlymine = entry.onlymine
+			tbl.showexpiry = entry.showexpiry

 			if tbl.onlymine then
 				mymask[tbl.buffname] = true
@@ -810,6 +857,7 @@ function Buffs:SaveEntry()
 	entry.disabled = frame.disabled:GetChecked()
 	entry.strict = frame.strict:GetChecked()
 	entry.onlymine = frame.onlymine:GetChecked()
+	entry.showexpiry = frame.showexpiry:GetChecked()

 	local color = utils.RGBPercToHex(frame.disptext:GetTextColor())
 	entry.color = color
@@ -976,6 +1024,7 @@ Buffs.defaults = {
 		buffname = L["Renew"],
 		disptext = L["STATUS_RENEW"],
 		color = "00FF10",
+        showexpiry = true,
 		disabled = (class ~= "PRIEST"),
 	},
 	{
@@ -1031,6 +1080,7 @@ Buffs.defaults = {
 		buffname = L["Rejuvenation"],
 		disptext = L["STATUS_REJUV"],
 		color = "bc64aa",
+        showexpiry = true,
 		disabled = (class ~= "DRUID"),
 	},
 	{
@@ -1045,6 +1095,7 @@ Buffs.defaults = {
 		buffname = L["Regrowth"],
 		disptext = L["STATUS_REGROWTH"],
 		color = "00FF10",
+        showexpiry = true,
 		disabled = (class ~= "DRUID"),
 	},
 	{