vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 ---------------------------------------------------------------------------
2 -- To Get an instance of ParserLib, call this:
3 -- local parser = ParserLib:GetInstance(version)
4 -- where the version is the variable 'vmajor' you see here.
5 ---------------------------------------------------------------------------
6 local vmajor, vminor = "1.1", 24
7  
8 ---------------------------------------------------------------------------
9 -- **Public ParserLib methods begins at line 155.
10 ---------------------------------------------------------------------------
11  
12 local stubvarname = "TekLibStub"
13 local libvarname = "ParserLib"
14  
15 -- Check to see if an update is needed
16 -- if not then just return out now before we do anything
17 local libobj = getglobal(libvarname)
18 if libobj and not libobj:NeedsUpgraded(vmajor, vminor) then return end
19  
20  
21 ---------------------------------------------------------------------------
22 -- Embedded Library Registration Stub
23 -- Written by Iriel <iriel@vigilance-committee.org>
24 -- Version 0.1 - 2006-03-05
25 -- Modified by Tekkub <tekkub@gmail.com>
26 ---------------------------------------------------------------------------
27  
28 local stubobj = getglobal(stubvarname)
29 if not stubobj then
30 stubobj = {}
31 setglobal(stubvarname, stubobj)
32  
33 -- Instance replacement method, replace contents of old with that of new
34 function stubobj:ReplaceInstance(old, new)
35 for k,v in pairs(old) do old[k]=nil end
36 for k,v in pairs(new) do old[k]=v end
37 end
38  
39 -- Get a new copy of the stub
40 function stubobj:NewStub(name)
41 local newStub = {}
42 self:ReplaceInstance(newStub, self)
43 newStub.libName = name
44 newStub.lastVersion = ''
45 newStub.versions = {}
46 return newStub
47 end
48  
49  
50 -- Get instance version
51 function stubobj:NeedsUpgraded(vmajor, vminor)
52 local versionData = self.versions[vmajor]
53 if not versionData or versionData.minor < vminor then return true end
54 end
55  
56  
57 -- Get instance version
58 function stubobj:GetInstance(version)
59 if not version then version = self.lastVersion end
60 local versionData = self.versions[version]
61 if not versionData then print(string.format("<%s> Cannot find library version: %s", self.libName, version or "")) return end
62 return versionData.instance
63 end
64  
65  
66 -- Register new instance
67 function stubobj:Register(newInstance)
68 local version,minor = newInstance:GetLibraryVersion()
69 self.lastVersion = version
70 local versionData = self.versions[version]
71 if not versionData then
72 -- This one is new!
73 versionData = {
74 instance = newInstance,
75 minor = minor,
76 old = {},
77 }
78 self.versions[version] = versionData
79 newInstance:LibActivate(self)
80 return newInstance
81 end
82 -- This is an update
83 local oldInstance = versionData.instance
84 local oldList = versionData.old
85 versionData.instance = newInstance
86 versionData.minor = minor
87 local skipCopy = newInstance:LibActivate(self, oldInstance, oldList)
88 table.insert(oldList, oldInstance)
89 if not skipCopy then
90 for i, old in ipairs(oldList) do self:ReplaceInstance(old, newInstance) end
91 end
92 return newInstance
93 end
94 end
95  
96  
97 if not libobj then
98 libobj = stubobj:NewStub(libvarname)
99 setglobal(libvarname, libobj)
100 end
101  
102  
103 local lib = {}
104  
105  
106 -- Return the library's current version
107 function lib:GetLibraryVersion()
108 return vmajor, vminor
109 end
110  
111  
112 -- Activate a new instance of this library
113 function lib:LibActivate(stub, oldLib, oldList)
114 local maj, min = self:GetLibraryVersion()
115  
116 if oldLib then
117 local omaj, omin = oldLib:GetLibraryVersion()
118 ----------------------------------------------------
119 -- ********************************************** --
120 -- **** Copy over any old data you need here **** --
121 -- ********************************************** --
122 ----------------------------------------------------
123 self.frame = oldLib.frame
124 self:OnLoad()
125  
126 if omin < 11 and oldLib.clients then
127 for event in oldLib.clients do
128 for i in oldLib.clients[event] do
129 if type(oldLib.clients[event][i]["func"]) == "string" then
130 oldLib.clients[event][i]["func"] = getglobal(oldLib.clients[event][i]["func"])
131 end
132 end
133 end
134 end
135 self.clients = oldLib.clients
136  
137  
138 else
139 ---------------------------------------------------
140 -- ********************************************* --
141 -- **** Do any initialization you need here **** --
142 -- ********************************************* --
143 ---------------------------------------------------
144 self:OnLoad()
145 end
146 -- nil return makes stub do object copy
147 end
148  
149  
150  
151  
152  
153  
154  
155 ----------------------------------------------
156 -- *ParserLib Public Methods* --
157 ----------------------------------------------
158  
159 -- Register an event to ParserLib.
160 function lib:RegisterEvent(addonID, event, handler)
161  
162 local eventExist
163 for i, v in self.supportedEvents do
164 if v == event then
165 eventExist = true
166 break
167 end
168 end
169  
170 if not eventExist then
171 self:Print( string.format("Event %s is not supported. (AddOnID %s)", event, addonID), 1, 0, 0 )
172 return
173 end
174  
175  
176 -- self:Print(string.format("Registering %s for addon %s.", event, addonID) ); -- debug
177  
178 if type(handler) == "string" then handler = getglobal(handler) end
179  
180 -- if not handler then self:Print("nil handler from " .. addonID, 1, 0, 0) end -- debug
181  
182 if self.clients[event] == nil then
183 self.clients[event] = {};
184 end
185  
186 table.insert(self.clients[event], { ["id"]=addonID, ["func"]=handler } );
187 self.frame:RegisterEvent(event);
188  
189 end
190  
191 -- Check if you have registered an event.
192 function lib:IsEventRegistered(addonID, event)
193 if self.clients[event] then
194 for i, v in self.clients[event] do
195 if v.id == addonID then return true end
196 end
197 end
198 end
199  
200 -- Unregister an event.
201 function lib:UnregisterEvent(addonID, event)
202 local empty = true
203  
204  
205 if not self.clients[event] then return end
206  
207 for i, v in self.clients[event] do
208 if v.id == addonID then
209 -- self:Print( format("Removing %s from %s", v.id, event) ) -- debug
210 table.remove(self.clients[event], i)
211 else
212 empty = false
213 end
214 end
215  
216 if empty then
217 -- self:Print("Unregistering event " .. event) -- debug
218 self.frame:UnregisterEvent(event)
219 self.clients[event] = nil
220 end
221 end
222  
223 -- Unregister all events.
224 function lib:UnregisterAllEvents(addonID)
225 local event, index, empty;
226  
227 for event in self.clients do
228 empty = true;
229  
230 for i, v in self.clients[event] do
231 if v.id == addonID then
232 -- self:Print( format("Removing %s for %s", v.id, event) ) -- debug
233 table.remove(self.clients[event], i)
234 -- self.clients[event][index] = nil;
235 else
236 empty = false;
237 end
238 end
239  
240 if empty then
241 -- self:Print("Unregistering event " .. event) -- debug
242 self.frame:UnregisterEvent(event);
243 self.clients[event] = nil;
244 end
245  
246 end
247  
248 end
249  
250 -- Parse custom messages, check documentation.html for more info.
251 function lib:Deformat(text, pattern)
252 if not self.customPatterns then self.customPatterns = {} end
253 if not self.customPatterns[pattern] then
254 self.customPatterns[pattern] = self:Curry(pattern)
255 end
256 return self.customPatterns[pattern](text)
257 end
258  
259 --------------------------------------------------------
260 -- Methods to control ParserLib behaviour --
261 --------------------------------------------------------
262  
263 -- Use CompostLib or not?
264 -- Not that at 1.1-23 CompostLib no longer slows down the speed of ParserLib,
265 -- because I found out that I was calling CompostLib:Recycle too frequently, which can be avoided.
266 function lib:UseCompost(flag)
267 self.vars.noCompost = not flag
268 end
269  
270  
271 ---------------------------------------------------
272 -- *End of ParserLib Public Methods* --
273 ---------------------------------------------------
274  
275  
276 ----------------------------------------------
277 -- ParserLib Private Methods
278 ----------------------------------------------
279  
280 -- Constants
281 ParserLib_SELF = 103
282 ParserLib_MELEE = 112
283 ParserLib_DAMAGESHIELD = 113
284  
285 -- lib.timing = true -- timer
286  
287 -- Stub function called by frame.OnEvent
288 local function ParserOnEvent() lib:OnEvent() end
289  
290 -- Sort the pattern so that they can be parsed in a correct sequence, will only do once for each registered event.
291 local function PatternCompare(a, b)
292  
293 local pa = getglobal(a)
294 local pb = getglobal(b)
295  
296 if not pa then ChatFrame1:AddMessage("|cffff0000Nil pattern: ".. a.."|r") end
297 if not pb then ChatFrame1:AddMessage("|cffff0000Nil pattern: ".. b.."|r") end
298  
299 local ca=0
300 for _ in string.gfind(pa, "%%%d?%$?[sd]") do ca=ca+1 end
301 local cb=0
302 for _ in string.gfind(pb, "%%%d?%$?[sd]") do cb=cb+1 end
303  
304 pa = string.gsub(pa, "%%%d?%$?[sd]", "")
305 pb = string.gsub(pb, "%%%d?%$?[sd]", "")
306  
307 if string.len(pa) == string.len(pb) then
308 return ca < cb;
309 else
310 return string.len(pa) > string.len(pb)
311 end
312  
313 end
314  
315 local FindString = {
316 [0] = function(m,p,t) return string.find(m,p), t end,
317 [1] = function(m,p,t) _,_,t[1] = string.find(m,p) if t[1] then return true, t else return false, t end end,
318 [2] = function(m,p,t) _,_,t[1],t[2] = string.find(m,p) if t[2] then return true, t else return false, t end end,
319 [3] = function(m,p,t) _,_,t[1],t[2],t[3] = string.find(m,p) if t[3] then return true, t else return false, t end end,
320 [4] = function(m,p,t) _,_,t[1],t[2],t[3],t[4] = string.find(m,p) if t[4] then return true, t else return false, t end end,
321 [5] = function(m,p,t) _,_,t[1],t[2],t[3],t[4],t[5] = string.find(m,p) if t[5] then return true, t else return false, t end end,
322 [6] = function(m,p,t) _,_,t[1],t[2],t[3],t[4],t[5],t[6] = string.find(m,p) if t[6] then return true, t else return false, t end end,
323 [7] = function(m,p,t) _,_,t[1],t[2],t[3],t[4],t[5],t[6],t[7] = string.find(m,p) if t[7] then return true, t else return false, t end end,
324 [8] = function(m,p,t) _,_,t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8] = string.find(m,p) if t[8] then return true, t else return false, t end end,
325 [9] = function(m,p,t) _,_,t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9] = string.find(m,p) if t[9] then return true, t else return false, t end end,
326 }
327  
328 -- Currently supported event list.
329 lib.supportedEvents = {
330  
331 "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS",
332 "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES",
333 "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS",
334 "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES",
335 "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS",
336 "CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES",
337 "CHAT_MSG_COMBAT_FACTION_CHANGE",
338 "CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS",
339 "CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES",
340 "CHAT_MSG_COMBAT_FRIENDLY_DEATH",
341 "CHAT_MSG_COMBAT_HONOR_GAIN",
342 "CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS",
343 "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES",
344 "CHAT_MSG_COMBAT_HOSTILE_DEATH",
345 "CHAT_MSG_COMBAT_PARTY_HITS",
346 "CHAT_MSG_COMBAT_PARTY_MISSES",
347 "CHAT_MSG_COMBAT_PET_HITS",
348 "CHAT_MSG_COMBAT_PET_MISSES",
349 "CHAT_MSG_COMBAT_SELF_HITS",
350 "CHAT_MSG_COMBAT_SELF_MISSES",
351 "CHAT_MSG_COMBAT_XP_GAIN",
352 "CHAT_MSG_SPELL_AURA_GONE_OTHER",
353 "CHAT_MSG_SPELL_AURA_GONE_SELF",
354 "CHAT_MSG_SPELL_AURA_GONE_PARTY",
355 "CHAT_MSG_SPELL_BREAK_AURA",
356 "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF",
357 "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE",
358 "CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF",
359 "CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE",
360 "CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF",
361 "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE",
362 "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS",
363 "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF",
364 "CHAT_MSG_SPELL_FAILED_LOCALPLAYER",
365 "CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF",
366 "CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE",
367 "CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF",
368 "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE",
369 "CHAT_MSG_SPELL_ITEM_ENCHANTMENTS",
370 "CHAT_MSG_SPELL_PARTY_BUFF",
371 "CHAT_MSG_SPELL_PARTY_DAMAGE",
372 "CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS",
373 "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE",
374 "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS",
375 "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE",
376 "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS",
377 "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE",
378 "CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS",
379 "CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE",
380 "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS",
381 "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE",
382 "CHAT_MSG_SPELL_PET_BUFF",
383 "CHAT_MSG_SPELL_PET_DAMAGE",
384 "CHAT_MSG_SPELL_SELF_BUFF",
385 "CHAT_MSG_SPELL_SELF_DAMAGE",
386 "CHAT_MSG_SPELL_TRADESKILLS",
387  
388 }
389  
390 function lib:GetCompost()
391  
392 if self.vars.noCompost then
393  
394 if not self.myCompost then
395 self.myCompost = {
396 Recycle = function() return {} end,
397 Acquire = function() return {} end,
398 Reclaim = function() end,
399 }
400 end
401 return self.myCompost
402  
403 else
404  
405 if not self.compost then
406 if AceLibrary and AceLibrary:HasInstance("Compost-2.0") then
407 self.compost = AceLibrary:GetInstance("Compost-2.0")
408 elseif CompostLib then
409 self.compost = CompostLib:GetInstance("compost-1")
410 else
411 -- Cannot find the existance of CompostLib
412 self.vars.noCompost = true
413 return self:GetCompost()
414 end
415 end
416 return self.compost
417  
418 end
419  
420 end
421  
422 -- Convert "%s hits %s for %d." to "(.+) hits (.+) for (%d+)."
423 -- Will additionaly return the sequence of tokens, for example:
424 -- "%2$s reflects %3$d %4$s damage to %1$s." will return:
425 -- "(.-) reflects (%+) (.-) damage to (.-)%.", 4 1 2 3.
426 -- ( [1]=2,[2]=3,[3]=4,[4]=1 Reverting indexes and become [1]=4, [2]=[1],[3]=2,[4]=3. )
427 function lib:ConvertPattern(pattern, anchor)
428  
429 local seq
430  
431 -- Add % to escape all magic characters used in LUA pattern matching, except $ and %
432 pattern = string.gsub(pattern,"([%^%(%)%.%[%]%*%+%-%?])","%%%1");
433  
434 -- Do these AFTER escaping the magic characters.
435 pattern = string.gsub(pattern,"%%s","(.-)"); -- %s to (.-)
436 pattern = string.gsub(pattern,"%%d","(%-?%%d+)"); -- %d to (%d+)
437  
438 if string.find(pattern,"%$") then
439 seq = {}; -- fills with ordered list of $s as they appear
440 local idx = 1; -- incremental index into field[]
441  
442 local tmpSeq = {}
443 for i in string.gfind(pattern,"%%(%d)%$.") do
444 tmpSeq[idx] = tonumber(i);
445 idx = idx + 1
446 end
447 for i, j in ipairs(tmpSeq) do
448 seq[j] = i
449 end
450 table.setn(seq, table.getn(tmpSeq))
451 pattern = string.gsub(pattern,"%%%d%$s","(.-)"); -- %1$s to (.-)
452 pattern = string.gsub(pattern,"%%%d%$d","(%-?%%d+)"); -- %1$d to (%d+)
453 end
454  
455 -- Escape $ now.
456 pattern = string.gsub(pattern,"%$","%%$");
457  
458 -- Anchor tag can improve string.find() performance by 100%.
459 if anchor then pattern = "^"..pattern end
460  
461 -- If the pattern ends with (.-), replace it with (.+), or the capsule will be lost.
462 if string.sub(pattern, -4) == "(.-)" then
463 pattern = string.sub(pattern, 0, -5) .. "(.+)";
464 end
465  
466 if not seq then return pattern end
467  
468 return pattern, seq[1], seq[2], seq[3], seq[4], seq[5], seq[6], seq[7], seq[8], seq[9], seq[10]
469 end
470  
471 function lib:OnLoad()
472  
473 -- Both table starts out empty, and load the data only when required.
474 self.eventTable = {}
475 self.patternTable = {}
476  
477  
478 self.vars = {}
479  
480 if self.timing then
481 self.timer = {
482 ParseMessage_LoadPatternList = 0,
483 ParseMessage_FindPattern = 0,
484 ParseMessage_FindPattern_Regexp = 0,
485 ParseMessage_FindPattern_Regexp_FindString = 0,
486 ParseMessage_FindPattern_LoadPatternInfo = 0,
487 ParseMessage_ParseInformation = 0,
488 ParseMessage_ParseTrailers = 0,
489 ParseMessage_ConvertTypes = 0,
490 NotifyClients = 0,
491 Compost_Acquire = 0,
492 Compost_Recycle = 0,
493 Compost_Reclaim = 0,
494 }
495 end
496  
497 if not self.clients then self.clients = {} end
498  
499 if not self.frame then
500 self.frame = CreateFrame("FRAME", "ParserLibFrame")
501 self.frame:SetScript("OnEvent", ParserOnEvent )
502 self.frame:Hide()
503 end
504  
505  
506 end
507  
508 function lib:OnEvent(e, a1)
509  
510 if not e then e = event end
511 if not a1 then a1 = arg1 end
512  
513 -- self:Print("Event: |cff3333ff"..e.."|r") -- debug
514  
515 -- Titan Honor+ was changing the global events... just change it back.
516 if e == "CHAT_MSG_HONORPLUS" then e = "CHAT_MSG_COMBAT_HONOR_GAIN" end
517  
518  
519 if self:ParseMessage(a1, e) then
520  
521 -- local timer = GetTime() -- timer
522 self:NotifyClients(e)
523 -- self.timer.NotifyClients = self.timer.NotifyClients + GetTime() - timer -- timer
524  
525 end
526  
527  
528 end
529  
530 function lib:NotifyClients(event)
531  
532 if not self.clients or not self.clients[event] then
533 -- self:Print(event .. " has no client to notify.") -- debug
534 return
535 end
536  
537 -- Noneed to recycle the table if there is only one client.
538 if table.getn(self.clients[event]) == 1 then
539 -- self:Print(event .. ", calling " .. self.clients[event][1].id) -- debug
540 self.clients[event][1].func(event, self.info)
541 return
542 end
543  
544 -- local timer = GetTime() -- timer
545 local info = self:GetCompost():Acquire()
546 -- self.timer.Compost_Acquire = GetTime() - timer + self.timer.Compost_Acquire -- timer
547  
548 for i, client in self.clients[event] do
549 -- self:Print(event .. ", calling " .. client.id) -- debug
550  
551 -- I can just do a compost:Recycle() here, but I hope this can improve the performance.
552 for j in info do if not self.info[j] then info[j] = nil end end
553 for j, v in self.info do info[j] = v end
554  
555 client.func(event, info)
556 end
557  
558 -- timer = GetTime() -- timer
559 self:GetCompost():Reclaim(info)
560 -- self.timer.reclaim = GetTime() - timer + self.timer.reclaim -- timer
561  
562 end
563  
564 function lib:Print(msg, r, g, b)
565 ChatFrame1:AddMessage(string.format("<%s-%s-%s> %s", libvarname, vmajor, vminor, msg), r, g, b)
566 end
567  
568  
569 -- message : the arg1 in the event
570 -- event : name says it all.
571 -- info : the table which will store the passed result, so THIS IS THE OUTPUT.
572 -- return : true if pattern found and parsed, nil otherwise.
573 function lib:ParseMessage(message, event)
574  
575 -- -- local currTime -- timer
576  
577  
578 -- currTime = GetTime() -- timer
579 if not self.eventTable[event] then self.eventTable[event] = self:LoadPatternList(event) end
580 local list = self.eventTable[event]
581 -- self.timer.ParseMessage_LoadPatternList = self.timer.ParseMessage_LoadPatternList + GetTime() - currTime -- timer
582  
583 if not list then return end
584  
585 -- Get the table to store parsed results.
586 if not self.info then
587 -- timer = GetTime() -- timer
588 self.info = self:GetCompost():Acquire()
589 -- self.timer.Compost_Acquire = GetTime() - timer + self.timer.Compost_Acquire -- timer
590 else
591 -- timer = GetTime() -- timer
592 self.info = self:GetCompost():Recycle(self.info)
593 -- self.timer.Compost_Recycle = GetTime() - timer + self.timer.Compost_Recycle -- timer
594 end
595  
596  
597 -- currTime = GetTime() -- timer
598 local pattern = self:FindPattern(message, list)
599 -- self.timer.ParseMessage_FindPattern = GetTime() - currTime + self.timer.ParseMessage_FindPattern -- timer
600  
601  
602 if not pattern then
603 -- create "unknown" event type.
604 self.info.type = "unknown"
605 self.info.message = message
606 return true
607 end
608  
609 -- currTime = GetTime() -- timer
610 self:ParseInformation(pattern)
611 -- self.timer.ParseMessage_ParseInformation = GetTime() - currTime + self.timer.ParseMessage_ParseInformation -- timer
612  
613  
614 -- currTime = GetTime() -- timer
615 if self.info.type == "hit" or self.info.type == "environment" then
616 self:ParseTrailers(message)
617 end
618 -- self.timer.ParseMessage_ParseTrailers = GetTime() - currTime + self.timer.ParseMessage_ParseTrailers -- timer
619  
620 -- currTime = GetTime() -- timer
621 self:ConvertTypes(self.info)
622 -- self.timer.ParseMessage_ConvertTypes = GetTime() - currTime + self.timer.ParseMessage_ConvertTypes -- timer
623  
624 return true
625  
626  
627 end
628  
629  
630 -- Search for pattern in 'patternList' which matches 'message', parsed tokens will be stored in table self.info
631 function lib:FindPattern(message, patternList)
632  
633 local pt, timer, found
634  
635 for i, v in patternList do
636  
637 -- timer = GetTime() -- timer
638 if not self.patternTable[v] then self.patternTable[v] = self:LoadPatternInfo(v) end
639 -- self.timer.ParseMessage_FindPattern_LoadPatternInfo = GetTime() - timer + self.timer.ParseMessage_FindPattern_LoadPatternInfo -- timer
640  
641 pt = self.patternTable[v]
642  
643 found = false
644  
645 -- timer = GetTime() -- timer
646 if self:OptimizerCheck(message, v) then
647 -- timer = GetTime() -- timer
648 found, self.info = FindString[pt.tc](message, pt.pattern, self.info)
649 -- self.timer.ParseMessage_FindPattern_Regexp_FindString = GetTime() - timer + self.timer.ParseMessage_FindPattern_Regexp_FindString -- timer
650 end
651 -- self.timer.ParseMessage_FindPattern_Regexp = GetTime() - timer + self.timer.ParseMessage_FindPattern_Regexp -- timer
652  
653 if found then
654 -- self:Print(message.." = " .. v .. ":" .. pt.pattern) -- debug
655 return v
656 end
657  
658  
659 end
660  
661  
662 end
663  
664  
665 -- Parses for trailors.
666 function lib:ParseTrailers(message)
667 local found, amount, info
668  
669 info = self.info
670  
671  
672 if not self.trailers then
673 self.trailers = {
674 CRUSHING_TRAILER = self:ConvertPattern(CRUSHING_TRAILER),
675 GLANCING_TRAILER = self:ConvertPattern(GLANCING_TRAILER),
676 ABSORB_TRAILER = self:ConvertPattern(ABSORB_TRAILER),
677 BLOCK_TRAILER = self:ConvertPattern(BLOCK_TRAILER),
678 RESIST_TRAILER = self:ConvertPattern(RESIST_TRAILER),
679 VULNERABLE_TRAILER = self:ConvertPattern(VULNERABLE_TRAILER),
680 }
681 end
682  
683 found = string.find(message, self.trailers.CRUSHING_TRAILER)
684 if found then
685 info.isCrushing = true
686 end
687 found = string.find(message, self.trailers.GLANCING_TRAILER)
688 if found then
689 info.isGlancing = true
690 end
691 found, _, amount = string.find(message, self.trailers.ABSORB_TRAILER)
692 if found then
693 info.amountAbsorb = amount
694 end
695 found, _, amount = string.find(message, self.trailers.BLOCK_TRAILER)
696 if found then
697 info.amountBlock = amount
698 end
699 found, _, amount = string.find(message, self.trailers.RESIST_TRAILER)
700 if found then
701 info.amountResist = amount
702 end
703 found, _, amount = string.find(message, self.trailers.VULNERABLE_TRAILER)
704 if found then
705 info.amountVulnerable = amount
706 end
707  
708 end
709  
710 function lib:ParseInformation(patternName)
711  
712 local patternInfo = self.patternTable[patternName]
713 local info = self.info
714  
715 -- Create an info table from pattern table, copies everything except the pattern string.
716 for i, v in patternInfo do
717 if i == 1 then
718 info.type = v
719 elseif type(i) == "number" then
720 if type(v) == "number" and v < 100 then
721 info[ self:GetInfoFieldName( self.patternTable[patternName][1], i) ] = info[v]
722 else
723 info[ self:GetInfoFieldName( self.patternTable[patternName][1], i) ] = v
724 end
725 end
726 end
727  
728 if info.type == "honor" and not info.amount then
729 info.isDishonor = true
730  
731 elseif info.type == "durability" and not info.item then
732 info.isAllItems = true
733 end
734  
735 for i in ipairs(info) do
736 info[i] = nil
737 end
738  
739 end
740  
741 function lib:ConvertTypes(info)
742 for i in info do
743 if string.find(i, "^amount") then info[i] = tonumber(info[i]) end
744 end
745 end
746  
747 function lib:OptimizerCheck(message, patternName)
748  
749 --if 1 then return true end
750 if not ParserLibOptimizer then return true end
751  
752 if not ParserLibOptimizer[patternName] then return true end
753  
754 if string.find(message, ParserLibOptimizer[patternName], 1, true) then return true end
755  
756 return false
757 end
758  
759 -- Most of the parts were learnt from BabbleLib by chknight, so credits goes to him.
760 function lib:Curry(pattern)
761 local cp, tt, n, f, o
762 local DoNothing = function(tok) return tok end
763  
764 tt = {}
765 for tk in string.gfind(pattern, "%%%d?%$?([sd])") do
766 table.insert(tt, tk)
767 end
768  
769 cp = { self:ConvertPattern(pattern, true) }
770 cp.p = cp[1]
771  
772 n = table.getn(cp)
773 for i=1,n-1 do
774 cp[i] = cp[i+1]
775 end
776 table.remove(cp, n)
777  
778 f = {}
779 o = {}
780 n = table.getn(tt)
781 for i=1, n do
782 if tt[i] == "s" then
783 f[i] = DoNothing
784 else
785 f[i] = tonumber
786 end
787 end
788  
789 if not cp[1] then
790 if n == 0 then
791 return function() end
792 elseif n == 1 then
793 return function(text)
794 _, _, o[1] = string.find(text, cp.p)
795 if o[1] then
796 return f[1](o[1])
797 end
798 end
799 elseif n == 2 then
800 return function(text)
801 _, _, o[1], o[2]= string.find(text, cp.p)
802 if o[1] then
803 return f[1](o[1]), f[2](o[2])
804 end
805 end
806 elseif n == 3 then
807 return function(text)
808 _, _, o[1], o[2], o[3] = string.find(text, cp.p)
809 if o[1] then
810 return f[1](o[1]), f[2](o[2]), f[3](o[3])
811 end
812 end
813 elseif n == 4 then
814 return function(text)
815 _, _, o[1], o[2], o[3], o[4] = string.find(text, cp.p)
816 if o[1] then
817 return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4])
818 end
819 end
820 elseif n == 5 then
821 return function(text)
822 _, _, o[1], o[2], o[3], o[4], o[5] = string.find(text, cp.p)
823 if o[1] then
824 return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5])
825 end
826 end
827 elseif n == 6 then
828 return function(text)
829 _, _, o[1], o[2], o[3], o[4], o[5], o[6] = string.find(text, cp.p)
830 if o[1] then
831 return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5]), f[6](o[6])
832 end
833 end
834 elseif n == 7 then
835 return function(text)
836 _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7] = string.find(text, cp.p)
837 if o[1] then
838 return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5]), f[6](o[6]), f[7](o[7])
839 end
840 end
841 elseif n == 8 then
842 return function(text)
843 _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8] = string.find(text, cp.p)
844 if o[1] then
845 return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5]), f[6](o[6]), f[7](o[7]), f[8](o[8])
846 end
847 end
848 elseif n == 9 then
849 return function(text)
850 _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8], o[9] = string.find(text, cp.p)
851 if o[1] then
852 return f[1](o[1]), f[2](o[2]), f[3](o[3]), f[4](o[4]), f[5](o[5]), f[6](o[6]), f[7](o[7]), f[8](o[8]), f[9](o[9])
853 end
854 end
855 end
856 else
857 if n == 0 then
858 return function() end
859 elseif n == 1 then
860 return function(text)
861 _, _, o[1] = string.find(text, cp.p)
862 if o[1] then
863 return f[cp[1]](o[cp[1]])
864 end
865 end elseif n == 2 then
866 return function(text)
867 _, _, o[1], o[2] = string.find(text, cp.p)
868 if o[1] then
869 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]])
870 end
871 end elseif n == 3 then
872 return function(text)
873 _, _, o[1], o[2], o[3] = string.find(text, cp.p)
874 if o[1] then
875 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]])
876 end
877 end
878 elseif n == 4 then
879 return function(text)
880 _, _, o[1], o[2], o[3], o[4] = string.find(text, cp.p)
881 if o[1] then
882 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]])
883 end
884 end elseif n == 5 then
885 return function(text)
886 _, _, o[1], o[2], o[3], o[4], o[5] = string.find(text, cp.p)
887 if o[1] then
888 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]])
889 end
890 end elseif n == 6 then
891 return function(text)
892 _, _, o[1], o[2], o[3], o[4], o[5], o[6] = string.find(text, cp.p)
893 if o[1] then
894 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]]), f[cp[6]](o[cp[6]])
895 end
896 end elseif n == 7 then
897 return function(text)
898 _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7] = string.find(text, cp.p)
899 if o[1] then
900 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]]), f[cp[6]](o[cp[6]]), f[cp[7]](o[cp[7]])
901 end
902 end elseif n == 8 then
903 return function(text)
904 _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8] = string.find(text, cp.p)
905 if o[1] then
906 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]]), f[cp[6]](o[cp[6]]), f[cp[7]](o[cp[7]]), f[cp[8]](o[cp[8]])
907 end
908 end elseif n == 9 then
909 return function(text)
910 _, _, o[1], o[2], o[3], o[4], o[5], o[6], o[7], o[8], o[9] = string.find(text, cp.p)
911 if o[1] then
912 return f[cp[1]](o[cp[1]]), f[cp[2]](o[cp[2]]), f[cp[3]](o[cp[3]]), f[cp[4]](o[cp[4]]), f[cp[5]](o[cp[5]]), f[cp[6]](o[cp[6]]), f[cp[7]](o[cp[7]]), f[cp[8]](o[cp[8]]), f[cp[9]](o[cp[9]])
913 end
914 end
915 end
916 end
917 end
918  
919  
920 function lib:PrintTable(args)
921 for k, v in args do
922 ChatFrame1:AddMessage(tostring(k) .. " = " .. tostring(v));
923 end
924 ChatFrame1:AddMessage("");
925 end
926  
927 -- Used to test the correcteness of ParserLib on different languages.
928 function lib:TestPatterns(sendToClients)
929  
930  
931 self:LoadEverything()
932  
933  
934 -- Creating the combat messages.
935 local testNumber = 123
936 local message
937 local messages = self:GetCompost():Acquire()
938 for patternName in self.patternTable do
939 messages[patternName] = self:GetCompost():Acquire()
940 messages[patternName].message = getglobal(patternName)
941 for i, v in self.patternTable[patternName] do
942 if i ~= "tc" and type(v) == "number" and v < 100 and i~=1 then
943 messages[patternName][v] = self:GetInfoFieldName(self.patternTable[patternName][1], i)
944 end
945 end
946 for i, v in ipairs(messages[patternName]) do
947 if string.find(v, "^amount") then
948 messages[patternName].message = string.gsub(messages[patternName].message, "%%%d?%$?d", testNumber, 1)
949 else
950 messages[patternName].message = string.gsub(messages[patternName].message, "%%%d?%$?s", string.upper(v), 1)
951 end
952 end
953 end
954  
955  
956 -- Begin the test.
957  
958 local info, msg
959 local startTime = GetTime()
960 local startMem = gcinfo()
961  
962 for _, event in self.supportedEvents do
963 for _, pattern in self:LoadPatternList(event) do
964 msg = messages[pattern].message
965 if sendToClients then self:OnEvent(event, msg) end
966 if self:ParseMessage(msg, event) then
967 info = self.info
968 for i, v in ipairs(messages[pattern]) do
969 if not info[v]
970 or ( string.find(v, "^amount") and info[v] ~= testNumber )
971 or ( not string.find(v, "^amount") and info[v] ~= string.upper(v) ) then
972 self:Print("Event: " .. event)
973 self:Print("Pattern: " .. pattern)
974 self:Print("Message: " .. msg)
975 self:PrintTable(messages[pattern])
976 self:PrintTable(info)
977 end
978 end
979 end
980 end
981 end
982  
983 self:Print( string.format("Test completed in %.4fs, memory cost %.2fKB.", GetTime() - startTime, gcinfo() - startMem) )
984  
985 self:GetCompost():Reclaim(messages, 1)
986  
987 end
988  
989 function lib:LoadEverything()
990  
991 -- Load all patterns and events.
992 for _, v in self.supportedEvents do
993 for _, w in self:LoadPatternList(v) do
994 if not self.patternTable[w] then
995 self.patternTable[w] = self:LoadPatternInfo(w)
996 end
997 end
998 end
999  
1000 end
1001  
1002 function lib:PrintTimers()
1003 if not self.timer then return end
1004  
1005 local total = 0
1006 for i in self.timer do
1007 total = total + self.timer[i]
1008 end
1009  
1010 if not self.timerIndex then
1011 self.timerIndex = {}
1012 for i in self.timer do
1013 table.insert(self.timerIndex, i)
1014 end
1015 table.sort(self.timerIndex)
1016 end
1017  
1018 DEFAULT_CHAT_FRAME:AddMessage("Time\t%\tDescription")
1019 for i, idx in self.timerIndex do
1020 DEFAULT_CHAT_FRAME:AddMessage(string.format("%.3f\t%.1f\t%s", self.timer[idx], 100*self.timer[idx]/total, idx) )
1021 end
1022  
1023 DEFAULT_CHAT_FRAME:AddMessage(total .. "\t100\tTotal")
1024 end
1025 -- Used to load eventTable elements on demand.
1026 function lib:LoadPatternList(eventName)
1027 local list
1028  
1029 --------------- Melee Hits ----------------
1030  
1031 if eventName == "CHAT_MSG_COMBAT_SELF_HITS" then
1032  
1033 if not self.eventTable["CHAT_MSG_COMBAT_SELF_HITS"] then
1034  
1035 self.eventTable["CHAT_MSG_COMBAT_SELF_HITS"] =
1036 self:LoadPatternCategoryTree(
1037 {
1038 "HitSelf",
1039 "EnvSelf",
1040 }
1041 )
1042  
1043 end
1044  
1045 list = self.eventTable["CHAT_MSG_COMBAT_SELF_HITS"]
1046  
1047 elseif eventName == "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS"
1048 or eventName == "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS"
1049 or eventName == "CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS"
1050 or eventName == "CHAT_MSG_COMBAT_PARTY_HITS"
1051 or eventName == "CHAT_MSG_COMBAT_PET_HITS" then
1052  
1053 if not self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS"] then
1054 self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS"] =
1055 self:LoadPatternCategoryTree( {
1056 "HitOtherOther",
1057 "EnvOther",
1058 } )
1059 end
1060 list = self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS"]
1061  
1062  
1063 elseif eventName == "CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"
1064 or eventName == "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS" then
1065  
1066 if not self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"] then
1067 self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"] =
1068 self:LoadPatternCategoryTree( {
1069 {
1070 "HitOtherOther",
1071 "HitOtherSelf",
1072 },
1073 "EnvOther",
1074 } )
1075 end
1076 list = self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS"]
1077  
1078  
1079  
1080 --------------- Melee Misses ----------------
1081  
1082  
1083  
1084 elseif eventName == "CHAT_MSG_COMBAT_SELF_MISSES" then
1085 if not self.eventTable["CHAT_MSG_COMBAT_SELF_MISSES"] then
1086 self.eventTable["CHAT_MSG_COMBAT_SELF_MISSES"] =
1087 self:LoadPatternCategoryTree( {
1088 "MissSelf",
1089 } )
1090 end
1091 list = self.eventTable["CHAT_MSG_COMBAT_SELF_MISSES"]
1092  
1093 elseif eventName == "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES"
1094 or eventName == "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES"
1095 or eventName == "CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES"
1096 or eventName == "CHAT_MSG_COMBAT_PARTY_MISSES"
1097 or eventName == "CHAT_MSG_COMBAT_PET_MISSES" then
1098  
1099 if not self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES"] then
1100 self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES"] =
1101 self:LoadPatternCategoryTree( {
1102 "MissOtherOther",
1103 } )
1104 end
1105  
1106 list = self.eventTable["CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES"]
1107  
1108  
1109 elseif eventName == "CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES"
1110 or eventName == "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES" then
1111  
1112 if not self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES"] then
1113 self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES"] =
1114 self:LoadPatternCategoryTree( {
1115 {
1116 "MissOtherOther",
1117 "MissOtherSelf",
1118 }
1119 } )
1120 end
1121  
1122 list = self.eventTable["CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES"]
1123  
1124 --------------- Spell Buffs ----------------
1125 elseif eventName == "CHAT_MSG_SPELL_SELF_BUFF" then
1126 if not self.eventTable["CHAT_MSG_SPELL_SELF_BUFF"] then
1127  
1128 if GetLocale() ~= "deDE" then
1129 self.eventTable["CHAT_MSG_SPELL_SELF_BUFF"] = self:LoadPatternCategoryTree(
1130 {
1131 "HealSelf",
1132 "EnchantSelf",
1133 "CastSelf",
1134 "PerformSelf",
1135 "DispelFailSelf",
1136 "SPELLCASTSELFSTART",
1137 "SPELLPERFORMSELFSTART",
1138 {
1139 "DrainSelf",
1140 "PowerGainSelf",
1141 "ExtraAttackSelf",
1142 },
1143 "SPELLSPLITDAMAGESELFOTHER",
1144 {
1145 "ProcResistSelf",
1146 "SpellMissSelf",
1147 }
1148 }
1149 )
1150  
1151 else
1152 self.eventTable["CHAT_MSG_SPELL_SELF_BUFF"] = self:LoadPatternCategoryTree(
1153 {
1154 "HealSelf",
1155 "CastSelf",
1156 "PerformSelf",
1157 "DispelFailSelf",
1158 "SPELLCASTSELFSTART",
1159 "SPELLPERFORMSELFSTART",
1160 {
1161 "DrainSelf",
1162 "PowerGainSelf",
1163 "ExtraAttackSelf",
1164 },
1165 "SPELLSPLITDAMAGESELFOTHER",
1166 {
1167 "ProcResistSelf",
1168 "SpellMissSelf",
1169 }
1170 }
1171 )
1172 end
1173  
1174 end
1175  
1176 list = self.eventTable["CHAT_MSG_SPELL_SELF_BUFF"]
1177  
1178  
1179 elseif eventName == "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF"
1180 or eventName == "CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF"
1181 or eventName == "CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF"
1182 or eventName == "CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF"
1183 or eventName == "CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"
1184 or eventName == "CHAT_MSG_SPELL_PARTY_BUFF"
1185 or eventName == "CHAT_MSG_SPELL_PET_BUFF" then
1186  
1187 if not self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"] then
1188  
1189 if GetLocale() ~= "deDE" then
1190 self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"] = self:LoadPatternCategoryTree(
1191 {
1192 {
1193 "HealOther",
1194 "PowerGainOther",
1195 "ExtraAttackOther",
1196 "DrainOther",
1197 },
1198 "SPELLCASTOTHERSTART",
1199 {
1200 "EnchantOther",
1201 "CastOther",
1202 "PerformOther",
1203 },
1204 "SPELLPERFORMOTHERSTART",
1205 "SpellMissOther",
1206 "ProcResistOther",
1207 "SplitDamageOther",
1208 "DispelFailOther",
1209 }
1210 )
1211  
1212 else -- Remove "EnchantOther" from German, since it's 100% ambiguous with SIMPLECASTOTHEROTHER, which is unsolvable.
1213 self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"] = self:LoadPatternCategoryTree(
1214 {
1215 {
1216 "HealOther",
1217 "PowerGainOther",
1218 "ExtraAttackOther",
1219 "DrainOther",
1220 },
1221 "SPELLCASTOTHERSTART",
1222 {
1223 "CastOther",
1224 "PerformOther",
1225 },
1226 "SPELLPERFORMOTHERSTART",
1227 "SpellMissOther",
1228 "ProcResistOther",
1229 "SplitDamageOther",
1230 "DispelFailOther",
1231 }
1232 )
1233 end
1234 end
1235  
1236 list = self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF"]
1237  
1238  
1239 --------------- Spell Damages ----------------
1240  
1241 elseif eventName == "CHAT_MSG_SPELL_SELF_DAMAGE" then
1242 if not self.eventTable["CHAT_MSG_SPELL_SELF_DAMAGE"] then
1243 self.eventTable["CHAT_MSG_SPELL_SELF_DAMAGE"] =
1244 self:LoadPatternCategoryTree( {
1245 "SpellHitSelf",
1246 {
1247 "CastSelf",
1248 "DurabilityDamageSelf",
1249 },
1250 "PerformSelf",
1251 "SpellMissSelf",
1252 "SPELLCASTSELFSTART",
1253 "SPELLPERFORMSELFSTART",
1254 "InterruptSelf",
1255 "DISPELFAILEDSELFOTHER",
1256 "ExtraAttackSelf"
1257 } )
1258  
1259 end
1260 list = self.eventTable["CHAT_MSG_SPELL_SELF_DAMAGE"]
1261  
1262  
1263 elseif eventName == "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE"
1264 or eventName == "CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE"
1265 or eventName == "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE"
1266 or eventName == "CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE"
1267 or eventName == "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"
1268 or eventName == "CHAT_MSG_SPELL_PARTY_DAMAGE"
1269 or eventName == "CHAT_MSG_SPELL_PET_DAMAGE" then
1270  
1271 if not self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"] then
1272 self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"] =
1273 self:LoadPatternCategoryTree( {
1274 "SpellHitOther",
1275 "SPELLCASTOTHERSTART",
1276 "SPELLPERFORMOTHERSTART",
1277 "DrainOther",
1278 "SpellMissOther",
1279 {
1280 "PROCRESISTOTHEROTHER",
1281 "PROCRESISTOTHERSELF",
1282 },
1283 "SplitDamageOther",
1284 {
1285 "CastOther",
1286 "InterruptOther",
1287 "DurabilityDamageOther",
1288 },
1289 "PerformOther",
1290 "ExtraAttackOther",
1291 {
1292 "DISPELFAILEDOTHEROTHER",
1293 "DISPELFAILEDOTHERSELF",
1294 },
1295 })
1296  
1297 end
1298 list = self.eventTable["CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE"]
1299  
1300  
1301 --------------- Periodic Buffs ----------------
1302  
1303 elseif eventName == "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS" then
1304  
1305 if not self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"] then
1306  
1307 self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"] =
1308 self:LoadPatternCategoryTree( {
1309 {
1310 "HotOther",
1311 "HotSelf",
1312 },
1313 {
1314 "BuffSelf",
1315 "BuffOther",
1316 "PowerGainOther",
1317 "PowerGainSelf",
1318 },
1319 "DrainSelf",
1320 "DotSelf", -- Don't think this will hapen but add it anyway.
1321 } )
1322 end
1323 list = self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"]
1324  
1325  
1326 elseif eventName == "CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS"
1327 or eventName == "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS"
1328 or eventName == "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"
1329 or eventName == "CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS" then
1330  
1331 if not self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"] then
1332 self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"] =
1333 self:LoadPatternCategoryTree( {
1334 {
1335 "HotOther",
1336 -- "DrainOther", -- Dont think this would happen but add it anyway.
1337 },
1338 {
1339 "BuffOther",
1340 "PowerGainOther",
1341 "DrainOther", -- When other players use Skull of Impending Doom.
1342 },
1343 "DotOther", -- Dont think this will happen but add anyway.
1344 "DebuffOther", -- Was fired on older WoW version.
1345 } )
1346 end
1347  
1348 list = self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"]
1349  
1350  
1351  
1352 --------------- Periodic Damages ----------------
1353  
1354 elseif eventName == "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE" then
1355 if not self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE"] then
1356  
1357 self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE"] =
1358 self:LoadPatternCategoryTree( {
1359 {
1360 "DotSelf",
1361 "DotOther",
1362 },
1363 {
1364 "DebuffSelf",
1365 "DebuffOther",
1366 },
1367 {
1368 "SPELLLOGABSORBOTHEROTHER",
1369 "SPELLLOGABSORBOTHERSELF",
1370 "SPELLLOGABSORBSELFSELF",
1371 "SPELLLOGABSORBSELFOTHER",
1372 },
1373 "DrainSelf",
1374 } )
1375 end
1376 list = self.eventTable["CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE"]
1377  
1378  
1379  
1380 elseif eventName == "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE"
1381 or eventName == "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE"
1382 or eventName == "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"
1383 or eventName == "CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE" then
1384  
1385 if not self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"] then
1386 self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"] =
1387 self:LoadPatternCategoryTree( {
1388 "DebuffOther",
1389 "DotOther",
1390 {
1391 "SPELLLOGABSORBOTHEROTHER",
1392 "SPELLLOGABSORBSELFOTHER",
1393 },
1394 "DrainOther",
1395 {
1396 "PowerGainOther",
1397 "BuffOther", -- Was fired on older WoW version.
1398 }
1399 } )
1400 end
1401 list = self.eventTable["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"]
1402  
1403 --------------- Damage Shields ----------------
1404  
1405  
1406 elseif eventName == "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF" then
1407 if not self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"] then
1408 self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"] = {
1409 "SPELLRESISTOTHEROTHER",
1410 "SPELLRESISTSELFOTHER",
1411 "DAMAGESHIELDOTHEROTHER",
1412 "DAMAGESHIELDSELFOTHER",
1413 }
1414 table.sort(self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"] , PatternCompare)
1415 end
1416 list = self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF"]
1417  
1418 elseif eventName == "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS" then
1419 if not self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"] then
1420 self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"] = {
1421 "SPELLRESISTOTHEROTHER",
1422 "SPELLRESISTOTHERSELF",
1423 "DAMAGESHIELDOTHEROTHER",
1424 "DAMAGESHIELDOTHERSELF",
1425 }
1426 table.sort(self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"] , PatternCompare)
1427 end
1428 list = self.eventTable["CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS"]
1429  
1430  
1431  
1432 --------------- Auras ----------------
1433  
1434 elseif eventName == "CHAT_MSG_SPELL_AURA_GONE_PARTY"
1435 or eventName == "CHAT_MSG_SPELL_AURA_GONE_OTHER" then
1436  
1437 if not self.eventTable["CHAT_MSG_SPELL_AURA_GONE_OTHER"] then
1438 self.eventTable["CHAT_MSG_SPELL_AURA_GONE_OTHER"] = {
1439 "AURAREMOVEDOTHER",
1440 }
1441 table.sort(self.eventTable["CHAT_MSG_SPELL_AURA_GONE_OTHER"] , PatternCompare)
1442 end
1443 list = self.eventTable["CHAT_MSG_SPELL_AURA_GONE_OTHER"]
1444  
1445 elseif eventName == "CHAT_MSG_SPELL_AURA_GONE_SELF" then
1446  
1447 if not self.eventTable["CHAT_MSG_SPELL_AURA_GONE_SELF"] then
1448 self.eventTable["CHAT_MSG_SPELL_AURA_GONE_SELF"] = {
1449 "AURAREMOVEDOTHER",
1450 "AURAREMOVEDSELF",
1451 }
1452 table.sort(self.eventTable["CHAT_MSG_SPELL_AURA_GONE_SELF"] , PatternCompare)
1453 end
1454 list = self.eventTable["CHAT_MSG_SPELL_AURA_GONE_SELF"]
1455  
1456 elseif eventName == "CHAT_MSG_SPELL_BREAK_AURA" then
1457  
1458 if not self.eventTable["CHAT_MSG_SPELL_BREAK_AURA"] then
1459 self.eventTable["CHAT_MSG_SPELL_BREAK_AURA"] = {
1460 "AURADISPELSELF",
1461 "AURADISPELOTHER",
1462 }
1463 table.sort(self.eventTable["CHAT_MSG_SPELL_BREAK_AURA"] , PatternCompare)
1464 end
1465 list = self.eventTable["CHAT_MSG_SPELL_BREAK_AURA"]
1466  
1467  
1468  
1469 elseif eventName == "CHAT_MSG_SPELL_ITEM_ENCHANTMENTS" then
1470  
1471 if not self.eventTable["CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"] then
1472 self.eventTable["CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"] = {
1473 "ITEMENCHANTMENTADDSELFSELF",
1474 "ITEMENCHANTMENTADDSELFOTHER",
1475 "ITEMENCHANTMENTADDOTHEROTHER",
1476 "ITEMENCHANTMENTADDOTHERSELF",
1477 }
1478 table.sort(self.eventTable["CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"] , PatternCompare)
1479 end
1480 list = self.eventTable["CHAT_MSG_SPELL_ITEM_ENCHANTMENTS"]
1481  
1482 --------------- Trade Skills ----------------
1483  
1484  
1485 elseif eventName == "CHAT_MSG_SPELL_TRADESKILLS" then
1486 if not self.eventTable["CHAT_MSG_SPELL_TRADESKILLS"] then
1487 self.eventTable["CHAT_MSG_SPELL_TRADESKILLS"] = {
1488 "TRADESKILL_LOG_FIRSTPERSON",
1489 "TRADESKILL_LOG_THIRDPERSON",
1490 "FEEDPET_LOG_FIRSTPERSON",
1491 "FEEDPET_LOG_THIRDPERSON",
1492 }
1493 table.sort(self.eventTable["CHAT_MSG_SPELL_TRADESKILLS"], PatternCompare )
1494 end
1495 list = self.eventTable["CHAT_MSG_SPELL_TRADESKILLS"]
1496  
1497 elseif eventName == "CHAT_MSG_SPELL_FAILED_LOCALPLAYER" then
1498  
1499 if not self.eventTable["CHAT_MSG_SPELL_FAILED_LOCALPLAYER"] then
1500 self.eventTable["CHAT_MSG_SPELL_FAILED_LOCALPLAYER"] = {
1501 "SPELLFAILPERFORMSELF",
1502 "SPELLFAILCASTSELF",
1503 }
1504 table.sort(self.eventTable["CHAT_MSG_SPELL_FAILED_LOCALPLAYER"], PatternCompare)
1505 end
1506 list = self.eventTable["CHAT_MSG_SPELL_FAILED_LOCALPLAYER"]
1507  
1508  
1509 elseif eventName == "CHAT_MSG_COMBAT_FACTION_CHANGE" then
1510  
1511 if not self.eventTable["CHAT_MSG_COMBAT_FACTION_CHANGE"] then
1512  
1513 self.eventTable["CHAT_MSG_COMBAT_FACTION_CHANGE"] = {
1514 "FACTION_STANDING_CHANGED",
1515 "FACTION_STANDING_DECREASED",
1516 "FACTION_STANDING_INCREASED",
1517 }
1518 table.sort(self.eventTable["CHAT_MSG_COMBAT_FACTION_CHANGE"] , PatternCompare)
1519 end
1520 list = self.eventTable["CHAT_MSG_COMBAT_FACTION_CHANGE"]
1521  
1522 elseif eventName == "CHAT_MSG_COMBAT_HONOR_GAIN" then
1523  
1524 if not self.eventTable["CHAT_MSG_COMBAT_HONOR_GAIN"] then
1525 self.eventTable["CHAT_MSG_COMBAT_HONOR_GAIN"] = {
1526 "COMBATLOG_HONORAWARD",
1527 "COMBATLOG_HONORGAIN",
1528 "COMBATLOG_DISHONORGAIN",
1529 }
1530 table.sort(self.eventTable["CHAT_MSG_COMBAT_HONOR_GAIN"] , PatternCompare)
1531 end
1532 list = self.eventTable["CHAT_MSG_COMBAT_HONOR_GAIN"]
1533 elseif eventName == "CHAT_MSG_COMBAT_XP_GAIN" then
1534  
1535 if not self.eventTable["CHAT_MSG_COMBAT_XP_GAIN"] then
1536 self.eventTable["CHAT_MSG_COMBAT_XP_GAIN"] = {
1537 "COMBATLOG_XPGAIN",
1538 "COMBATLOG_XPGAIN_EXHAUSTION1",
1539 "COMBATLOG_XPGAIN_EXHAUSTION1_GROUP",
1540 "COMBATLOG_XPGAIN_EXHAUSTION1_RAID",
1541 "COMBATLOG_XPGAIN_EXHAUSTION2",
1542 "COMBATLOG_XPGAIN_EXHAUSTION2_GROUP",
1543 "COMBATLOG_XPGAIN_EXHAUSTION2_RAID",
1544 "COMBATLOG_XPGAIN_EXHAUSTION4",
1545 "COMBATLOG_XPGAIN_EXHAUSTION4_GROUP",
1546 "COMBATLOG_XPGAIN_EXHAUSTION4_RAID",
1547 "COMBATLOG_XPGAIN_EXHAUSTION5",
1548 "COMBATLOG_XPGAIN_EXHAUSTION5_GROUP",
1549 "COMBATLOG_XPGAIN_EXHAUSTION5_RAID",
1550 "COMBATLOG_XPGAIN_FIRSTPERSON",
1551 "COMBATLOG_XPGAIN_FIRSTPERSON_GROUP",
1552 "COMBATLOG_XPGAIN_FIRSTPERSON_RAID",
1553 "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED",
1554 "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED_GROUP",
1555 "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED_RAID",
1556 "COMBATLOG_XPLOSS_FIRSTPERSON_UNNAMED",
1557 }
1558 table.sort(self.eventTable["CHAT_MSG_COMBAT_XP_GAIN"] , PatternCompare)
1559 end
1560 list = self.eventTable["CHAT_MSG_COMBAT_XP_GAIN"]
1561  
1562 elseif eventName == "CHAT_MSG_COMBAT_FRIENDLY_DEATH"
1563 or eventName == "CHAT_MSG_COMBAT_HOSTILE_DEATH" then
1564  
1565 if not self.eventTable["CHAT_MSG_COMBAT_HOSTILE_DEATH"] then
1566 self.eventTable["CHAT_MSG_COMBAT_HOSTILE_DEATH"] = {
1567 "SELFKILLOTHER",
1568 "PARTYKILLOTHER",
1569 "UNITDESTROYEDOTHER",
1570 "UNITDIESOTHER",
1571 "UNITDIESSELF",
1572 }
1573  
1574 table.sort(self.eventTable["CHAT_MSG_COMBAT_HOSTILE_DEATH"] , PatternCompare)
1575 end
1576 list = self.eventTable["CHAT_MSG_COMBAT_HOSTILE_DEATH"]
1577  
1578 end
1579  
1580  
1581 if not list then
1582 -- self:Print(string.format("Event '%s' not found.", eventName), 1, 0,0); -- debug
1583 end
1584  
1585 return list
1586  
1587 end
1588  
1589 function lib:LoadPatternCategory(category)
1590  
1591 local list
1592  
1593 if category == "AuraChange" then list = {
1594 "AURACHANGEDOTHER",
1595 "AURACHANGEDSELF",
1596 }
1597 elseif category == "AuraDispel" then list = {
1598 "AURADISPELOTHER",
1599 "AURADISPELSELF",
1600 }
1601 elseif category == "BuffOther" then list = {
1602 "AURAADDEDOTHERHELPFUL",
1603 "AURAAPPLICATIONADDEDOTHERHELPFUL",
1604 }
1605 elseif category == "BuffSelf" then list = {
1606 "AURAADDEDSELFHELPFUL",
1607 "AURAAPPLICATIONADDEDSELFHELPFUL",
1608 }
1609 elseif category == "CastOther" then list = {
1610 "SIMPLECASTOTHEROTHER",
1611 "SIMPLECASTOTHERSELF",
1612 "SPELLTERSE_OTHER",
1613 }
1614 elseif category == "CastSelf" then list = {
1615 "SIMPLECASTSELFOTHER",
1616 "SIMPLECASTSELFSELF",
1617 "SPELLTERSE_SELF",
1618 }
1619 elseif category == "DebuffOther" then list = {
1620 "AURAADDEDOTHERHARMFUL",
1621 "AURAAPPLICATIONADDEDOTHERHARMFUL",
1622 }
1623 elseif category == "DebuffSelf" then list = {
1624 "AURAADDEDSELFHARMFUL",
1625 "AURAAPPLICATIONADDEDSELFHARMFUL",
1626 }
1627 elseif category == "DispelFailOther" then list = {
1628 "DISPELFAILEDOTHEROTHER",
1629 "DISPELFAILEDOTHERSELF",
1630  
1631 }
1632 elseif category == "DispelFailSelf" then list = {
1633 "DISPELFAILEDSELFOTHER",
1634 "DISPELFAILEDSELFSELF",
1635 }
1636 elseif category == "DmgShieldOther" then list = {
1637 "DAMAGESHIELDOTHEROTHER",
1638 "DAMAGESHIELDOTHERSELF",
1639 }
1640 elseif category == "DmgShieldSelf" then list = {
1641 "DAMAGESHIELDSELFOTHER",
1642 }
1643 elseif category == "DurabilityDamageSelf" then list = {
1644 "SPELLDURABILITYDAMAGEALLSELFOTHER",
1645 "SPELLDURABILITYDAMAGESELFOTHER",
1646 }
1647 elseif category == "DurabilityDamageOther" then list = {
1648 "SPELLDURABILITYDAMAGEALLOTHEROTHER",
1649 "SPELLDURABILITYDAMAGEALLOTHERSELF",
1650 "SPELLDURABILITYDAMAGEOTHEROTHER",
1651 "SPELLDURABILITYDAMAGEOTHERSELF",
1652 }
1653 elseif category == "EnchantOther" then list = {
1654 "ITEMENCHANTMENTADDOTHEROTHER",
1655 "ITEMENCHANTMENTADDOTHERSELF",
1656 }
1657 elseif category == "EnchantSelf" then list = {
1658 "ITEMENCHANTMENTADDSELFOTHER",
1659 "ITEMENCHANTMENTADDSELFSELF",
1660 }
1661 elseif category == "ExtraAttackOther" then list = {
1662 "SPELLEXTRAATTACKSOTHER",
1663 "SPELLEXTRAATTACKSOTHER_SINGULAR",
1664 }
1665 elseif category == "ExtraAttackSelf" then list = {
1666 "SPELLEXTRAATTACKSSELF",
1667 "SPELLEXTRAATTACKSSELF_SINGULAR",
1668 }
1669 elseif category == "Fade" then list = {
1670 "AURAREMOVEDOTHER",
1671 "AURAREMOVEDSELF",
1672 }
1673 elseif category == "HealOther" then list = {
1674 "HEALEDCRITOTHEROTHER",
1675 "HEALEDCRITOTHERSELF",
1676 "HEALEDOTHEROTHER",
1677 "HEALEDOTHERSELF",
1678 }
1679 elseif category == "HealSelf" then list = {
1680 "HEALEDCRITSELFOTHER",
1681 "HEALEDCRITSELFSELF",
1682 "HEALEDSELFOTHER",
1683 "HEALEDSELFSELF",
1684 }
1685 elseif category == "HitOtherOther" then list = {
1686 "COMBATHITCRITOTHEROTHER",
1687 "COMBATHITCRITSCHOOLOTHEROTHER",
1688 "COMBATHITOTHEROTHER",
1689 "COMBATHITSCHOOLOTHEROTHER",
1690 }
1691 elseif category == "HitOtherSelf" then list = {
1692  
1693 "COMBATHITCRITOTHERSELF",
1694 "COMBATHITCRITSCHOOLOTHERSELF",
1695 "COMBATHITOTHERSELF",
1696 "COMBATHITSCHOOLOTHERSELF",
1697 }
1698 elseif category == "HitSelf" then list = {
1699 "COMBATHITSCHOOLSELFOTHER",
1700 "COMBATHITSELFOTHER",
1701 "COMBATHITCRITSCHOOLSELFOTHER",
1702 "COMBATHITCRITSELFOTHER",
1703 }
1704 elseif category == "MissOtherOther" then list = {
1705 "MISSEDOTHEROTHER",
1706 "VSABSORBOTHEROTHER",
1707 "VSBLOCKOTHEROTHER",
1708 "VSDEFLECTOTHEROTHER",
1709 "VSDODGEOTHEROTHER",
1710 "VSEVADEOTHEROTHER",
1711 "VSIMMUNEOTHEROTHER",
1712 "VSPARRYOTHEROTHER",
1713 "VSRESISTOTHEROTHER",
1714 "IMMUNEDAMAGECLASSOTHEROTHER",
1715 "IMMUNEOTHEROTHER",
1716  
1717 }
1718 elseif category == "MissOtherSelf" then list = {
1719 "MISSEDOTHERSELF",
1720 "VSABSORBOTHERSELF",
1721 "VSBLOCKOTHERSELF",
1722 "VSDEFLECTOTHERSELF",
1723 "VSDODGEOTHERSELF",
1724 "VSEVADEOTHERSELF",
1725 "VSIMMUNEOTHERSELF",
1726 "VSPARRYOTHERSELF",
1727 "VSRESISTOTHERSELF",
1728 "IMMUNEDAMAGECLASSOTHERSELF",
1729 "IMMUNEOTHERSELF",
1730 }
1731 elseif category == "MissSelf" then list = {
1732 "MISSEDSELFOTHER",
1733 "VSABSORBSELFOTHER",
1734 "VSBLOCKSELFOTHER",
1735 "VSDEFLECTSELFOTHER",
1736 "VSDODGESELFOTHER",
1737 "VSEVADESELFOTHER",
1738 "VSIMMUNESELFOTHER",
1739 "VSPARRYSELFOTHER",
1740 "VSRESISTSELFOTHER",
1741 "IMMUNEDAMAGECLASSSELFOTHER",
1742 "IMMUNESELFOTHER",
1743 "IMMUNESELFSELF",
1744 }
1745 elseif category == "PowerGainOther" then list = {
1746 "POWERGAINOTHEROTHER",
1747 "POWERGAINOTHERSELF",
1748 }
1749 elseif category == "PerformOther" then list = {
1750 "OPEN_LOCK_OTHER",
1751 "SIMPLEPERFORMOTHEROTHER",
1752 "SIMPLEPERFORMOTHERSELF",
1753 "SPELLTERSEPERFORM_OTHER",
1754 }
1755 elseif category == "PerformSelf" then list = {
1756 "OPEN_LOCK_SELF",
1757 "SIMPLEPERFORMSELFOTHER",
1758 "SIMPLEPERFORMSELFSELF",
1759 "SPELLTERSEPERFORM_SELF",
1760 }
1761 elseif category == "ProcResistOther" then list = {
1762 "PROCRESISTOTHEROTHER",
1763 "PROCRESISTOTHERSELF",
1764 }
1765 elseif category == "ProcResistSelf" then list = {
1766 "PROCRESISTSELFOTHER",
1767 "PROCRESISTSELFSELF",
1768 }
1769 elseif category == "EnvOther" then list = {
1770 "VSENVIRONMENTALDAMAGE_DROWNING_OTHER",
1771 "VSENVIRONMENTALDAMAGE_FALLING_OTHER",
1772 "VSENVIRONMENTALDAMAGE_FATIGUE_OTHER",
1773 "VSENVIRONMENTALDAMAGE_FIRE_OTHER",
1774 "VSENVIRONMENTALDAMAGE_LAVA_OTHER",
1775 "VSENVIRONMENTALDAMAGE_SLIME_OTHER",
1776 }
1777 elseif category == "EnvSelf" then list = {
1778 "VSENVIRONMENTALDAMAGE_DROWNING_SELF",
1779 "VSENVIRONMENTALDAMAGE_FALLING_SELF",
1780 "VSENVIRONMENTALDAMAGE_FATIGUE_SELF",
1781 "VSENVIRONMENTALDAMAGE_FIRE_SELF",
1782 "VSENVIRONMENTALDAMAGE_LAVA_SELF",
1783 "VSENVIRONMENTALDAMAGE_SLIME_SELF",
1784 }
1785 -- HoT effects on others. (not casted by others)
1786 elseif category == "HotOther" then list = {
1787 "PERIODICAURAHEALOTHEROTHER",
1788 "PERIODICAURAHEALSELFOTHER",
1789 }
1790 -- HoT effects on you. (not casted by you)
1791 elseif category == "HotSelf" then list = {
1792 "PERIODICAURAHEALSELFSELF",
1793 "PERIODICAURAHEALOTHERSELF",
1794 }
1795 elseif category == "PowerGainSelf" then list = {
1796 "POWERGAINSELFSELF",
1797 "POWERGAINSELFOTHER",
1798 }
1799 elseif category == "BuffOther" then list = {
1800 "AURAAPPLICATIONADDEDOTHERHELPFUL",
1801 "AURAADDEDOTHERHELPFUL",
1802 }
1803 elseif category == "BuffSelf" then list = {
1804 "AURAADDEDSELFHELPFUL",
1805 "AURAAPPLICATIONADDEDSELFHELPFUL",
1806 }
1807 elseif category == "DrainSelf" then list = {
1808 "SPELLPOWERLEECHSELFOTHER",
1809 "SPELLPOWERDRAINSELFOTHER",
1810 "SPELLPOWERDRAINSELFSELF",
1811 }
1812 elseif category == "DrainOther" then list = {
1813 "SPELLPOWERLEECHOTHEROTHER",
1814 "SPELLPOWERLEECHOTHERSELF",
1815 "SPELLPOWERDRAINOTHEROTHER",
1816 "SPELLPOWERDRAINOTHERSELF",
1817 }
1818 -- DoT effects on others (not casted by others)
1819 elseif category == "DotOther" then list = {
1820 "PERIODICAURADAMAGEOTHEROTHER",
1821 "PERIODICAURADAMAGESELFOTHER",
1822 }
1823 -- DoT effects on you (not casted by you)
1824 elseif category == "DotSelf" then list = {
1825 "PERIODICAURADAMAGEOTHERSELF",
1826 "PERIODICAURADAMAGESELFSELF",
1827 }
1828 elseif category == "SpellHitOther" then list = {
1829 "SPELLLOGCRITOTHEROTHER",
1830 "SPELLLOGCRITOTHERSELF",
1831 "SPELLLOGCRITSCHOOLOTHEROTHER",
1832 "SPELLLOGCRITSCHOOLOTHERSELF",
1833 "SPELLLOGOTHEROTHER",
1834 "SPELLLOGOTHERSELF",
1835 "SPELLLOGSCHOOLOTHEROTHER",
1836 "SPELLLOGSCHOOLOTHERSELF",
1837 }
1838 elseif category == "SpellHitSelf" then list = {
1839 "SPELLLOGCRITSELFOTHER",
1840 "SPELLLOGCRITSELFSELF",
1841 "SPELLLOGCRITSCHOOLSELFOTHER",
1842 "SPELLLOGCRITSCHOOLSELFSELF",
1843 "SPELLLOGSELFOTHER",
1844 "SPELLLOGSELFSELF",
1845 "SPELLLOGSCHOOLSELFOTHER",
1846 "SPELLLOGSCHOOLSELFSELF",
1847 }
1848 elseif category == "SpellMissSelf" then list = {
1849 "IMMUNESPELLSELFOTHER",
1850 "IMMUNESPELLSELFSELF",
1851 "SPELLBLOCKEDSELFOTHER",
1852 "SPELLDEFLECTEDSELFOTHER",
1853 "SPELLDEFLECTEDSELFSELF",
1854 "SPELLDODGEDSELFOTHER",
1855 "SPELLDODGEDSELFSELF",
1856 "SPELLEVADEDSELFOTHER",
1857 "SPELLEVADEDSELFSELF",
1858 "SPELLIMMUNESELFOTHER",
1859 "SPELLIMMUNESELFSELF",
1860 "SPELLLOGABSORBSELFOTHER",
1861 "SPELLLOGABSORBSELFSELF",
1862 "SPELLMISSSELFOTHER",
1863 "SPELLMISSSELFSELF",
1864 "SPELLPARRIEDSELFOTHER",
1865 "SPELLPARRIEDSELFSELF",
1866 "SPELLREFLECTSELFOTHER",
1867 "SPELLREFLECTSELFSELF",
1868 "SPELLRESISTSELFOTHER",
1869 "SPELLRESISTSELFSELF",
1870 }
1871 elseif category == "SpellMissOther" then list = {
1872 "IMMUNESPELLOTHEROTHER",
1873 "IMMUNESPELLOTHERSELF",
1874 "SPELLBLOCKEDOTHEROTHER",
1875 "SPELLBLOCKEDOTHERSELF",
1876 "SPELLDODGEDOTHEROTHER",
1877 "SPELLDODGEDOTHERSELF",
1878 "SPELLDEFLECTEDOTHEROTHER",
1879 "SPELLDEFLECTEDOTHERSELF",
1880 "SPELLEVADEDOTHEROTHER",
1881 "SPELLEVADEDOTHERSELF",
1882 "SPELLIMMUNEOTHEROTHER",
1883 "SPELLIMMUNEOTHERSELF",
1884 "SPELLLOGABSORBOTHEROTHER",
1885 "SPELLLOGABSORBOTHERSELF",
1886 "SPELLMISSOTHEROTHER",
1887 "SPELLMISSOTHERSELF",
1888 "SPELLPARRIEDOTHEROTHER",
1889 "SPELLPARRIEDOTHERSELF",
1890 "SPELLREFLECTOTHEROTHER",
1891 "SPELLREFLECTOTHERSELF",
1892 "SPELLRESISTOTHEROTHER",
1893 "SPELLRESISTOTHERSELF",
1894 }
1895 elseif category == "InterruptOther" then list = {
1896 "SPELLINTERRUPTOTHEROTHER",
1897 "SPELLINTERRUPTOTHERSELF",
1898 }
1899 elseif category == "InterruptSelf" then list = {
1900 "SPELLINTERRUPTSELFOTHER",
1901 }
1902 elseif category == "SplitDamageOther" then list = {
1903 "SPELLSPLITDAMAGEOTHEROTHER",
1904 "SPELLSPLITDAMAGEOTHERSELF",
1905 }
1906 else return { category }
1907 end
1908  
1909 return list
1910  
1911 end
1912  
1913 -- Load categories recursively. First layer will not be sorted.
1914 function lib:LoadPatternCategoryTree(catTree, reSort)
1915 if type(catTree) ~= "table" then return end
1916  
1917 local resultList = {}
1918 local list
1919  
1920 for i, v in catTree do
1921  
1922 if type(v) == "table" then
1923 list = self:LoadPatternCategoryTree(v, true)
1924 else -- should be string.
1925 list = self:LoadPatternCategory(v)
1926 table.sort(list, PatternCompare)
1927 end
1928  
1929 for j, w in list do
1930 table.insert(resultList, w)
1931 end
1932  
1933 end
1934  
1935 if reSort then
1936 table.sort(resultList, PatternCompare)
1937 end
1938  
1939 return resultList
1940  
1941  
1942 end
1943  
1944 -- Used to load patternTable elements on demand.
1945 function lib:LoadPatternInfo(patternName)
1946  
1947 local patternInfo
1948  
1949 if patternName == "AURAADDEDOTHERHELPFUL" then
1950 patternInfo = { "buff", 1, 2, nil, }
1951 elseif patternName == "AURAADDEDSELFHELPFUL" then
1952 patternInfo = { "buff", ParserLib_SELF, 1, nil, }
1953 elseif patternName == "AURAAPPLICATIONADDEDOTHERHELPFUL" then
1954 patternInfo = { "buff", 1, 2, 3, }
1955 elseif patternName == "AURAAPPLICATIONADDEDSELFHELPFUL" then
1956 patternInfo = { "buff", ParserLib_SELF, 1, 2, }
1957  
1958 elseif patternName == "OPEN_LOCK_OTHER" then
1959 patternInfo = { "cast", 1, 2, 3, nil, nil, }
1960 elseif patternName == "OPEN_LOCK_SELF" then
1961 patternInfo = { "cast", ParserLib_SELF, 1, 2, nil, nil, }
1962 elseif patternName == "SIMPLECASTOTHEROTHER" then
1963 patternInfo = { "cast", 1, 2, 3, nil, nil, }
1964 elseif patternName == "SIMPLECASTOTHERSELF" then
1965 patternInfo = { "cast", 1, 2, ParserLib_SELF, nil, nil, }
1966 elseif patternName == "SIMPLECASTSELFOTHER" then
1967 patternInfo = { "cast", ParserLib_SELF, 1, 2, nil, nil, }
1968 elseif patternName == "SIMPLECASTSELFSELF" then
1969 patternInfo = { "cast", ParserLib_SELF, 1, ParserLib_SELF, nil, nil, }
1970 elseif patternName == "SIMPLEPERFORMOTHEROTHER" then
1971 patternInfo = { "cast", 1, 2, 3, nil, nil, }
1972 elseif patternName == "SIMPLEPERFORMOTHERSELF" then
1973 patternInfo = { "cast", 1, 2, ParserLib_SELF, nil, nil, }
1974 elseif patternName == "SIMPLEPERFORMSELFOTHER" then
1975 patternInfo = { "cast", ParserLib_SELF, 1, 2, nil, nil, }
1976 elseif patternName == "SIMPLEPERFORMSELFSELF" then
1977 patternInfo = { "cast", ParserLib_SELF, 1, ParserLib_SELF, nil, nil, }
1978 elseif patternName == "SPELLCASTOTHERSTART" then
1979 patternInfo = { "cast", 1, 2, nil, true, nil, }
1980 elseif patternName == "SPELLCASTSELFSTART" then
1981 patternInfo = { "cast", ParserLib_SELF, 1, nil, true, nil, }
1982 elseif patternName == "SPELLPERFORMOTHERSTART" then
1983 patternInfo = { "cast", 1, 2, nil, true, nil, }
1984 elseif patternName == "SPELLPERFORMSELFSTART" then
1985 patternInfo = { "cast", ParserLib_SELF, 1, nil, true, nil, }
1986 elseif patternName == "SPELLTERSEPERFORM_OTHER" then
1987 patternInfo = { "cast", 1, 2, nil, nil, nil, }
1988 elseif patternName == "SPELLTERSEPERFORM_SELF" then
1989 patternInfo = { "cast", ParserLib_SELF, 1, nil, nil, nil, }
1990 elseif patternName == "SPELLTERSE_OTHER" then
1991 patternInfo = { "cast", 1, 2, nil, nil, nil, }
1992 elseif patternName == "SPELLTERSE_SELF" then
1993 patternInfo = { "cast", ParserLib_SELF, 1, nil, nil, nil, }
1994  
1995 elseif patternName == "TRADESKILL_LOG_FIRSTPERSON" then
1996 patternInfo = { "create", ParserLib_SELF, 1, }
1997 elseif patternName == "TRADESKILL_LOG_THIRDPERSON" then
1998 patternInfo = { "create", 1, 2, }
1999  
2000 elseif patternName == "PARTYKILLOTHER" then
2001 patternInfo = { "death", 1, 2, nil, }
2002 elseif patternName == "SELFKILLOTHER" then
2003 patternInfo = { "death", 1, ParserLib_SELF, nil, }
2004 elseif patternName == "UNITDESTROYEDOTHER" then
2005 patternInfo = { "death", 1, nil, true, }
2006 elseif patternName == "UNITDIESOTHER" then
2007 patternInfo = { "death", 1, nil, nil, }
2008 elseif patternName == "UNITDIESSELF" then
2009 patternInfo = { "death", ParserLib_SELF, nil, nil, }
2010  
2011 elseif patternName == "AURAADDEDOTHERHARMFUL" then
2012 patternInfo = { "debuff", 1, 2, nil, }
2013 elseif patternName == "AURAADDEDSELFHARMFUL" then
2014 patternInfo = { "debuff", ParserLib_SELF, 1, nil, }
2015 elseif patternName == "AURAAPPLICATIONADDEDOTHERHARMFUL" then
2016 patternInfo = { "debuff", 1, 2, 3, }
2017 elseif patternName == "AURAAPPLICATIONADDEDSELFHARMFUL" then
2018 patternInfo = { "debuff", ParserLib_SELF, 1, 2, }
2019  
2020 elseif patternName == "AURADISPELOTHER" then
2021 patternInfo = { "dispel", 1, 2, nil, nil, }
2022 elseif patternName == "AURADISPELSELF" then
2023 patternInfo = { "dispel", ParserLib_SELF, 1, nil, nil, }
2024 elseif patternName == "DISPELFAILEDOTHEROTHER" then
2025 patternInfo = { "dispel", 2, 3, 1, true, }
2026 elseif patternName == "DISPELFAILEDOTHERSELF" then
2027 patternInfo = { "dispel", ParserLib_SELF, 2, 1, true, }
2028 elseif patternName == "DISPELFAILEDSELFOTHER" then
2029 patternInfo = { "dispel", 1, 2, ParserLib_SELF, true, }
2030 elseif patternName == "DISPELFAILEDSELFSELF" then
2031 patternInfo = { "dispel", ParserLib_SELF, 1, ParserLib_SELF, true, }
2032  
2033 elseif patternName == "SPELLPOWERDRAINOTHEROTHER" then
2034 patternInfo = { "drain", 1, 5, 2, 3, 4, }
2035 elseif patternName == "SPELLPOWERDRAINOTHERSELF" then
2036 patternInfo = { "drain", 1, ParserLib_SELF, 2, 3, 4, }
2037 elseif patternName == "SPELLPOWERDRAINSELFOTHER" then
2038 patternInfo = { "drain", ParserLib_SELF, 4, 1, 2, 3, }
2039 elseif patternName == "SPELLPOWERDRAINSELFSELF" then
2040 patternInfo = { "drain", ParserLib_SELF, ParserLib_SELF, 1, 2, 3, }
2041  
2042 elseif patternName == "SPELLDURABILITYDAMAGEALLOTHEROTHER" then
2043 patternInfo = { "durability", 1, 2, 3, nil, }
2044 elseif patternName == "SPELLDURABILITYDAMAGEALLOTHERSELF" then
2045 patternInfo = { "durability", 1, 2, ParserLib_SELF, nil, }
2046 elseif patternName == "SPELLDURABILITYDAMAGEALLSELFOTHER" then
2047 patternInfo = { "durability", ParserLib_SELF, 1, 2, nil, }
2048 elseif patternName == "SPELLDURABILITYDAMAGEOTHEROTHER" then
2049 patternInfo = { "durability", 1, 2, 3, 4, }
2050 elseif patternName == "SPELLDURABILITYDAMAGEOTHERSELF" then
2051 patternInfo = { "durability", 1, 2, ParserLib_SELF, 3, }
2052 elseif patternName == "SPELLDURABILITYDAMAGESELFOTHER" then
2053 patternInfo = { "durability", ParserLib_SELF, 1, 2, 3, }
2054  
2055 elseif patternName == "ITEMENCHANTMENTADDOTHEROTHER" then
2056 patternInfo = { "enchant", 1, 3, 2, 4, }
2057 elseif patternName == "ITEMENCHANTMENTADDOTHERSELF" then
2058 patternInfo = { "enchant", 1, ParserLib_SELF, 2, 3, }
2059 elseif patternName == "ITEMENCHANTMENTADDSELFOTHER" then
2060 patternInfo = { "enchant", ParserLib_SELF, 2, 1, 3, }
2061 elseif patternName == "ITEMENCHANTMENTADDSELFSELF" then
2062 patternInfo = { "enchant", ParserLib_SELF, ParserLib_SELF, 1, 2, }
2063  
2064 elseif patternName == "VSENVIRONMENTALDAMAGE_DROWNING_OTHER" then
2065 patternInfo = { "environment", 1, 2, "drown", }
2066 elseif patternName == "VSENVIRONMENTALDAMAGE_DROWNING_SELF" then
2067 patternInfo = { "environment", ParserLib_SELF, 1, "drown", }
2068 elseif patternName == "VSENVIRONMENTALDAMAGE_FALLING_OTHER" then
2069 patternInfo = { "environment", 1, 2, "fall", }
2070 elseif patternName == "VSENVIRONMENTALDAMAGE_FALLING_SELF" then
2071 patternInfo = { "environment", ParserLib_SELF, 1, "fall", }
2072 elseif patternName == "VSENVIRONMENTALDAMAGE_FATIGUE_OTHER" then
2073 patternInfo = { "environment", 1, 2, "exhaust", }
2074 elseif patternName == "VSENVIRONMENTALDAMAGE_FATIGUE_SELF" then
2075 patternInfo = { "environment", ParserLib_SELF, 1, "exhaust", }
2076 elseif patternName == "VSENVIRONMENTALDAMAGE_FIRE_OTHER" then
2077 patternInfo = { "environment", 1, 2, "fire", }
2078 elseif patternName == "VSENVIRONMENTALDAMAGE_FIRE_SELF" then
2079 patternInfo = { "environment", ParserLib_SELF, 1, "fire", }
2080 elseif patternName == "VSENVIRONMENTALDAMAGE_LAVA_OTHER" then
2081 patternInfo = { "environment", 1, 2, "lava", }
2082 elseif patternName == "VSENVIRONMENTALDAMAGE_LAVA_SELF" then
2083 patternInfo = { "environment", ParserLib_SELF, 1, "lava", }
2084 elseif patternName == "VSENVIRONMENTALDAMAGE_SLIME_OTHER" then
2085 patternInfo = { "environment", 1, 2, "slime", }
2086 elseif patternName == "VSENVIRONMENTALDAMAGE_SLIME_SELF" then
2087 patternInfo = { "environment", ParserLib_SELF, 1, "slime", }
2088  
2089 elseif patternName == "COMBATLOG_XPGAIN" then
2090 patternInfo = { "experience", 2, nil, nil, nil, nil, nil, nil, nil, 1, }
2091 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION1" then
2092 patternInfo = { "experience", 2, 1, 3, 4, nil, nil, nil, nil, nil, }
2093 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION1_GROUP" then
2094 patternInfo = { "experience", 2, 1, 3, 4, nil, nil, nil, 5, nil, }
2095 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION1_RAID" then
2096 patternInfo = { "experience", 2, 1, 3, 4, nil, nil, 5, nil, nil, }
2097 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION2" then
2098 patternInfo = { "experience", 2, 1, 3, 4, nil, nil, nil, nil, nil, }
2099 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION2_GROUP" then
2100 patternInfo = { "experience", 2, 1, 3, 4, nil, nil, nil, 5, nil, }
2101 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION2_RAID" then
2102 patternInfo = { "experience", 2, 1, 3, 4, nil, nil, 5, nil, nil, }
2103 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION4" then
2104 patternInfo = { "experience", 2, 1, nil, nil, 3, 4, nil, nil, nil, }
2105 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION4_GROUP" then
2106 patternInfo = { "experience", 2, 1, nil, nil, 3, 4, nil, 5, nil, }
2107 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION4_RAID" then
2108 patternInfo = { "experience", 2, 1, nil, nil, 3, 4, 5, nil, nil, }
2109 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION5" then
2110 patternInfo = { "experience", 2, 1, nil, nil, 3, 4, nil, nil, nil, }
2111 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION5_GROUP" then
2112 patternInfo = { "experience", 2, 1, nil, nil, 3, 4, nil, 5, nil, }
2113 elseif patternName == "COMBATLOG_XPGAIN_EXHAUSTION5_RAID" then
2114 patternInfo = { "experience", 2, 1, nil, nil, 3, 4, 5, nil, nil, }
2115 elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON" then
2116 patternInfo = { "experience", 2, 1, nil, nil, nil, nil, nil, nil, nil, }
2117 elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_GROUP" then
2118 patternInfo = { "experience", 2, 1, nil, nil, nil, nil, nil, 3, nil, }
2119 elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_RAID" then
2120 patternInfo = { "experience", 2, 1, nil, nil, nil, nil, 3, nil, nil, }
2121 elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED" then
2122 patternInfo = { "experience", 1, nil, nil, nil, nil, nil, nil, nil, nil, }
2123 elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED_GROUP" then
2124 patternInfo = { "experience", 1, nil, nil, nil, nil, nil, nil, 2, nil, }
2125 elseif patternName == "COMBATLOG_XPGAIN_FIRSTPERSON_UNNAMED_RAID" then
2126 patternInfo = { "experience", 1, nil, nil, nil, nil, nil, 2, nil, nil, }
2127 elseif patternName == "COMBATLOG_XPLOSS_FIRSTPERSON_UNNAMED" then
2128 patternInfo = { "experience", 1, nil, nil, nil, nil, nil, nil, nil, nil, }
2129  
2130 elseif patternName == "SPELLEXTRAATTACKSOTHER" then
2131 patternInfo = { "extraattack", 1, 3, 2, }
2132 elseif patternName == "SPELLEXTRAATTACKSOTHER_SINGULAR" then
2133 patternInfo = { "extraattack", 1, 3, 2, }
2134 elseif patternName == "SPELLEXTRAATTACKSSELF" then
2135 patternInfo = { "extraattack", ParserLib_SELF, 2, 1, }
2136 elseif patternName == "SPELLEXTRAATTACKSSELF_SINGULAR" then
2137 patternInfo = { "extraattack", ParserLib_SELF, 2, 1, }
2138  
2139 elseif patternName == "AURAREMOVEDOTHER" then
2140 patternInfo = { "fade", 2, 1, }
2141 elseif patternName == "AURAREMOVEDSELF" then
2142 patternInfo = { "fade", ParserLib_SELF, 1, }
2143  
2144 elseif patternName == "SPELLFAILCASTSELF" then
2145 patternInfo = { "fail", ParserLib_SELF, 1, 2, }
2146 elseif patternName == "SPELLFAILPERFORMSELF" then
2147 patternInfo = { "fail", ParserLib_SELF, 1, 2, }
2148  
2149 elseif patternName == "FEEDPET_LOG_FIRSTPERSON" then
2150 patternInfo = { "feedpet", ParserLib_SELF, 1, }
2151 elseif patternName == "FEEDPET_LOG_THIRDPERSON" then
2152 patternInfo = { "feedpet", 1, 2, }
2153  
2154 elseif patternName == "POWERGAINOTHEROTHER" then
2155 patternInfo = { "gain", 4, 1, 5, 2, 3, }
2156 elseif patternName == "POWERGAINOTHERSELF" then
2157 patternInfo = { "gain", 3, ParserLib_SELF, 4, 1, 2, }
2158 elseif patternName == "POWERGAINSELFOTHER" then
2159 patternInfo = { "gain", ParserLib_SELF, 1, 4, 2, 3, }
2160 elseif patternName == "POWERGAINSELFSELF" then
2161 patternInfo = { "gain", ParserLib_SELF, ParserLib_SELF, 3, 1, 2, }
2162  
2163 elseif patternName == "HEALEDCRITOTHEROTHER" then
2164 patternInfo = { "heal", 1, 3, 2, 4, true, nil, }
2165 elseif patternName == "HEALEDCRITOTHERSELF" then
2166 patternInfo = { "heal", 1, ParserLib_SELF, 2, 3, true, nil, }
2167 elseif patternName == "HEALEDCRITSELFOTHER" then
2168 patternInfo = { "heal", ParserLib_SELF, 2, 1, 3, true, nil, }
2169 elseif patternName == "HEALEDCRITSELFSELF" then
2170 patternInfo = { "heal", ParserLib_SELF, ParserLib_SELF, 1, 2, true, nil, }
2171 elseif patternName == "HEALEDOTHEROTHER" then
2172 patternInfo = { "heal", 1, 3, 2, 4, nil, nil, }
2173 elseif patternName == "HEALEDOTHERSELF" then
2174 patternInfo = { "heal", 1, ParserLib_SELF, 2, 3, nil, nil, }
2175 elseif patternName == "HEALEDSELFOTHER" then
2176 patternInfo = { "heal", ParserLib_SELF, 2, 1, 3, nil, nil, }
2177 elseif patternName == "HEALEDSELFSELF" then
2178 patternInfo = { "heal", ParserLib_SELF, ParserLib_SELF, 1, 2, nil, nil, }
2179 elseif patternName == "PERIODICAURAHEALOTHEROTHER" then
2180 patternInfo = { "heal", 3, 1, 4, 2, nil, true, }
2181 elseif patternName == "PERIODICAURAHEALOTHERSELF" then
2182 patternInfo = { "heal", 2, ParserLib_SELF, 3, 1, nil, true, }
2183 elseif patternName == "PERIODICAURAHEALSELFOTHER" then
2184 patternInfo = { "heal", ParserLib_SELF, 1, 3, 2, nil, true, }
2185 elseif patternName == "PERIODICAURAHEALSELFSELF" then
2186 patternInfo = { "heal", ParserLib_SELF, ParserLib_SELF, 2, 1, nil, true, }
2187  
2188 elseif patternName == "COMBATHITCRITOTHEROTHER" then
2189 patternInfo = { "hit", 1, 2, ParserLib_MELEE, 3, nil, true, nil, nil, }
2190 elseif patternName == "COMBATHITCRITOTHERSELF" then
2191 patternInfo = { "hit", 1, ParserLib_SELF, ParserLib_MELEE, 2, nil, true, nil, nil, }
2192 elseif patternName == "COMBATHITCRITSCHOOLOTHEROTHER" then
2193 patternInfo = { "hit", 1, 2, ParserLib_MELEE, 3, 4, true, nil, nil, }
2194 elseif patternName == "COMBATHITCRITSCHOOLOTHERSELF" then
2195 patternInfo = { "hit", 1, ParserLib_SELF, ParserLib_MELEE, 2, 3, true, nil, nil, }
2196 elseif patternName == "COMBATHITCRITSCHOOLSELFOTHER" then
2197 patternInfo = { "hit", ParserLib_SELF, 1, ParserLib_MELEE, 2, 3, true, nil, nil, }
2198 elseif patternName == "COMBATHITCRITSELFOTHER" then
2199 patternInfo = { "hit", ParserLib_SELF, 1, ParserLib_MELEE, 2, nil, true, nil, nil, }
2200 elseif patternName == "COMBATHITOTHEROTHER" then
2201 patternInfo = { "hit", 1, 2, ParserLib_MELEE, 3, nil, nil, nil, nil, }
2202 elseif patternName == "COMBATHITOTHERSELF" then
2203 patternInfo = { "hit", 1, ParserLib_SELF, ParserLib_MELEE, 2, nil, nil, nil, nil, }
2204 elseif patternName == "COMBATHITSCHOOLOTHEROTHER" then
2205 patternInfo = { "hit", 1, 2, ParserLib_MELEE, 3, 4, nil, nil, nil, }
2206 elseif patternName == "COMBATHITSCHOOLOTHERSELF" then
2207 patternInfo = { "hit", 1, ParserLib_SELF, ParserLib_MELEE, 2, 3, nil, nil, nil, }
2208 elseif patternName == "COMBATHITSCHOOLSELFOTHER" then
2209 patternInfo = { "hit", ParserLib_SELF, 1, ParserLib_MELEE, 2, 3, nil, nil, nil, }
2210 elseif patternName == "COMBATHITSELFOTHER" then
2211 patternInfo = { "hit", ParserLib_SELF, 1, ParserLib_MELEE, 2, nil, nil, nil, nil, }
2212 elseif patternName == "DAMAGESHIELDOTHEROTHER" then
2213 patternInfo = { "hit", 1, 4, ParserLib_DAMAGESHIELD, 2, 3, nil, nil, nil, }
2214 elseif patternName == "DAMAGESHIELDOTHERSELF" then
2215 patternInfo = { "hit", 1, ParserLib_SELF, ParserLib_DAMAGESHIELD, 2, 3, nil, nil, nil, }
2216 elseif patternName == "DAMAGESHIELDSELFOTHER" then
2217 patternInfo = { "hit", ParserLib_SELF, 3, ParserLib_DAMAGESHIELD, 1, 2, nil, nil, nil, }
2218 elseif patternName == "PERIODICAURADAMAGEOTHEROTHER" then
2219 patternInfo = { "hit", 4, 1, 5, 2, 3, nil, true, nil, }
2220 elseif patternName == "PERIODICAURADAMAGEOTHERSELF" then
2221 patternInfo = { "hit", 3, ParserLib_SELF, 4, 1, 2, nil, true, nil, }
2222 elseif patternName == "PERIODICAURADAMAGESELFOTHER" then
2223 patternInfo = { "hit", ParserLib_SELF, 1, 4, 2, 3, nil, true, nil, }
2224 elseif patternName == "PERIODICAURADAMAGESELFSELF" then
2225 patternInfo = { "hit", ParserLib_SELF, ParserLib_SELF, 3, 1, 2, nil, true, nil, }
2226 elseif patternName == "SPELLLOGCRITOTHEROTHER" then
2227 patternInfo = { "hit", 1, 3, 2, 4, nil, true, nil, nil, }
2228 elseif patternName == "SPELLLOGCRITOTHERSELF" then
2229 patternInfo = { "hit", 1, ParserLib_SELF, 2, 3, nil, true, nil, nil, }
2230 elseif patternName == "SPELLLOGCRITSCHOOLOTHEROTHER" then
2231 patternInfo = { "hit", 1, 3, 2, 4, 5, true, nil, nil, }
2232 elseif patternName == "SPELLLOGCRITSCHOOLOTHERSELF" then
2233 patternInfo = { "hit", 1, ParserLib_SELF, 2, 3, 4, true, nil, nil, }
2234 elseif patternName == "SPELLLOGCRITSCHOOLSELFOTHER" then
2235 patternInfo = { "hit", ParserLib_SELF, 2, 1, 3, 4, true, nil, nil, }
2236 elseif patternName == "SPELLLOGCRITSCHOOLSELFSELF" then
2237 patternInfo = { "hit", ParserLib_SELF, ParserLib_SELF, 1, 2, 3, true, nil, nil, }
2238 elseif patternName == "SPELLLOGCRITSELFOTHER" then
2239 patternInfo = { "hit", ParserLib_SELF, 2, 1, 3, nil, true, nil, nil, }
2240 elseif patternName == "SPELLLOGCRITSELFSELF" then
2241 patternInfo = { "hit", ParserLib_SELF, ParserLib_SELF, 1, 2, nil, true, nil, nil, }
2242 elseif patternName == "SPELLLOGOTHEROTHER" then
2243 patternInfo = { "hit", 1, 3, 2, 4, nil, nil, nil, nil, }
2244 elseif patternName == "SPELLLOGOTHERSELF" then
2245 patternInfo = { "hit", 1, ParserLib_SELF, 2, 3, nil, nil, nil, nil, }
2246 elseif patternName == "SPELLLOGSCHOOLOTHEROTHER" then
2247 patternInfo = { "hit", 1, 3, 2, 4, 5, nil, nil, nil, }
2248 elseif patternName == "SPELLLOGSCHOOLOTHERSELF" then
2249 patternInfo = { "hit", 1, ParserLib_SELF, 2, 3, 4, nil, nil, nil, }
2250 elseif patternName == "SPELLLOGSCHOOLSELFOTHER" then
2251 patternInfo = { "hit", ParserLib_SELF, 2, 1, 3, 4, nil, nil, nil, }
2252 elseif patternName == "SPELLLOGSCHOOLSELFSELF" then
2253 patternInfo = { "hit", ParserLib_SELF, ParserLib_SELF, 1, 2, 3, nil, nil, nil, }
2254 elseif patternName == "SPELLLOGSELFOTHER" then
2255 patternInfo = { "hit", ParserLib_SELF, 2, 1, 3, nil, nil, nil, nil, }
2256 elseif patternName == "SPELLLOGSELFSELF" then
2257 patternInfo = { "hit", ParserLib_SELF, ParserLib_SELF, 1, 2, nil, nil, nil, nil, }
2258 elseif patternName == "SPELLSPLITDAMAGEOTHEROTHER" then
2259 patternInfo = { "hit", 1, 3, 2, 4, nil, nil, nil, true, }
2260 elseif patternName == "SPELLSPLITDAMAGEOTHERSELF" then
2261 patternInfo = { "hit", 1, ParserLib_SELF, 2, 3, nil, nil, nil, true, }
2262 elseif patternName == "SPELLSPLITDAMAGESELFOTHER" then
2263 patternInfo = { "hit", ParserLib_SELF, 2, 1, 3, nil, nil, nil, true, }
2264  
2265 elseif patternName == "COMBATLOG_DISHONORGAIN" then
2266 patternInfo = { "honor", nil, 1, nil, }
2267 elseif patternName == "COMBATLOG_HONORAWARD" then
2268 patternInfo = { "honor", 1, nil, nil, }
2269 elseif patternName == "COMBATLOG_HONORGAIN" then
2270 patternInfo = { "honor", 3, 1, 2, }
2271  
2272 elseif patternName == "SPELLINTERRUPTOTHEROTHER" then
2273 patternInfo = { "interrupt", 1, 2, 3, }
2274 elseif patternName == "SPELLINTERRUPTOTHERSELF" then
2275 patternInfo = { "interrupt", 1, ParserLib_SELF, 2, }
2276 elseif patternName == "SPELLINTERRUPTSELFOTHER" then
2277 patternInfo = { "interrupt", ParserLib_SELF, 1, 2, }
2278  
2279 elseif patternName == "SPELLPOWERLEECHOTHEROTHER" then
2280 patternInfo = { "leech", 1, 5, 2, 3, 4, 6, 7, 8, }
2281 elseif patternName == "SPELLPOWERLEECHOTHERSELF" then
2282 patternInfo = { "leech", 1, ParserLib_SELF, 2, 3, 4, 5, 6, 7, }
2283 elseif patternName == "SPELLPOWERLEECHSELFOTHER" then
2284 patternInfo = { "leech", ParserLib_SELF, 4, 1, 2, 3, ParserLib_SELF, 5, 6, }
2285  
2286 elseif patternName == "IMMUNEDAMAGECLASSOTHEROTHER" then
2287 patternInfo = { "miss", 2, 1, ParserLib_MELEE, "immune", }
2288 elseif patternName == "IMMUNEDAMAGECLASSOTHERSELF" then
2289 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "immune", }
2290 elseif patternName == "IMMUNEDAMAGECLASSSELFOTHER" then
2291 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "immune", }
2292 elseif patternName == "IMMUNEOTHEROTHER" then
2293 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "immune", }
2294 elseif patternName == "IMMUNEOTHERSELF" then
2295 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "immune", }
2296 elseif patternName == "IMMUNESELFOTHER" then
2297 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "immune", }
2298 elseif patternName == "IMMUNESELFSELF" then
2299 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, ParserLib_MELEE, "immune", }
2300 elseif patternName == "IMMUNESPELLOTHEROTHER" then
2301 patternInfo = { "miss", 2, 1, 3, "immune", }
2302 elseif patternName == "IMMUNESPELLOTHERSELF" then
2303 patternInfo = { "miss", 1, ParserLib_SELF, 2, "immune", }
2304 elseif patternName == "IMMUNESPELLSELFOTHER" then
2305 patternInfo = { "miss", ParserLib_SELF, 1, 2, "immune", }
2306 elseif patternName == "IMMUNESPELLSELFSELF" then
2307 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "immune", }
2308 elseif patternName == "MISSEDOTHEROTHER" then
2309 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "miss", }
2310 elseif patternName == "MISSEDOTHERSELF" then
2311 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "miss", }
2312 elseif patternName == "MISSEDSELFOTHER" then
2313 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "miss", }
2314 elseif patternName == "PROCRESISTOTHEROTHER" then
2315 patternInfo = { "miss", 2, 1, 3, "resist", }
2316 elseif patternName == "PROCRESISTOTHERSELF" then
2317 patternInfo = { "miss", 1, ParserLib_SELF, 2, "resist", }
2318 elseif patternName == "PROCRESISTSELFOTHER" then
2319 patternInfo = { "miss", ParserLib_SELF, 1, 2, "resist", }
2320 elseif patternName == "PROCRESISTSELFSELF" then
2321 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "resist", }
2322 elseif patternName == "SPELLBLOCKEDOTHEROTHER" then
2323 patternInfo = { "miss", 1, 3, 2, "block", }
2324 elseif patternName == "SPELLBLOCKEDOTHERSELF" then
2325 patternInfo = { "miss", 1, ParserLib_SELF, 2, "block", }
2326 elseif patternName == "SPELLBLOCKEDSELFOTHER" then
2327 patternInfo = { "miss", ParserLib_SELF, 2, 1, "block", }
2328 elseif patternName == "SPELLDEFLECTEDOTHEROTHER" then
2329 patternInfo = { "miss", 1, 3, 2, "deflect", }
2330 elseif patternName == "SPELLDEFLECTEDOTHERSELF" then
2331 patternInfo = { "miss", 1, ParserLib_SELF, 2, "deflect", }
2332 elseif patternName == "SPELLDEFLECTEDSELFOTHER" then
2333 patternInfo = { "miss", ParserLib_SELF, 2, 1, "deflect", }
2334 elseif patternName == "SPELLDEFLECTEDSELFSELF" then
2335 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "deflect", }
2336 elseif patternName == "SPELLDODGEDOTHEROTHER" then
2337 patternInfo = { "miss", 1, 3, 2, "dodge", }
2338 elseif patternName == "SPELLDODGEDOTHERSELF" then
2339 patternInfo = { "miss", 1, ParserLib_SELF, 2, "dodge", }
2340 elseif patternName == "SPELLDODGEDSELFOTHER" then
2341 patternInfo = { "miss", ParserLib_SELF, 2, 1, "dodge", }
2342 elseif patternName == "SPELLDODGEDSELFSELF" then
2343 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "dodge", }
2344 elseif patternName == "SPELLEVADEDOTHEROTHER" then
2345 patternInfo = { "miss", 1, 3, 2, "evade", }
2346 elseif patternName == "SPELLEVADEDOTHERSELF" then
2347 patternInfo = { "miss", 1, ParserLib_SELF, 2, "evade", }
2348 elseif patternName == "SPELLEVADEDSELFOTHER" then
2349 patternInfo = { "miss", ParserLib_SELF, 2, 1, "evade", }
2350 elseif patternName == "SPELLEVADEDSELFSELF" then
2351 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "evade", }
2352 elseif patternName == "SPELLIMMUNEOTHEROTHER" then
2353 patternInfo = { "miss", 1, 3, 2, "immune", }
2354 elseif patternName == "SPELLIMMUNEOTHERSELF" then
2355 patternInfo = { "miss", 1, ParserLib_SELF, 2, "immune", }
2356 elseif patternName == "SPELLIMMUNESELFOTHER" then
2357 patternInfo = { "miss", ParserLib_SELF, 2, 1, "immune", }
2358 elseif patternName == "SPELLIMMUNESELFSELF" then
2359 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "immune", }
2360 elseif patternName == "SPELLLOGABSORBOTHEROTHER" then
2361 patternInfo = { "miss", 1, 3, 2, "absorb", }
2362 elseif patternName == "SPELLLOGABSORBOTHERSELF" then
2363 patternInfo = { "miss", 1, ParserLib_SELF, 2, "absorb", }
2364 elseif patternName == "SPELLLOGABSORBSELFOTHER" then
2365 patternInfo = { "miss", ParserLib_SELF, 2, 1, "absorb", }
2366 elseif patternName == "SPELLLOGABSORBSELFSELF" then
2367 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "absorb", }
2368 elseif patternName == "SPELLMISSOTHEROTHER" then
2369 patternInfo = { "miss", 1, 3, 2, "miss", }
2370 elseif patternName == "SPELLMISSOTHERSELF" then
2371 patternInfo = { "miss", 1, ParserLib_SELF, 2, "miss", }
2372 elseif patternName == "SPELLMISSSELFOTHER" then
2373 patternInfo = { "miss", ParserLib_SELF, 2, 1, "miss", }
2374 elseif patternName == "SPELLMISSSELFSELF" then
2375 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "miss", }
2376 elseif patternName == "SPELLPARRIEDOTHEROTHER" then
2377 patternInfo = { "miss", 1, 3, 2, "parry", }
2378 elseif patternName == "SPELLPARRIEDOTHERSELF" then
2379 patternInfo = { "miss", 1, ParserLib_SELF, 2, "parry", }
2380 elseif patternName == "SPELLPARRIEDSELFOTHER" then
2381 patternInfo = { "miss", ParserLib_SELF, 2, 1, "parry", }
2382 elseif patternName == "SPELLPARRIEDSELFSELF" then
2383 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "parry", }
2384 elseif patternName == "SPELLREFLECTOTHEROTHER" then
2385 patternInfo = { "miss", 1, 3, 2, "reflect", }
2386 elseif patternName == "SPELLREFLECTOTHERSELF" then
2387 patternInfo = { "miss", 1, ParserLib_SELF, 2, "reflect", }
2388 elseif patternName == "SPELLREFLECTSELFOTHER" then
2389 patternInfo = { "miss", ParserLib_SELF, 2, 1, "reflect", }
2390 elseif patternName == "SPELLREFLECTSELFSELF" then
2391 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "reflect", }
2392 elseif patternName == "SPELLRESISTOTHEROTHER" then
2393 patternInfo = { "miss", 1, 3, 2, "resist", }
2394 elseif patternName == "SPELLRESISTOTHERSELF" then
2395 patternInfo = { "miss", 1, ParserLib_SELF, 2, "resist", }
2396 elseif patternName == "SPELLRESISTSELFOTHER" then
2397 patternInfo = { "miss", ParserLib_SELF, 2, 1, "resist", }
2398 elseif patternName == "SPELLRESISTSELFSELF" then
2399 patternInfo = { "miss", ParserLib_SELF, ParserLib_SELF, 1, "resist", }
2400 elseif patternName == "VSABSORBOTHEROTHER" then
2401 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "absorb", }
2402 elseif patternName == "VSABSORBOTHERSELF" then
2403 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "absorb", }
2404 elseif patternName == "VSABSORBSELFOTHER" then
2405 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "absorb", }
2406 elseif patternName == "VSBLOCKOTHEROTHER" then
2407 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "block", }
2408 elseif patternName == "VSBLOCKOTHERSELF" then
2409 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "block", }
2410 elseif patternName == "VSBLOCKSELFOTHER" then
2411 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "block", }
2412 elseif patternName == "VSDEFLECTOTHEROTHER" then
2413 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "deflect", }
2414 elseif patternName == "VSDEFLECTOTHERSELF" then
2415 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "deflect", }
2416 elseif patternName == "VSDEFLECTSELFOTHER" then
2417 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "deflect", }
2418 elseif patternName == "VSDODGEOTHEROTHER" then
2419 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "dodge", }
2420 elseif patternName == "VSDODGEOTHERSELF" then
2421 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "dodge", }
2422 elseif patternName == "VSDODGESELFOTHER" then
2423 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "dodge", }
2424 elseif patternName == "VSEVADEOTHEROTHER" then
2425 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "evade", }
2426 elseif patternName == "VSEVADEOTHERSELF" then
2427 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "evade", }
2428 elseif patternName == "VSEVADESELFOTHER" then
2429 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "evade", }
2430 elseif patternName == "VSIMMUNEOTHEROTHER" then
2431 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "immune", }
2432 elseif patternName == "VSIMMUNEOTHERSELF" then
2433 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "immune", }
2434 elseif patternName == "VSIMMUNESELFOTHER" then
2435 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "immune", }
2436 elseif patternName == "VSPARRYOTHEROTHER" then
2437 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "parry", }
2438 elseif patternName == "VSPARRYOTHERSELF" then
2439 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "parry", }
2440 elseif patternName == "VSPARRYSELFOTHER" then
2441 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "parry", }
2442 elseif patternName == "VSRESISTOTHEROTHER" then
2443 patternInfo = { "miss", 1, 2, ParserLib_MELEE, "resist", }
2444 elseif patternName == "VSRESISTOTHERSELF" then
2445 patternInfo = { "miss", 1, ParserLib_SELF, ParserLib_MELEE, "resist", }
2446 elseif patternName == "VSRESISTSELFOTHER" then
2447 patternInfo = { "miss", ParserLib_SELF, 1, ParserLib_MELEE, "resist", }
2448  
2449 elseif patternName == "FACTION_STANDING_CHANGED" then
2450 patternInfo = { "reputation", 2, nil, 1, nil, }
2451 elseif patternName == "FACTION_STANDING_DECREASED" then
2452 patternInfo = { "reputation", 1, 2, nil, true, }
2453 elseif patternName == "FACTION_STANDING_INCREASED" then
2454 patternInfo = { "reputation", 1, 2, nil, nil, }
2455 end
2456  
2457 if not patternInfo then
2458 -- self:Print("LoadPatternInfo(): Cannot find " .. patternName ); -- debug
2459 return
2460 end
2461  
2462 local pattern = getglobal(patternName); -- Get the pattern from GlobalStrings.lua
2463  
2464 -- How many regexp tokens in this pattern?
2465 local tc = 0
2466 for _ in string.gfind(pattern, "%%%d?%$?([sd])") do tc = tc + 1 end
2467  
2468 -- Convert string.format tokens into LUA regexp tokens.
2469 pattern = { self:ConvertPattern(pattern, true) }
2470  
2471 local n = table.getn(pattern)
2472 if n > 1 then -- Extra return values are the remapped token sequences.
2473  
2474 for j in patternInfo do
2475 if type(patternInfo[j]) == "number" and patternInfo[j] < 100 then
2476 patternInfo[j] = pattern[patternInfo[j]+1] -- Remap to correct token sequence.
2477 end
2478 end
2479  
2480 end
2481  
2482 patternInfo.tc = tc
2483 patternInfo.pattern = pattern[1]
2484  
2485 return patternInfo
2486  
2487 end
2488  
2489 -- Fields of the patternTable.
2490 lib.infoMap = {
2491 hit = { "source", "victim", "skill", "amount", "element", "isCrit", "isDOT", "isSplit" },
2492 heal = { "source", "victim", "skill", "amount", "isCrit", "isDOT" },
2493 miss = { "source", "victim", "skill", "missType" },
2494 death = { "victim", "source", "isItem" },
2495 debuff = { "victim", "skill", "amountRank" },
2496 buff = { "victim", "skill", "amountRank" },
2497 fade = { "victim", "skill" },
2498 cast = { "source", "skill", "victim", "isBegin", "isVictim" },
2499 gain = { "source", "victim", "skill", "amount", "attribute" },
2500 drain = { "source", "victim", "skill", "amount", "attribute" },
2501 leech = { "source", "victim", "skill", "amount", "attribute", "sourceGained", "amountGained", "attributeGained" },
2502 dispel = { "victim", "skill", "source", "isFailed" },
2503 extraattack = { "victim", "skill", "amount" },
2504 environment = { "victim", "amount", "damageType" },
2505 experience = { "amount", "source", "bonusAmount", "bonusType", "penaltyAmount", "penaltyType", "amountRaidPenalty", "amountGroupBonus", "victim" },
2506 reputation = { "faction", "amount", "rank", "isNegative" },
2507 feedpet = { "victim", "item" },
2508 enchant = { "source", "victim", "skill", "item" },
2509 fail = { "source", "skill", "reason" },
2510 interrupt = { "source", "victim", "skill" },
2511 create = { "source", "item" },
2512 honor = { "amount", "source", "sourceRank" }, -- if amount == nil then isDishonor = true.
2513 durability = { "source", "skill", "victim", "item" }, -- is not item then isAllItems = true
2514 unknown = { "message" },
2515 }
2516  
2517 function lib:GetInfoFieldName(infoType, fieldIndex)
2518 if self.infoMap[infoType] then
2519 return self.infoMap[infoType][fieldIndex-1] -- Skip the first field in patternTable which is 'type'.
2520 end
2521 end
2522  
2523 --------------------------------
2524 -- Load this bitch! --
2525 --------------------------------
2526 libobj:Register(lib)