Compare with Previous | Blame | View Log
--[[ Blessed by Ailae of Emeriss-EU Credits to zork (of Roth UI) for texture. ]] local ADDON, ns = ... local pguid local locked = true -- default position local defaults = { framePoint = "CENTER", xOfs = 0, yOfs = -150, } local db -- cosmetics local font = SystemFont_Shadow_Med1 local fontTimer = SystemFont_Shadow_Large local iconSize = 36 local Blessed = CreateFrame("Frame", "Blessed_Anchor", UIParent) Blessed:RegisterEvent("ADDON_LOADED") Blessed:SetScript("OnEvent", function(self, event, ...) self[event](self, ...) end) -- Add a prefix local function Print(output) print("|cff00aaffBlessed:|r " .. output) end -- Format: [spell] = (duration) local spells = { [1044] = 6, -- Hand of Freedom [1022] = 10, -- Hand of Protection [6940] = 12, -- Hand of Sacrifice [1038] = 10, -- Hand of Salvation [53563] = 300, -- Light's Beacon [54428] = 15, -- Divine Plea [53657] = 60, -- Judgement of the Pure (Rank 3, but who hasn't got 3/3 in this?) [87342] = 20, -- Holy Shield [84963] = 12, -- Inquisition [82327] = 10, -- Holy Radiance -- [88819] = 12, -- Daybreak [85433] = 15, -- Sacred Duty [94686] = 15, -- Crusader [54149] = 15, -- Infusion of Light } -- Empty tables for our frames local frames = {} local framePool = {} function Blessed:Init() self:SetBackdrop({ bgFile = [=[Interface\ChatFrame\ChatFrameBackground]=], insets = {top = 0, left = 0, bottom = 0, right = 0}, }) self:SetBackdropColor(1, 1, 1, 0) self:SetWidth(iconSize) self:SetHeight(iconSize) self:SetPoint(db.framePoint, db.xOfs, db.yOfs) self:SetMovable(true) -- yeh bebe, move it! self:SetScript("OnMouseDown", function() if(IsShiftKeyDown() and not locked) then self:ClearAllPoints() self:StartMoving() end end) self:SetScript("OnMouseUp", function() self:StopMovingOrSizing() db.framePoint, _, _, db.xOfs, db.yOfs = self:GetPoint() end) local text = self:CreateFontString(nil, "OVERLAY") text:SetFontObject(font) text:SetPoint("TOP", self, "TOP", 0, 16) text:SetTextColor(1, 0.82, 0) text:SetText("") self.header = text end function Blessed:ADDON_LOADED(name) if name ~= "Blessed" then return end self:UnregisterEvent("ADDON_LOADED") BlessedDB = BlessedDB or defaults db = BlessedDB local class = select(2, UnitClass("player")) if class == "PALADIN" then -- only do stuff if player is a paladin self:RegisterEvent("PLAYER_ENTERING_WORLD") self:Init() SLASH_Blessed1 = "/blessed" SlashCmdList.Blessed = function(input) local input = string.lower(input) if (input == "test") then self:SetupIcon(54428, "Test Icon", pguid, pguid) Print("Showing test-timer.") elseif (input == "lock") then if locked then self:EnableMouse(true) locked = false self.header:SetText("Blessed") self:SetBackdropColor(1, 1, 1, 0.25) Print("Unlocked. Press down SHIFT and drag the square to move.") else self:EnableMouse(false) locked = true self.header:SetText("") self:SetBackdropColor(1, 1, 1, 0) Print("Locked.") end elseif (input == "debug") then Print("Number of frames in the pool: " .. (#framePool or 0)) Print("Current durations:") for k, v in pairs(spells) do local name, _, _, _, _, _, _, _, _ = GetSpellInfo(k) if not name then Print("No value for key: " .. k) end Print(name .. ": " .. v) end else Print("Incorrect or no command given. Please use '/blessed test' (display a test-timer) or '/blessed lock' (to toggle lock).") end end else print("This addon has no use for any other class than a Paladin, you should consider disabling it for this character.") end end -- Only activate buff-tracking if the player is a paladin function Blessed:PLAYER_ENTERING_WORLD() self:UnregisterEvent("PLAYER_ENTERING_WORLD") self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") pguid = UnitGUID("player") -- this is to make sure talents are loaded or if we need -- to delay the check if (GetNumTalentTabs() == 0) then self:RegisterEvent("PLAYER_ALIVE") else self:UpdateDurations() end self:RegisterEvent("CHARACTER_POINTS_CHANGED") self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED") end -- Talents are only available at this point when you're logging in -- so we need to update durations. function Blessed:PLAYER_ALIVE() self:UpdateDurations() self:UnregisterEvent("PLAYER_ALIVE") end -- Check talents for updates function Blessed:UpdateDurations() -- Hand of Freedom local _, _, _, _, rank, maxRank, _, _ = GetTalentInfo(3, 4) if rank == maxRank then spells[1044] = 10 else spells[1044] = 6 end end -- Perform checks for all these events Blessed.CHARACTER_POINTS_CHANGED = Blessed.UpdateDurations Blessed.ACTIVE_TALENT_GROUP_CHANGED = Blessed.UpdateDurations -- Handle stuff, plx function Blessed:COMBAT_LOG_EVENT_UNFILTERED(timestamp, combatEvent, sourceGUID, sourceName, sourceFlags, destGUID, destName, destFlags, ...) if sourceGUID and sourceGUID ~= pguid then return end if (combatEvent == "SPELL_AURA_REMOVED") then local spellID, _, _, _ = select(1, ...) if spells[spellID] then self:RemoveFrame(spellID .. sourceGUID .. destGUID) end elseif (combatEvent == "SPELL_AURA_APPLIED") then local spellID, spellName, _, _ = select(1, ...) if (spells[spellID]) then -- special handling for Inquisition, sigh if spellID == 84963 and spellName then local duration, expirationTime = select(6, UnitAura("player", spellName)) spells[84963] = duration end self:SetupIcon(spellID, destName, sourceGUID, destGUID) end elseif (combatEvent == "SPELL_AURA_REFRESH") then local spellID, spellName, _, _ = select(1, ...) if (spells[spellID]) then self:RemoveFrame(spellID .. sourceGUID .. destGUID) -- special handling for Inquisition, sigh if spellID == 84963 and spellName then local duration, expirationTime = select(6, UnitAura("player", spellName)) spells[84963] = duration end self:SetupIcon(spellID, destName, sourceGUID, destGUID) end end end -- Reanchor frames -- If it's frame #1, anchor it to anchorframe (teehee). If it's frame #n (!1) anchor it to the right of frame #n-1. function Blessed:UpdateFrames() if #frames == 0 then return end for i, frame in ipairs(frames) do frame:ClearAllPoints() if i > 1 then frame:SetPoint("LEFT", frames[i - 1], "RIGHT", 15, 0) else frame:SetPoint("CENTER", self, "CENTER") end end end -- Remove bar function Blessed:RemoveFrame(id) if #frames == 0 then return end for i, frame in pairs(frames) do if frame.id == id then frame:Hide() table.remove(frames, i) table.insert(framePool, frame) self:UpdateFrames() -- reanchor frames end end end -- Update barinfo local function update(self, elapsed) self.time = GetTime() if self.time - self.lastUpdate < 1 then return end self.duration = self.duration - (self.time - self.lastUpdate) self.lastUpdate = self.time self.timer:SetTextColor(1, 1, 1) if self.duration > 60 then self.timer:SetFormattedText("%.0fm", ceil(self.duration/60)) else self.timer:SetFormattedText("%.0f", floor(self.duration)) end if self.duration <= 0 then Blessed:RemoveFrame(self.id) elseif self.duration <= 5 then -- indicate that there is equalorless than 5 secs left self.timer:SetTextColor(1, 0, 0) end end -- Framemananger, return a new frame if there's no old frame available function Blessed:GetFrame() if (#framePool > 0) then return table.remove(framePool, 1) end local frame = CreateFrame("Frame", nil, UIParent) frame:SetHeight(iconSize) frame:SetWidth(iconSize) frame:SetPoint("CENTER", self) -- Icon frame.icon = frame:CreateTexture(nil, "ARTWORK") frame.icon:SetHeight(iconSize) frame.icon:SetWidth(iconSize) frame.icon:SetTexCoord(0.03, 0.97, 0.02, 0.97) frame.icon:SetAllPoints(frame) -- Targettext frame.target = frame:CreateFontString(nil, "OVERLAY") frame.target:SetFontObject(font) frame.target:SetPoint("BOTTOM", frame, "TOP", 0, 5) frame.target:SetTextColor(1, 1, 1) frame.target:SetShadowOffset(1, -1) -- Timertext frame.timer = frame:CreateFontString(nil, "OVERLAY") frame.timer:SetFontObject(fontTimer) frame.timer:SetPoint("TOP", frame, "BOTTOM", 0, -5) frame.timer:SetTextColor(1, 1, 1) frame.timer:SetShadowOffset(1, -1) -- Cooldown-model (beta) frame.cd = CreateFrame("Cooldown", nil, frame, "CooldownFrameTemplate") frame.cd:SetHeight(iconSize) frame.cd:SetWidth(iconSize) frame.cd:SetPoint("TOPLEFT", frame, "TOPLEFT", 2, -2) frame.cd:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -2, 2) frame.cd.noCooldownCount = true -- prevent OmniCC if present -- Overlay frame.overlay = CreateFrame("Frame", nil, frame) frame.overlay:SetAllPoints(frame) frame.overlay:SetParent(frame) -- Border frame.border = frame.overlay:CreateTexture(nil, "OVERLAY") frame.border:SetParent(frame) frame.border:SetTexture('Interface\\AddOns\\Blessed\\simplesquare_roth') frame.border:SetPoint('TOPRIGHT', frame, 2, 2) frame.border:SetPoint('BOTTOMLEFT', frame, -2, -2) frame.border:SetVertexColor(0.3, 0.3, 0.3) return frame end -- Setup a timer local color = {} function Blessed:SetupIcon(spellID, targetName, sourceGUID, targetGUID) local frame = self:GetFrame() local duration = spells[spellID] local icon = select(3, GetSpellInfo(spellID)) targetName = string.sub(targetName, 0, 3) local class = select(2, GetPlayerInfoByGUID(targetGUID)) if targetGUID == pguid then targetName = "You!" class = "PALADIN" end frame.icon:SetTexture(icon) color = RAID_CLASS_COLORS[class] or { r = 1, g = 1, b =1 } frame.target:SetTextColor(color.r, color.g, color.b) frame.target:SetText(targetName or "Unknown") if duration > 60 then frame.timer:SetFormattedText("%.0fm", ceil(duration/60)) else frame.timer:SetFormattedText("%.0f", floor(duration)) end frame.timer:SetTextColor(1, 1, 1) -- Nifty stuff frame.duration = duration frame.id = spellID .. sourceGUID .. targetGUID frame.lastUpdate = GetTime() frame.cd:SetCooldown(GetTime(), duration) table.insert(frames, frame) frame:SetScript("OnUpdate", update) -- when a frame is shown, reanchor all the frames accordingly self:UpdateFrames() frame:Show() end