vanilla-wow-addons – Rev 1

Subversion Repositories:
Rev:
--[[
Name: Banzai-1.0
Revision: $Rev: 14544 $
Author(s): Rabbit (rabbit.magtheridon@gmail.com), maia
Documentation: http://www.wowace.com/index.php/Banzai-1.0_API_Documentation
SVN: http://svn.wowace.com/root/trunk/BanzaiLib/Banzai-1.0
Description: Aggro notification library.
Dependencies: AceLibrary, AceEvent-2.0, RosterLib-2.0
]]

-------------------------------------------------------------------------------
-- Locals
-------------------------------------------------------------------------------

local MAJOR_VERSION = "Banzai-1.0"
local MINOR_VERSION = "$Revision: 14544 $"

if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
if not AceLibrary:HasInstance("RosterLib-2.0") then error(MAJOR_VERSION .. " requires RosterLib-2.0.") end
if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end

local lib = {}
AceLibrary("AceEvent-2.0"):embed(lib)

local RL = nil
local roster = nil
local playerName = nil

-------------------------------------------------------------------------------
-- Compost Heap, courtesy of Tekkub/SEEA.
-------------------------------------------------------------------------------

local table_setn
do
        local version = GetBuildInfo()
        if string.find(version, "^2%.") then
                -- 2.0.0
                table_setn = function() end
        else
                table_setn = table.setn
        end
end

local heap = {}
setmetatable(heap, {__mode = "kv"})

local function acquire()
        local t = next(heap)
        if t then
                heap[t] = nil
                assert(not next(t), "A table in the compost heap has been modified!")
        end
        t = t or {}
        return t
end


local function reclaim(t, d)
        if type(t) ~= "table" then return end
        if d and d > 0 then
                for i in pairs(t) do
                        if type(t[i]) == "table" then reclaim(t[i], d - 1) end
                end
        end
        for i in pairs(t) do t[i] = nil end
        table_setn(t, 0)
        heap[t] = true
end

-------------------------------------------------------------------------------
-- Initialization
-------------------------------------------------------------------------------

-- Activate a new instance of this library
function activate(self, oldLib, oldDeactivate)
        if oldLib then
                self.vars = oldLib.vars
                if oldLib:IsEventScheduled("UpdateAggroList") then
                        oldLib:CancelScheduledEvent("UpdateAggroList")
                end
        end

        RL = AceLibrary("RosterLib-2.0")
        roster = RL.roster
        playerName = UnitName("player")
        self:ScheduleRepeatingEvent("UpdateAggroList", self.UpdateAggroList, 0.2, self)

        if oldDeactivate then oldDeactivate(oldLib) end
end

-------------------------------------------------------------------------------
-- Library
-------------------------------------------------------------------------------

function lib:UpdateAggroList()
        local oldBanzai = acquire()

        for i, unit in pairs(roster) do
                oldBanzai[unit.unitid] = unit.banzai

                -- deduct aggro for all, increase it later for everyone with aggro
                if not unit.banzaiModifier then unit.banzaiModifier = 0 end
                unit.banzaiModifier = math.max(0, unit.banzaiModifier - 5)

                -- check for aggro
                local targetId = unit.unitid .. "target"
                local targetName = UnitName(targetId .. "target")
                if roster[targetName] and UnitCanAttack("player", targetId) and UnitCanAttack(targetId, "player") then
                        if not roster[targetName].banzaiModifier then roster[targetName].banzaiModifier = 0 end
                        roster[targetName].banzaiModifier = roster[targetName].banzaiModifier + 10
                        if not roster[targetName].banzaiTarget then roster[targetName].banzaiTarget = acquire() end
                        table.insert(roster[targetName].banzaiTarget, targetId)
                end

                -- cleanup
                unit.banzaiModifier = math.max(0, unit.banzaiModifier)
                unit.banzaiModifier = math.min(25, unit.banzaiModifier)

                -- set aggro
                unit.banzai = (unit.banzaiModifier > 15)
        end

        for i, unit in pairs(roster) do
                if oldBanzai[unit.unitid] ~= nil and oldBanzai[unit.unitid] ~= unit.banzai then
                        -- Aggro status has changed.
                        if unit.banzai == true and unit.banzaiTarget then
                                -- Unit has aggro
                                self:TriggerEvent("Banzai_UnitGainedAggro", unit.unitid, unit.banzaiTarget)
                                if unit.name == playerName then
                                        self:TriggerEvent("Banzai_PlayerGainedAggro", unit.banzaiTarget)
                                end
                        elseif unit.banzai == false then
                                -- Unit lost aggro
                                self:TriggerEvent("Banzai_UnitLostAggro", unit.unitid)
                                if unit.name == playerName then
                                        self:TriggerEvent("Banzai_PlayerLostAggro", unit.unitid)
                                end
                        end
                end
                reclaim(unit.banzaiTarget)
                unit.banzaiTarget = nil
        end

        reclaim(oldBanzai)
        oldBanzai = nil
end

-------------------------------------------------------------------------------
-- API
-------------------------------------------------------------------------------

function lib:GetUnitAggroByUnitId( unitId )
        local rosterUnit = RL:GetUnitObjectFromUnit(unitId)
        if not rosterUnit then return nil end
        return rosterUnit.banzai
end

function lib:GetUnitAggroByUnitName( unitName )
        local rosterUnit = RL:GetUnitObjectFromName(unitName)
        if not rosterUnit then return nil end
        return rosterUnit.banzai
end

-------------------------------------------------------------------------------
-- Register
-------------------------------------------------------------------------------
AceLibrary:Register(lib, MAJOR_VERSION, MINOR_VERSION, activate)