# HG changeset patch # User Chris Mellon # Date 1286980054 18000 # Node ID 7309cc67cac0dc0b5dd80d1bfa07cb096f68d5c5 # Parent ede17cc71b667e8bb89a056f2fa12e105a6e28d8 Hooray support for debuffs diff -r ede17cc71b66 -r 7309cc67cac0 KBF.lua --- a/KBF.lua Tue Oct 12 22:11:46 2010 -0500 +++ b/KBF.lua Wed Oct 13 09:27:34 2010 -0500 @@ -6,12 +6,8 @@ function kbf:OnInitialize() - self.options = { - barWidth = 200 + 16 + 8, - barHeight = 16 + 8 - } + self.debuffFrames = {} self.anchor = self:CreateAnchorFrame() - self.buffBars = {} self.anchor:Show() self:RegisterEvent("UNIT_AURA") -- set up the countdown timer @@ -41,20 +37,50 @@ end function kbf:OnUpdate() + local unit = self.secureFrame:GetAttribute("unit") + local buffCount = 0 for idx=1,99 do local frame = self.secureFrame:GetAttribute("child"..idx) - if not frame then break end + if not (frame and frame:IsShown()) then break end + buffCount = buffCount + 1 if self.dirty then - local unit = self.secureFrame:GetAttribute("unit") - self:BindBarToBuff(frame, unit) + if self:BindBarToBuff(frame, unit) then break end end - if frame.expirationTime then - local remaining = frame.expirationTime - GetTime() - remaining = math.max(0, remaining) - local perc = remaining / frame.duration - frame.timertext:SetText(self:FormatTimeText(remaining)) - frame.statusbar:SetValue(remaining) + self:UpdateBarExpirationTime(frame) + end + -- temporary enchants + -- TODO: The blizz secure aura header binds both temp enchants + -- to the main hand. No support for cancelling weapon enchants + -- until this gets fixed up + + -- debuffs + for idx=1,99 do + local frame = self.debuffFrames[idx] + if self.dirty then + local name, rank, icon, stacks, debuffType, duration, expirationTime = UnitAura(unit, idx, "HARMFUL") + if not name then + -- out of debuffs, hide all the rest of them + for jdx = idx, 99 do + local bar = self.debuffFrames[jdx] + if bar then bar:Hide() else break end + end + break + end + if not frame then + frame = self:ConstructBar(nil, 1, 0, 0) + self.debuffFrames[idx] = frame + end + self:SetBarAppearance(frame, name, icon, stacks, duration, expirationTime) + frame:ClearAllPoints() + -- position it under all the buffs, with a half-bar spacing + frame:SetPoint("TOP", self.anchor, "BOTTOM", 0, (buffCount * -16) - 8) + frame:Show() + buffCount = buffCount + 1 + else + -- not dirty, so no frame means we're done + if not frame then break end end + self:UpdateBarExpirationTime(frame) end self.dirty = nil end @@ -64,14 +90,29 @@ self.dirty = true end +function kbf:UpdateBarExpirationTime(frame) + if frame.expirationTime then + local remaining = frame.expirationTime - GetTime() + remaining = math.max(0, remaining) + local perc = remaining / frame.duration + frame.timertext:SetText(self:FormatTimeText(remaining)) + frame.statusbar:SetValue(remaining) + end +end + function kbf:BindBarToBuff(parentFrame, unit) local index = parentFrame:GetAttribute("index") local filter = parentFrame:GetAttribute("filter") - local name, rank, icon, count, debuffType, duration, expirationTime, + local name, rank, icon, stacks, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellId = UnitAura(unit, index, filter) + if not name then return end if not parentFrame.icon then self:ConstructBar(parentFrame) end + self:SetBarAppearance(parentFrame, name, icon, stacks, duration, expirationTime) +end + +function kbf:SetBarAppearance(parentFrame, name, icon, stacks, duration, expirationTime) parentFrame.icon:SetNormalTexture(icon) if stacks and stacks > 0 then parentFrame.text:SetText(string.format("%s(%d)", name, stacks)) @@ -112,20 +153,27 @@ end -- creates a icon + statusbar bar -function kbf:ConstructBar(frame) +function kbf:ConstructBar(frame, r, g, b) local texture = "Interface\\TargetingFrame\\UI-StatusBar" -- Because of secureframe suckiness, these height & width numbers -- have to be consistent with the stuff in KBF.xml local height = 16 local width = 200 -- this is the width *without* the icon local font, _ style = GameFontHighlight:GetFont() - local bgcolor = {1, 0, 0, 0.5} - local color = {0, 1, 0, 1} + local r = r or 0 + local g = g or 1 + local b = b or 0 + local bgcolor = {r, g, b, 0.5} + local color = {r, g, b, 1} local fontsize = 11 local timertextwidth = fontsize * 3.6 local textcolor = {1, 1, 1, 1} local timertextcolor = {1, 1, 1, 1} - --local bar = CreateFrame("Button", nil, UIParent) -- the "top level" frame that represents the bar as a whole + if not frame then + frame = CreateFrame("Button", nil, UIParent) -- the "top level" frame that represents the bar as a whole + frame:SetHeight(16) + frame:SetWidth(200 + 16) + end local bar = frame bar.icon = CreateFrame("Button", nil, bar) -- the icon bar.statusbarbg = CreateFrame("StatusBar", nil, bar) -- the bars background @@ -196,8 +244,8 @@ text:SetPoint("TOPLEFT", anchor, "TOPLEFT", 0, 0) text:SetPoint("BOTTOMRIGHT", anchor, "BOTTOMRIGHT", 0, 0) text:SetText("KBF ANCHOR") - anchor:SetWidth(self.options.barWidth) - anchor:SetHeight(self.options.barHeight) + anchor:SetWidth(200 + 16 + 8) + anchor:SetHeight(16 + 8) -- movability anchor:EnableMouse(true) anchor:SetMovable(true) @@ -215,8 +263,6 @@ frame:SetAttribute("point", "TOP") frame:SetAttribute("wrapAfter", 100) -- required due to bugs in secure header frame:SetAttribute("consolidateTo", nil) - --frame:SetAttribute("wrapXOffset", 0) - --frame:SetAttribute("wrapYOffset", -34) frame:SetAttribute("xOffset", 0) frame:SetAttribute("yOffset", -16) frame:SetAttribute("minWidth", 216) @@ -224,13 +270,10 @@ frame:SetAttribute("unit", "player") -- TODO: figure out the vehicle swapping stuff frame:SetAttribute("sortMethod", "NAME") frame:SetAttribute("sortOrder", "-") - frame:SetAttribute("includeWeapons", 1) + -- TODO: SecureAuraHeader doesn't correcltly implement the temp enchants + --frame:SetAttribute("weaponTemplate", "KBFSecureUnitAuraTemplate") + --frame:SetAttribute("includeWeapons", 1) frame:SetPoint("TOP", anchor, "BOTTOM", 0, 0) --- frame:SetBackdrop({bgFile = "Interface/Tooltips/UI-Tooltip-Background", --- edgeFile = "Interface/Tooltips/UI-Tooltip-Border", --- tile = true, tileSize = 16, edgeSize = 16, --- insets = { left = 4, right = 4, top = 4, bottom = 4 }, --- }) frame:Show() -- has to be shown, otherwise the child frames don't show self.secureFrame = frame return anchor