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"),
},
{