Quantcast WoWInterface: SVN - Blessed - Rev 31 - /trunk/Blessed/Blessed.lua

WoWInterface SVN Blessed

[/] [trunk/] [Blessed/] [Blessed.lua] - Rev 31

Compare with Previous | Blame | View Log

--[[
        Blessed
        by Ailae of Emeriss-EU
        
        Credits to zork (of Roth UI) for texture.
]]

local addon, Blessed = ...
local pguid

-- Times, times, times
local durations = {
        [1044] = 6,     -- Hand of Freedom
        [1022] = 10,    -- Hand of Protection
        [6940] = 12,    -- Hand of Sacrifice
        [1038] = 10,    -- Hand of Salvation
        [31842] = 20,   -- Divine Favor
        [54428] = 9,    -- Divine Plea
        [31821] = 6,    -- Devotion Aura
        [84963] = 10,   -- Inquisition
        [88819] = 10,   -- Daybreak
        [94686] = 8,    -- Supplication
        [54149] = 15,   -- Infusion of Light
        [31884] = 20,   -- Avenging Wrath
        [85499] = 8,    -- Speed of Light
        [20925] = 30,   -- Sacred Shield
        [86698] = 30,   -- Guardian of Ancient Kings (Retribution)
        [86669] = 30,   -- Guardian of Ancient Kings (Holy)
        [86659] = 12,   -- Guardian of Ancient Kings (Protection)
        -- [86678] = 7, -- Light of the Ancient Kings
        [114039] = 6,   -- Hand of Purity
        [105809] = 18,  -- Holy Avenger 
        [114250] = 15,  -- Selfless Healer
        [114163] = 30,  -- Eternal Flame (yes, haste affects it...)
        [90174] = 8,    -- Divine Purpose
        [31850] = 10,   -- Ardent Defender
}

-- defaults
local defaults = {
        pandaria = true,
        framePoint = "CENTER",
        xOfs = 0,
        yOfs = -150,
        locked = true,
        spells = {
                [1044] = true,  -- Hand of Freedom
                [1022] = true,  -- Hand of Protection
                [6940] = true,  -- Hand of Sacrifice
                [1038] = true,  -- Hand of Salvation
                [53563] = true, -- Beacon of Light
                [31842] = true, -- Divine Favor
                [54428] = true, -- Divine Plea
                [31821] = true, -- Devotion Aura
                [84963] = true, -- Inquisition
                [88819] = true, -- Daybreak
                [94686] = true, -- Supplication
                [54149] = true, -- Infusion of Light
                [31884] = true, -- Avenging Wrath
                [85499] = true, -- Speed of Light
                [20925] = true, -- Sacred Shield
                [86698] = true, -- Guardian of Ancient Kings (Retribution)
                [86669] = true, -- Guardian of Ancient Kings (Holy)
                [86659] = true, -- Guardian of Ancient Kings (Protection)
                [114039] = true, -- Hand of Purity
                [105809] = true, -- Holy Avenger
                [114250] = true, -- Selfless Healer
                [114163] = true, -- Eternal Flame
                [90174] = true, -- Divine Purpose
                [31850] = true, -- Ardent Defender
        },
}

local db

-- cosmetics
local iconSize = 36

-- Add a prefix
local function Print(...)
        print("|cff00aaffBlessed:|r", ...)
end

local INQUISITION = GetSpellInfo(84963)
local SELFLESSHEALER = GetSpellInfo(114250)
local DAYBREAK = GetSpellInfo(88819)

-- Return for anything unknown
local colors = setmetatable({
                DEATHKNIGHT = "c41e3a",
                DRUID = "ff7c0a",
                HUNTER = "aad372",      
                MAGE = "68ccef",
                PALADIN = "f48cba",
                PRIEST = "ffffff",
                ROGUE = "fff468",
                SHAMAN = "0070dd",
                WARLOCK = "9382c9",
                WARRIOR = "c69b6d",
                MONK = "00ff96",
        }, { __index = function()
                return "ffffff"
        end 
})

-- Empty tables for our frames
local frames = {}
local framePool = {}

