vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2 Name: SpecialEvents-Aura-2.0
3 Revision: $Rev: 14863 $
4 Author: Tekkub Stoutwrithe (tekkub@gmail.com)
5 Website: http://www.wowace.com/
6 Description: Special events for Aura's, (de)buffs gained, lost etc.
7 Dependencies: AceLibrary, AceEvent-2.0, Gratuity-2.0
8 ]]
9  
10  
11 local vmajor, vminor = "SpecialEvents-Aura-2.0", "$Revision: 14863 $"
12  
13 if not AceLibrary then error(vmajor .. " requires AceLibrary.") end
14 if not AceLibrary:HasInstance("AceEvent-2.0") then error(vmajor .. " requires AceEvent-2.0.") end
15 if not AceLibrary:IsNewVersion(vmajor, vminor) then return end
16  
17 local lib = {}
18 AceLibrary("AceEvent-2.0"):embed(lib)
19  
20 local gratuity = AceLibrary("Gratuity-2.0")
21 local RL
22 local debuffTextureCache = {}
23 local buffTextureCache = {}
24  
25 local table_setn
26 do
27 local version = GetBuildInfo()
28 if string.find(version, "^2%.") then
29 -- 2.0.0
30 table_setn = function() end
31 else
32 table_setn = table.setn
33 end
34 end
35  
36 ----------------------------
37 -- Compost Heap --
38 ----------------------------
39  
40 local heap = {}
41 setmetatable(heap, {__mode = "kv"})
42  
43  
44 local function acquire(a1,a2,a3,a4,a5)
45 local t = next(heap)
46 if t then
47 heap[t] = nil
48 assert(not next(t), "A table in the compost heap has been modified!")
49 end
50 t = t or {}
51  
52 if a1 ~= nil then table.insert(t, a1) end
53 if a2 ~= nil then table.insert(t, a2) end
54 if a3 ~= nil then table.insert(t, a3) end
55 if a4 ~= nil then table.insert(t, a4) end
56 if a5 ~= nil then table.insert(t, a5) end
57 return t
58 end
59  
60  
61 local function reclaim(t, d)
62 if type(t) ~= "table" then return end
63  
64 if d and d > 0 then
65 for i in pairs(t) do
66 if type(t[i]) == "table" then reclaim(t[i], d - 1) end
67 end
68 end
69  
70 for i in pairs(t) do t[i] = nil end
71 t.reset = 1
72 t.reset = nil
73 table_setn(t, 0)
74  
75 heap[t] = true
76 end
77  
78  
79 ----------------------------
80 -- Initialization --
81 ----------------------------
82  
83 local function registerevents(self)
84 self:RegisterEvent("PLAYER_LEAVING_WORLD")
85 self:RegisterEvent("UNIT_AURA", "AuraScan")
86 self:RegisterEvent("UNIT_AURASTATE", "AuraScan")
87 self:RegisterEvent("PLAYER_AURAS_CHANGED")
88 self:RegisterEvent("PLAYER_TARGET_CHANGED")
89 self:RegisterEvent("PLAYER_REGEN_ENABLED")
90 -- check if RosterLib exists. We need to do that here and not earlier.
91 RL = AceLibrary:HasInstance("RosterLib-2.0") and AceLibrary("RosterLib-2.0") or nil
92 if RL then
93 RL:Enable()
94 self:RegisterBucketEvent("RosterLib_UnitChanged",0.2)
95 else
96 self:RegisterEvent("PARTY_MEMBERS_CHANGED",1)
97 self:RegisterEvent("RAID_ROSTER_UPDATE",1)
98 end
99 end
100  
101  
102 -- Activate a new instance of this library
103 function activate(self, oldLib, oldDeactivate)
104 if oldLib then
105 self.vars = oldLib.vars
106 if oldLib:IsEventRegistered("UNIT_AURA") then registerevents(self) end
107 if oldLib:IsEventRegistered("RosterLib_UnitChanged") then
108 if RL then RL:Disable() end
109 oldLib:UnregisterAllEvents()
110 end
111 else self.vars = {buffs = {}, debuffs = {}} end
112  
113 self:RegisterEvent("PLAYER_ENTERING_WORLD")
114  
115 if oldDeactivate then oldDeactivate(oldLib) end
116 end
117  
118  
119 function lib:PLAYER_ENTERING_WORLD()
120 self:ScanAllAuras()
121 registerevents(self)
122 end
123  
124  
125 function lib:PLAYER_LEAVING_WORLD()
126 self:UnregisterAllEvents()
127 self:RegisterEvent("PLAYER_ENTERING_WORLD")
128 if RL then
129 RL:Disable()
130 end
131 end
132  
133  
134 --------------------------------
135 -- Tracking methods --
136 --------------------------------
137  
138 function lib:PLAYER_AURAS_CHANGED()
139 self:AuraScan("player")
140 if GetNumRaidMembers() > 0 then
141 local u
142 for i=1,GetNumRaidMembers() do
143 if UnitIsUnit("raid"..i, "player") then u = "raid"..i end
144 end
145 self:AuraScan(u)
146 end
147 end
148  
149  
150 function lib:PLAYER_TARGET_CHANGED()
151 self:AuraScan("target")
152 self:TriggerEvent("SpecialEvents_AuraTargetChanged")
153 end
154  
155  
156 function lib:RosterLib_UnitChanged(units)
157 for unit in pairs(units) do
158 if unit and UnitExists(unit) then
159 self:AuraScan(unit)
160 end
161 end
162 if GetNumRaidMembers() > 0 then
163 self:TriggerEvent("SpecialEvents_AuraRaidRosterUpdate")
164 else
165 self:TriggerEvent("SpecialEvents_AuraPartyMembersChanged")
166 end
167 end
168  
169  
170 function lib:PARTY_MEMBERS_CHANGED()
171 if UnitExists("pet") then self:AuraScan("pet") end
172  
173 for i=1,4 do
174 if UnitExists("party"..i) then self:AuraScan("party"..i) end
175 if UnitExists("partypet"..i) then self:AuraScan("partypet"..i) end
176 end
177 self:TriggerEvent("SpecialEvents_AuraPartyMembersChanged")
178 end
179  
180  
181 function lib:RAID_ROSTER_UPDATE()
182 for i=1,40 do
183 if UnitExists("raid"..i) then self:AuraScan("raid"..i) end
184 if UnitExists("raidpet"..i) then self:AuraScan("raidpet"..i) end
185 end
186 self:TriggerEvent("SpecialEvents_AuraRaidRosterUpdate")
187 end
188  
189 function lib:PLAYER_REGEN_ENABLED()
190 reclaim(debuffTextureCache)
191 debuffTextureCache = acquire()
192 reclaim(buffTextureCache)
193 buffTextureCache = acquire()
194 end
195  
196 function lib:ScanAllAuras()
197 if UnitExists("player") then self:AuraScan("player") end
198 if UnitExists("pet") then self:AuraScan("pet") end
199  
200 for i=1,4 do
201 if UnitExists("party"..i) then self:AuraScan("party"..i) end
202 if UnitExists("partypet"..i) then self:AuraScan("partypet"..i) end
203 end
204  
205 for i=1,40 do
206 if UnitExists("raid"..i) then self:AuraScan("raid"..i) end
207 if UnitExists("raidpet"..i) then self:AuraScan("raidpet"..i) end
208 end
209  
210 if UnitExists("target") then self:AuraScan("target") end
211 --~~ if UnitExists("mouseover") then self:AuraScan("mouseover") end
212 end
213  
214  
215 function lib:AuraScan(targ)
216 local maxbuffs, maxdebuffs, t = 16, 16, targ or arg1
217 local oldd, oldb = self.vars.debuffs[t], self.vars.buffs[t]
218 local newd, newb = acquire(), acquire()
219  
220 if t == "player" then
221 for i=0,(maxbuffs-1) do
222 local bidx = GetPlayerBuff(i, "HELPFUL")
223 if bidx and bidx ~= -1 then
224 gratuity:SetPlayerBuff(bidx)
225 local txt = gratuity:GetLine(1)
226 if txt then newb[txt] = i end
227 end
228 end
229  
230 for i=0,(maxdebuffs-1) do
231 local didx = GetPlayerBuff(i, "HARMFUL")
232 if didx and didx ~= -1 then
233 gratuity:SetPlayerBuff(didx)
234 local txt, txtr = gratuity:GetLine(1)
235  
236 local apps = GetPlayerBuffApplications(didx)
237 local texture = GetPlayerBuffTexture(didx)
238 local dbtype = GetPlayerBuffDispelType(didx)
239  
240 if txt then
241 local txtindex = txt
242 if texture then txtindex = txtindex..texture end
243 newd[txtindex] = acquire(i, txt, apps, dbtype, texture)
244 end
245 end
246 end
247 else
248 for i=1,maxbuffs do
249 local txt
250 local texture, apps = UnitBuff (t, i)
251 if texture then
252 if not buffTextureCache[texture] then
253 gratuity:SetUnitBuff(t,i)
254 txt = gratuity:GetLine(1)
255 buffTextureCache[texture] = txt
256 else
257 txt = buffTextureCache[texture]
258 end
259 if txt then newb[txt] = i end
260 end
261 end
262  
263 for i=1,maxdebuffs do
264 local txt
265 local texture, apps, dbtype = UnitDebuff (t, i)
266 if texture then
267 if not debuffTextureCache[texture] then
268 gratuity:SetUnitDebuff(t,i)
269 txt = gratuity:GetLine(1)
270 debuffTextureCache[texture] = txt
271 else
272 txt = debuffTextureCache[texture]
273 end
274 if txt then
275 local txtindex = txt .. texture
276 reclaim(newd[txtindex])
277 newd[txtindex] = acquire(i, txt, apps, dbtype, texture)
278 end
279 end
280 end
281 end
282  
283 self.vars.buffs[t] = newb
284 self.vars.debuffs[t] = newd
285  
286 if oldb then
287 for b,i in pairs(oldb) do
288 if not newb[b] then
289 self:TriggerEvent("SpecialEvents_UnitBuffLost", t, b)
290 if t == "player" then self:TriggerEvent("SpecialEvents_PlayerBuffLost", b) end
291 end
292 end
293 end
294  
295 if oldd then
296 for d,i in pairs(oldd) do
297 if type(i) ~= "table" then
298 local t = ""
299 for d,i in pairs(oldd) do t = t.." "..d.."="..i end
300 error(string.format("Debuff error! Unit: %s, Table dump:%s", targ, t))
301 elseif not newd[d] then
302 self:TriggerEvent("SpecialEvents_UnitDebuffLost", t, i[2], i[3], i[4], i[5])
303 if t == "player" then self:TriggerEvent("SpecialEvents_PlayerDebuffLost", i[2], i[3], i[4], i[5]) end
304 end
305 end
306 end
307  
308 for b,i in pairs(newb) do
309 if (not oldb or not oldb[b]) then
310 self:TriggerEvent("SpecialEvents_UnitBuffGained", t, b)
311 if t == "player" then self:TriggerEvent("SpecialEvents_PlayerBuffGained", b, i) end
312 end
313 end
314  
315 for d,i in pairs(newd) do
316 assert(type(i) == "table", string.format("Debuff: %s - Value not a table: %s", d, type(i) == "table" and "table" or i or "nil"))
317  
318 local o2 = oldd and type(oldd[d]) == "table" and oldd[d][2]
319 if not o2 or o2 ~= i[2] then
320 self:TriggerEvent("SpecialEvents_UnitDebuffGained", t, i[2], i[3], i[4], i[5])
321 if t == "player" then self:TriggerEvent("SpecialEvents_PlayerDebuffGained", i[2], i[3], i[4], i[5]) end
322 end
323 end
324  
325 reclaim(oldb)
326 reclaim(oldd, 1)
327 end
328  
329  
330 -----------------------------
331 -- Query Methods --
332 -----------------------------
333  
334 function lib:UnitHasBuff(targ, buff)
335 if self.vars.buffs[targ] then return self.vars.buffs[targ][buff] end
336 end
337  
338  
339 function lib:UnitHasDebuff(targ, debuff)
340 if self.vars.debuffs[targ] then
341 for i, v in pairs(self.vars.debuffs[targ]) do
342 if v[2] == debuff then
343 return v[1], v[3]
344 end
345 end
346 end
347 end
348  
349  
350 function lib:UnitHasDebuffType(targ, debufftype)
351 if self.vars.debuffs[targ] then
352 for i,v in pairs(self.vars.debuffs[targ]) do
353 if v[4] == debufftype then return v end
354 end
355 end
356 end
357  
358  
359 function lib:BuffIter(unitid)
360 local f = function(unitid, i)
361 if not self.vars.buffs[unitid] then return end
362 local idx = next(self.vars.buffs[unitid], i)
363 local v = self.vars.buffs[unitid][idx]
364 if v then return idx, v end
365 end
366 return f, unitid, nil
367 end
368  
369 function lib:DebuffIter(unitid)
370 local idx = nil
371 local f = function(unitid)
372 if not self.vars.debuffs[unitid] then return end
373 idx = next(self.vars.debuffs[unitid], idx)
374 local v = self.vars.debuffs[unitid][idx]
375 if v then return v[2], v[3], v[4], v[5] end
376 end
377 return f, unitid, nil
378 end
379  
380 --------------------------------
381 -- Load this bitch! --
382 --------------------------------
383 AceLibrary:Register(lib, vmajor, vminor, activate)