--[[ Name: Banzai-1.1 Revision: $Rev: 21576 $ Author(s): Rabbit (rabbit.magtheridon@gmail.com), maia Documentation: http://www.wowace.com/index.php/Banzai-1.1_API_Documentation SVN: http://svn.wowace.com/wowace/trunk/BanzaiLib/Banzai-1.1 Description: Aggro notification library. Dependencies: AceLibrary, AceOO-2.0, AceEvent-2.0, Roster-2.1 ]] --[[ BanzaiLib is copyrighted 2006 by Rabbit. This addon is distributed under the terms of the Creative Commons Attribution-NonCommercial-ShareAlike 2.0 license. http://creativecommons.org/licenses/by-nc-sa/2.5/ You may distribute and use these libraries without making your mod adhere to the same license, as long as you preserve the license text embedded in the libraries. Any and all questions regarding our stance and licensing should be directed to the #wowace IRC channel on irc.freenode.net. ]] ------------------------------------------------------------------------------- -- Locals ------------------------------------------------------------------------------- local MAJOR_VERSION = "Banzai-1.1" local MINOR_VERSION = "$Revision: 21576 $" if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary.") end if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end if AceLibrary:HasInstance("Banzai-1.0") then error(MAJOR_VERSION .. " can't run alongside Banzai-1.0.") end if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0.") end if not AceLibrary:HasInstance("AceEvent-2.0") then error(MAJOR_VERSION .. " requires AceEvent-2.0.") end if not AceLibrary:HasInstance("Roster-2.1") then error(MAJOR_VERSION .. " requires Roster-2.1.") end local lib = {} AceLibrary("AceEvent-2.0"):embed(lib) local RL = nil local roster = nil local playerName = nil ------------------------------------------------------------------------------- -- Local heap ------------------------------------------------------------------------------- local new, del do local cache = setmetatable({},{__mode='k'}) function new() local t = next(cache) if t then cache[t] = nil return t else return {} end end function del(t) for k in pairs(t) do t[k] = nil end cache[t] = true return nil end 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") self:StartOrStop() end else self.vars = {} end RL = AceLibrary("Roster-2.1") roster = RL.roster playerName = UnitName("player") if not self.vars then self.vars = {} end self:RegisterEvent("AceEvent_EventRegistered", "StartOrStop") self:RegisterEvent("AceEvent_EventUnregistered", "StartOrStop") if oldDeactivate then oldDeactivate(oldLib) end end ------------------------------------------------------------------------------- -- Events ------------------------------------------------------------------------------- function lib:StartOrStop() local aceEvent = AceLibrary("AceEvent-2.0") if aceEvent:IsEventRegistered("Banzai_UnitGainedAggro") or aceEvent:IsEventRegistered("Banzai_PlayerGainedAggro") or aceEvent:IsEventRegistered("Banzai_UnitLostAggro") or aceEvent:IsEventRegistered("Banzai_PlayerLostAggro") or aceEvent:IsEventRegistered("Banzai_Run") then if not self:IsEventScheduled("UpdateAggroList") then self:ScheduleRepeatingEvent("UpdateAggroList", self.UpdateAggroList, 0.2, self) self.vars.running = true self:TriggerEvent("Banzai_Enabled") end elseif self:IsEventRegistered("UpdateAggroList") then self:CancelScheduledEvent("UpdateAggroList") for i, unit in pairs(roster) do unit.banzai = nil unit.banzaiModifier = nil end self.vars.running = nil self:TriggerEvent("Banzai_Disabled") end end ------------------------------------------------------------------------------- -- Library ------------------------------------------------------------------------------- function lib:UpdateAggroList() local oldBanzai = nil for name, unit in pairs(roster) do if not oldBanzai then oldBanzai = new() end oldBanzai[name] = 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" if UnitExists(targetId) and UnitExists(targetId .. "target") then 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 = new() end table.insert(roster[targetName].banzaiTarget, targetId) end 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 name, unit in pairs(roster) do if oldBanzai[name] ~= nil and oldBanzai[name] ~= 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 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 name == playerName then self:TriggerEvent("Banzai_PlayerLostAggro", unit.unitid) end end end if unit.banzaiTarget then unit.banzaiTarget = del(unit.banzaiTarget) end end if oldBanzai then oldBanzai = del(oldBanzai) end end ------------------------------------------------------------------------------- -- API ------------------------------------------------------------------------------- function lib:GetUnitAggroByUnitId( unitId ) if not self.vars.running then error(MAJOR_VERSION.." is not running. You must register for one of the events.") end local rosterUnit = RL:GetUnitObjectFromUnit(unitId) if not rosterUnit then return nil end return rosterUnit.banzai end function lib:GetUnitAggroByUnitName( unitName ) if not self.vars.running then error(MAJOR_VERSION.." is not running. You must register for one of the events.") end local rosterUnit = RL:GetUnitObjectFromName(unitName) if not rosterUnit then return nil end return rosterUnit.banzai end function lib:IsRunning() return self:IsEventScheduled("UpdateAggroList") end ------------------------------------------------------------------------------- -- Register ------------------------------------------------------------------------------- AceLibrary:Register(lib, MAJOR_VERSION, MINOR_VERSION, activate)