Thread: oUF_AuraBars
View Single Post
09-16-12, 01:27 AM   #4
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Oh, I think I see what the problem is. Try this:
Code:
local debuffs = {}

local function UpdateDebuff(self, event, unit)
	if self.unit ~= unit then return end
	local DebuffBars = self.DebuffBars

	local numDebuffs = 0

	for i = 1, 40 do
		local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellID = UnitDebuff(unit, i)
		if not name then break end

		if DebuffBars.filter(self, unit, name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellID) then
			numDebuffs = numDebuffs + 1

			local t = debuffs[numDebuffs]
			if not t then
				t = table_create()
				debuffs[numDebuffs] = t
			end

			t.name = name
			t.rank = rank
			t.icon = icon
			t.count = count
			t.debuffType = debuffType
			t.duration = duration
			t.expirationTime = expirationTime
			t.unitCaster = unitCaster
			t.isStealable = isStealable
			t.noTime = duration == 0 and expirationTime == 0
			t.filter = DebuffBars.enemyAuraType
			t.shouldConsolidate = shouldConsolidate
			t.spellID = spellID
		end
	end

	for i = #debuffs, numDebuffs + 1, -1 do
		debuffs[i] = table_delete(debuffs[i])
	end

	table.sort(debuffs, DebuffBars.sort or default_sort)

	local bars = DebuffBars.bars
	for i = 1, numDebuffs do
		if DebuffBars:GetWidth() == 0 then
			break
		end

		local bar = bars[i]
		if not bar then
			bar = CreateAuraBar(self, i == 1 and DebuffBars or bars[i - 1])
			bars[i] = bar
		end
		bar:Show()

		local statusbar = bar.statusBar

		local debuff = debuffs[i]
		bar.aura = debuff

		if debuff.noTime then -- something weird here
			statusbar:SetMinMaxValues(0, 1)
			statusbar:SetValue(1)
		else
			if DebuffBars.scaleTime then
				local maxvalue = math.min(DebuffBars.scaleTime, debuff.duration)
				statusbar:SetMinMaxValues(0, maxvalue)
				statusbar:SetWidth((maxvalue/DebuffBars.scaleTime)*((DebuffBars.auraBarWidth or DebuffBars:GetWidth())-(statusbar:GetHeight()+(DebuffBars.gap or 0))))-- icon size + gap
			else
				statusbar:SetMinMaxValues(0, debuff.duration)
			end
			statusbar:SetValue(debuff.expirationTime - GetTime())
		end

		statusbar.icon:SetTexture(debuff.icon)
		statusbar.spellname:SetText(debuff.count > 1 and format("%s [%d]", debuff.name, debuff.count) or debuff.name)
		statusbar.spelltime:SetText(not debuff.noTime and FormatTime(debuff.expirationTime - GetTime()))

		local r, g, b
		local color = DebuffBars.debuffColor
		if color then
			r, g, b = color[1], color[2], color[3] -- don't use unpack; 3 table lookups is faster than 1 function call
		else
			color = DebuffTypeColor[debuff.debuffType or "none"]
			r, g, b = color.r, color.g, color.b
		end
		statusbar:SetStatusBarColor(r, g, b)
	end

	for i = numDebuffs + 1, #bars do
		local bar = bars[i]
		bar.aura = table_delete(bar.aura)
		bar:Hide()
	end
end
Also, add this anywhere before the UpdateBuff and UpdateDebuff functions:
Code:
local table_create, table_delete
do
	local pool = { }

	local function table_create()
		local t = next(pool)
		if t then
			pool[t] = nil
		end
		return t or {}
	end

	local function table_delete(t)
		if type(t) == "table" then
			for k, v in pairs(t) do
				t[k] = nil
			end
			t[true] = true
			t[true] = nil
			pool[t] = true
		end
		return nil
	end
end

local default_sort = function(a, b)
	if a.noTime then
		if b.noTime then
			-- both timeless, sort by name REVERSE
			return a.name < b.name
		else
			-- a timeless, b not
			return true
		end
	else
		if b.noTime then
			-- b timeless, a not
			return false
		else
			-- neither timeless, sort by expiry time
			return a.expires > b.expires
		end
	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 : 09-16-12 at 10:33 PM.
  Reply With Quote