function Blessed:Init()
        local frame = self.frame
        frame:SetBackdrop({
                bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
                insets = {top = 0, left = 0, bottom = 0, right = 0},
        })
        frame:SetBackdropColor(1, 1, 1, 0)

        frame:SetSize(iconSize, iconSize)
        frame:SetPoint(db.framePoint, db.xOfs, db.yOfs)

        frame:SetMovable(true)

        frame:SetScript("OnMouseDown", function()
                if(IsShiftKeyDown() and not db.locked) then
                        frame:ClearAllPoints()
                        frame:StartMoving()
                end
        end)

        frame:SetScript("OnMouseUp", function()
                frame:StopMovingOrSizing()
                db.framePoint, _, _, db.xOfs, db.yOfs = frame:GetPoint()
        end)

        local text = frame:CreateFontString(nil, "OVERLAY")
        text:SetFontObject(SystemFont_Shadow_Med1)
        text:SetPoint("TOP", frame, "TOP", 0, 16)
        text:SetTextColor(1, 0.82, 0)
        frame.header = text
end

function Blessed:ToggleLock()
        if db.locked then
                self.frame.header:SetText(addon)
                self.frame:SetBackdropColor(1, 1, 1, 0.25)
        else 
                self.frame.header:SetText("")
                self.frame:SetBackdropColor(1, 1, 1, 0)
        end
        self.frame:EnableMouse(db.locked)
        db.locked = not db.locked
end

function Blessed:RestoreDefaultSpells()
        db.spells = {}
        
        for k,v in pairs(defaults.spells) do
                db.spells[k] = v
        end
        
        Print("Spells have been reset to default.")
end

function Blessed:PLAYER_LOGIN()
        BlessedDB = BlessedDB or defaults
        db = BlessedDB
        if not db.pandaria then
                self:RestoreDefaultSpells()
                db.pandaria = true
        end
        
        -- If new spells have been added, add them to our savedvars
        for k,v in pairs(defaults.spells) do
                if db.spells[k] == nil then
                        db.spells[k] = v
                end
        end
                
        -- Force lock on login
        if not db.locked then db.locked = true end
        
        local _, class = 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 == "lock") then
                                self:ToggleLock()
                        else
                                InterfaceOptionsFrame_OpenToCategory(self.panel)
                        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 (GetNumSpecializations() == 0) then
                self:RegisterEvent("PLAYER_ALIVE")
        else
                self:UpdateDurations()
        end     
        
        self.PLAYER_ALIVE = self.UpdateDurations
        
        self:RegisterEvent("CHARACTER_POINTS_CHANGED")
        self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
        self:RegisterEvent("GLYPH_ADDED")
end

