vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 -- stuff for the startup log
2 local SW_SL_RegExCreate = 0;
3 local SW_SL_RegExAdded = 0;
4  
5 function SW_SL_Add(msg)
6 table.insert(SW_StartupLog, msg);
7 end
8 function SW_SL_AddTrailer(msg)
9 SW_StartupLog[table.getn(SW_StartupLog)] = SW_StartupLog[table.getn(SW_StartupLog)].. msg;
10 end
11 function SW_SL_SetLastOk()
12 SW_SL_AddTrailer(SW_SL["OK"]);
13 end
14 function SW_SL_Finalize()
15 SW_SL_Add(SW_SL["MAP_REGEX"].." "..SW_SL_RegExAdded.."/"..SW_SL_RegExCreate);
16 SW_DumpTable(SW_StartupLog,nil,1,true);
17 SW_StartupLog = nil;
18  
19 end
20  
21 function SW_DEV_FFN(func)
22 if func == nil then return; end
23 if type(func) ~= "function" then
24 return "Not a function";
25 end
26 local ret = "??";
27 local vars = getfenv();
28 for k,v in pairs(vars) do
29 if type(v) == "function" then
30 if func == v then
31 return k;
32 end
33 end
34 end
35 return ret;
36 end
37 function SW_DEV_FindVar(str, chkVal)
38 local vars = getfenv();
39 local sLen =string.len(str);
40 SW_printStr( "------ "..str.." ------");
41 for k,v in pairs(vars) do
42 if chkVal then
43 if type(v) == "string" then
44 if string.find(v, str) then
45  
46 SW_printStr(k.." ==> "..v);
47 end
48 end
49 else
50  
51 if string.find(k, str) then
52 if type(v) == "string" then
53 SW_printStr(k.." ==> "..v);
54 else
55 SW_printStr(k.." ("..type(v)..")");
56 end
57 end
58 end
59 end
60 end
61 function SW_DEV_CC(hideCorrectlyOrdered)
62 local s1, s2;
63 local headPrinted = false;
64 local startS, endS;
65 local problematic = {};
66 local mainEnding = {};
67 local mainSDI = 0;
68 SW_printStr("-------------SW_DEV_CC--------------");
69 -- get all problematic regex
70 -- (these end in a string capture.)
71 local re = "(.+)%(%.%-%)(.-)$";
72 for i,toCheck in ipairs(SW_EventRegexMap[SW_DEV_EVENTDUMMY]) do
73  
74 s1 = SW_RegEx_Lookup[toCheck]["r"];
75 _,_,startS, endS = string.find(s1, re);
76  
77 if endS ~= nil and string.len( endS ) <=20 then
78 -- the end capture may not include another capture
79 if not (string.find(endS,"%(%.%-%)") or string.find(endS,"%(%%d%+%)") ) then
80 --SW_printStr(s1.." "..endS);
81 problematic[s1] = {startS, endS, toCheck};
82 if mainEnding[endS] == nil then
83 mainEnding[endS] = 1;
84 else
85 mainEnding[endS] = mainEnding[endS] + 1;
86 end
87 end
88 end
89 end
90 SW_DumpTable(mainEnding);
91  
92 --SW_DumpTable(problematic);
93  
94 for k, v in pairs(problematic) do
95 headPrinted = false;
96 --s2 = v[1].."(.-)"..v[2];
97 s2 = v[1];
98 mainSDI = SW_DEV_GetDummyIndex(k);
99  
100 for i,toCheck in ipairs(SW_EventRegexMap[SW_DEV_EVENTDUMMY]) do
101 s1 = SW_RegEx_Lookup[toCheck]["r"];
102  
103 if string.sub(s1,1,string.len(s2))== s2 then
104 -- it will collide with istelf..
105 if k ~= s1 then
106 if (not hideCorrectlyOrdered) or (mainSDI < SW_DEV_GetDummyIndex(s1)) then
107  
108 if not headPrinted then
109 SW_printStr(" ");
110 SW_printStr("----CHECK "..v[3].." "..k);
111 headPrinted = true;
112 end
113 SW_printStr(toCheck.." "..s1.." LateSort:"..((SW_RegEx_Lookup[toCheck]["ls"]) or "NO"));
114  
115 end
116 end
117 end
118 end
119 end
120  
121 end
122 function SW_DEV_GetDummyIndex(regEx)
123  
124 for i,toCheck in ipairs(SW_EventRegexMap[SW_DEV_EVENTDUMMY]) do
125 if regEx == SW_RegEx_Lookup[toCheck]["r"] then
126 return i;
127 end
128 end
129 end
130 -- this function is used to create "junk" for testing
131 --[[
132 -- need this to map var names to var values
133 local SW_G_VARS = getfenv();
134 -- note to self check GetCVar
135 local junkIndex =0;
136  
137 SW_DEV_JUNK_STRINGS ={};
138  
139 local function SW_CreateJunk(varName)
140 local strMain = getglobal(varName);
141 local str ="";
142  
143 if strMain == nil then return end;
144  
145 for i=1,SW_DEV_ITEMS_PER_REGEX do
146  
147 --[[
148 str = string.gsub(strMain, '(%%(%d?)$?([sd]))',
149 function(all,num,type)
150 if type == 's' then
151 return (string.rep(string.char(math.random(97,122)), math.random(3,5)));
152 else
153 return (math.random(1000));
154 end
155 end);
156 --]]
157 str = string.gsub(strMain, '(%%(%d?)$?([sd]))',
158 function(all,num,type)
159 if type == 's' then
160 return ("STRING");
161 else
162 return (12345);
163 end
164 end);
165 table.insert(SW_DEV_JUNK_STRINGS, str);
166 end
167 end
168 --]]
169 --[[
170 used this to find ending collisions
171 only "bad" one found in en,de,fr is en: PERIODICAURAHEALSELFSELF
172 fr has some with extra attack messages, but not using these atm
173 SW_EndingTest = {};
174 SW_EndingCol = {};
175  
176 function SW_TestEnding(str)
177 local tmpStr = string.gsub(str, "(%%%d?$?s%.)$", "");
178  
179 for k,v in pairs(SW_EndingTest) do
180 if string.sub(k,1,string.len(tmpStr))==tmpStr then
181 if SW_EndingCol[tmpStr] == nil then
182 SW_EndingCol[tmpStr] = 1;
183 else
184 SW_EndingCol[tmpStr] = SW_EndingCol[tmpStr] +1;
185 end
186  
187 end
188 end
189 if SW_EndingTest[str] == nil then
190 SW_EndingTest[str] = 0;
191 end
192 end
193 --]]
194 --this converts a GlobalVariable to a regex we can use
195 -- and add it to SW_RegEx_Lookup
196 local function SW_InitVar(varName,types,fromSelf,toSelf,isCrit,lateSort)
197 local str = getglobal(varName);
198 --SW_TestEnding(str);
199 --check if we are trying to work on a global thats not available
200 if str == nil then
201 SW_printStr("SW_InitVar varName NIL: "..varName);
202 return
203 end;
204 --SW_CreateJunk(varName);
205  
206 if types == nil then return end;
207  
208 --fixes ambiguous strings
209 -- fix log strings is a localized function
210 local strTmp = SW_FixLogStrings(str);
211 if str ~= strTmp then
212 setglobal(varName, strTmp);
213 str = strTmp;
214 end
215  
216 SW_SL_RegExCreate = SW_SL_RegExCreate +1;
217 SW_RegEx_Lookup[varName] ={};
218  
219 -- "p" stands for positions maps found for numbered vals (e.g. %3$s)
220 -- in a different langugage these might be used in a different order
221 SW_RegEx_Lookup[varName]["p"] ={};
222  
223 SW_RegEx_Lookup[varName]["types"] = types;
224 if lateSort then
225 SW_RegEx_Lookup[varName]["ls"] = 1;
226 end
227 if fromSelf then
228 SW_RegEx_Lookup[varName]["fromSelf"] = 1;
229 end
230 if toSelf then
231 SW_RegEx_Lookup[varName]["toSelf"] = 1;
232 end
233 if isCrit then
234 SW_RegEx_Lookup[varName]["isCrit"] = 1;
235 end
236 local index=0;
237 local needPosLookup = false;
238  
239  
240 -- first we have to "sanitze" the string ^()%.[]*+-? are special chars in a regex (dont escape the $ and %)
241 -- so we are escaping these with %
242 str = string.gsub(str, "([%.%(%)%+%-%?%[%]%^])", "%%%1");
243  
244 -- the inner function actually does the work
245 str = string.gsub(str, '(%%(%d?)$?([sd]))',
246 function(all,num,type) -- e.g. %3$s all = %3$s num=3 type=s
247 index = index+1;
248 --1.0.2 , fixed the french version bug through "tonumber .. omg DOH .. oh well
249 -- this will help all non englisch versions
250 SW_RegEx_Lookup[varName]["p"][index] = tonumber(num);
251 if num ~= "" then
252 -- if num is "" then the string e.g. only used %s and not %1$s
253 -- and we dont need a lookup - its already in order
254 needPosLookup = true;
255 end
256  
257 --this is the actual replacement that makes the regex
258 -- use non greedy for strings
259 if type == 's' then
260 return ('(.-)');
261 else
262 return ('(%d+)');
263 end
264 end);
265  
266 -- saves how many captures to expect later using this regex
267 SW_RegEx_Lookup[varName]["i"] = index;
268  
269 --generate maps for heal dmg etc info
270 if index == getn(types) then
271 local playerName = "";
272 local mm = {};
273 local medm = {};
274 local i;
275 local max = getn(types);
276  
277 --1 = target
278 --2 = caster/attacker/initiator
279 --3 = someString (normally spell names, or item names)
280 -- 51 = dmg 52 = heal
281 --{from,to,dmg,heal, what}
282 for i, val in ipairs(types) do
283 if val == 2 then
284 mm[1] = i;
285 medm[1] = i;
286 elseif val == 1 then
287 mm[2] = i;
288 medm[2] = i;
289 elseif val == 51 then
290 mm[3] = i;
291 medm[3] = i;
292 elseif val == 52 then
293 mm[4] = i;
294 medm[4] = i;
295 elseif val == 3 then
296 mm[5] = i;
297 medm[5] = i;
298 elseif val == 7 then
299 mm[6] = i;
300 medm[6] = i;
301 end
302 end
303 if fromSelf then
304 mm[1]= -1;
305 end
306 if toSelf then
307 mm[2]= -1;
308 end
309  
310  
311 SW_RegEx_Lookup[varName]["basicInfo"] = mm;
312 --SW_RegEx_Lookup[varName]["fullInfo"] = medm;
313 else
314 SW_printStr(RED_FONT_COLOR_CODE.."SW_InitVar "..varName.." "..index.."~="..getn(types).." caputerN~=TypeN" , 1);
315 end
316  
317 if needPosLookup then
318 -- check if we really do need it
319 -- could be in order anyways
320 needPosLookup = false;
321 for k, v in pairs(SW_RegEx_Lookup[varName]["p"]) do
322 -- make k, v numbers, so they will compare
323 -- k,v are of different types so this wouldn't work otherwise
324 k = k+0;
325 v = v+0;
326 if k~=v then
327 needPosLookup = true;
328 break;
329 end
330 end
331 end
332 -- now we are sure if we need it or not
333 if not needPosLookup then
334 -- %s %d etc. used info is "in order"
335 -- or %1$s %2$d etc. was used but all in correct order
336 -- just junk it
337 SW_RegEx_Lookup[varName]["p"] = nil;
338 end
339  
340 --if string.sub(str,1,1) == "(" then
341 --SW_RegEx_Lookup[varName]["r"] = str; -- the regex
342 --else
343 SW_RegEx_Lookup[varName]["r"] = "^"..str; -- the regex
344 --end
345 --[[ Interesting have to comment this out so wow will work??
346 maybe because this is a local function ?
347 if SW_DEV_CREATE_JUNK_STRINGS then
348 SW_CreateJunk(varName);
349 end
350 ]]--
351 end
352  
353 --------------------- the global vars to define a regex for -------------------------------
354 function SW_CreateRegexFromGlobals()
355 -- take these out while finding matches and collisions
356 --SW_InitVar("VULNERABLE_TRAILER");
357 --SW_InitVar("ABSORB_TRAILER");
358 --SW_InitVar("BLOCK_TRAILER");
359 --SW_InitVar("RESIST_TRAILER");
360 SW_SL_Add(SW_SL["REGEX"]);
361 --[[ new way, a lot more info
362 name of string var,
363 Arrray of types
364 The array is mapped 1 to 1 to the captures AFTER the captures have been sorted
365 (for different languages they may be in different order)
366  
367 1 = target
368 2 = caster/attacker/initiator
369 3 = someString (normally spell names, or item names)
370 4 = unused
371 5x = Number
372 6x = number 2
373 where x
374 1= Damage
375 2 = Heal
376 3 = Other
377 4 = LeechFrom amount(victim of leech )
378 5 = LeechTo amount (leech transferred to)
379 7 = School
380 8 = LeechFrom (String what is leeched health, mana, etc)
381 9 = LeechTo (string what has been transferred healt, mana, etc)
382 10 = Leech benefit (the person the got the "good side" of the leech
383 (leech and drain use the same types, some fields are just not set)
384 After the array:
385 fromself, (did one self start the cast/attack? )
386 toself, (did one self get the heal/hit...)
387 iscrit, (is this a crit?)
388 lateSort (special indicated to check these last; used in recuCheck,
389 used to push back some regex that capture to early)
390  
391 note to self... new in 1.9 true if this locale:
392 LOCALE_enGB, LOCALE_enUS, LOCALE_frFR, LOCALE_deDE, LOCALE_koKR, LOCALE_zhCN, LOCALE zhTW
393  
394 ]]--
395 if (LOCALE_frFR) then
396 -- captures to early in fr version
397 SW_InitVar("COMBATHITCRITOTHEROTHER",{2,1,51},nil,nil,true,true);
398 SW_InitVar("COMBATHITCRITSCHOOLOTHEROTHER",{2,1,51,7},nil,nil,true,true);
399 else
400 SW_InitVar("COMBATHITCRITOTHEROTHER",{2,1,51},nil,nil,true,nil);
401 SW_InitVar("COMBATHITCRITSCHOOLOTHEROTHER",{2,1,51,7},nil,nil,true,nil);
402 end
403  
404 SW_InitVar("COMBATHITCRITOTHERSELF",{2,51},nil,true,true,nil);
405 SW_InitVar("COMBATHITCRITSCHOOLOTHERSELF",{2,51,7},nil,true,true,nil);
406 SW_InitVar("COMBATHITCRITSCHOOLSELFOTHER",{1,51,7},true,nil,true,nil);
407 SW_InitVar("COMBATHITCRITSELFOTHER",{1,51},true,nil,true,nil);
408  
409 if (LOCALE_zhCN or LOCALE_zhTW) then
410 SW_InitVar("COMBATHITOTHEROTHER",{2,1,51},nil,nil,nil,true);
411 SW_InitVar("COMBATHITSCHOOLOTHEROTHER",{2,1,51,7},nil,nil,nil,true);
412 SW_InitVar("COMBATHITSCHOOLOTHERSELF",{2,51,7},nil,true,nil,true);
413 else
414 SW_InitVar("COMBATHITOTHEROTHER",{2,1,51},nil,nil,nil,nil);
415 SW_InitVar("COMBATHITSCHOOLOTHEROTHER",{2,1,51,7},nil,nil,nil,nil);
416 SW_InitVar("COMBATHITSCHOOLOTHERSELF",{2,51,7},nil,true,nil,nil);
417 end
418  
419 SW_InitVar("COMBATHITOTHERSELF",{2,51},nil,true,nil,nil);
420 SW_InitVar("COMBATHITSCHOOLSELFOTHER",{1,51,7},true,nil,nil,nil);
421 SW_InitVar("COMBATHITSELFOTHER",{1,51},true,nil,nil,nil);
422 SW_InitVar("DAMAGESHIELDOTHEROTHER",{2,51,7,1},nil,nil,nil,nil);
423 SW_InitVar("DAMAGESHIELDOTHERSELF",{2,51,7},nil,true,nil,nil);
424 SW_InitVar("DAMAGESHIELDSELFOTHER",{51,7,1},true,nil,nil,nil);
425 SW_InitVar("ERR_COMBAT_DAMAGE_SSI",{2,1,51},nil,nil,nil,true);
426 SW_InitVar("HEALEDCRITOTHEROTHER",{2,3,1,52},nil,nil,true,nil);
427 SW_InitVar("HEALEDCRITOTHERSELF",{2,3,52},nil,true,true,nil);
428 SW_InitVar("HEALEDCRITSELFOTHER",{3,1,52},true,nil,true,nil);
429 SW_InitVar("HEALEDCRITSELFSELF",{3,52},true,true,true,nil);
430 SW_InitVar("HEALEDOTHEROTHER",{2,3,1,52},nil,nil,nil,nil);
431 SW_InitVar("HEALEDOTHERSELF",{2,3,52},nil,true,nil,nil);
432 SW_InitVar("HEALEDSELFOTHER",{3,1,52},true,nil,nil,nil);
433 SW_InitVar("HEALEDSELFSELF",{3,52},true,true,nil,nil);
434 SW_InitVar("PERIODICAURADAMAGEOTHEROTHER",{1,51,7,2,3},nil,nil,nil,nil);
435 SW_InitVar("PERIODICAURADAMAGEOTHERSELF",{51,7,2,3},nil,true,nil,nil);
436 SW_InitVar("PERIODICAURADAMAGESELFOTHER",{1,51,7,3},true,nil,nil,nil);
437 SW_InitVar("PERIODICAURADAMAGESELFSELF",{51,7,3},true,true,nil,nil);
438 SW_InitVar("PERIODICAURAHEALOTHEROTHER",{1,52,2,3},nil,nil,nil,nil);
439 SW_InitVar("PERIODICAURAHEALOTHERSELF",{52,2,3},nil,true,nil,nil);
440 SW_InitVar("PERIODICAURAHEALSELFOTHER",{1,52,3},true,nil,nil,nil);
441  
442 if LOCALE_enGB or LOCALE_enUS then
443 -- captures to early in en versions
444 SW_InitVar("PERIODICAURAHEALSELFSELF",{52,3},true,true,nil,true);
445 else
446 SW_InitVar("PERIODICAURAHEALSELFSELF",{52,3},true,true,nil,nil);
447 end
448  
449 SW_InitVar("PET_DAMAGE_PERCENTAGE",{53},nil,nil,nil,nil);
450 SW_InitVar("SPELLEXTRAATTACKSOTHER",{1,53,3},nil,nil,nil,nil);
451 SW_InitVar("SPELLEXTRAATTACKSOTHER_SINGULAR",{1,53,3},nil,nil,nil,nil);
452 SW_InitVar("SPELLEXTRAATTACKSSELF",{53,3},nil,true,nil,nil);
453 SW_InitVar("SPELLEXTRAATTACKSSELF_SINGULAR",{3,53},nil,true,nil,nil);
454 SW_InitVar("SPELLHAPPINESSDRAINOTHER",{1,2,53},nil,nil,nil,nil);
455 SW_InitVar("SPELLHAPPINESSDRAINSELF",{1,53},true,nil,nil,nil);
456 SW_InitVar("SPELLLOGCRITOTHEROTHER",{2,3,1,51},nil,nil,true,nil);
457 SW_InitVar("SPELLLOGCRITOTHERSELF",{2,3,51},nil,true,true,nil);
458 SW_InitVar("SPELLLOGCRITSCHOOLOTHEROTHER",{2,3,1,51,7},nil,nil,true,nil);
459 SW_InitVar("SPELLLOGCRITSCHOOLOTHERSELF",{2,3,51,7},nil,true,true,nil);
460 SW_InitVar("SPELLLOGCRITSCHOOLSELFOTHER",{3,1,51,7},true,nil,true,nil);
461 SW_InitVar("SPELLLOGCRITSCHOOLSELFSELF",{3,51,7},true,true,true,nil);
462 SW_InitVar("SPELLLOGCRITSELFOTHER",{3,1,51},true,nil,true,nil);
463 SW_InitVar("SPELLLOGCRITSELFSELF",{3,51},true,true,true,nil);
464 SW_InitVar("SPELLLOGOTHEROTHER",{2,3,1,51},nil,nil,nil,nil);
465 SW_InitVar("SPELLLOGOTHERSELF",{2,3,51},nil,true,nil,nil);
466 SW_InitVar("SPELLLOGSCHOOLOTHEROTHER",{2,3,1,51,7},nil,nil,nil,nil);
467 SW_InitVar("SPELLLOGSCHOOLOTHERSELF",{2,3,51,7},nil,true,nil,nil);
468 SW_InitVar("SPELLLOGSCHOOLSELFOTHER",{3,1,51,7},true,nil,nil,nil);
469 SW_InitVar("SPELLLOGSCHOOLSELFSELF",{3,51,7},true,true,nil,nil);
470 SW_InitVar("SPELLLOGSELFOTHER",{3,1,51},true,nil,nil,nil);
471 SW_InitVar("SPELLLOGSELFSELF",{3,51},true,true,nil,nil);
472  
473 if LOCALE_enGB or LOCALE_enUS then
474 SW_InitVar("SPELLPOWERDRAINOTHEROTHER",{2,3,54,8,1},nil,nil,nil,true);
475 SW_InitVar("SPELLPOWERDRAINOTHERSELF",{2,3,54,8},nil,true,nil,true);
476 else
477 SW_InitVar("SPELLPOWERDRAINOTHEROTHER",{2,3,54,8,1},nil,nil,nil,nil);
478 SW_InitVar("SPELLPOWERDRAINOTHERSELF",{2,3,54,8},nil,true,nil,nil);
479 end
480 SW_InitVar("SPELLPOWERDRAINSELFOTHER",{3,54,8,1},true,nil,nil,nil);
481 SW_InitVar("SPELLPOWERLEECHOTHEROTHER",{2,3,54,8,1,10,65,9},nil,nil,nil,nil);
482 SW_InitVar("SPELLPOWERLEECHOTHERSELF",{2,3,54,8,10,65,9},nil,true,nil,nil);
483 SW_InitVar("SPELLPOWERLEECHSELFOTHER",{3,54,8,1,65,9},true,nil,nil,nil);
484 SW_InitVar("SPELLSPLITDAMAGEOTHEROTHER",{2,3,1,51},nil,nil,nil,nil);
485 SW_InitVar("SPELLSPLITDAMAGEOTHERSELF",{2,3,51},nil,true,nil,nil);
486 SW_InitVar("SPELLSPLITDAMAGESELFOTHER",{2,1,51},nil,nil,nil,nil);
487 SW_InitVar("VSENVIRONMENTALDAMAGE_DROWNING_OTHER",{1,51},nil,nil,nil,nil);
488 SW_InitVar("VSENVIRONMENTALDAMAGE_DROWNING_SELF",{51},nil,true,nil,nil);
489 SW_InitVar("VSENVIRONMENTALDAMAGE_FALLING_OTHER",{1,51},nil,nil,nil,nil);
490 SW_InitVar("VSENVIRONMENTALDAMAGE_FALLING_SELF",{51},nil,true,nil,nil);
491 SW_InitVar("VSENVIRONMENTALDAMAGE_FATIGUE_OTHER",{1,51},nil,nil,nil,nil);
492 SW_InitVar("VSENVIRONMENTALDAMAGE_FATIGUE_SELF",{51},nil,true,nil,nil);
493 SW_InitVar("VSENVIRONMENTALDAMAGE_FIRE_OTHER",{1,51},nil,nil,nil,nil);
494 SW_InitVar("VSENVIRONMENTALDAMAGE_FIRE_SELF",{51},nil,true,nil,nil);
495 SW_InitVar("VSENVIRONMENTALDAMAGE_LAVA_OTHER",{1,51},nil,nil,nil,nil);
496 SW_InitVar("VSENVIRONMENTALDAMAGE_LAVA_SELF",{51},nil,true,nil,nil);
497 SW_InitVar("VSENVIRONMENTALDAMAGE_SLIME_OTHER",{1,51},nil,nil,nil,nil);
498 SW_InitVar("VSENVIRONMENTALDAMAGE_SLIME_SELF",{51},nil,true,nil,nil);
499  
500 --1.4 removed in wow 1.10
501 -- it doesn't hurt to leave them in for easy transition 1.9->1.10
502 --[[
503 SW_InitVar("POWERGAIN_OTHER",{1,53,3},nil,nil,nil,true);
504 SW_InitVar("POWERGAIN_SELF",{53,3},nil,true,nil,true);
505 SW_InitVar("GENERICPOWERGAIN_OTHER",{1,53,3},nil,nil,nil,true);
506 SW_InitVar("GENERICPOWERGAIN_SELF",{53,3},nil,true,nil,true);
507 --]]
508  
509 --1.4 wow 1.10 changed powergain stuff
510 -- mana/ health etc isnt really a "LeechTo" but this fits best
511 -- 1.5.1 selfself and selfother changed to late sort
512 SW_InitVar("POWERGAINOTHEROTHER",{1,53,9,2,3},nil,nil,nil,nil);
513 SW_InitVar("POWERGAINOTHERSELF",{53,9,2,3},nil,true,nil,nil);
514 SW_InitVar("POWERGAINSELFOTHER",{1,53,9,3},true,nil,nil,true);
515 SW_InitVar("POWERGAINSELFSELF",{53,9,3},true,true,nil,true);
516 --1.4 wow 1.10 aura stuff
517 SW_InitVar("AURAAPPLICATIONADDEDOTHERHARMFUL",{1,3,53},nil,nil,nil,nil);
518 SW_InitVar("AURAAPPLICATIONADDEDOTHERHELPFUL",{1,3,53},nil,nil,nil,nil);
519 SW_InitVar("AURAAPPLICATIONADDEDSELFHARMFUL",{3,53},nil,true,nil,nil);
520 SW_InitVar("AURAAPPLICATIONADDEDSELFHELPFUL",{3,53},nil,true,nil,nil);
521  
522 -- 1.5.1 for decursing (could be used for more)
523 SW_InitVar("SIMPLECASTOTHEROTHER",{2,3,1},nil,nil,nil,nil);
524 SW_InitVar("SIMPLECASTOTHERSELF",{2,3},nil,true,nil,nil);
525 SW_InitVar("SIMPLECASTSELFOTHER",{3,1},true,nil,nil,nil);
526 SW_InitVar("SIMPLECASTSELFSELF",{3},true,true,nil,true);
527  
528 -- this one is very generic %s casts %s
529 -- could use this to count totem placement
530 --SW_InitVar("SPELLCASTGOOTHER",{2,3},nil,nil,nil,true);
531  
532 -- 1.5.3.beta.1 Added but not used, but will cause blocking events w/o
533 -- noticed this through the curse patchwerk kill video ;)
534 SW_InitVar("COMBATLOG_HONORGAIN",{1,3,53},true,nil,nil,nil);
535  
536 SW_SL_SetLastOk();
537 end
538  
539 local function SW_AddToMap(eventName, regexName, map)
540 if map == nil then map = SW_EventRegexMap; end
541  
542 -- first check if we have the info needed
543 --added this for WOW 1.10 POWERGAINXX changes
544 if SW_RegEx_Lookup[regexName] == nil then
545 --DEFAULT_CHAT_FRAME:AddMessage(regexName);
546  
547 return;
548 end
549 if SW_RegEx_Lookup[regexName]["r"] == nil then return; end
550  
551 if map[eventName] == nil then
552 map[eventName] ={};
553 end
554 --use insert we want to sort this later using table.sort
555 table.insert(map[eventName], regexName);
556  
557 SW_SL_RegExAdded = SW_SL_RegExAdded +1;
558 end
559  
560 --[[ this resorts SW_EventRegexMap based on the regular expression
561 to be used
562 This is done to minimize the chance of a collision
563 rule 1 -> anything that starts with a string and not a capture goes first
564 rule 2 -> if it starts with a capture not followed by a space it goes first
565 rule 3 - > less captures go first
566 rule 4 -> longer strings go first
567 ]]--
568 local function recuCheck(a, b, opt)
569  
570 local l = SW_RegEx_Lookup[a]["r"];
571 local r = SW_RegEx_Lookup[b]["r"];
572  
573 if opt == nil then
574 local sl = string.sub(l,2,2);
575 local sr = string.sub(r,2,2);
576 if sl == "(" then
577 if sr == "(" then
578 return recuCheck(a, b, 1);
579 else
580 return false;
581 end
582 else
583 if sr == "(" then
584 return true;
585 else
586 return recuCheck(a, b, 1);
587 end
588 end
589 elseif opt == 1 then
590 if SW_RegEx_Lookup[a]["ls"] and SW_RegEx_Lookup[b]["ls"] then
591 return recuCheck(a, b, 2);
592 end
593 if SW_RegEx_Lookup[a]["ls"] then
594 return false;
595 end
596 if SW_RegEx_Lookup[b]["ls"] then
597 return true;
598 end
599 return recuCheck(a, b, 2);
600 elseif opt == 2 then
601 local sl = string.sub(l,1,5);
602 local sr = string.sub(r,1,5);
603 local slf = string.sub(l,1,2);
604  
605 if sl == sr and slf == "^(" then
606  
607 sl = string.sub(l,6,6);
608 sr = string.sub(r,6,6);
609 if sl == sr then
610 return recuCheck(a, b, 3);
611 else
612 if sl == " " then
613 return false;
614 elseif sr == " " then
615 return true;
616 else
617 return recuCheck(a, b, 3);
618 end
619 end
620 else
621 return recuCheck(a, b, 3);
622 end
623  
624 elseif opt == 3 then
625 if SW_RegEx_Lookup[a]["i"] == SW_RegEx_Lookup[b]["i"] then
626 return recuCheck(a, b, 4);
627 else
628 return SW_RegEx_Lookup[a]["i"] < SW_RegEx_Lookup[b]["i"];
629 end
630 elseif opt == 4 then
631 return string.len(l) > string.len(r);
632  
633 else
634 return false;
635 end
636 end
637  
638 local function SW_finalizeMap()
639 SW_SL_Add(SW_SL["MAP_SORT"]);
640  
641 for k,v in pairs(SW_EventRegexMap) do
642 table.sort(v,
643 function(a,b)
644 return recuCheck(a,b);
645 end);
646 end
647  
648 SW_SL_SetLastOk();
649  
650 end
651  
652 function SW_CreateEventRegexMap()
653 SW_SL_Add(SW_SL["MAP"]);
654  
655 -- first we need the "dummy" for non handeled events
656 -- added an extra "dummy" for text only events --SW_DECURSEDUMMY
657 for k,_ in pairs(SW_RegEx_Lookup) do
658 if string.sub(k,1,string.len("SIMPLECAST"))=="SIMPLECAST" or string.sub(k,1,string.len("SPELLCASTGO"))=="SPELLCASTGO" then
659 SW_AddToMap(SW_DECURSEDUMMY, k);
660 else
661 SW_AddToMap(SW_DEV_EVENTDUMMY, k);
662 end
663 end
664  
665 for k,v in pairs(SW_Map) do
666 for _, regExName in pairs(v) do
667 SW_AddToMap(k, regExName);
668 end
669 end
670 for k,v in pairs(SW_EnviroMap) do
671 for _, regExName in pairs(v) do
672 SW_AddToMap(k, regExName, SW_EventRegexMapEnviro);
673 end
674 end
675  
676 SW_SL_SetLastOk();
677 SW_finalizeMap();
678  
679 -- pulling the SW_TmpMap info here, its already sorted
680 --[[
681 for i,v in ipairs(SW_EventRegexMap[SW_DEV_EVENTDUMMY]) do
682 local tmp = string.sub(SW_RegEx_Lookup[v]["r"],1,4);
683 if tmp == "(.+)" then
684 tmp = string.sub(SW_RegEx_Lookup[v]["r"],5,5);
685 if tmp ~= " " then
686 if SW_TmpMap == nil then SW_TmpMap = {}; end
687 table.insert(SW_TmpMap, v);
688 end
689 end
690 end
691 --]]
692 end;
693 -- this is called if there was no direct Event->Regexp entry
694 -- and a regex was found using the event dummy
695 function SW_lateAdd(eventName, regexName, map, saveToMap, checkDupes)
696 if checkDupes then
697 for _,v in ipairs(map[eventName]) do
698 if v == regexName then return; end
699 end
700 end
701 SW_AddToMap(eventName, regexName, map);
702 table.sort(map[eventName],
703 function(a,b)
704 return recuCheck(a,b);
705 end);
706 -- now add it to the map thats saved
707 if saveToMap ~= nil then
708 if saveToMap[eventName] == nil then
709 saveToMap[eventName] ={};
710 end
711 table.insert(saveToMap[eventName], regexName);
712 end
713  
714 end
715 ------------------------- Events to listen to --------------------------------
716  
717 --[[
718 1.5 added pausing and unpausing of data collection
719 so changed the event definition here and split it into 2 parts
720 events that have to be on always, and events that can be switched
721 --]]
722 SW_EventCollection = {
723 SW_EventsMandatory = {
724 "PLAYER_TARGET_CHANGED",
725 "VARIABLES_LOADED",
726 --"UNIT_COMBAT", hmm i wasn't using this?
727 "UNIT_PET",
728 "PARTY_MEMBERS_CHANGED",
729 "PARTY_LEADER_CHANGED",
730 "RAID_ROSTER_UPDATE",
731 "PLAYER_ENTERING_WORLD",
732  
733 -- for joining
734 "CHAT_MSG_GUILD",
735 "CHAT_MSG_OFFICER",
736 "CHAT_MSG_PARTY",
737 "CHAT_MSG_RAID",
738 "CHAT_MSG_CHANNEL",
739 -- 1.5.3 added in wow 1.11
740 "CHAT_MSG_RAID_LEADER",
741  
742 -- 1.5.beta.2 this better not be off DOH
743 "SPELLS_CHANGED",
744 },
745 SW_EventsSwitched = {
746 "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS",
747 "CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES",
748 "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS",
749 "CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES",
750 "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS",
751 "CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES",
752 "CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS",
753 "CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES",
754 "CHAT_MSG_COMBAT_FRIENDLY_DEATH",
755 "CHAT_MSG_COMBAT_HONOR_GAIN",
756 "CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS",
757 "CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES",
758 "CHAT_MSG_COMBAT_HOSTILE_DEATH",
759 "CHAT_MSG_COMBAT_LOG_ERROR",
760 "CHAT_MSG_COMBAT_LOG_MISC_INFO",
761 "CHAT_MSG_COMBAT_PARTY_HITS",
762 "CHAT_MSG_COMBAT_PARTY_MISSES",
763 "CHAT_MSG_COMBAT_PET_HITS",
764 "CHAT_MSG_COMBAT_PET_MISSES",
765 "CHAT_MSG_COMBAT_SELF_HITS",
766 "CHAT_MSG_COMBAT_SELF_MISSES",
767 "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF",
768 "CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE",
769 "CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF",
770 "CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE",
771 "CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF",
772 "CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE",
773 "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS",
774 "CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF",
775 "CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF",
776 "CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE",
777 "CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF",
778 "CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE",
779 "CHAT_MSG_SPELL_PARTY_BUFF",
780 "CHAT_MSG_SPELL_PARTY_DAMAGE",
781 "CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS",
782 "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE",
783 "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS",
784 "CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE",
785 "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS",
786 "CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE",
787 "CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS",
788 "CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE",
789 "CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS",
790 "CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE",
791 "CHAT_MSG_SPELL_PET_BUFF",
792 "CHAT_MSG_SPELL_PET_DAMAGE",
793 "CHAT_MSG_SPELL_SELF_BUFF",
794 "CHAT_MSG_SPELL_SELF_DAMAGE",
795 "PLAYER_REGEN_DISABLED",
796 "PLAYER_REGEN_ENABLED",
797  
798 -- added for 1.3.0 to get mana efficiency
799 "SPELLCAST_CHANNEL_START",
800 "SPELLCAST_STOP",
801 "SPELLCAST_FAILED",
802 "SPELLCAST_INTERRUPTED",
803  
804 -- added 1.4 for death count
805 "CHAT_MSG_COMBAT_FRIENDLY_DEATH",
806 "CHAT_MSG_COMBAT_HOSTILE_DEATH",
807 },
808  
809 }
810 function SW_UnpauseEvents()
811 local coreFrame = getglobal("SW_CoreFrame");
812 for i, val in ipairs(SW_EventCollection.SW_EventsSwitched) do
813 coreFrame:RegisterEvent(val);
814 end
815  
816 end
817 function SW_PauseEvents()
818 local coreFrame = getglobal("SW_CoreFrame");
819 for i, val in ipairs(SW_EventCollection.SW_EventsSwitched) do
820 coreFrame:UnregisterEvent(val);
821 end
822 end
823 function SW_RegisterEvents()
824 SW_SL_Add(SW_SL["EVENTS"]);
825  
826 for i, val in ipairs(SW_EventCollection.SW_EventsMandatory) do
827 this:RegisterEvent(val);
828 end
829  
830 --[[
831 -- used to check what kinds of targets are tracked
832 this:RegisterEvent("PLAYER_TARGET_CHANGED");
833 --this:RegisterEvent("CHAT_MSG_CHANNEL_LIST");
834  
835 this:RegisterEvent("VARIABLES_LOADED");
836 this:RegisterEvent("UNIT_COMBAT");
837 this:RegisterEvent("UNIT_PET");
838 this:RegisterEvent("PARTY_MEMBERS_CHANGED");
839 -- 1.4.2 added leader change
840 this:RegisterEvent("PARTY_LEADER_CHANGED");
841 this:RegisterEvent("RAID_ROSTER_UPDATE");
842 this:RegisterEvent("PLAYER_ENTERING_WORLD");
843 --this:RegisterEvent("CHAT_MSG_AFK");
844 --this:RegisterEvent("CHAT_MSG_BG_SYSTEM_ALLIANCE");
845 --this:RegisterEvent("CHAT_MSG_BG_SYSTEM_HORDE");
846 --this:RegisterEvent("CHAT_MSG_BG_SYSTEM_NEUTRAL");
847 --this:RegisterEvent("CHAT_MSG_CHANNEL_LIST");
848 this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_HITS");
849 this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_CREATURE_MISSES");
850 this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_PARTY_HITS");
851 this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_PARTY_MISSES");
852 this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS");
853 this:RegisterEvent("CHAT_MSG_COMBAT_CREATURE_VS_SELF_MISSES");
854 this:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLYPLAYER_HITS");
855 this:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLYPLAYER_MISSES");
856 this:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLY_DEATH");
857 this:RegisterEvent("CHAT_MSG_COMBAT_HONOR_GAIN");
858 this:RegisterEvent("CHAT_MSG_COMBAT_HOSTILEPLAYER_HITS");
859 this:RegisterEvent("CHAT_MSG_COMBAT_HOSTILEPLAYER_MISSES");
860 this:RegisterEvent("CHAT_MSG_COMBAT_HOSTILE_DEATH");
861 this:RegisterEvent("CHAT_MSG_COMBAT_LOG_ERROR");
862 this:RegisterEvent("CHAT_MSG_COMBAT_LOG_MISC_INFO");
863 --this:RegisterEvent("CHAT_MSG_COMBAT_MISC_INFO");
864 this:RegisterEvent("CHAT_MSG_COMBAT_PARTY_HITS");
865 this:RegisterEvent("CHAT_MSG_COMBAT_PARTY_MISSES");
866 this:RegisterEvent("CHAT_MSG_COMBAT_PET_HITS");
867 this:RegisterEvent("CHAT_MSG_COMBAT_PET_MISSES");
868 this:RegisterEvent("CHAT_MSG_COMBAT_SELF_HITS");
869 this:RegisterEvent("CHAT_MSG_COMBAT_SELF_MISSES");
870 --this:RegisterEvent("CHAT_MSG_COMBAT_XP_GAIN");
871 --this:RegisterEvent("CHAT_MSG_DND");
872 --this:RegisterEvent("CHAT_MSG_EMOTE");
873 this:RegisterEvent("CHAT_MSG_GUILD");
874 --this:RegisterEvent("CHAT_MSG_IGNORED");
875 --this:RegisterEvent("CHAT_MSG_LOOT");
876 --this:RegisterEvent("CHAT_MSG_MONSTER_EMOTE");
877 --this:RegisterEvent("CHAT_MSG_MONSTER_SAY");
878 --this:RegisterEvent("CHAT_MSG_MONSTER_WHISPER");
879 --this:RegisterEvent("CHAT_MSG_MONSTER_YELL");
880 this:RegisterEvent("CHAT_MSG_OFFICER");
881 this:RegisterEvent("CHAT_MSG_PARTY");
882 this:RegisterEvent("CHAT_MSG_RAID");
883 this:RegisterEvent("CHAT_MSG_CHANNEL");
884 --this:RegisterEvent("CHAT_MSG_SKILL");
885  
886 --this:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_OTHER");
887 --this:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_PARTY");
888 --this:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_SELF");
889 --this:RegisterEvent("CHAT_MSG_SPELL_BREAK_AURA");
890  
891 this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_CREATURE_BUFF");
892 this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_CREATURE_DAMAGE");
893 this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_PARTY_BUFF");
894 this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_PARTY_DAMAGE");
895 this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_SELF_BUFF");
896 this:RegisterEvent("CHAT_MSG_SPELL_CREATURE_VS_SELF_DAMAGE");
897 this:RegisterEvent("CHAT_MSG_SPELL_DAMAGESHIELDS_ON_OTHERS");
898 this:RegisterEvent("CHAT_MSG_SPELL_DAMAGESHIELDS_ON_SELF");
899  
900 this:RegisterEvent("CHAT_MSG_SPELL_FRIENDLYPLAYER_BUFF");
901 this:RegisterEvent("CHAT_MSG_SPELL_FRIENDLYPLAYER_DAMAGE");
902 this:RegisterEvent("CHAT_MSG_SPELL_HOSTILEPLAYER_BUFF");
903 this:RegisterEvent("CHAT_MSG_SPELL_HOSTILEPLAYER_DAMAGE");
904  
905 this:RegisterEvent("CHAT_MSG_SPELL_PARTY_BUFF");
906 this:RegisterEvent("CHAT_MSG_SPELL_PARTY_DAMAGE");
907 this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS");
908 this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE");
909 this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_BUFFS");
910 this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_FRIENDLYPLAYER_DAMAGE");
911 this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS");
912 this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE");
913 this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_PARTY_BUFFS");
914 this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_PARTY_DAMAGE");
915 this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS");
916 this:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_SELF_DAMAGE");
917 this:RegisterEvent("CHAT_MSG_SPELL_PET_BUFF");
918 this:RegisterEvent("CHAT_MSG_SPELL_PET_DAMAGE");
919 this:RegisterEvent("CHAT_MSG_SPELL_SELF_BUFF");
920 this:RegisterEvent("CHAT_MSG_SPELL_SELF_DAMAGE");
921  
922 --this:RegisterEvent("CHAT_MSG_SPELL_TRADESKILLS");
923 --this:RegisterEvent("CHAT_MSG_SYSTEM");
924 --this:RegisterEvent("CHAT_MSG_TEXT_EMOTE");
925 --this:RegisterEvent("CHAT_MSG_WHISPER");
926 --this:RegisterEvent("CHAT_MSG_WHISPER_INFORM");
927 --this:RegisterEvent("CHAT_MSG_SAY");
928  
929 --this:RegisterEvent("SPELLCAST_STOP");
930 --this:RegisterEvent("UNIT_HEALTH");
931  
932 -- added for 1.3.0 to get mana efficiency
933  
934 this:RegisterEvent("SPELLCAST_CHANNEL_START");
935 --this:RegisterEvent("SPELLCAST_START");
936 this:RegisterEvent("SPELLCAST_STOP");
937 this:RegisterEvent("SPELLCAST_FAILED");
938 this:RegisterEvent("SPELLCAST_INTERRUPTED");
939 this:RegisterEvent("SPELLS_CHANGED");
940  
941 this:RegisterEvent("PLAYER_REGEN_DISABLED");
942 this:RegisterEvent("PLAYER_REGEN_ENABLED");
943  
944 -- added 1.4 for death count
945 this:RegisterEvent("CHAT_MSG_COMBAT_FRIENDLY_DEATH");
946 this:RegisterEvent("CHAT_MSG_COMBAT_HOSTILE_DEATH");
947 --this:RegisterEvent("SPELLCAST_DELAYED");
948 --this:RegisterEvent("SPELLCAST_CHANNEL_START");
949 --this:RegisterEvent("SPELLCAST_CHANNEL_UPDATE");
950 --]]
951 SW_SL_SetLastOk();
952 end
953  
954 --[[
955 A wrapper arround timing
956 If added to saved variables (and inited again)
957 will retain cross session seconds ( and milliseconds)
958  
959 to save it accross sessions add myTimer to SavedVariables AND IN
960 VARIABLES_LOADED: myTimer = SW_C_Timer:new(myTimer);
961  
962 --]]
963 SW_C_Timer = {
964 -- epoch time at init
965 epochInit = time(),
966 -- system up time at init
967 upTimeInit = GetTime(),
968  
969 new = function (self, o)
970 o = o or {};
971 setmetatable(o, self);
972 self.__index = self;
973  
974 if o.epochTS ~= nil then
975 o.uTS = (o.epochTS + o.msO) - self.epochInit ;
976 else
977 self.setToNow(o);
978 end
979 return o;
980 end,
981  
982 setToNow = function(self)
983 self.epochTS = time();
984 self.uTS = GetTime() - self.upTimeInit;
985 -- store the millisecond offset
986 self.msO = self.uTS - (self.epochTS - self.epochInit);
987 end,
988  
989 -- now return value is not to be used cross session (don't save it)
990 now = function(self)
991 return GetTime() - self.upTimeInit;
992 end,
993  
994 elapsed = function(self)
995 return self.msRound((GetTime() - self.upTimeInit) - self.uTS);
996 end,
997  
998 -- one must be a timer object, the other value may be a number
999 -- only numbers recieved through :now() make sense
1000 __sub = function(lh, rh)
1001 if type(rh) == "number" then
1002 return lh.uTS - rh;
1003 elseif type(lh) == "number" then
1004 return lh - rh.uTS;
1005 else
1006 return lh.msRound(lh.uTS - rh.uTS);
1007 end
1008 end,
1009  
1010 msRound = function(val)
1011 return math.floor((val) * 1000 + 0.5)/1000;
1012 end,
1013 absDiff = function(self, rh)
1014 local ret = self - rh;
1015 if ret < 0 then ret = -ret; end
1016 return ret;
1017 end,
1018  
1019 -- seconds since startup
1020 SSS = function(self)
1021 return GetTime() - self.upTimeInit;
1022 end,
1023  
1024 dump = function(self)
1025 SW_DumpTable(self);
1026 end,
1027 }
1028 --------- My fun function so don't complain
1029 SW_RND_Strings = {
1030 ["CWATER"] = {
1031 "pinkelt in eine Flasche...",
1032 "erleichtert sich.",
1033 "machts euch in Kirschgeschmack.",
1034 "denkt 'Wasser, ja Wasser wollte Ich schon immer machen.'",
1035 "macht euch ein POWER drink.",
1036 "ahhh, besser!",
1037 "sammelt seine Tr\195\164nen in einer Flasche",
1038 "macht noch mehr Blubberwasser.",
1039 "sagt euch da\195\159 Er kein Bier herbeizaubern kann.",
1040 "machts euch in Pfirsichgeschmack",
1041 "zieht die Nase hoch...",
1042 "kriegt ein mulmiges Gefuehl im Magen.",
1043 },
1044 ["CBREAD"] = {
1045 "backe backe BROT!",
1046 "schmei\195\159t euch Brot an den Kopf!",
1047 "hat einen eigenartigen Gesichtsausdruck.",
1048 "PLOP!",
1049 "transmutiert Luft zu Brot.",
1050 "sucht sich ein B\195\164ckermeister.",
1051  
1052 },
1053 };
1054  
1055 function SW_GetRndString(baseIndex)
1056 if SW_RND_Strings[baseIndex] == nil then return; end
1057 local index = math.random(table.getn(SW_RND_Strings[baseIndex]));
1058 SendChatMessage(SW_RND_Strings[baseIndex][index], "EMOTE");
1059 end
1060 -------------------------- Dump Functions mostly for dev --------------------
1061  
1062 function SW_printStr(str, toChannelNR)
1063 local chNR =1;
1064 if SW_DEV_INWOW then
1065 if toChannelNR ~= nil then chNR = toChannelNR; end
1066 local con = getglobal("SW_FrameConsole_Text"..chNR.."_MsgFrame");
1067 if con ~= nil then
1068 if str == nil then
1069 con:AddMessage("NIL");
1070 elseif type(str) == "boolean" then
1071 local v2 = "Bool:false";
1072 if str then
1073 v2 = "Bool:true";
1074 end
1075 SW_printStr (v2);
1076 else
1077 con:AddMessage(str);
1078 end
1079  
1080 --con:ScrollToBottom();
1081 end
1082 else
1083 print(str);
1084 end
1085 end
1086  
1087 function SW_DumpKeys(table)
1088 if table ==nil then return; end
1089 if type(table) ~= "table" then return; end
1090 SW_printStr("-- KEYS -- ");
1091 for k, v in pairs (table) do
1092 SW_printStr(k);
1093  
1094 end
1095 end
1096 function SW_DumpTable(table, ds, ch, hideKey)
1097 if ch == nil then ch = 1; end
1098 if table ==nil then return "table is nil"; end
1099 if ds == nil then
1100 ds=""
1101 SW_printStr("----------------------");
1102 end
1103  
1104 for k, v in pairs (table) do
1105 if type(v) ~= "table" then
1106 if v == nil then
1107 if hideKey then
1108 SW_printStr (ds.."NIL", ch);
1109 else
1110 SW_printStr (ds.."["..k.."]=NIL", ch);
1111 end
1112 elseif type(v) == "boolean" then
1113 local v2 = "Bool:false";
1114 if v then
1115 v2 = "Bool:true";
1116 end
1117 if hideKey then
1118 SW_printStr (ds..v2, ch);
1119 else
1120 SW_printStr (ds.."["..k.."]="..v2, ch);
1121 end
1122 elseif type(v) == "function" then
1123 if hideKey then
1124 SW_printStr (ds.."function", ch);
1125 else
1126 SW_printStr (ds.."["..k.."]=function", ch);
1127 end
1128 else
1129 if hideKey then
1130 SW_printStr (ds..v, ch);
1131 else
1132 SW_printStr (ds.."["..k.."]="..v, ch);
1133 end
1134 end
1135 else
1136  
1137 if not hideKey then
1138 SW_printStr (ds.."["..k.."]=", ch);
1139 end
1140 SW_DumpTable(v, ds.." ");
1141 end
1142  
1143 end
1144  
1145 end
1146  
1147 function SW_DumpRegs()
1148 for k,v in pairs (SW_RegEx_Lookup) do
1149 if v["r"] == nil then
1150 SW_printStr(k.." EMPTY <- No global found with this name");
1151 else
1152 SW_printStr(k.." "..v["r"]);
1153 end
1154  
1155 end
1156 end
1157 function SW_DumpResultList(...)
1158 local i = 1;
1159 local ret = "";
1160 while arg[i] ~= nil do
1161 ret = ret..arg[i].." ";
1162 i = i + 1;
1163 end
1164 SW_printStr(ret);
1165 end
1166  
1167 function SW_DumpFMAsVar()
1168 SW_printStr("SW_DefaultMap={");
1169 for k, v in pairs (SW_DEV_FINDMATCH) do
1170 SW_printStr("\t[\""..k.."\"] = {") ;
1171 for e, _ in pairs (v) do
1172 -- dont add VSENVIRONMENTALDAMAGE
1173 if string.sub(e,1,string.len("VSENVIRONMENTALDAMAGE"))~="VSENVIRONMENTALDAMAGE" then
1174 SW_printStr("\t\t\""..e.."\",") ;
1175 end
1176  
1177  
1178 end
1179 SW_printStr("\t},") ;
1180 end
1181 SW_printStr("}");
1182 end