vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 CCWatchDetails = {
2 name = "CCWatch",
3 version = CWATCH_VERSION,
4 releaseDate = "March 27, 2006",
5 author = "phoenixfire2001&elwen",
6 website = "http://www.curse-gaming.com/mod.php?addid=3650",
7 category = MYADDONS_CATEGORY_COMBAT,
8 description = CCWATCH_DESCRIPTION,
9 optionsframe = "CCWatchOptionsFrame"
10 };
11  
12 CCWatchHelp = {
13 "/ccw : affiche les commandes possibles\n"..
14 "/ccw config : affiche l'interface graphique\n"..
15 "\n"..
16 ""
17 }
18  
19 --CCWATCH_INITIALIZATION_EVENT = "SPELL_CHANGED"
20  
21 CCWatchLoaded = false;
22  
23 CCWatchObject = nil;
24  
25 CCWATCH_MAXBARS = 5;
26  
27 CCW_EWARN_FADED = 1;
28 CCW_EWARN_APPLIED = 2;
29 CCW_EWARN_BROKEN = 4;
30 CCW_EWARN_LOWTIME = 8;
31  
32 --[[
33 local function DebugCompareStrings(str1, str2)
34 local str = "";
35 if str1 == str2 then
36 test = str1.." == "..str2;
37 else
38 local str = "";
39 local len = string.len(str1);
40 if len > string.len(str2) then
41 len = string.len(str2);
42 end
43 local i;
44 for i=1,len do
45 s1char = string.sub(str1, i, i);
46 s2char = string.sub(str1, i, i);
47 str = i.." : "..s1char.." ["..string.byte(s1char) .."] -> "..s2char.." ["..string.byte(s2char).."]";
48 if s1char ~= s2char then
49 str = str.." => DIFFERENT";
50 end
51 CCWatch_AddMessage(str);
52 end
53 end
54 end
55 --]]
56  
57 function CCWatchWarn(msg, effect, target, time)
58 local ncc = 0;
59 local cc = CCWATCH.WARNTYPE;
60 -- Emote, Say, Party, Raid, Yell, Custom:<ccname>
61 if cc == "RAID" and UnitInRaid("player") == nil then
62 cc = "PARTY";
63 end
64 if cc == "PARTY" and GetNumPartyMembers() == 0 then
65 return;
66 end
67 if cc == "CHANNEL" then
68 ncc = GetChannelName(CCWATCH.WARNCUSTOMCC);
69 end
70 if time ~= nil then
71 msg = format(msg, target, effect, time);
72 else
73 msg = format(msg, target, effect);
74 end
75 if cc == "EMOTE" then
76 msg = CCWATCH_WARN_EMOTE..msg;
77 end
78 SendChatMessage(msg, cc, nil, ncc);
79 end
80  
81 function CCWatch_Config()
82 CCWATCH.CCS = {}
83  
84 if CCWatch_ConfigCC ~= nil then
85 CCWatch_ConfigCC();
86 else
87 CCWatch_AddMessage("No CC config");
88 end
89 if CCWatch_ConfigDebuff ~= nil then
90 CCWatch_ConfigDebuff();
91 else
92 CCWatch_AddMessage("No Debuff config");
93 end
94 if CCWatch_ConfigBuff ~= nil then
95 CCWatch_ConfigBuff();
96 else
97 CCWatch_AddMessage("No Buff config");
98 end
99 end
100  
101 function CCWatch_OnLoad()
102 CCWatch_Globals();
103 CCWatch_Config();
104  
105 CCWatchObject = this;
106  
107 -- this:RegisterEvent(CCWATCH_INITIALIZATION_EVENT);
108 this:RegisterEvent("UNIT_AURA");
109 this:RegisterEvent("UNIT_COMBAT");
110  
111 if UnitLevel("player") < 60 then
112 this:RegisterEvent("CHAT_MSG_COMBAT_XP_GAIN");
113 -- TODO : add this
114 -- this:RegisterEvent("CHAT_MSG_COMBAT_HONOR_GAIN");
115 end
116 -- register this also for < 60 (pvp)
117 this:RegisterEvent("CHAT_MSG_COMBAT_HOSTILE_DEATH");
118  
119 this:RegisterEvent("CHAT_MSG_SPELL_AURA_GONE_OTHER");
120 this:RegisterEvent("CHAT_MSG_SPELL_BREAK_AURA");
121  
122 this:RegisterEvent("SPELLCAST_START");
123 this:RegisterEvent("SPELLCAST_STOP");
124 this:RegisterEvent("SPELLCAST_FAILED");
125 this:RegisterEvent("SPELLCAST_INTERRUPTED");
126  
127 this:RegisterEvent("PLAYER_TARGET_CHANGED");
128  
129 SLASH_CCWATCH1 = "/ccwatch";
130 SLASH_CCWATCH2 = "/ccw";
131 SlashCmdList["CCWATCH"] = function(msg)
132 CCWatch_SlashCommandHandler(msg);
133 end
134  
135 CCWatch_AddMessage(CCWATCH_FULLVERSION..CCWATCH_LOADED);
136 end
137  
138 function CCWatch_BarUnlock()
139 CCWATCH.STATUS = 2;
140 CCWatchCC:EnableMouse(1);
141 CCWatchDebuff:EnableMouse(1);
142 CCWatchBuff:EnableMouse(1);
143  
144 local i;
145 for i=1,CCWATCH_MAXBARS do
146 getglobal("CCWatchBarCC"..i):Show();
147 getglobal("CCWatchBarDebuff"..i):Show();
148 getglobal("CCWatchBarBuff"..i):Show();
149 end
150 end
151  
152 function CCWatch_BarLock()
153 CCWATCH.STATUS = 1;
154 CCWatchCC:EnableMouse(0);
155 CCWatchDebuff:EnableMouse(0);
156 CCWatchBuff:EnableMouse(0);
157  
158 local i;
159 for i=1,CCWATCH_MAXBARS do
160 getglobal("CCWatchBarCC"..i):Hide();
161 getglobal("CCWatchBarDebuff"..i):Hide();
162 getglobal("CCWatchBarBuff"..i):Hide();
163 end
164 end
165  
166 function CCWatch_SlashCommandHandler(msg)
167 if( msg ) then
168 local command = string.lower(msg);
169 if( command == "on" ) then
170 if( CCWATCH.STATUS == 0 ) then
171 CCWATCH.STATUS = 1;
172 CCWatch_Save[CCWATCH.PROFILE].status = CCWATCH.STATUS;
173 CCWatch_AddMessage(CCWATCH_ENABLED);
174 end
175 elseif( command == "off" ) then
176 if( CCWATCH.STATUS ~= 0 ) then
177 CCWATCH.STATUS = 0;
178 CCWatch_Save[CCWATCH.PROFILE].status = CCWATCH.STATUS;
179 CCWatch_AddMessage(CCWATCH_DISABLED);
180 end
181 elseif( command == "unlock" ) then
182 CCWatch_BarUnlock();
183 CCWatch_AddMessage(CCWATCH_UNLOCKED);
184 CCWatchOptionsFrameUnlock:SetChecked(true);
185 elseif( command == "lock" ) then
186 CCWatch_BarLock();
187 CCWatch_AddMessage(CCWATCH_LOCKED);
188 CCWatchOptionsFrameUnlock:SetChecked(false);
189 elseif( command == "invert" ) then
190 CCWATCH.INVERT = not CCWATCH.INVERT;
191 CCWatch_Save[CCWATCH.PROFILE].invert = CCWATCH.INVERT;
192 if CCWATCH.INVERT then
193 CCWatch_AddMessage(CCWATCH_INVERSION_ON);
194 else
195 CCWatch_AddMessage(CCWATCH_INVERSION_OFF);
196 end
197 CCWatchOptionsFrameInvert:SetChecked(CCWATCH.INVERT);
198 elseif( command == "timers off" ) then
199 CCWatch_Save[CCWATCH.PROFILE].timers = 0;
200 CCWATCH.TIMERS = CCWatch_Save[CCWATCH.PROFILE].timers;
201 CCWatch_AddMessage(CCWATCH_TIMERS_OFF)
202 CCWatchTimersDropDownText:SetText(CCWATCH_OPTION_TIMERS_OFF);
203 elseif( command == "timers on" ) then
204 CCWatch_Save[CCWATCH.PROFILE].timers = 1;
205 CCWATCH.TIMERS = CCWatch_Save[CCWATCH.PROFILE].timers;
206 CCWatch_AddMessage(CCWATCH_TIMERS_ON)
207 CCWatchTimersDropDownText:SetText(CCWATCH_OPTION_TIMERS_ON);
208 elseif( command == "timers rev" ) then
209 CCWatch_Save[CCWATCH.PROFILE].timers = 2;
210 CCWATCH.TIMERS = CCWatch_Save[CCWATCH.PROFILE].timers;
211 CCWatch_AddMessage(CCWATCH_TIMERS_REVERSE)
212 CCWatchTimersDropDownText:SetText(CCWATCH_OPTION_TIMERS_REVERSE);
213 elseif( command == "grow off" ) then
214 CCWatch_Save[CCWATCH.PROFILE].growth = 0;
215 CCWATCH.GROWTH = CCWatch_Save[CCWATCH.PROFILE].growth;
216 CCWatch_AddMessage(CCWATCH_GROW_OFF)
217 CCWatchGrowthDropDownText:SetText(CCWATCH_OPTION_GROWTH_OFF);
218 elseif( command == "grow up" ) then
219 CCWatch_Save[CCWATCH.PROFILE].growth = 1;
220 CCWATCH.GROWTH = CCWatch_Save[CCWATCH.PROFILE].growth;
221 CCWatch_AddMessage(CCWATCH_GROW_UP)
222 CCWatchGrowthDropDownText:SetText(CCWATCH_OPTION_GROWTH_UP);
223 elseif( command == "grow down" ) then
224 CCWatch_Save[CCWATCH.PROFILE].growth = 2;
225 CCWATCH.GROWTH = CCWatch_Save[CCWATCH.PROFILE].growth;
226 CCWatch_AddMessage(CCWATCH_GROW_DOWN)
227 CCWatchGrowthDropDownText:SetText(CCWATCH_OPTION_GROWTH_DOWN);
228 elseif( command == "clear" ) then
229 CCWatch_Save[CCWATCH.PROFILE] = nil;
230 CCWatch_Globals();
231 CCWatch_Config();
232 CCWatch_LoadVariables();
233 elseif( command == "u" ) then
234 CCWatch_Config();
235 CCWatch_LoadConfCCs();
236 CCWatch_LoadCustomCCs();
237 CCWatch_UpdateClassSpells(true);
238 elseif( command == "config" ) then
239 CCWatchOptionsFrame:Show();
240 elseif( string.sub(command, 1, 5) == "scale" ) then
241 local scale = tonumber(string.sub(command, 7))
242 if( scale <= 3.0 and scale >= 0.25 ) then
243 CCWatch_Save[CCWATCH.PROFILE].scale = scale;
244 CCWATCH.SCALE = scale;
245 CCWatchCC:SetScale(CCWATCH.SCALE);
246 CCWatchDebuff:SetScale(CCWATCH.SCALE);
247 CCWatchBuff:SetScale(CCWATCH.SCALE);
248 CCWatch_AddMessage(CCWATCH_SCALE..scale);
249 CCWatchSliderScale:SetValue(CCWATCH.SCALE);
250 else
251 CCWatch_Help()
252 end
253 elseif( string.sub(command, 1, 5) == "width" ) then
254 local width = tonumber(string.sub(command, 7))
255 if( width <= 300 and width >= 50 ) then
256 CCWatch_Save[CCWATCH.PROFILE].width = width;
257 CCWATCH.WIDTH = width;
258 CCWatch_SetWidth(CCWATCH.WIDTH);
259 CCWatch_AddMessage(CCWATCH_WIDTH..width);
260 CCWatchSliderWidth:SetValue(CCWATCH.WIDTH);
261 else
262 CCWatch_Help()
263 end
264 elseif( string.sub(command, 1, 5) == "alpha" ) then
265 local alpha = tonumber(string.sub(command, 7))
266 if( alpha <= 1 and alpha >= 0 ) then
267 CCWatch_Save[CCWATCH.PROFILE].alpha = alpha;
268 CCWATCH.ALPHA = alpha;
269 CCWatch_AddMessage(CCWATCH_ALPHA..alpha);
270 CCWatchSliderAlpha:SetValue(CCWATCH.ALPHA);
271 else
272 CCWatch_Help()
273 end
274 elseif( command == "print" ) then
275 CCWatch_AddMessage(CCWATCH_PROFILE_TEXT..CCWATCH.PROFILE);
276 if( CCWATCH.STATUS == 0 ) then
277 CCWatch_AddMessage(CCWATCH_DISABLED);
278 elseif( CCWATCH.STATUS == 2 ) then
279 CCWatch_AddMessage(CCWATCH_UNLOCKED);
280 else
281 CCWatch_AddMessage(CCWATCH_ENABLED);
282 end
283 if CCWATCH.INVERT then
284 CCWatch_AddMessage(CCWATCH_INVERSION_ON);
285 else
286 CCWatch_AddMessage(CCWATCH_INVERSION_OFF);
287 end
288 if CCWATCH.TIMERS == 0 then
289 CCWatch_AddMessage(CCWATCH_TIMERS_OFF);
290 elseif CCWATCH.TIMERS == 1 then
291 CCWatch_AddMessage(CCWATCH_TIMERS_ON);
292 else
293 CCWatch_AddMessage(CCWATCH_TIMERS_REVERSE);
294 end
295 if CCWATCH.GROWTH == 0 then
296 CCWatch_AddMessage(CCWATCH_GROW_OFF);
297 elseif CCWATCH.GROWTH == 1 then
298 CCWatch_AddMessage(CCWATCH_GROW_UP);
299 else
300 CCWatch_AddMessage(CCWATCH_GROW_DOWN);
301 end
302 CCWatch_Config();
303 CCWatch_LoadConfCCs();
304 CCWatch_LoadCustomCCs();
305 CCWatch_UpdateClassSpells(true); -- Update at the same time
306  
307 CCWatch_AddMessage(CCWATCH_SCALE..CCWATCH.SCALE);
308 CCWatch_AddMessage(CCWATCH_WIDTH..CCWATCH.WIDTH);
309 CCWatch_AddMessage(CCWATCH_ALPHA..CCWATCH.ALPHA);
310 elseif( string.sub(command, 1, 6) == "warncc" ) then
311 local cc = string.sub(command, 8);
312 if cc ~= "EMOTE" or cc ~= "SAY" or cc ~= "PARTY" or cc ~= "RAID"
313 or cc ~= "YELL" or cc ~= "CHANNEL" then
314 CCWatch_Save[CCWATCH.PROFILE].WarnCustomCC = cc;
315 CCWATCH.WARNCUSTOMCC = cc;
316 CCWatch_Save[CCWATCH.PROFILE].WarnType = "CHANNEL";
317 CCWatch_AddMessage(CCWATCH_WARNCC_CUSTOM..cc);
318 else
319 CCWatch_Save[CCWATCH.PROFILE].WarnType = cc;
320 CCWatch_AddMessage(CCWATCH_WARNCC_SETTO..cc);
321 end
322 CCWATCH.WARNTYPE = CCWatch_Save[CCWATCH.PROFILE].WarnType;
323 elseif( command == "warn" ) then
324 if CCWATCH.WARNMSG then
325 CCWATCH.WARNMSG = 0;
326 CCWatch_AddMessage(CCWATCH_WARN_DISABLED);
327 else
328 CCWATCH.WARNMSG = bit.bor(CCW_EWARN_FADED, CCW_EWARN_APPLIED, CCW_EWARN_BROKEN, CCW_EWARN_LOWTIME);
329 CCWatch_AddMessage(CCWATCH_WARN_ENABLED);
330 UpdateWarnUIPage();
331 end
332 CCWatch_Save[CCWATCH.PROFILE].WarnMsg = CCWATCH.WARNMSG;
333 else
334 CCWatch_Help();
335 end
336 end
337 end
338  
339 function CCWatch_OnEvent(event)
340 -- if ( CCWATCH.STATUS == 0 and event ~= CCWATCH_INITIALIZATION_EVENT ) then
341 if ( CCWATCH.STATUS == 0 ) then
342 return
343 end
344  
345 CCWatch_EventHandler[event](arg1, arg2, arg3, arg4, arg5);
346 end
347  
348 CCWatch_EventHandler = {}
349  
350 local SpellCast = nil;
351  
352 --CCWatch_EventHandler[CCWATCH_INITIALIZATION_EVENT] = function()
353 -- if not CCWatchObject then
354 -- if(myAddOnsFrame_Register) then
355 -- myAddOnsFrame_Register(CCWatchDetails, CCWatchHelp);
356 -- end
357 -- CCWatch_LoadVariables();
358 -- end
359 --end
360  
361 CCWatch_EventHandler["SPELLCAST_START"] = function()
362 SpellCast = arg1;
363 -- duration = arg2; -- might wanna play with it to deduce the used rank
364 end
365  
366 CCWatch_EventHandler["SPELLCAST_STOP"] = function()
367 local effect;
368 effect = SpellCast;
369 local target = UnitName("target");
370 if effect ~= nil and target ~= nil then
371 if CCWATCH.CCS[effect] then
372 local group = CCWATCH.CCS[effect].GROUP;
373 local etype = CCWATCH.CCS[effect].ETYPE;
374 local index = 0;
375 -- find the effect in the queue, if it's not there index stays 0
376 if etype == ETYPE_BUFF then
377 table.foreach( CCWATCH.GROUPSBUFF[group].EFFECT, function(k,v) if( v == effect ) then index = k end end );
378 elseif etype == ETYPE_DEBUFF then
379 table.foreach( CCWATCH.GROUPSDEBUFF[group].EFFECT, function(k,v) if( v == effect ) then index = k end end );
380 else
381 table.foreach( CCWATCH.GROUPSCC[group].EFFECT, function(k,v) if( v == effect ) then index = k end end );
382 end
383  
384 if( index ~= 0 ) then
385 -- Found the effect in a group, hence it is active, hence we are resetting it
386 CCWATCH.UNIT_AURA.TIME = GetTime();
387 CCWATCH.UNIT_AURA.TARGET = target;
388 CCWATCH.CCS[effect].TARGET = target;
389 local diff = CCWATCH.UNIT_AURA.TIME - CCWATCH.CCS[effect].TIMER_START;
390 CCWATCH.CCS[effect].TIMER_START = CCWATCH.CCS[effect].TIMER_START + diff;
391 CCWATCH.CCS[effect].TIMER_END = CCWATCH.CCS[effect].TIMER_END + diff;
392 end
393 end
394 end
395 SpellCast = nil;
396 end
397  
398 CCWatch_EventHandler["SPELLCAST_FAILED"] = function()
399 SpellCast = nil;
400 end
401  
402 CCWatch_EventHandler["SPELLCAST_INTERRUPTED"] = function()
403 SpellCast = nil;
404 end
405  
406 CCWatch_EventHandler["UNIT_AURA"] = function()
407 if( arg1 == "target") then
408 CCWATCH.UNIT_AURA.TARGET = UnitName("target");
409 CCWATCH.UNIT_AURA.TIME = GetTime();
410  
411 -- get rid of any old events so they don't clutter the queue
412 while table.getn(CCWATCH.EFFECT) > 0 and (CCWATCH.UNIT_AURA.TIME - CCWATCH.EFFECT[1].TIME) > CCWATCH.THRESHOLD do
413 CCWatch_UnqueueEvent();
414 end
415  
416 if table.getn(CCWATCH.EFFECT) > 0 then
417 CCWatch_EffectHandler[CCWATCH.EFFECT[1].STATUS]();
418 end
419 end
420 end
421  
422 CCWatch_EventHandler["PLAYER_TARGET_CHANGED"] = function()
423 if not UnitCanAttack("player", "target") then
424 return;
425 end
426 local index = 0;
427 local target = UnitName("target");
428 -- 1. Check if current target is present in the list
429 table.foreach( CCWATCH.LASTTARGETS, function(k,v) if( v.TARGET == target ) then index = k end end );
430 local ltime = GetTime();
431 if index == 0 then
432 -- 2. add it
433 CCWatch_AddLastTarget(target, ltime);
434 else
435 -- or update target time effect
436 CCWATCH.LASTTARGETS[index].TIME = ltime;
437 end
438 end
439  
440 CCWatch_EventHandler["CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE"] = function()
441 local mobname;
442 local effect;
443 for mobname, effect in string.gfind( arg1, CCWATCH_TEXT_ON ) do
444 if( CCWATCH.STYLE > 1 or CCWatch_CheckRecentTargets(mobname) ) then
445 if CCWATCH.CCS[effect] and CCWATCH.CCS[effect].MONITOR and bit.band(CCWATCH.CCS[effect].ETYPE, CCWATCH.MONITORING) ~= 0 then
446 CCWatch_QueueEvent(effect, mobname, GetTime(), 1)
447  
448 CCWatch_EffectHandler[1]();
449 end
450 end
451 end
452 end
453  
454 CCWatch_EventHandler["CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS"] = function()
455 local mobname;
456 local effect;
457 for mobname, effect in string.gfind( arg1, CCWATCH_TEXT_BUFF_ON ) do
458 if( CCWATCH.STYLE > 1 or CCWatch_CheckRecentTargets(mobname) ) then
459 if CCWATCH.CCS[effect] and CCWATCH.CCS[effect].MONITOR and bit.band(CCWATCH.CCS[effect].ETYPE, CCWATCH.MONITORING) ~=0 then
460 CCWatch_QueueEvent(effect, mobname, GetTime(), 1)
461  
462 CCWatch_EffectHandler[1]();
463 end
464 end
465 end
466 end
467  
468 CCWatch_EventHandler["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS"] = CCWatch_EventHandler["CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS"];
469 CCWatch_EventHandler["CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE"] = CCWatch_EventHandler["CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE"];
470  
471 CCWatch_EventHandler["CHAT_MSG_SPELL_AURA_GONE_OTHER"] = function()
472 local mobname;
473 local effect;
474 for effect, mobname in string.gfind( arg1, CCWATCH_TEXT_OFF ) do
475 if CCWATCH.CCS[effect] then
476 if( CCWATCH.CCS[effect].TARGET == mobname ) then
477 CCWatch_QueueEvent(effect, mobname, GetTime(), 2)
478  
479 CCWatch_EffectHandler[2]();
480 end
481 end
482 end
483 end
484  
485 CCWatch_EventHandler["CHAT_MSG_SPELL_BREAK_AURA"] = function()
486 local mobname;
487 local effect;
488 for mobname, effect in string.gfind( arg1, CCWATCH_TEXT_BREAK ) do
489 if( CCWATCH.CCS[effect] ) then
490 if( CCWATCH.CCS[effect].TARGET == mobname ) then
491 CCWatch_QueueEvent(effect, mobname, GetTime(), 3)
492  
493 CCWatch_EffectHandler[3]();
494 end
495 end
496 end
497 end
498  
499 local DeadMob = "";
500 local function CCWHandleTargetDeath(k, v)
501 if( v ) then
502 if( v.TARGET == DeadMob ) then
503 --CCWatch_AddMessage("Removing effect "..k);
504 CCWATCH.CCS[k].TIMER_END = GetTime();
505 CCWatch_RemoveEffect(k, false);
506 end
507 end
508 end
509  
510 CCWatch_EventHandler["CHAT_MSG_COMBAT_HOSTILE_DEATH"] = function()
511 local mobname;
512 for mobname in string.gfind( arg1, CCWATCH_TEXT_DIE ) do
513 -- for each effect (arg oO) check if target is current
514 DeadMob = mobname;
515 table.foreach(CCWATCH.CCS, CCWHandleTargetDeath);
516 end
517 end
518  
519 CCWatch_EventHandler["CHAT_MSG_COMBAT_XP_GAIN"] = function()
520 local mobname;
521 for mobname in string.gfind( arg1, CCWATCH_TEXT_DIEXP ) do
522 -- for each effect (arg oO) check if target is current
523 DeadMob = mobname;
524 table.foreach(CCWATCH.CCS, CCWHandleTargetDeath);
525 end
526 end
527  
528 CCWatch_EventHandler["UNIT_COMBAT"] = function()
529 if( GetComboPoints() > 0 ) then
530 CCWATCH.COMBO = GetComboPoints();
531 end
532 end
533  
534 CCWatch_EffectHandler = {}
535  
536 CCWatch_EffectHandler[0] = function()
537 -- no effect
538  
539 end
540  
541 CCWatch_EffectHandler[1] = function()
542 -- applied
543 if( CCWATCH.STYLE ~= 0 or math.abs( CCWATCH.UNIT_AURA.TIME - CCWATCH.EFFECT[1].TIME ) < CCWATCH.THRESHOLD ) then
544 local effect = CCWATCH.EFFECT[1].TYPE;
545 local mobname = CCWATCH.EFFECT[1].TARGET;
546  
547 if( GetTime() > ( CCWATCH.CCS[effect].TIMER_END + 15 ) or mobname ~= CCWATCH.CCS[effect].TARGET ) then
548 -- quick & dirty hack for shared DR between Seduce & Fear)
549 if( effect == CCWATCH_FEAR or effect == CCWATCH_SEDUCE ) then
550 CCWATCH.CCS[CCWATCH_FEAR].DIMINISH = 1;
551 CCWATCH.CCS[CCWATCH_SEDUCE].DIMINISH = 1;
552 else
553 CCWATCH.CCS[effect].DIMINISH = 1;
554 end
555 end
556  
557 CCWATCH.CCS[effect].TARGET = mobname;
558 CCWATCH.CCS[effect].PLAYER = UnitIsPlayer("target");
559 CCWATCH.CCS[effect].TIMER_START = GetTime();
560 if( CCWATCH.CCS[effect].PVPCC and CCWATCH.CCS[effect].PLAYER ) then
561 CCWATCH.CCS[effect].TIMER_END = CCWATCH.CCS[effect].TIMER_START + (CCWATCH.CCS[effect].PVPCC / CCWATCH.CCS[effect].DIMINISH);
562 else
563 CCWATCH.CCS[effect].TIMER_END = CCWATCH.CCS[effect].TIMER_START + (CCWATCH.CCS[effect].LENGTH / CCWATCH.CCS[effect].DIMINISH);
564 end
565 if( CCWATCH.CCS[effect].COMBO ) then
566 CCWATCH.CCS[effect].TIMER_END = CCWATCH.CCS[effect].TIMER_END + CCWATCH.CCS[effect].A * CCWATCH.COMBO;
567 end
568  
569 CCWatch_AddEffect(effect);
570  
571 CCWatch_UnqueueEvent();
572 if CCWATCH.CCS[effect].WARN > 0 and bit.band(CCWATCH.WARNMSG, CCW_EWARN_APPLIED) then
573 CCWatchWarn(CCWATCH_WARN_APPLIED, effect, mobname);
574 end
575 end
576 end
577  
578 CCWatch_EffectHandler[2] = function()
579 -- faded
580 local effect = CCWATCH.EFFECT[1].TYPE;
581 local target = CCWATCH.CCS[effect].TARGET;
582 local bUnqueueDone = false;
583 if( target == CCWATCH.EFFECT[1].TARGET ) then
584 -- target and CC target names match, wait for UNIT_AURA to ensure target match
585 if( CCWATCH.STYLE ~= 0 or math.abs( CCWATCH.UNIT_AURA.TIME - CCWATCH.EFFECT[1].TIME ) < CCWATCH.THRESHOLD ) then
586 CCWATCH.CCS[effect].TIMER_END = GetTime();
587 CCWatch_RemoveEffect(effect, false);
588 CCWatch_UnqueueEvent();
589 bUnqueueDone = true;
590 -- unless the debuff is gone from the target, then no need for UNIT_AURA to confirm it
591 elseif CCWATCH.STYLE == 0 and CCWatch_EffectGone(effect) then
592 CCWATCH.CCS[effect].TIMER_END = GetTime()
593 CCWatch_RemoveEffect(effect, false);
594 CCWatch_UnqueueEvent();
595 bUnqueueDone = true;
596 end
597 else
598 -- target and CC target names don't match, retargetting has occured, no need to wait for UNIT_AuRA
599 CCWATCH.CCS[effect].TIMER_END = GetTime();
600 CCWatch_RemoveEffect(effect, false);
601 CCWatch_UnqueueEvent();
602 bUnqueueDone = true;
603 end
604  
605 -- another hack, to avoid spamming, because when the effect is broken, SOMETIME, WoW also send a faded message (see combat log)
606 if bUnqueueDone and CCWATCH.CCS[effect].WARN > 0 and CCWATCH.CCS[effect].WARN ~= 3 and bit.band(CCWATCH.WARNMSG, CCW_EWARN_FADED) then
607 CCWatchWarn(CCWATCH_WARN_FADED, effect, target);
608 end
609 end
610  
611 CCWatch_EffectHandler[3] = function()
612 -- broken
613 local effect = CCWATCH.EFFECT[1].TYPE;
614 local target = CCWATCH.CCS[effect].TARGET;
615 local bUnqueueDone = false;
616 if( target == CCWATCH.EFFECT[1].TARGET ) then
617 -- target and CC target names match, wait for UNIT_AURA to ensure target match
618 if( CCWATCH.STYLE ~= 0 or math.abs( CCWATCH.UNIT_AURA.TIME - CCWATCH.EFFECT[1].TIME ) < CCWATCH.THRESHOLD ) then
619 CCWATCH.CCS[effect].TIMER_END = GetTime();
620 CCWatch_RemoveEffect(effect, false);
621 CCWatch_UnqueueEvent();
622 bUnqueueDone = true;
623 -- unless the debuff is gone from the target, then no need for UNIT_AURA to confirm it
624 elseif CCWATCH.STYLE == 0 and CCWatch_EffectGone(effect) then
625 CCWATCH.CCS[effect].TIMER_END = GetTime()
626 CCWatch_RemoveEffect(effect, false);
627 CCWatch_UnqueueEvent();
628 bUnqueueDone = true;
629 end
630 else
631 -- target and CC target names don't match, retargetting has occured, no need to wait for UNIT_AuRA
632 CCWATCH.CCS[effect].TIMER_END = GetTime();
633  
634 CCWatch_RemoveEffect(effect, false);
635 CCWatch_UnqueueEvent();
636 bUnqueueDone = true;
637 end
638 if bUnqueueDone and CCWATCH.CCS[effect].WARN > 0 and bit.band(CCWATCH.WARNMSG, CCW_EWARN_BROKEN) then
639 CCWatchWarn(CCWATCH_WARN_BROKEN, effect, target);
640 CCWATCH.CCS[effect].WARN = 3;
641 end
642 end
643  
644  
645 function CCWatch_QueueEvent(effect, mobname, time, status)
646 local effect_structure = {}
647 effect_structure.TYPE = effect;
648 effect_structure.TARGET = mobname;
649 effect_structure.TIME = time;
650 effect_structure.STATUS = status
651 table.insert( CCWATCH.EFFECT, effect_structure )
652 end
653  
654 function CCWatch_UnqueueEvent()
655 table.remove( CCWATCH.EFFECT, 1)
656 end
657  
658 function CCWatch_EffectGone(effect)
659 local i;
660 local effectgone = false; -- assume effect is gone unless we find it
661 for i = 1,16 do
662 if UnitDebuff("target", i) == CCWATCH.CCS[effect].TEXTURE then
663 effectgone = true
664 end
665 end
666 return effectgone;
667 end
668  
669 function CCWatch_AddEffect(effect)
670 -- first remove any old copies of this effect, to avoid nasty overlap and properly set diminishing returns for multi-CC
671 local group = CCWATCH.CCS[effect].group
672 local GROUPS;
673 CCWatch_RemoveEffect(effect, true)
674  
675 if CCWATCH.CCS[effect].ETYPE == ETYPE_BUFF then
676 GROUPS = CCWATCH.GROUPSBUFF;
677 elseif CCWATCH.CCS[effect].ETYPE == ETYPE_DEBUFF then
678 GROUPS = CCWATCH.GROUPSDEBUFF;
679 else
680 GROUPS = CCWATCH.GROUPSCC;
681 end
682 if CCWATCH.GROWTH == 1 then
683 group = 1
684 -- start at the bottom and find the first available bar, otherwise queue to #CCWATCH_MAXBARS
685 while group < CCWATCH_MAXBARS and table.getn(GROUPS[group].EFFECT) > 0 do
686 group = group + 1
687 end
688 CCWATCH.CCS[effect].GROUP = group
689 elseif CCWATCH.GROWTH == 2 then
690 group = CCWATCH_MAXBARS
691 -- start at the top and find the first available bar, otherwise queue to #1
692 while group > 1 and table.getn(GROUPS[group].EFFECT) > 0 do
693 group = group - 1
694 end
695 CCWATCH.CCS[effect].GROUP = group
696 end
697  
698 -- new effect goes at the head of the queue... always displaying newest effect
699 CCWatch_QueueEffect(effect)
700 end
701  
702 function CCWatch_RemoveEffect(effect, dr)
703 local group = CCWATCH.CCS[effect].GROUP;
704 local GROUPS;
705 CCWatch_UnqueueEffect(effect);
706  
707 if CCWATCH.CCS[effect].ETYPE == ETYPE_BUFF then
708 GROUPS = CCWATCH.GROUPSBUFF;
709 elseif CCWATCH.CCS[effect].ETYPE == ETYPE_DEBUFF then
710 GROUPS = CCWATCH.GROUPSDEBUFF;
711 else
712 GROUPS = CCWATCH.GROUPSCC;
713 end
714  
715 if CCWATCH.GROWTH == 1 then
716 while group < CCWATCH_MAXBARS and table.getn(GROUPS[group].EFFECT) == 0 and table.getn(GROUPS[group+1].EFFECT) > 0 do
717 local move_effect = GROUPS[group+1].EFFECT[1];
718 CCWatch_UnqueueEffect(move_effect);
719 CCWATCH.CCS[move_effect].GROUP = group
720 CCWatch_QueueEffect(move_effect);
721 group = group + 1
722 end
723 elseif CCWATCH.GROWTH == 2 then
724 while group > 1 and table.getn(GROUPS[group].EFFECT) == 0 and table.getn(GROUPS[group-1].EFFECT) > 0 do
725 local move_effect = GROUPS[group-1].EFFECT[1];
726 CCWatch_UnqueueEffect(move_effect);
727 CCWATCH.CCS[move_effect].GROUP = group
728 CCWatch_QueueEffect(move_effect);
729 group = group - 1
730 end
731 end
732  
733 -- set diminishing returns based on CCS[effect].DIMINISHES (documented in CCWatch_ConfigXX.lua)
734 if( dr and ((CCWATCH.CCS[effect].PLAYER and CCWATCH.CCS[effect].DIMINISHES > 0) or CCWATCH.CCS[effect].DIMINISHES == 1) ) then
735 -- quick & dirty hack for shared DR between Seduce & Fear)
736 if( effect == CCWATCH_FEAR or effect == CCWATCH_SEDUCE ) then
737 CCWATCH.CCS[CCWATCH_FEAR].DIMINISH = 2 * CCWATCH.CCS[CCWATCH_FEAR].DIMINISH;
738 CCWATCH.CCS[CCWATCH_SEDUCE].DIMINISH = 2 * CCWATCH.CCS[CCWATCH_SEDUCE].DIMINISH;
739 else
740 CCWATCH.CCS[effect].DIMINISH = 2 * CCWATCH.CCS[effect].DIMINISH;
741 end
742 end
743  
744 -- ensure if warnable, that WARN is set back to 1
745 -- 2 = warn at low time already sent
746 -- 3 = broken message seen so no faded message to send if any received
747 if CCWATCH.CCS[effect].WARN > 0 then
748 CCWATCH.CCS[effect].WARN = 1;
749 end
750 end
751  
752 function CCWatch_QueueEffect(effect)
753 local group = CCWATCH.CCS[effect].GROUP;
754 local GROUPS;
755 local ext = "";
756  
757 if CCWATCH.CCS[effect].ETYPE == ETYPE_BUFF then
758 GROUPS = CCWATCH.GROUPSBUFF;
759 ext = "Buff";
760 elseif CCWATCH.CCS[effect].ETYPE == ETYPE_DEBUFF then
761 GROUPS = CCWATCH.GROUPSDEBUFF;
762 ext = "Debuff";
763 else
764 GROUPS = CCWATCH.GROUPSCC;
765 ext = "CC";
766 end
767  
768 table.insert( GROUPS[group].EFFECT, 1, effect )
769  
770 local activebarText = getglobal("CCWatchBar"..ext..group.."Text");
771 activebarText:SetText(effect..": "..CCWATCH.CCS[effect].TARGET);
772  
773 -- if queue was empty show bar
774 if( table.getn(GROUPS[group].EFFECT) == 1 ) then
775 local activebar = getglobal("CCWatchBar"..ext..group);
776 activebar:Show();
777 if CCWATCH.CCS[effect].COLOR then
778 getglobal("CCWatchBar"..ext..group.."StatusBar"):SetStatusBarColor(CCWATCH.CCS[effect].COLOR.r, CCWATCH.CCS[effect].COLOR.g, CCWATCH.CCS[effect].COLOR.b);
779 end
780 end
781 end
782  
783 function CCWatch_UnqueueEffect(effect)
784 local group = CCWATCH.CCS[effect].GROUP;
785 local GROUPS;
786 local ext = "";
787  
788 if CCWATCH.CCS[effect].ETYPE == ETYPE_BUFF then
789 GROUPS = CCWATCH.GROUPSBUFF;
790 ext = "Buff";
791 elseif CCWATCH.CCS[effect].ETYPE == ETYPE_DEBUFF then
792 GROUPS = CCWATCH.GROUPSDEBUFF;
793 ext = "Debuff";
794 else
795 GROUPS = CCWATCH.GROUPSCC;
796 ext = "CC";
797 end
798  
799 local index = 0;
800 -- find the effect in the queue, if it's not there index stays 0
801 table.foreach( GROUPS[group].EFFECT, function(k,v) if( v == effect ) then index = k end end );
802 if( index ~= 0 ) then
803 -- CCWATCH.CCS[GROUPS[group].EFFECT[index]].TARGET = ""; -- resetting target for mob death removal
804 -- commented because of conflict with DR requiring to keep the target name.
805 -- the name resetting was an unneeded attempt to avoid extra unqueue
806 table.remove( GROUPS[group].EFFECT, index );
807 end
808  
809 -- if queue isn't empty set new name
810 if( table.getn(GROUPS[group].EFFECT) > 0 ) then
811 local activebarText = getglobal("CCWatchBar"..ext..group.."Text");
812 local effect = GROUPS[group].EFFECT[1];
813 activebarText:SetText(effect..": "..CCWATCH.CCS[effect].TARGET);
814 else
815 local activebarText = getglobal("CCWatchBar"..ext..group.."Text");
816 activebarText:SetText("CCWatch "..ext.." Bar "..group);
817 end
818 end
819  
820 function CCWatchBarCC_OnShow(group)
821 CCWatchBar_OnShow(group, CCWATCH.GROUPSCC, "CC");
822 end
823  
824 function CCWatchBarDebuff_OnShow(group)
825 CCWatchBar_OnShow(group, CCWATCH.GROUPSDEBUFF, "Debuff");
826 end
827  
828 function CCWatchBarBuff_OnShow(group)
829 CCWatchBar_OnShow(group, CCWATCH.GROUPSBUFF, "Buff");
830 end
831  
832 function CCWatchBar_OnShow(group, GROUPS, ext)
833 local barname = "CCWatch"..ext;
834 getglobal(barname):SetScale(CCWATCH.SCALE);
835  
836 -- local status = GetTime();
837  
838 barname = "CCWatchBar"..ext..group;
839 local activebar = getglobal(barname);
840 activebar:SetBackdropColor(0, 0, 0, 0.35);
841 activebar:SetAlpha(CCWATCH.ALPHA);
842  
843 getglobal(barname.."StatusBar"):SetStatusBarColor(CCWATCH.COTNORMALCOLOR.r, CCWATCH.COTNORMALCOLOR.g, CCWATCH.COTNORMALCOLOR.b);
844 if( table.getn(GROUPS[group].EFFECT) == 0 ) then
845 getglobal(barname.."Text"):SetText("CCWatch Bar "..ext.." "..group);
846 end
847  
848 getglobal(barname.."StatusBarSpark"):SetPoint("CENTER", barname.."StatusBar", "LEFT", 0, 0);
849 end
850  
851  
852 function CCWatchBarCC1_OnShow() CCWatchBarCC_OnShow(1) end
853 function CCWatchBarCC2_OnShow() CCWatchBarCC_OnShow(2) end
854 function CCWatchBarCC3_OnShow() CCWatchBarCC_OnShow(3) end
855 function CCWatchBarCC4_OnShow() CCWatchBarCC_OnShow(4) end
856 function CCWatchBarCC5_OnShow() CCWatchBarCC_OnShow(5) end
857  
858 function CCWatchBarDebuff1_OnShow() CCWatchBarDebuff_OnShow(1) end
859 function CCWatchBarDebuff2_OnShow() CCWatchBarDebuff_OnShow(2) end
860 function CCWatchBarDebuff3_OnShow() CCWatchBarDebuff_OnShow(3) end
861 function CCWatchBarDebuff4_OnShow() CCWatchBarDebuff_OnShow(4) end
862 function CCWatchBarDebuff5_OnShow() CCWatchBarDebuff_OnShow(5) end
863  
864 function CCWatchBarBuff1_OnShow() CCWatchBarBuff_OnShow(1) end
865 function CCWatchBarBuff2_OnShow() CCWatchBarBuff_OnShow(2) end
866 function CCWatchBarBuff3_OnShow() CCWatchBarBuff_OnShow(3) end
867 function CCWatchBarBuff4_OnShow() CCWatchBarBuff_OnShow(4) end
868 function CCWatchBarBuff5_OnShow() CCWatchBarBuff_OnShow(5) end
869  
870 function CCWatch_OnUpdate()
871 if( CCWATCH.STATUS == 0 ) then
872 return
873 end
874  
875 -- local status = GetTime();
876 table.foreach( CCWATCH.GROUPSCC, CCWatch_GroupCCUpdate );
877 table.foreach( CCWATCH.GROUPSDEBUFF, CCWatch_GroupDebuffUpdate );
878 table.foreach( CCWATCH.GROUPSBUFF, CCWatch_GroupBuffUpdate );
879 end
880  
881 function CCWatch_GroupCCUpdate(group)
882 CCWatch_GroupUpdate(group, CCWATCH.GROUPSCC, "CC");
883 end
884  
885 function CCWatch_GroupDebuffUpdate(group)
886 CCWatch_GroupUpdate(group, CCWATCH.GROUPSDEBUFF, "Debuff");
887 end
888  
889 function CCWatch_GroupBuffUpdate(group)
890 CCWatch_GroupUpdate(group, CCWATCH.GROUPSBUFF, "Buff");
891 end
892  
893 local function ComputeColor(colorhigh, colorlow, high, low, cur)
894 local factor = (cur - low) / (high - low);
895 -- should be divided by 2, but would lead to too dark cases
896 return (colorhigh.r*factor + colorlow.r*(1-factor)),
897 (colorhigh.g*factor + colorlow.g*(1-factor)),
898 (colorhigh.b*factor + colorlow.b*(1-factor));
899 end
900  
901 local function GetTheRightColorFromTime(curTime)
902 if curTime > 2 * CCWATCH.COTLOWVALUE then
903 return CCWATCH.COTNORMALCOLOR.r, CCWATCH.COTNORMALCOLOR.g, CCWATCH.COTNORMALCOLOR.b;
904 elseif curTime > CCWATCH.COTLOWVALUE then
905 return ComputeColor(CCWATCH.COTNORMALCOLOR, CCWATCH.COTLOWCOLOR, 2*CCWATCH.COTLOWVALUE, CCWATCH.COTLOWVALUE, curTime);
906 elseif curTime > CCWATCH.COTURGEVALUE then
907 return ComputeColor(CCWATCH.COTLOWCOLOR, CCWATCH.COTURGECOLOR, CCWATCH.COTLOWVALUE, CCWATCH.COTURGEVALUE, curTime);
908 else
909 return CCWATCH.COTURGECOLOR.r, CCWATCH.COTURGECOLOR.g, CCWATCH.COTURGECOLOR.b;
910 end
911 end
912  
913 function CCWatch_GroupUpdate(group, GROUPS, ext)
914 local activebar = getglobal("CCWatchBar"..ext..group)
915  
916 if( table.getn(GROUPS[group].EFFECT) > 0 ) then
917 -- active effect on this bar
918 activebar:SetAlpha(CCWATCH.ALPHA);
919  
920 local status = GetTime();
921 local effect = GROUPS[group].EFFECT[1]
922 local activebarStatusBar = getglobal("CCWatchBar"..ext..group.."StatusBar");
923 local activebarTextBar = getglobal("CCWatchBar"..ext..group.."StatusBarText");
924 local str = "";
925  
926 if( status <= CCWATCH.CCS[effect].TIMER_END ) then
927 -- CC hasn't expired
928 activebarStatusBar:SetMinMaxValues(CCWATCH.CCS[effect].TIMER_START, CCWATCH.CCS[effect].TIMER_END);
929 local sparkPosition = ((status - CCWATCH.CCS[effect].TIMER_START) / (CCWATCH.CCS[effect].TIMER_END - CCWATCH.CCS[effect].TIMER_START)) * CCWATCH.WIDTH;
930 if( CCWATCH.INVERT ) then
931 sparkPosition = CCWATCH.WIDTH - sparkPosition;
932 activebarStatusBar:SetValue(CCWATCH.CCS[effect].TIMER_START + CCWATCH.CCS[effect].TIMER_END - status);
933 else
934 activebarStatusBar:SetValue(status);
935 end
936 local elapsedTime = CCWATCH.CCS[effect].TIMER_END - status;
937 if( sparkPosition < 1 ) then
938 sparkPosition = 1;
939 end
940 local activebarSpark = getglobal("CCWatchBar"..ext..group.."StatusBarSpark");
941 activebarSpark:SetPoint("CENTER", "CCWatchBar"..ext..group.."StatusBar", "LEFT", sparkPosition, 0);
942 if CCWATCH.TIMERS == 1 then
943 str = format("%.2f", status - CCWATCH.CCS[effect].TIMER_START);
944 elseif CCWATCH.TIMERS == 2 then
945 str = format("%.2f", elapsedTime);
946 end
947 activebarTextBar:SetText(str);
948 if CCWATCH.COLOROVERTIME and not CCWATCH.CCS[effect].COLOR then
949 local r, g, b = GetTheRightColorFromTime(elapsedTime);
950 activebarStatusBar:SetStatusBarColor(r, g, b);
951 end
952  
953 if CCWATCH.CCS[effect].WARN > 0 and bit.band(CCWATCH.WARNMSG, CCW_EWARN_LOWTIME) then
954 if CCWATCH.CCS[effect].TIMER_END - CCWATCH.CCS[effect].TIMER_START > CCWATCH.WARNLOW and CCWATCH.WARNLOW > elapsedTime then
955 if CCWATCH.CCS[effect].WARN == 1 then
956 CCWatchWarn(CCWATCH_WARN_LOWTIME, effect, CCWATCH.CCS[effect].TARGET, CCWATCH.WARNLOW);
957 CCWATCH.CCS[effect].WARN = 2;
958 end
959 elseif CCWATCH.CCS[effect].WARN == 2 then -- reset if ever disconnected while fighting
960 CCWATCH.CCS[effect].WARN = 1;
961 end
962 end
963 elseif status > CCWATCH.CCS[effect].TIMER_END + 0.2 then
964 -- CC has expired. Try to leave room for a fade effect to be catched, then remove anyway
965 CCWatch_RemoveEffect(effect, false)
966 end
967  
968 elseif( activebar:GetAlpha() > 0 ) then
969 -- otherwise fade out this bar if not unlocked
970 if( CCWATCH.STATUS == 1 ) then
971 local activebarText = getglobal("CCWatchBar"..ext..group.."Text");
972 activebarText:SetText("TimeOut");
973 local alpha = activebar:GetAlpha() - 0.2;
974 if( alpha > 0 ) then
975 activebar:SetAlpha(alpha);
976 else
977 activebar:Hide();
978 end
979 end
980 else
981 -- done fading, hide this bar
982 activebar:Hide();
983 end
984 end
985  
986 local function GetConfCC(k, v)
987 --CCWatch_AddMessage("Updating conf for : "..k);
988 if CCWATCH.CCS[k] then
989 CCWATCH.CCS[k].MONITOR = v.MONITOR;
990 CCWATCH.CCS[k].WARN = v.WARN;
991 CCWATCH.CCS[k].COLOR = v.COLOR;
992 end
993 end
994  
995 local function GetSavedCC(k, v)
996 if v == nil then
997 --CCWatch_AddMessage("Removing "..k);
998 CCWATCH.CCS[k] = nil;
999 return;
1000 end
1001 if v.GROUP == nil or v.ETYPE == nil or v.LENGTH == nil or v.DIMINISHES == nil then
1002 CCWATCH.CCS[k] = nil;
1003 return;
1004 end
1005 --CCWatch_AddMessage("Adding "..k.." ("..type(k)..")");
1006 CCWATCH.CCS[k] = {
1007 GROUP = v.GROUP,
1008 ETYPE = v.ETYPE,
1009 LENGTH = v.LENGTH,
1010 DIMINISHES = v.DIMINISHES,
1011 WARN = v.WARN,
1012 COLOR = v.COLOR,
1013  
1014 TARGET = "",
1015 PLAYER = nil,
1016 TIMER_START = 0,
1017 TIMER_END = 0,
1018 DIMINISH = 1,
1019 MONITOR = true
1020 }
1021 end
1022  
1023  
1024 function CCWatch_LoadConfCCs()
1025 -- update array with CC conf
1026 table.foreach(CCWatch_Save[CCWATCH.PROFILE].ConfCC, GetConfCC);
1027 end
1028  
1029 function CCWatch_LoadCustomCCs()
1030 -- update array with saved CCs
1031 table.foreach(CCWatch_Save[CCWATCH.PROFILE].SavedCC, GetSavedCC);
1032 end
1033  
1034 function CCWatch_LoadVariablesOnUpdate(arg1)
1035 if not CCWATCH.LOADEDVARIABLES then
1036 if(myAddOnsFrame_Register) then
1037 myAddOnsFrame_Register(CCWatchDetails, CCWatchHelp);
1038 end
1039 CCWatch_LoadVariables();
1040 CCWATCH.LOADEDVARIABLES = true;
1041 end
1042 end
1043  
1044 function CCWatch_LoadVariables()
1045 CCWATCH.PROFILE = UnitName("player").." of "..GetCVar("RealmName");
1046  
1047 if CCWatch_Save[CCWATCH.PROFILE] == nil then
1048 CCWatch_Save[CCWATCH.PROFILE] = {};
1049 end
1050  
1051 if CCWatch_Save[CCWATCH.PROFILE].SavedCC == nil then
1052 CCWatch_Save[CCWATCH.PROFILE].SavedCC = {};
1053 end
1054  
1055 if CCWatch_Save[CCWATCH.PROFILE].ConfCC == nil then
1056 CCWatch_Save[CCWATCH.PROFILE].ConfCC = {};
1057 end
1058  
1059 if CCWatch_Save[CCWATCH.PROFILE].status == nil then
1060 CCWatch_Save[CCWATCH.PROFILE].status = CCWATCH.STATUS;
1061 end
1062  
1063 if CCWatch_Save[CCWATCH.PROFILE].invert == nil then
1064 CCWatch_Save[CCWATCH.PROFILE].invert = false;
1065 end
1066  
1067 if CCWatch_Save[CCWATCH.PROFILE].growth == nil then
1068 CCWatch_Save[CCWATCH.PROFILE].growth = 0;
1069 end
1070  
1071 if CCWatch_Save[CCWATCH.PROFILE].scale == nil then
1072 CCWatch_Save[CCWATCH.PROFILE].scale = 1;
1073 end
1074  
1075 if CCWatch_Save[CCWATCH.PROFILE].width == nil then
1076 CCWatch_Save[CCWATCH.PROFILE].width = 160;
1077 end
1078  
1079 if CCWatch_Save[CCWATCH.PROFILE].alpha == nil then
1080 CCWatch_Save[CCWATCH.PROFILE].alpha = 1;
1081 end
1082  
1083 if CCWatch_Save[CCWATCH.PROFILE].arcanist == nil then
1084 CCWatch_Save[CCWATCH.PROFILE].arcanist = false;
1085 end
1086  
1087 if CCWatch_Save[CCWATCH.PROFILE].timers == nil then
1088 CCWatch_Save[CCWATCH.PROFILE].timers = 1;
1089 end
1090  
1091 if CCWatch_Save[CCWATCH.PROFILE].style == nil then
1092 CCWatch_Save[CCWATCH.PROFILE].style = 0;
1093 end
1094  
1095 if CCWatch_Save[CCWATCH.PROFILE].Monitoring == nil then
1096 CCWatch_Save[CCWATCH.PROFILE].Monitoring = bit.bor(ETYPE_CC, ETYPE_DEBUFF, ETYPE_BUFF);
1097 end
1098  
1099 if CCWatch_Save[CCWATCH.PROFILE].WarnType == nil then
1100 CCWatch_Save[CCWATCH.PROFILE].WarnType = "PARTY";
1101 end
1102  
1103 if CCWatch_Save[CCWATCH.PROFILE].WarnLow == nil then
1104 CCWatch_Save[CCWATCH.PROFILE].WarnLow = 10;
1105 end
1106  
1107 if CCWatch_Save[CCWATCH.PROFILE].WarnMsg == nil then
1108 CCWatch_Save[CCWATCH.PROFILE].WarnMsg = bit.bor(CCW_EWARN_FADED, CCW_EWARN_APPLIED, CCW_EWARN_BROKEN, CCW_EWARN_LOWTIME);
1109 end
1110  
1111 if CCWatch_Save[CCWATCH.PROFILE].WarnCustomCC == nil then
1112 CCWatch_Save[CCWATCH.PROFILE].WarnCustomCC = "";
1113 end
1114  
1115 if CCWatch_Save[CCWATCH.PROFILE].ColorOverTime == nil then
1116 CCWatch_Save[CCWATCH.PROFILE].ColorOverTime = false;
1117 end
1118  
1119 if CCWatch_Save[CCWATCH.PROFILE].CoTUrgeColor == nil then
1120 CCWatch_Save[CCWATCH.PROFILE].CoTUrgeColor = { r=1, g=0, b=0 };
1121 end
1122  
1123 if CCWatch_Save[CCWATCH.PROFILE].CoTLowColor == nil then
1124 CCWatch_Save[CCWATCH.PROFILE].CoTLowColor = { r=1, g=0.5, b=0 };
1125 end
1126  
1127 if CCWatch_Save[CCWATCH.PROFILE].CoTNormalColor == nil then
1128 CCWatch_Save[CCWATCH.PROFILE].CoTNormalColor = { r=1, g=1, b=0 };
1129 end
1130  
1131 if CCWatch_Save[CCWATCH.PROFILE].CoTUrgeValue == nil then
1132 CCWatch_Save[CCWATCH.PROFILE].CoTUrgeValue = 1;
1133 end
1134  
1135 if CCWatch_Save[CCWATCH.PROFILE].CoTLowValue == nil then
1136 CCWatch_Save[CCWATCH.PROFILE].CoTLowValue = 5;
1137 end
1138  
1139 if CCWatch_Save[CCWATCH.PROFILE].LeadingTimer == nil then
1140 CCWatch_Save[CCWATCH.PROFILE].LeadingTimer = true;
1141 end
1142  
1143 CCWATCH.ARCANIST = CCWatch_Save[CCWATCH.PROFILE].arcanist;
1144  
1145 CCWatch_LoadConfCCs();
1146 CCWatch_LoadCustomCCs();
1147 CCWatch_UpdateTextures();
1148 -- CCWatch_UpdateClassSpells(false);
1149 CCWatch_UpdateClassSpells(true);
1150  
1151 CCWATCH.STATUS = CCWatch_Save[CCWATCH.PROFILE].status;
1152 CCWATCH.INVERT = CCWatch_Save[CCWATCH.PROFILE].invert;
1153 CCWATCH.TIMERS = CCWatch_Save[CCWATCH.PROFILE].timers;
1154 CCWATCH.GROWTH = CCWatch_Save[CCWATCH.PROFILE].growth;
1155 CCWATCH.SCALE = CCWatch_Save[CCWATCH.PROFILE].scale;
1156 CCWATCH.WIDTH = CCWatch_Save[CCWATCH.PROFILE].width;
1157 CCWATCH.ALPHA = CCWatch_Save[CCWATCH.PROFILE].alpha;
1158  
1159 CCWATCH.MONITORING = CCWatch_Save[CCWATCH.PROFILE].Monitoring;
1160 CCWATCH.WARNTYPE = CCWatch_Save[CCWATCH.PROFILE].WarnType;
1161 CCWATCH.WARNLOW = CCWatch_Save[CCWATCH.PROFILE].WarnLow;
1162 CCWATCH.WARNMSG = CCWatch_Save[CCWATCH.PROFILE].WarnMsg;
1163 CCWATCH.WARNCUSTOMCC = CCWatch_Save[CCWATCH.PROFILE].WarnCustomCC;
1164 CCWATCH.COLOROVERTIME = CCWatch_Save[CCWATCH.PROFILE].ColorOverTime;
1165 CCWATCH.COTURGECOLOR = CCWatch_Save[CCWATCH.PROFILE].CoTUrgeColor;
1166 CCWATCH.COTLOWCOLOR = CCWatch_Save[CCWATCH.PROFILE].CoTLowColor;
1167 CCWATCH.COTNORMALCOLOR = CCWatch_Save[CCWATCH.PROFILE].CoTNormalColor;
1168 CCWATCH.COTURGEVALUE = CCWatch_Save[CCWATCH.PROFILE].CoTUrgeValue;
1169 CCWATCH.COTLOWVALUE = CCWatch_Save[CCWATCH.PROFILE].CoTLowValue;
1170  
1171 CCWATCH.LEADINGTIMER = CCWatch_Save[CCWATCH.PROFILE].LeadingTimer;
1172 CCWatch_SetLeadingTimer(CCWATCH.LEADINGTIMER);
1173  
1174 if bit.band(CCWATCH.MONITORING, ETYPE_CC) ~= 0 or bit.band(CCWATCH.MONITORING, ETYPE_DEBUFF) ~= 0 then
1175 CCWatchObject:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE");
1176 CCWatchObject:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_DAMAGE");
1177 end
1178 if bit.band(CCWATCH.MONITORING, ETYPE_BUFF) ~= 0 then
1179 CCWatchObject:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_CREATURE_BUFFS");
1180 CCWatchObject:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_HOSTILEPLAYER_BUFFS");
1181 end
1182  
1183 CCWATCH.STYLE = CCWatch_Save[CCWATCH.PROFILE].style;
1184  
1185 CCWatchCC:SetScale(CCWATCH.SCALE);
1186 CCWatchDebuff:SetScale(CCWATCH.SCALE);
1187 CCWatchBuff:SetScale(CCWATCH.SCALE);
1188 CCWatch_SetWidth(CCWATCH.WIDTH);
1189  
1190 if( CCWATCH.STATUS == 2 ) then
1191 CCWatch_BarUnlock();
1192 end
1193  
1194 CCWatchOptions_Init();
1195  
1196 CCWatch_BarLock();
1197  
1198 -- Pure cosmetic for Unlock move
1199 local i;
1200 for i=1,CCWATCH_MAXBARS do
1201 getglobal("CCWatchBarCC"..i.."StatusBarText"):SetText("0.00");
1202 getglobal("CCWatchBarDebuff"..i.."StatusBarText"):SetText("0.00");
1203 getglobal("CCWatchBarBuff"..i.."StatusBarText"):SetText("0.00");
1204 end
1205 end
1206  
1207 function CCWatch_SetLeadingTimer(bLeading)
1208 local point;
1209 local relpoint;
1210 if bLeading then
1211 point = "RIGHT";
1212 relpoint = "LEFT";
1213 else
1214 point = "LEFT";
1215 relpoint = "RIGHT";
1216 end
1217  
1218 local i;
1219 local bar;
1220 for i=1,CCWATCH_MAXBARS do
1221 bar = getglobal("CCWatchBarCC"..i.."StatusBarText");
1222 bar:ClearAllPoints();
1223 bar:SetPoint(point, getglobal("CCWatchBarCC"..i.."StatusBar"), relpoint);
1224  
1225 bar = getglobal("CCWatchBarDebuff"..i.."StatusBarText");
1226 bar:ClearAllPoints();
1227 bar:SetPoint(point, getglobal("CCWatchBarDebuff"..i.."StatusBar"), relpoint);
1228  
1229 bar = getglobal("CCWatchBarBuff"..i.."StatusBarText");
1230 bar:ClearAllPoints();
1231 bar:SetPoint(point, getglobal("CCWatchBarBuff"..i.."StatusBar"), relpoint);
1232 end
1233 end
1234  
1235  
1236 function CCWatch_UpdateTextures()
1237 local i = 1
1238 while true do
1239 local name, rank = GetSpellName(i, BOOKTYPE_SPELL)
1240 if not name then return end
1241 if CCWATCH.CCS[name] then
1242 CCWATCH.CCS[name].TEXTURE = GetSpellTexture(i, BOOKTYPE_SPELL)
1243 elseif CCWATCH_SPELLS[name] then
1244 if CCWATCH_SPELLS[name].EFFECTNAME then
1245 CCWATCH.CCS[CCWATCH_SPELLS[name].EFFECTNAME].TEXTURE = GetSpellTexture(i, BOOKTYPE_SPELL);
1246 else
1247 CCWatch_AddMessage("Warning : ranked spell '"..name.."' has a different name from its effect, but no effect name in its definition.");
1248 end
1249 end
1250 i = i + 1
1251 end
1252 end
1253  
1254 function CCWatch_UpdateImpGouge(bPrint)
1255 local talentname, texture, _, _, rank, _, _, _ = GetTalentInfo( 2, 1 );
1256 if texture then
1257 if bPrint then
1258 CCWatch_AddMessage(talentname.." "..CCWATCH_RANK.." "..rank.." "..CCWATCH_DETECTED);
1259 end
1260 if rank ~= 0 then
1261 CCWATCH.CCS[CCWATCH_GOUGE].LENGTH = 4 + rank * 0.5;
1262 end
1263 elseif CCWATCH.CCS[CCWATCH_GOUGE].LENGTH == nil then
1264 CCWATCH.CCS[CCWATCH_GOUGE].LENGTH = 4;
1265 end
1266 end
1267  
1268 function CCWatch_UpdateImpGarotte(bPrint)
1269 local talentname, texture, _, _, rank, _, _, _ = GetTalentInfo( 3, 8 );
1270 if texture then
1271 if bPrint then
1272 CCWatch_AddMessage(talentname.." "..CCWATCH_RANK.." "..rank.." "..CCWATCH_DETECTED);
1273 end
1274 if rank ~= 0 then
1275 CCWATCH.CCS[CCWATCH_GAROTTE].LENGTH = 18 + rank * 3;
1276 end
1277 elseif CCWATCH.CCS[CCWATCH_GAROTTE].LENGTH == nil then
1278 CCWATCH.CCS[CCWATCH_GAROTTE].LENGTH = 18;
1279 end
1280 end
1281  
1282 function CCWatch_UpdateKidneyShot(bPrint)
1283 local i = 1
1284 while true do
1285 local name, rank = GetSpellName(i, BOOKTYPE_SPELL)
1286 if not name then
1287 if( CCWATCH.CCS[CCWATCH_KS].LENGTH == nil ) then
1288 CCWATCH.CCS[CCWATCH_KS].LENGTH = 1;
1289 end
1290 return
1291 end
1292  
1293 if( name == CCWATCH_KS ) then
1294 if bPrint then
1295 CCWatch_AddMessage(name.." "..CCWATCH_RANK.." "..rank.." "..CCWATCH_DETECTED);
1296 end
1297 if( string.sub(rank,string.len(rank)) == "1" ) then
1298 CCWATCH.CCS[CCWATCH_KS].LENGTH = 0;
1299 else
1300 CCWATCH.CCS[CCWATCH_KS].LENGTH = 1;
1301 end
1302 return
1303 end
1304  
1305 i = i + 1
1306 end
1307 end
1308  
1309 function CCWatch_UpdateImpTrap(bPrint)
1310 local talentname, texture, _, _, rank, _, _, _ = GetTalentInfo( 3, 7 );
1311 if texture then
1312 if bPrint then
1313 CCWatch_AddMessage(talentname.." "..CCWATCH_RANK.." "..rank.." "..CCWATCH_DETECTED);
1314 end
1315 if rank ~= 0 then
1316 -- Freezing Trap is a true multi rank, hence already updated
1317 CCWATCH.CCS[CCWATCH_FREEZINGTRAP].LENGTH = CCWATCH.CCS[CCWATCH_FREEZINGTRAP].LENGTH * (1 + rank * 0.15);
1318 end
1319 end
1320 end
1321  
1322  
1323 function CCWatch_UpdateImpSeduce(bPrint)
1324 local talentname, texture, _, _, rank, _, _, _ = GetTalentInfo( 2, 7 );
1325 if texture then
1326 if bPrint then
1327 CCWatch_AddMessage(talentname.." "..CCWATCH_RANK.." "..rank.." "..CCWATCH_DETECTED);
1328 end
1329 if rank ~= 0 then
1330 CCWATCH.CCS[CCWATCH_SEDUCE].LENGTH = 15 * (1 + rank * 0.10);
1331 end
1332 end
1333 end
1334  
1335  
1336 function CCWatch_UpdateBrutalImpact(bPrint)
1337 local talentname, texture, _, _, rank, _, _, _ = GetTalentInfo( 2, 4 );
1338 if texture then
1339 if bPrint then
1340 CCWatch_AddMessage(talentname.." "..CCWATCH_RANK.." "..rank.." "..CCWATCH_DETECTED);
1341 end
1342 if rank ~= 0 then
1343 -- Bash is a true multi rank, hence already updated
1344 CCWATCH.CCS[CCWATCH_POUNCE].LENGTH = 2 + rank * 0.50;
1345 CCWATCH.CCS[CCWATCH_BASH].LENGTH = CCWATCH.CCS[CCWATCH_BASH].LENGTH + rank * 0.50;
1346 end
1347 end
1348 end
1349  
1350  
1351 function CCWatch_UpdatePermafrost(bPrint)
1352 local talentname, texture, _, _, rank, _, _, _ = GetTalentInfo( 3, 2 );
1353 if texture then
1354 if bPrint then
1355 CCWatch_AddMessage(talentname.." "..CCWATCH_RANK.." "..rank.." "..CCWATCH_DETECTED);
1356 end
1357 if rank ~= 0 then
1358 -- Frostbolt is a true multi rank, hence already updated
1359 CCWATCH.CCS[CCWATCH_CONEOFCOLD].LENGTH = 8 + 0.50 + rank * 0.50;
1360 CCWATCH.CCS[CCWATCH_FROSTBOLT].LENGTH = CCWATCH.CCS[CCWATCH_FROSTBOLT].LENGTH + 0.50 + rank * 0.50;
1361 end
1362 end
1363 end
1364  
1365 function CCWatch_UpdateImpShadowWordPain(bPrint)
1366 local talentname, texture, _, _, rank, _, _, _ = GetTalentInfo( 3, 4 );
1367 if texture then
1368 if bPrint then
1369 CCWatch_AddMessage(talentname.." "..CCWATCH_RANK.." "..rank.." "..CCWATCH_DETECTED);
1370 end
1371 if rank ~= 0 then
1372 CCWATCH.CCS[CCWATCH_SHADOWWORDPAIN].LENGTH = 18 + rank * 3;
1373 end
1374 end
1375 end
1376  
1377  
1378 function CCWatch_GetSpellRank(spellname, spelleffect, bPrint)
1379 local i = 1;
1380 local gotone = false;
1381 local maxrank = CCWATCH_SPELLS[spellname].RANKS;
1382  
1383 while true do
1384 local name, rank = GetSpellName(i, BOOKTYPE_SPELL)
1385  
1386 if not name then
1387 if not gotone then
1388 if bPrint then
1389 CCWatch_AddMessage(spellname.." "..CCWATCH_NOTDETECTED);
1390 end
1391 if( CCWATCH.CCS[spelleffect].LENGTH == nil ) then
1392 CCWATCH.CCS[spelleffect].LENGTH = CCWATCH_SPELLS[spellname].DURATION[maxrank];
1393 end
1394 end
1395 return;
1396 end
1397  
1398 if( name == spellname ) then
1399 local currank = 1;
1400 while currank <= maxrank do
1401 if( tonumber(string.sub(rank,string.len(rank))) == currank) then
1402 if bPrint then
1403 CCWatch_AddMessage(spellname.." "..CCWATCH_RANK.." "..currank.." "..CCWATCH_DETECTED);
1404 end
1405  
1406 CCWATCH.CCS[spelleffect].LENGTH = CCWATCH_SPELLS[spellname].DURATION[currank];
1407 gotone = true;
1408 end
1409 currank = currank + 1;
1410 end
1411 end
1412  
1413 i = i + 1
1414 end
1415 end
1416  
1417 function CCWatch_UpdateClassSpells(bPrint)
1418 local _, eclass = UnitClass("player");
1419 CCWatchOptionsFrameArcanist:Hide();
1420 if eclass == "ROGUE" then
1421 CCWatch_GetSpellRank(CCWATCH_SAP, CCWATCH_SAP, bPrint);
1422 CCWatch_UpdateImpGouge(bPrint);
1423 CCWatch_UpdateKidneyShot(bPrint);
1424 if CCWatch_ConfigBuff ~= nil then
1425 CCWatch_UpdateImpGarotte(bPrint);
1426 end
1427 elseif eclass == "WARLOCK" then
1428 CCWatch_GetSpellRank(CCWATCH_FEAR, CCWATCH_FEAR, bPrint);
1429 CCWatch_GetSpellRank(CCWATCH_BANISH, CCWATCH_BANISH, bPrint);
1430 CCWatch_UpdateImpSeduce(bPrint);
1431 elseif eclass == "PALADIN" then
1432 CCWatch_GetSpellRank(CCWATCH_HOJ, CCWATCH_HOJ, bPrint);
1433 if CCWatch_ConfigBuff ~= nil then
1434 CCWatch_GetSpellRank(CCWATCH_DIVINESHIELD, CCWATCH_DIVINESHIELD, bPrint);
1435 end
1436 elseif eclass == "HUNTER" then
1437 CCWatch_GetSpellRank(CCWATCH_FREEZINGTRAP_SPELL, CCWATCH_FREEZINGTRAP, bPrint);
1438 CCWatch_GetSpellRank(CCWATCH_SCAREBEAST, CCWATCH_SCAREBEAST, bPrint);
1439 CCWatch_UpdateImpTrap(bPrint);
1440 elseif eclass == "PRIEST" then
1441 CCWatch_GetSpellRank(CCWATCH_SHACKLE, CCWATCH_SHACKLE, bPrint);
1442 if CCWatch_ConfigDebuff ~= nil then
1443 CCWatch_UpdateImpShadowWordPain(bPrint);
1444 end
1445 elseif eclass == "MAGE" then
1446 CCWatch_GetSpellRank(CCWATCH_POLYMORPH, CCWATCH_POLYMORPH, bPrint);
1447 if CCWatch_ConfigDebuff ~= nil then
1448 CCWatch_GetSpellRank(CCWATCH_FROSTBOLT, CCWATCH_FROSTBOLT, bPrint);
1449 CCWatch_GetSpellRank(CCWATCH_FIREBALL, CCWATCH_FIREBALL, bPrint);
1450 CCWatch_UpdatePermafrost(bPrint);
1451 end
1452 CCWatchOptionsFrameArcanist:Show();
1453 if CCWATCH.ARCANIST then
1454 CCWATCH.CCS[CCWATCH_POLYMORPH].LENGTH = CCWATCH.CCS[CCWATCH_POLYMORPH].LENGTH + 15;
1455 end
1456 elseif eclass == "DRUID" then
1457 CCWatch_GetSpellRank(CCWATCH_ROOTS, CCWATCH_ROOTS, bPrint);
1458 CCWatch_GetSpellRank(CCWATCH_HIBERNATE, CCWATCH_HIBERNATE, bPrint);
1459 CCWatch_GetSpellRank(CCWATCH_BASH, CCWATCH_BASH, bPrint);
1460 CCWatch_UpdateBrutalImpact(bPrint);
1461 end
1462 end
1463  
1464 function CCWatch_Help()
1465 CCWatch_AddMessage(CCWATCH_FULLVERSION..CCWATCH_HELP1);
1466 CCWatch_AddMessage(CCWATCH_HELP2);
1467 CCWatch_AddMessage(CCWATCH_HELP3);
1468 CCWatch_AddMessage(CCWATCH_HELP4);
1469 CCWatch_AddMessage(CCWATCH_HELP5);
1470 CCWatch_AddMessage(CCWATCH_HELP6);
1471 CCWatch_AddMessage(CCWATCH_HELP7);
1472 CCWatch_AddMessage(CCWATCH_HELP8);
1473 CCWatch_AddMessage(CCWATCH_HELP9);
1474 CCWatch_AddMessage(CCWATCH_HELP10);
1475 CCWatch_AddMessage(CCWATCH_HELP11);
1476 CCWatch_AddMessage(CCWATCH_HELP12);
1477 CCWatch_AddMessage(CCWATCH_HELP13);
1478 CCWatch_AddMessage(CCWATCH_HELP14);
1479 CCWatch_AddMessage(CCWATCH_HELP15);
1480 CCWatch_AddMessage(CCWATCH_HELP16);
1481 CCWatch_AddMessage(CCWATCH_HELP17);
1482 end
1483  
1484 function CCWatch_SetWidth(width)
1485 local i, j, k;
1486 for j, k in ipairs({"CC","Debuff","Buff"}) do
1487 for i=1,CCWATCH_MAXBARS do
1488 getglobal("CCWatchBar"..k..i):SetWidth(width + 10);
1489 getglobal("CCWatchBar"..k..i.."Text"):SetWidth(width);
1490 getglobal("CCWatchBar"..k..i.."StatusBar"):SetWidth(width);
1491 end
1492 getglobal("CCWatch"..k):SetWidth(width + 10);
1493 end
1494 end
1495  
1496  
1497  
1498 function CCWatch_CheckRecentTargets(mobname)
1499 local target = UnitName("target");
1500 -- Simple compare if using current target monitoring
1501 if CCWATCH.STYLE == 0 then
1502 return mobname == target;
1503 end
1504 local index = 0;
1505 -- Check mobname against the list
1506 table.foreach( CCWATCH.LASTTARGETS, function(k,v) if( v.TARGET == mobname ) then index = k end end );
1507 if index ~= 0 then
1508 return true;
1509 end
1510  
1511 -- return false if target not found
1512 return false;
1513 end
1514  
1515 function CCWatch_AddLastTarget(mobname, time)
1516 local lt_struct = {}
1517 lt_struct.TARGET = mobname;
1518 lt_struct.TIME = time;
1519  
1520 -- CCWatch_AddMessage("Adding "..mobname);
1521  
1522 -- if the array is full
1523 if table.getn(CCWATCH.LASTTARGETS) >= 5 then
1524 -- remove the oldest target
1525 local oldest = 0;
1526 local index = 0;
1527 table.foreach(CCWATCH.LASTTARGETS, function(k,v) if oldest == 0 then oldest = v.TIME; index = k; elseif( v.TIME < oldest ) then oldest = v.TIME; index = k; end end);
1528 -- CCWatch_AddMessage("Removing old target : "..CCWATCH.LASTTARGETS[index].TARGET);
1529 table.remove(CCWATCH.LASTTARGETS, index);
1530 end
1531 table.insert( CCWATCH.LASTTARGETS, lt_struct )
1532 -- DEBUG :
1533 -- local targets = "Current targets : "
1534 -- table.foreach(CCWATCH.LASTTARGETS, function(k,v) targets = targets.."'"..v.TARGET.."',"; end);
1535 -- CCWatch_AddMessage(targets);
1536 end
1537  
1538 function CCWatch_AddMessage(msg)
1539 DEFAULT_CHAT_FRAME:AddMessage("<CCWatch> "..msg);
1540 end