-- Check talents for updates (Hand of Freedom)
function Blessed:UpdateDurations()      
        -- Sanctified Wrath increases duration of Avenging Wrath
        local _, _, _, _, wrath = GetTalentInfo(14)
        if wrath then durations[31884] = 30     end

        -- Glyph of Inquisition
        for i=1, NUM_GLYPH_SLOTS do
                local _, _, _, glyph = GetGlyphSocketInfo(i)
                if glyph == 63225 then
                        durations[84963] = 20
                end
        end
        
        -- Divine Plea glyph (not really needed, there's no applied event anymore)
        -- for i=1, NUM_GLYPH_SLOTS do
                -- local glyph = select(4, GetGlyphSocketInfo(i))
                -- if glyph == 63223 then
                        -- db.spells.54428 = false
                -- end
        -- end
        
        self:UnregisterEvent("PLAYER_ALIVE")
end

-- Perform checks for all these events
Blessed.CHARACTER_POINTS_CHANGED = Blessed.UpdateDurations
Blessed.ACTIVE_TALENT_GROUP_CHANGED = Blessed.UpdateDurations
Blessed.GLYPH_ADDED = Blessed.UpdateDurations

-- Handle stuff, plx
function Blessed:COMBAT_LOG_EVENT_UNFILTERED(timestamp, combatEvent, hideCaster, sourceGUID, sourceName, sourceFlags, sourceFlagsTwo, destGUID, destName, destFlags, destFlagsTwo, spellID, ...)
        if sourceGUID ~= pguid or not db.spells[spellID] then return end
        
        -- Selfless healer
        if (combatEvent == "SPELL_AURA_APPLIED_DOSE") then
                self:RemoveFrame(spellID, destGUID)
                self:SetupIcon(spellID, destName, destGUID)     
        elseif (combatEvent == "SPELL_AURA_REMOVED") then
                self:RemoveFrame(spellID, destGUID)
        elseif (combatEvent == "SPELL_AURA_APPLIED") then
                -- Only track Devotion Aura on player
                if spellID == 31821 and destGUID ~= pguid then return end
                
                -- Always get rid of Beacon, to avoid duplicates due to being in different realms
                if spellID == 53563 then
                        self:RemoveFrame(spellID, nil)
                end
                self:SetupIcon(spellID, destName, destGUID)
        elseif (combatEvent == "SPELL_AURA_REFRESH") then
                self:RemoveFrame(spellID, destGUID)
                self:SetupIcon(spellID, destName, destGUID)
        end
end

-- Reanchor frames
function Blessed:UpdateFrames()
        if #frames == 0 then return end
        
        for i, frame in pairs(frames) do
                frame:ClearAllPoints()
                if i > 1 then
                        frame:SetPoint("LEFT", frames[i - 1], "RIGHT", iconSize/2, 0)
                else
                        frame:SetPoint("CENTER", self.frame, "CENTER")
                end
        end
end

-- Remove bar
function Blessed:RemoveFrame(spellID, destGUID)
        if #frames == 0 then return end
        
        for i, frame in pairs(frames) do
                if frame.id == spellID and (frame.guid == destGUID or not destGUID) then
                        frame:Hide()
                        table.remove(frames, i)
                        table.insert(framePool, frame)
                        self:UpdateFrames()
                end
        end
end

-- Update barinfo
local function update(self, elapsed)
        if not self.duration then return end
        self.duration = self.duration - elapsed
        self.update = self.update - elapsed
        if self.update > 0 then return end
        
        self.update = self.update + 1
        self.timer:SetFormattedText("%.0f", self.duration)
        
        if self.duration <= 0 then              
                Blessed:RemoveFrame(self.id, self.guid)
        elseif self.duration <= 5 then 
                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:SetSize(iconSize, iconSize)
        frame:SetPoint("CENTER", self.frame)
        
        -- Icon
        frame.icon = frame:CreateTexture(nil, "ARTWORK")
        frame.icon:SetSize(iconSize, 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(SystemFont_Shadow_Med1)
        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(SystemFont_Shadow_Large)
        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:SetSize(iconSize, 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
        
        -- Border
        frame.border = frame: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
function Blessed:SetupIcon(spellID, destName, destGUID)
        local frame = self:GetFrame()
        local duration = durations[spellID]
        
        if spellID == 84963 then
                local _, _, _, _, _, d = UnitAura("player", INQUISITION)
                duration = d
        end
        
        local _, _, icon = GetSpellInfo(spellID)
        local _, class = GetPlayerInfoByGUID(destGUID)
                
        frame.icon:SetTexture(icon)
        if spellID == 114250 then
                local _, _, _, stacks = UnitAura("player", SELFLESSHEALER)
                frame.target:SetFormattedText("|cff%s%s|r (%d)", colors[class], destGUID ~= pguid and string.sub(destName, 0, 3) or "You!", stacks or 0)
        elseif spellID == 88819 then
                local _, _, _, stacks = UnitAura("player", DAYBREAK)
                frame.target:SetFormattedText("|cff%s%s|r (%d)", colors[class], destGUID ~= pguid and string.sub(destName, 0, 3) or "You!", stacks or 0)        
        else
                frame.target:SetFormattedText("|cff%s%s|r", colors[class], destGUID ~= pguid and string.sub(destName, 0, 3) or "You!")
        end
        
        if spellID ~= 53563 then
                frame.timer:SetFormattedText("%.0f", floor(duration))
                frame.timer:SetTextColor(1, 1, 1)
                frame.duration = duration
                frame.cd:SetCooldown(GetTime(), duration)
        else
                frame.duration = nil
                frame.timer:SetTextColor(1, 1, 1)
                frame.timer:SetText("*")
                frame.cd:Hide()
        end
        
        frame.id = spellID
        frame.guid = destGUID
        
        frame.update = 1
        table.insert(frames, frame)

        frame:SetScript("OnUpdate", update)     
        
        self:UpdateFrames()
        frame:Show()
end

Blessed.frame = CreateFrame("Frame", nil, UIParent)
Blessed.frame:SetScript("OnEvent", function(self, event, ...) return Blessed[event] and Blessed[event](Blessed, ...) end)

function Blessed:RegisterEvent(event) return self.frame:RegisterEvent(event) end
function Blessed:UnregisterEvent(event) return self.frame:UnregisterEvent(event) end

Blessed:RegisterEvent("PLAYER_LOGIN")

Compare with Previous | Blame