vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 -- Locally bound frame cache
2 local frameCache = CT_RA_Cache;
3  
4 -- CT_RA_CustomOnClickFunction
5  
6 -- Set this variable (CT_RA_CustomOnClickFunction) in your own mod to your function to handle OnClicks.
7 -- Two arguments are passed, button and raidid.
8 -- Button is a string that refers to the mouse button pressed, "LeftButton" or "RightButton".
9 -- Raidid is a string with the unit id, such as "raid1".
10  
11 -- Example: function MyFunction(button, raidid) doStuff(); end
12 -- CT_RA_CustomOnClickFunction = MyFunction;
13  
14 -- Note! If the function returns true, the default CTRA behaviour will not be called.
15 -- If it returns false or nil, the default behaviour will be called.
16  
17 -- Variables
18 CHAT_MSG_CTRAID = "CTRaid";
19 CT_RA_Squelch = 0;
20 CT_RA_Comm_MessageQueue = { };
21 CT_RA_Level = 0;
22 CT_RA_Stats = {
23 {
24 { }
25 }
26 };
27 CT_RA_PTargets = { };
28 CT_RA_BuffsToCure = { };
29 CT_RA_BuffsToRecast = { };
30 CT_RA_RaidParticipant = nil; -- Used to see what player participated in the raid on this account
31  
32 CT_RA_Auras = {
33 ["buffs"] = { },
34 ["debuffs"] = { }
35 };
36 CT_RA_LastSend = nil;
37 CT_RA_ClassPositions = {
38 [CT_RA_WARRIOR] = 1,
39 [CT_RA_DRUID] = 2,
40 [CT_RA_MAGE] = 3,
41 [CT_RA_WARLOCK] = 4,
42 [CT_RA_ROGUE] = 5,
43 [CT_RA_HUNTER] = 6,
44 [CT_RA_PRIEST] = 7,
45 [CT_RA_PALADIN] = 8,
46 [CT_RA_SHAMAN] = 8
47 };
48  
49 CT_RA_Emergency_RaidHealth = { };
50 CT_RA_Emergency_Units = { };
51  
52 CT_RA_LastSent = { };
53 CT_RA_BuffTimeLeft = { };
54 CT_RA_ResFrame_Options = { };
55 CT_RA_CurrPlayerName = "";
56  
57 CT_RA_NumRaidMembers = 0;
58  
59 ChatTypeGroup["CTRAID"] = {
60 "CHAT_MSG_CTRAID"
61 };
62 ChatTypeInfo["CTRAID"] = { sticky = 0 };
63 tinsert(OtherMenuChatTypeGroups, "CTRAID");
64 CHAT_CTRAID_GET = "";
65 CT_RA_ChatInfo = {
66 ["Default"] = {
67 ["r"] = 1.0,
68 ["g"] = 0.5,
69 ["b"] = 0,
70 ["show"] = {
71 "ChatFrame1"
72 }
73 }
74 };
75  
76 CT_oldFCF_Tab_OnClick = FCF_Tab_OnClick;
77 function CT_newFCF_Tab_OnClick(button)
78 CT_oldFCF_Tab_OnClick(button);
79 if ( button == "RightButton" ) then
80 local frameName = "ChatFrame" .. this:GetID();
81 local frame = getglobal(frameName);
82 local info = CT_RA_ChatInfo["Default"];
83 if ( CT_RA_ChatInfo[UnitName("player")] ) then
84 info = CT_RA_ChatInfo[UnitName("player")];
85 end
86 for k, v in info["show"] do
87 if ( v == frameName ) then
88 local y = 1;
89 while ( frame.messageTypeList[y] ) do
90 y = y + 1;
91 end
92 frame.messageTypeList[y] = "CTRAID";
93 end
94 end
95 end
96 end
97 FCF_Tab_OnClick = CT_newFCF_Tab_OnClick;
98  
99 CT_oldFCF_SetChatTypeColor = FCF_SetChatTypeColor;
100 function CT_newFCF_SetChatTypeColor()
101 CT_oldFCF_SetChatTypeColor();
102 if ( UIDROPDOWNMENU_MENU_VALUE == "CTRAID" ) then
103 local r,g,b = ColorPickerFrame:GetColorRGB();
104 local chatInfo = CT_RA_ChatInfo[UnitName("player")];
105 local chatTypeInfo = ChatTypeInfo["CTRAID"];
106 if ( not chatInfo ) then
107 CT_RA_ChatInfo[UnitName("player")] = CT_RA_ChatInfo["Default"];
108 end
109 chatInfo.r = r;
110 chatInfo.g = g;
111 chatInfo.b = b;
112 chatTypeInfo.r = r;
113 chatTypeInfo.g = g;
114 chatTypeInfo.b = b;
115 end
116 end
117 FCF_SetChatTypeColor = CT_newFCF_SetChatTypeColor;
118  
119 CT_oldFCF_CancelFontColorSettings = FCF_CancelFontColorSettings;
120 function CT_newFCF_CancelFontColorSettings(prev)
121 CT_oldFCF_CancelFontColorSettings(prev);
122 if ( prev.r and UIDROPDOWNMENU_MENU_VALUE == "CTRAID" ) then
123 local chatInfo = CT_RA_ChatInfo[UnitName("player")];
124 local chatTypeInfo = ChatTypeInfo["CTRAID"];
125 if ( not chatInfo ) then
126 CT_RA_ChatInfo[UnitName("player")] = CT_RA_ChatInfo["Default"];
127 end
128 chatInfo.r = prev.r;
129 chatInfo.g = prev.g;
130 chatInfo.b = prev.b;
131 chatTypeInfo.r = prev.r;
132 chatTypeInfo.g = prev.g;
133 chatTypeInfo.b = prev.b;
134 end
135 end
136 FCF_CancelFontColorSettings = CT_newFCF_CancelFontColorSettings;
137 CT_oldFCFMessageTypeDropDown_OnClick = FCFMessageTypeDropDown_OnClick;
138 function CT_newFCFMessageTypeDropDown_OnClick()
139 CT_oldFCFMessageTypeDropDown_OnClick();
140 if ( not CT_RA_ChatInfo[UnitName("player")] ) then
141 CT_RA_ChatInfo[UnitName("player")] = CT_RA_ChatInfo["Default"];
142 end
143 if ( this.value == "CTRAID" ) then
144 local chatInfo = CT_RA_ChatInfo[UnitName("player")];
145 local chatTypeInfo = ChatTypeInfo["CTRAID"];
146 local currChatFrame = FCF_GetCurrentChatFrame():GetName();
147 if ( UIDropDownMenuButton_GetChecked() ) then
148 for k, v in chatInfo["show"] do
149 if ( v == currChatFrame ) then
150 chatInfo["show"][k] = nil;
151 break;
152 end
153 end
154 else
155 tinsert(chatInfo["show"], currChatFrame);
156 end
157 end
158 end
159 FCFMessageTypeDropDown_OnClick = CT_newFCFMessageTypeDropDown_OnClick;
160  
161 function CT_RA_ShowHideWindows()
162 local tempOptions = CT_RAMenu_Options["temp"];
163 if ( tempOptions["HiddenGroups"] ) then
164 tempOptions["ShowGroups"] = tempOptions["HiddenGroups"];
165 tempOptions["HiddenGroups"] = nil;
166  
167 local num = 0;
168 for k, v in tempOptions["ShowGroups"] do
169 num = num + 1;
170 getglobal("CT_RAOptionsGroupCB" .. k):SetChecked(1);
171 end
172 if ( num > 0 ) then
173 CT_RACheckAllGroups:SetChecked(1);
174 else
175 CT_RACheckAllGroups:SetChecked(nil);
176 end
177 else
178 tempOptions["HiddenGroups"] = tempOptions["ShowGroups"];
179 tempOptions["ShowGroups"] = { };
180 for i = 1, 8, 1 do
181 getglobal("CT_RAOptionsGroupCB" .. i):SetChecked(nil);
182 end
183 CT_RACheckAllGroups:SetChecked(nil);
184 end
185 CT_RA_UpdateRaidGroup(0);
186 end
187  
188 function CT_RA_SetGroup()
189 local tempOptions = CT_RAMenu_Options["temp"];
190 tempOptions["ShowGroups"][this.id] = this:GetChecked();
191 local num = 0;
192 for k, v in tempOptions["ShowGroups"] do
193 num = num + 1;
194 end
195 if ( num > 0 ) then
196 CT_RACheckAllGroups:SetChecked(1);
197 else
198 CT_RACheckAllGroups:SetChecked(nil);
199 end
200 CT_RA_UpdateRaidGroup(0);
201 end
202  
203 function CT_RA_CheckAllGroups()
204 local tempOptions = CT_RAMenu_Options["temp"];
205 if ( not tempOptions["ShowGroups"] ) then tempOptions["ShowGroups"] = { }; end
206 for i = 1, 8, 1 do
207 tempOptions["ShowGroups"][i] = this:GetChecked();
208 getglobal("CT_RAOptionsGroupCB" .. i):SetChecked(this:GetChecked());
209 end
210 CT_RA_UpdateRaidGroup(0);
211 end
212  
213 function CT_RA_ParseEvent(event)
214 local nick, sMsg, msg;
215 if ( event == "CHAT_MSG_ADDON" ) then
216 nick, sMsg = arg4, arg2;
217 else
218 nick, sMsg = arg2, arg1;
219 end
220 local numRaidMembers = GetNumRaidMembers();
221 local name, rank, subgroup, level, class, fileName, zone, online, isDead, raidid, frame;
222 for i = 1, numRaidMembers, 1 do
223 if ( UnitName("raid" .. i) == nick ) then
224 raidid = i;
225 name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(i);
226 frame = getglobal("CT_RAMember"..i);
227 break;
228 end
229 end
230  
231 local playerName = UnitName("player");
232 local unitStats = CT_RA_Stats[nick];
233 local ctraChannel = CT_RA_Channel;
234  
235 if ( name and not unitStats ) then
236 CT_RA_Stats[nick] = {
237 ["Buffs"] = { },
238 ["Debuffs"] = { },
239 ["Position"] = { }
240 };
241 unitStats = CT_RA_Stats[nick];
242 end
243  
244 if ( ( event == "CHAT_MSG_RAID" or event == "CHAT_MSG_RAID_LEADER" ) and type(sMsg) == "string" ) then
245 if ( frame ) then
246 -- We have a valid frame
247 msg = gsub(sMsg, "%%", "%%%%");
248  
249 if ( stats and raidid ) then
250 if ( arg6 and not unitStats[arg6] and ( arg6 == "AFK" or arg6 == "DND" ) ) then
251 unitStats[arg6] = { 1, 0 };
252 CT_RA_UpdateUnitDead(frame);
253 elseif ( arg2 == name and ( not arg6 or arg6 == "" ) and ( unitStats["DND"] or unitStats["AFK"] ) ) then
254 unitStats["DND"] = nil;
255 unitStats["AFK"] = nil;
256 CT_RA_UpdateUnitDead(frame);
257 end
258 end
259 if ( rank and rank < 1 and CT_RA_Squelch and CT_RA_Squelch > 0 ) then
260 if ( CT_RA_Level >= 1 and CT_RA_IsSendingWithVersion(1.468) ) then
261 SendChatMessage("<CTRaid> Quiet mode is enabled in the raid. Please be quiet. " .. floor(CT_RA_Squelch) .. " seconds remaining.", "WHISPER", nil, name);
262 end
263 return;
264 end
265  
266 if ( rank and rank >= 1 and string.find(sMsg, "<CTRaid> Disbanding raid on request by (.+)") ) then
267 LeaveParty();
268 return;
269 end
270 if ( rank >= 1 ) then
271 if ( name ~= playerName and sMsg == "<CTRaid> Quiet mode is over." ) then
272 if ( CT_RA_Squelch > 0 ) then
273 CT_RA_Squelch = 0;
274 CT_RA_Print("<CTRaid> Quiet mode has been disabled by " .. name .. ".", 1, 0.5, 0);
275 end
276 elseif ( name ~= playerName and sMsg == "<CTRaid> Quiet mode, no talking." ) then
277 if ( CT_RA_Squelch == 0 ) then
278 CT_RA_Squelch = 5*60;
279 CT_RA_Print("<CTRaid> Quiet Mode has been enabled by " .. name .. ".", 1, 0.5, 0);
280 end
281 end
282 return;
283 end
284 end
285 elseif ( event == "CHAT_MSG_WHISPER" and type(sMsg) == "string" ) then
286 local tempOptions = CT_RAMenu_Options["temp"];
287 if ( tempOptions["KeyWord"] and strlower(sMsg) == strlower(tempOptions["KeyWord"]) ) then
288 local temp = arg2;
289 if ( numRaidMembers == 40 or ( GetNumPartyMembers() == 4 and numRaidMembers == 0 ) ) then
290 CT_RA_Print("<CTRaid> Player '|c00FFFFFF" .. temp .. "|r' requested invite, group is currently full.", 1, 0.5, 0);
291 SendChatMessage("<CTRaid> The group is currently full.", "WHISPER", nil, temp);
292 else
293 CT_RA_Print("<CTRaid> Invited '|c00FFFFFF" .. temp .. "|r' by Keyword Inviting.", 1, 0.5, 0);
294 InviteByName(temp);
295 CT_RA_UpdateFrame.lastInvite = 1;
296 CT_RA_UpdateFrame.inviteName = temp;
297 end
298 else
299 local _, _, secRem = string.find(sMsg, "<CTRaid> Quiet mode is enabled in the raid%. Please be quiet%. (%d+) seconds remaining%.");
300 if ( secRem and CT_RA_Squelch == 0 ) then
301 if ( rank >= 1 ) then
302 CT_RA_Squelch = tonumber(secRem);
303 CT_RA_Print("<CTRaid> Quiet Mode has been enabled for " .. secRem .. " seconds by " .. name .. ".", 1, 0.5, 0);
304 end
305 end
306 end
307 elseif ( event == "CHAT_MSG_WHISPER_INFORM" ) then
308 if ( arg1 == "<CTRaid> You are already grouped." ) then
309 CT_RA_Print("<CTRaid> Informed '|c00FFFFFF" .. arg2 .. "|r' that he or she is already grouped.", 1, 0.5, 0);
310 end
311 elseif ( event == "CHAT_MSG_COMBAT_FRIENDLY_DEATH" ) then
312 if ( not CT_RAMenu_Options["temp"]["HideTankNotifications"] ) then
313 local _, _, name = string.find(sMsg, CT_RA_TANKHASDIEDREGEXP);
314 if ( name ) then
315 for k, v in CT_RA_MainTanks do
316 if ( v == name ) then
317 CT_RA_WarningFrame:AddMessage("TANK " .. name .. " HAS DIED!", 1, 0, 0, 1, UIERRORS_HOLD_TIME);
318 PlaySoundFile("Sound\\interface\\igQuestFailed.wav");
319 break;
320 end
321 end
322 end
323 end
324 elseif ( strsub(event, 1, 15) == "CHAT_MSG_SYSTEM" and type(sMsg) == "string" ) then
325 local useless, useless, plr = string.find(sMsg, CT_RA_HASLEFTRAIDREGEXP);
326 if ( CT_RA_RaidParticipant and plr and plr ~= CT_RA_RaidParticipant ) then
327 CT_RA_CurrPositions[plr] = nil;
328 CT_RA_Stats[plr] = nil;
329 for k, v in CT_RA_MainTanks do
330 if ( v == plr ) then
331 CT_RA_MainTanks[k] = nil;
332 CT_RATarget.MainTanks[k] = nil;
333 break;
334 end
335 end
336 elseif ( string.find(sMsg, CT_RA_HASJOINEDRAIDREGEXP) ) then
337 if ( CT_RA_Level >= 2 ) then
338 local useless, useless, plr = string.find(sMsg, CT_RA_HASJOINEDRAIDREGEXP);
339 if ( plr and CT_RATab_AutoPromotions[plr] ) then
340 PromoteToAssistant(plr);
341 CT_RA_Print("<CTRaid> Auto-Promoted |c00FFFFFF" .. plr .. "|r.", 1, 0.5, 0);
342 end
343 end
344 elseif ( string.find(sMsg, CT_RA_AFKMESSAGE) or sMsg == MARKED_AFK ) then
345 local _, _, msg = string.find(sMsg, CT_RA_AFKMESSAGE);
346 if ( msg and msg ~= DEFAULT_AFK_MESSAGE ) then
347 if ( strlen(msg) > 20 ) then
348 msg = strsub(msg, 1, 20) .. "...";
349 end
350 CT_RA_AddMessage("AFK " .. msg);
351 else
352 CT_RA_AddMessage("AFK");
353 end
354 elseif ( string.find(sMsg, CT_RA_DNDMESSAGE) ) then
355 local _, _, msg = string.find(sMsg, CT_RA_DNDMESSAGE);
356 if ( msg and msg ~= DEFAULT_DND_MESSAGE ) then
357 if ( strlen(msg) > 20 ) then
358 msg = strsub(msg, 1, 20) .. "...";
359 end
360 CT_RA_AddMessage("DND " .. msg);
361 else
362 CT_RA_AddMessage("DND");
363 end
364 elseif ( sMsg == CLEARED_AFK ) then
365 CT_RA_AddMessage("UNAFK");
366 elseif ( sMsg == CLEARED_DND ) then
367 CT_RA_AddMessage("UNDND");
368 end
369  
370 elseif ( event == "CHAT_MSG_ADDON" and arg1 == "CTRA" and arg3 == "RAID" ) then
371 if ( frame ) then
372 -- Unit is in raid
373 local eventtype = strsub(event, 10);
374 local info = ChatTypeInfo[eventtype];
375 event = "CHAT_MSG_CTRAID";
376 if ( arg6 and not unitStats[arg6] and ( arg6 == "AFK" or arg6 == "DND" ) ) then
377 unitStats[arg6] = { 1, 0 };
378 CT_RA_UpdateUnitDead(frame);
379 elseif ( ( not arg6 or arg6 == "" ) and ( unitStats["DND"] or unitStats["AFK"] ) ) then
380 unitStats["DND"] = nil;
381 unitStats["AFK"] = nil;
382 CT_RA_UpdateUnitDead(frame);
383 end
384 if ( not sMsg ) then
385 return;
386 end
387 local msg = string.gsub(sMsg, "%$", "s");
388 msg = string.gsub(msg, "§", "S");
389 if ( strsub(msg, strlen(msg)-7) == " ...hic!") then
390 msg = strsub(msg, 1, strlen(msg)-8);
391 end
392 local tempUpdate, message;
393 if ( string.find(msg, "#") ) then
394 local arr = CT_RA_Split(msg, "#");
395 for k, v in arr do
396 tempUpdate, message = CT_RA_ParseMessage(name, v);
397 if ( message ) then
398 CT_RA_Print(message, 1, 0.5, 0);
399 end
400 if ( tempUpdate ) then
401 for k, v in tempUpdate do
402 tinsert(update, v);
403 end
404 end
405 end
406 else
407 tempUpdate, message = CT_RA_ParseMessage(name, msg);
408 if ( message ) then
409 CT_RA_Print(message, 1, 0.5, 0);
410 end
411 if ( tempUpdate ) then
412 for k, v in tempUpdate do
413 tinsert(update, v);
414 end
415 end
416 end
417 if ( type(update) == "table" ) then
418 for k, v in update do
419 if ( type(v) == "number" ) then
420 CT_RA_UpdateUnitStatus(getglobal("CT_RAMember" .. v));
421 else
422 for i = 1, GetNumRaidMembers(), 1 do
423 local uName = UnitName("raid" .. i);
424 if ( uName and uName == v ) then
425 CT_RA_UpdateUnitStatus(getglobal("CT_RAMember" .. i));
426 break;
427 end
428 end
429 end
430 end
431 end
432 end
433 elseif ( event == "CHAT_MSG_PARTY" ) then
434 if ( frame ) then
435 if ( arg6 and not unitStats[arg6] and ( arg6 == "AFK" or arg6 == "DND" ) ) then
436 unitStats[arg6] = { 1, 0 };
437 CT_RA_UpdateUnitDead(frame);
438 elseif ( ( not arg6 or arg6 == "" ) and ( unitStats["DND"] or unitStats["AFK"] ) ) then
439 unitStats["DND"] = nil;
440 unitStats["AFK"] = nil;
441 CT_RA_UpdateUnitDead(frame);
442 end
443 end
444 end
445 end
446  
447 CT_RA_oldChatFrame_OnEvent = ChatFrame_OnEvent;
448 function CT_RA_newChatFrame_OnEvent(event)
449 if ( strsub(event, 1, 13) == "CHAT_MSG_RAID" ) then
450 local tempOptions = CT_RAMenu_Options["temp"];
451 local name, rank;
452 for i = 1, GetNumRaidMembers(), 1 do
453 name, rank = GetRaidRosterInfo(i);
454 if ( name == arg2 ) then
455 if ( rank and rank < 1 and CT_RA_Squelch > 0 ) then
456 return;
457 end
458 break;
459 end
460 end
461 if ( not rank ) then
462 rank = 0;
463 end
464 if ( rank >= 1 and ( arg1 == "<CTRaid> Quiet mode, no talking." or arg1 == "<CTRaid> Quiet mode is over." ) ) then
465 return;
466 end
467 local useless, useless, chan = string.find(gsub(arg1, "%%", "%%%%"), "^<CTMod> This is an automatic message sent by CT_RaidAssist. Channel changed to: (.+)$");
468 if ( chan ) then
469 return;
470 end
471 if ( rank == 2 and ( not tempOptions["leaderColor"] or tempOptions["leaderColor"].enabled ) ) then
472 CT_RA_oldAddMessage = this.AddMessage;
473 this.AddMessage = CT_RA_newAddMessage;
474 CT_RA_oldChatFrame_OnEvent(event);
475 this.AddMessage = CT_RA_oldAddMessage;
476 return;
477 end
478 elseif ( event == "CHAT_MSG_WHISPER" ) then
479 local tempOptions = CT_RAMenu_Options["temp"];
480 if ( ( tempOptions["KeyWord"] and strlower(arg1) == strlower(tempOptions["KeyWord"]) ) or arg1 == "<CTRaid> Quiet mode is enabled in the raid. Please be quiet." ) then
481 return;
482 end
483 elseif ( strsub(event, 1, 16) == "CHAT_MSG_CHANNEL" and CT_RA_Channel and arg9 and strlower(arg9) == strlower(CT_RA_Channel) ) then
484 local type = strsub(event, 10);
485 if ( type ~= "CHANNEL_LIST" and type ~= "SYSTEM" ) then
486 return;
487 end
488 end
489 CT_RA_oldChatFrame_OnEvent(event);
490 end
491 ChatFrame_OnEvent = CT_RA_newChatFrame_OnEvent;
492  
493 function CT_RA_newAddMessage(obj, msg, r, g, b)
494 local tempOptions = CT_RAMenu_Options["temp"];
495 local newR, newG, newB = 1, 1, 0;
496 if ( tempOptions["leaderColor"] ) then
497 newR, newG, newB = tempOptions["leaderColor"].r, tempOptions["leaderColor"].g, tempOptions["leaderColor"].b;
498 end
499 return CT_RA_oldAddMessage(obj, string.gsub(msg, "(|Hplayer:.-|h%[)([%w]+)(%])", "%1|c00" .. CT_RA_RGBToHex(newR, newG, newB) .. "%2|r%3"), r, g, b);
500 end
501  
502 function CT_RA_ParseMessage(nick, msg)
503 local tempOptions = CT_RAMenu_Options["temp"];
504 local useless, val1, val2, val3, val4, frame, raidid, rank, update;
505 local numRaidMembers = GetNumRaidMembers();
506 local playerName = UnitName("player");
507  
508 for i = 1, numRaidMembers, 1 do
509 if ( UnitName("raid" .. i) == nick ) then
510 raidid = i;
511 useless, rank = GetRaidRosterInfo(i);
512 frame = getglobal("CT_RAMember"..i);
513 break;
514 end
515 end
516  
517 if ( not raidid or not frame ) then
518 return;
519 end
520  
521 local unitStats = CT_RA_Stats[nick];
522 if ( not unitStats ) then
523 if ( not update ) then
524 update = { };
525 end
526 CT_RA_Stats[nick] = {
527 ["Buffs"] = { },
528 ["Debuffs"] = { },
529 ["Position"] = { }
530 };
531 unitStats = CT_RA_Stats[nick];
532 tinsert(update, raidid);
533 end
534 unitStats["Reporting"] = 1;
535  
536 -- Check buff renewal
537 useless, useless, val1, val2, val3 = string.find(msg, "^RN ([^%s]+) ([^%s]+) ([^%s]+)$"); -- timeleft(1), id(2), num(3)
538 if ( tonumber(val1) and tonumber(val2) and tonumber(val3) ) then
539 -- Buffs
540 local buff;
541 for k, v in tempOptions["BuffArray"] do
542 if ( tonumber(val2) == v["index"] ) then
543 buff = v;
544 break;
545 end
546 end
547 if ( not buff and tonumber(val2) == -1 ) then
548 buff = { ["show"] = 1, ["name"] = CT_RA_FEIGNDEATH[CT_RA_GetLocale()] };
549 elseif ( not buff ) then
550 return update;
551 end
552 local name = buff["name"];
553 if ( type(name) == "table" ) then
554 if ( tonumber(val3) ) then
555 name = name[tonumber(val3)];
556 else
557 return update;
558 end
559 end
560 local text = CT_RA_BuffTextures[name];
561 if ( not name or not text ) then
562 return update;
563 end
564 unitStats["Buffs"][name] = { text[1], tonumber(val1) };
565 return update;
566 end
567  
568 -- Check status requests
569 if ( msg == "SR" ) then
570 if ( unitStats ) then
571 unitStats["Buffs"] = { };
572 unitStats["Debuffs"] = { };
573 table.setn(unitStats["Buffs"], 0);
574 table.setn(unitStats["Debuffs"], 0);
575 end
576 CT_RA_ScanPartyAuras("raid" .. raidid);
577 CT_RA_UpdateFrame.scheduleUpdate = 8;
578 CT_RA_UpdateFrame.scheduleMTUpdate = 8;
579 return update;
580 end
581  
582 if ( strsub(msg, 1, 2) == "S " ) then
583 for str in string.gfind(msg, " B [^%s]+ [^%s]+ [^#]+ #") do
584 useless, useless, val1, val3, val2 = string.find(str, "B ([^%s]+) ([^%s]+) (.+) #");
585 if ( val1 and val2 and val3 ) then
586 unitStats["Buffs"][val2] = { val1, tonumber(val3) };
587 CT_RA_UpdateUnitBuffs(unitStats["Buffs"], frame, nick);
588 end
589 end
590 return update;
591 end
592  
593 if ( strsub(msg, 1, 3) == "MS " ) then
594 if ( rank >= 1 ) then
595 if ( tempOptions["PlayRSSound"] ) then
596 PlaySoundFile("Sound\\Doodad\\BellTollNightElf.wav");
597 end
598 CT_RAMessageFrame:AddMessage(nick .. ": " .. strsub(msg, 3), tempOptions["DefaultAlertColor"].r, tempOptions["DefaultAlertColor"].g, tempOptions["DefaultAlertColor"].b, 1.0, UIERRORS_HOLD_TIME);
599 end
600 return update;
601 end
602  
603 useless, useless, val1 = string.find(msg, "^V ([%d%.]+)$");
604 if ( tonumber(val1) ) then
605 unitStats["Version"] = tonumber(val1);
606 return update;
607 end
608  
609  
610 if ( strsub(msg, 1, 4) == "SET " ) then
611 local useless, useless, num, name = string.find(msg, "^SET (%d+) (.+)$");
612 if ( num and name ) then
613 if ( rank >= 1 ) then
614 for k, v in CT_RA_MainTanks do
615 if ( v == name ) then
616 CT_RA_MainTanks[k] = nil;
617 CT_RATarget.MainTanks[k] = nil;
618 end
619 end
620 local mtID = 0;
621 for i = 1, numRaidMembers, 1 do
622 if ( UnitName("raid" .. i) == name ) then
623 mtID = i;
624 break;
625 end
626 end
627 CT_RA_MainTanks[tonumber(num)] = name;
628 CT_RATarget.MainTanks[tonumber(num)] = { mtID, name };
629 CT_RATarget_UpdateInfoBox();
630 CT_RATarget_UpdateStats();
631 CT_RAOptions_Update();
632 CT_RA_UpdateMTs();
633 end
634 end
635 return update;
636 end
637  
638 if ( strsub(msg, 1, 2) == "R " ) then
639 local useless, useless, name = string.find(msg, "^R (.+)$");
640 if ( name ) then
641 for k, v in CT_RA_MainTanks do
642 if ( v == name ) then
643 for i = 1, GetNumRaidMembers(), 1 do
644 local user, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(i);
645 if ( rank >= 1 and user == nick ) then
646 CT_RA_MainTanks[k] = nil;
647 CT_RATarget.MainTanks[k] = nil;
648 CT_RA_UpdateMTs();
649 CT_RAOptions_Update();
650 return update;
651 end
652 end
653 end
654 end
655 end
656 return update;
657 end
658  
659 if ( msg == "DB" ) then
660 if ( rank >= 1 ) then
661 CT_RA_Print("<CTRaid> Disbanding raid on request by '|c00FFFFFF" .. nick .. "|r'.", 1, 0.5, 0);
662 LeaveParty();
663 end
664 return update;
665 end
666  
667 if ( msg == "RESSED" ) then
668 unitStats["Ressed"] = 1;
669 CT_RA_UpdateUnitDead(frame);
670 return update;
671 end
672  
673 if ( msg == "NORESSED" ) then
674 unitStats["Ressed"] = nil;
675 CT_RA_UpdateUnitDead(frame);
676 return update;
677 end
678  
679 if ( msg == "CANRES" ) then
680 unitStats["Ressed"] = 2;
681 CT_RA_UpdateUnitDead(frame);
682 return update;
683 end
684  
685 if ( strsub(msg, 1, 3) == "RES" ) then
686 if ( msg == "RESNO" ) then
687 CT_RA_Ressers[nick] = nil;
688 else
689 local _, _, player = string.find(msg, "^RES (.+)$");
690 if ( player ) then
691 CT_RA_Ressers[nick] = player;
692 end
693 end
694 CT_RA_UpdateResFrame();
695 return update;
696 end
697 -- Check ready
698  
699 if ( msg == "CHECKREADY" ) then
700 if ( rank >= 1 ) then
701 CT_RA_CheckReady_Person = nick;
702 if ( nick ~= playerName ) then
703 PlaySoundFile("Sound\\interface\\levelup2.wav");
704 CT_RA_ReadyFrame:Show();
705 end
706 end
707 return update;
708 elseif ( ( msg == "READY" or msg == "NOTREADY" ) and CT_RA_CheckReady_Person == playerName ) then
709 if ( msg == "READY" ) then
710 unitStats["notready"] = nil;
711 else
712 unitStats["notready"] = 2;
713 end
714 local all_ready = true;
715 local nobody_ready = true;
716 for k, v in CT_RA_Stats do
717 if ( v["notready"] ) then
718 all_ready = false;
719 if ( v["notready"] == 1 ) then
720 nobody_ready = false;
721 end
722 end
723 end
724 if ( all_ready ) then
725 CT_RA_Print("<CTRaid> Everybody is ready.", 1, 1, 0);
726 elseif ( not all_ready and nobody_ready ) then
727 CT_RA_UpdateFrame.readyTimer = 0.1;
728 end
729 CT_RA_UpdateUnitDead(frame);
730 return update;
731 end
732  
733 -- Check Rly
734 if ( msg == "CHECKRLY" ) then
735 if ( rank >= 1 ) then
736 CT_RA_CheckRly_Person = nick;
737 if ( nick ~= UnitName("player") ) then
738 PlaySoundFile("Sound\\interface\\levelup2.wav");
739 CT_RA_RlyFrame:Show();
740 end
741 end
742 return update;
743 elseif ( ( msg == "YARLY" or msg == "NORLY" ) and CT_RA_CheckRly_Person == playerName ) then
744 if ( msg == "YARLY" ) then
745 unitStats["rly"] = nil;
746 else
747 unitStats["rly"] = 1;
748 end
749 local all_ready = true;
750 local nobody_ready = true;
751 for k, v in CT_RA_Stats do
752 if ( v["rly"] ) then
753 all_ready = false;
754 if ( v["rly"] == 1 ) then
755 nobody_ready = false;
756 end
757 end
758 end
759 if ( all_ready ) then
760 CT_RA_Print("<CTRaid> Ya rly.", 1, 1, 0);
761 elseif ( not all_ready and nobody_ready ) then
762 CT_RA_UpdateFrame.rlyTimer = 0.1;
763 end
764 CT_RA_UpdateUnitDead(frame);
765 return update;
766 end
767  
768 -- Check AFK
769  
770 if ( msg == "AFK" ) then
771 unitStats["AFK"] = { 1, 0 };
772 CT_RA_UpdateUnitDead(frame);
773 return update;
774 elseif ( msg == "UNAFK" ) then
775 unitStats["AFK"] = nil;
776 CT_RA_UpdateUnitDead(frame);
777 return update;
778 elseif ( msg == "DND" ) then
779 unitStats["DND"] = { 1, 0 };
780 CT_RA_UpdateUnitDead(frame);
781 return update;
782 elseif ( msg == "UNDND" ) then
783 unitStats["DND"] = nil;
784 CT_RA_UpdateUnitDead(frame);
785 return update;
786 elseif ( strsub(msg, 1, 3) == "AFK" ) then
787 -- With reason
788 unitStats["AFK"] = { strsub(msg, 5), 0 };
789 CT_RA_UpdateUnitDead(frame);
790 return update;
791 elseif ( strsub(msg, 1, 3) == "DND" ) then
792 -- With reason
793 unitStats["DND"] = { strsub(msg, 5), 0 };
794 CT_RA_UpdateUnitDead(frame);
795 return update;
796 end
797  
798 -- Check duration
799 if ( msg == "DURC" ) then
800 if ( rank == 0 ) then
801 return;
802 end
803 local currDur, maxDur, brokenItems = CT_RADurability_GetDurability();
804 CT_RA_AddMessage("DUR " .. currDur .. " " .. maxDur .. " " .. brokenItems .. " " .. nick);
805 return update;
806 elseif ( string.find(msg, "^DUR ") ) then
807 local _, _, currDur, maxDur, brokenItems, callPerson = string.find(msg, "^DUR (%d+) (%d+) (%d+) ([^%s]+)$");
808 if ( currDur and maxDur and brokenItems and callPerson == playerName ) then
809 currDur, maxDur = tonumber(currDur), tonumber(maxDur);
810 local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(raidid);
811 CT_RADurability_Add(nick, "|c00FFFFFF" .. floor((currDur/maxDur)*100+0.5) .. "%|r (|c00FFFFFF" .. brokenItems .. " broken items|r)", fileName, floor((currDur/maxDur)*100+0.5));
812 end
813 return update;
814 end
815  
816 -- Check resists (Thanks Sudo!)
817 if ( msg == "RSTC" ) then
818 if ( rank == 0 ) then
819 return update;
820 end
821 if ( tempOptions["DisableQuery"] ) then
822 CT_RA_AddMessage("RST -1 " .. nick);
823 else
824 local resistStr = "";
825 for i = 2, 6, 1 do
826 local _, res, _, _ = UnitResistance("player", i);
827 resistStr = resistStr .. " " .. res;
828 end
829 CT_RA_AddMessage("RST" .. resistStr .. " " .. nick);
830 end
831 return update;
832 elseif ( string.find(msg, "^RST ") ) then
833 local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(raidid);
834 local _, _, plrName = string.find(msg, "^RST %-1 ([^%s]+)$");
835 if ( plrName and plrName == playerName ) then
836 CT_RADurability_Add(nick, "|c00FFFFFFDisabled Queries|r", fileName, -1, -1, -1, -1, -1);
837 else
838 local _, _, FR, NR, FRR, SR, AR, callPerson = string.find(msg, "^RST (%d+) (%d+) (%d+) (%d+) (%d+) ([^%s]+)$");
839 if ( FR and callPerson == playerName ) then
840 CT_RADurability_Add(nick, "", fileName, tonumber(FR), tonumber(NR), tonumber(FRR), tonumber(SR), tonumber(AR) );
841 end
842 end
843 return update;
844 end
845  
846 -- Check reagents
847 if ( msg == "REAC" ) then
848 if ( rank == 0 ) then
849 return update;
850 end
851 local numItems = CT_RAReagents_GetReagents();
852 if ( numItems and numItems >= 0 ) then
853 CT_RA_AddMessage("REA " .. numItems .. " " .. nick);
854 end
855 return update;
856 elseif ( string.find(msg, "^REA ") ) then
857 local _, _, numItems, callPerson = string.find(msg, "^REA ([^%s]+) ([^%s]+)$");
858 if ( numItems and callPerson and callPerson == playerName ) then
859 local classes = {
860 [CT_RA_PRIEST] = CT_REG_PRIEST,
861 [CT_RA_MAGE] = CT_REG_MAGE,
862 [CT_RA_DRUID] = CT_REG_DRUID,
863 [CT_RA_WARLOCK] = CT_REG_WARLOCK,
864 [CT_RA_PALADIN] = CT_REG_PALADIN,
865 [CT_RA_SHAMAN] = CT_REG_SHAMAN
866 };
867 local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(raidid);
868 if ( numItems ~= "1" ) then
869 CT_RADurability_Add(nick, "|c00FFFFFF" .. numItems .. "|r " .. classes[UnitClass("raid"..raidid)] .. "s", fileName, numItems);
870 else
871 CT_RADurability_Add(nick, "|c00FFFFFF" .. numItems .. "|r " .. classes[UnitClass("raid"..raidid)], fileName, numItems );
872 end
873 end
874 return update;
875 end
876  
877 -- Check items
878 if ( string.find(msg, "^ITMC ") ) then
879 local _, _, itemName = string.find(msg, "^ITMC (.+)$");
880 if ( itemName ) then
881 if ( rank == 0 ) then
882 return;
883 end
884 if ( tempOptions["DisableQuery"] ) then
885 CT_RA_AddMessage("ITM " .. -1 .. " " .. itemName .. " " .. nick);
886 else
887 local numItems = CT_RAItem_GetItems(itemName);
888 if ( numItems and numItems > 0 ) then
889 CT_RA_AddMessage("ITM " .. numItems .. " " .. itemName .. " " .. nick);
890 end
891 end
892 end
893 return update;
894 elseif ( string.find(msg, "^ITM ") ) then
895 local _, _, numItems, itemName, callPerson = string.find(msg, "^ITM ([-%d]+) (.+) ([^%s]+)$");
896 if ( numItems and itemName and callPerson and callPerson == UnitName("player") ) then
897 local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(raidid);
898 if ( numItems == "-1" ) then
899 CT_RADurability_Add(nick, "|c00FFFFFFDisabled Queries|r", fileName, "0", class);
900 elseif ( numItems ~= "1" ) then
901 CT_RADurability_Add(nick, "|c00FFFFFF" .. numItems .. "|r " .. itemName .. "s", fileName, numItems);
902 else
903 CT_RADurability_Add(nick, "|c00FFFFFF" .. numItems .. "|r " .. itemName, fileName, numItems);
904 end
905 end
906 return update;
907 end
908  
909 -- Check cooldowns
910 if ( string.find(msg, "^CD %d+ %d+$") ) then
911 local _, _, num, cooldown = string.find(msg, "^CD (%d+) (%d+)$");
912 if ( num == "1" ) then
913 unitStats["Rebirth"] = tonumber(cooldown)*60;
914 elseif ( num == "2" ) then
915 unitStats["Reincarnation"] = tonumber(cooldown)*60;
916 elseif ( num == "3" ) then
917 unitStats["Soulstone"] = tonumber(cooldown)*60;
918 end
919 return update;
920 end
921  
922 -- Assist requests
923 if ( string.find(msg, "^ASSISTME (.+)$") ) then
924 if ( rank >= 1 ) then
925 local _, _, name = string.find(msg, "^ASSISTME (.+)$");
926 if ( name and name == playerName ) then
927 CT_RATarget.assistPerson = { nick, 20 };
928 ShowUIPanel(CT_RA_AssistFrame);
929 end
930 end
931 return update;
932 elseif ( string.find(msg, "^STOPASSIST (.+)$") ) then
933 if ( rank >= 1 ) then
934 local _, _, name = string.find(msg, "^STOPASSIST (.+)$");
935 if ( name and name == playerName ) then
936 HideUIPanel(CT_RA_AssistFrame);
937 end
938 end
939 return update;
940 end
941  
942 -- Vote
943 local _, _, question = string.find(msg, "^VOTE (.+)$");
944 if ( question ) then
945 if ( rank >= 1 ) then
946 CT_RA_VotePerson = { nick, 0, 0, question };
947 if ( nick ~= playerName ) then
948 PlaySoundFile("Sound\\interface\\levelup2.wav");
949 CT_RA_VoteFrame.question = question;
950 CT_RA_VoteFrame:Show();
951 end
952 end
953 return update;
954 elseif ( ( msg == "VOTEYES" or msg == "VOTENO" ) and CT_RA_VotePerson and CT_RA_VotePerson[1] == playerName ) then
955 if ( msg == "VOTEYES" ) then
956 CT_RA_VotePerson[2] = CT_RA_VotePerson[2] + 1;
957 elseif ( msg == "VOTENO" ) then
958 CT_RA_VotePerson[3] = CT_RA_VotePerson[3] + 1;
959 end
960 return update;
961 end
962  
963 return update;
964 end
965  
966 -- Send messages
967 function CT_RA_AddMessage(msg)
968 tinsert(CT_RA_Comm_MessageQueue, msg);
969 end
970  
971 function CT_RA_SendMessage(msg)
972 if ( GetNumRaidMembers() == 0 ) then return; end -- Mod should be disabled if not in raid
973 SendAddonMessage("CTRA", msg, "RAID");
974 end
975  
976 function CT_RA_OnEvent(event)
977 if ( event == "PLAYER_LEAVING_WORLD" ) then
978 CT_RAFrame.disableEvents = true;
979 return;
980 elseif ( CT_RAFrame.disableEvents and event ~= "PLAYER_ENTERING_WORLD" ) then
981 return;
982 elseif ( event == "PLAYER_ENTERING_WORLD" or event == "RAID_ROSTER_UPDATE" ) then
983 CT_RAFrame.disableEvents = nil;
984 local numRaidMembers = GetNumRaidMembers();
985 local playerName = UnitName("player");
986 local tempOptions = CT_RAMenu_Options["temp"];
987 if ( event == "RAID_ROSTER_UPDATE" ) then
988 if ( numRaidMembers == 0 ) then
989 CT_RA_MainTanks = { };
990 CT_RA_PTargets = { };
991 CT_RATarget.MainTanks = { };
992 CT_RA_Stats = { };
993 CT_RA_ButtonIndexes = { };
994 CT_RA_Emergency_UpdateHealth();
995 CT_RA_UpdateMTs();
996 CT_RA_UpdatePTs();
997 CT_RAMetersFrame:Hide();
998 elseif ( CT_RA_NumRaidMembers == 0 and numRaidMembers > 0 ) then
999 CT_RA_UpdateFrame.SS = 10;
1000 if ( CT_RA_UpdateFrame.time ) then
1001 CT_RA_UpdateFrame.time = nil;
1002 end
1003 if ( not CT_RA_HasJoinedRaid ) then
1004 CT_RA_Print("<CTRaid> First raid detected. Thanks for using CT_RaidAssist!", 1, 0.5, 0);
1005 end
1006 CT_RA_PartyMembers = { };
1007 CT_RA_HasJoinedRaid = 1;
1008 if ( CT_RA_Squelch > 0 ) then
1009 CT_RA_Print("<CTRaid> Quiet Mode has been automatically disabled (joined raid).", 1, 0.5, 0);
1010 CT_RA_Squelch = 0;
1011 end
1012 end
1013 CT_RA_CheckGroups();
1014 end
1015 if ( numRaidMembers > 0 ) then
1016 if ( tempOptions["StatusMeters"] and tempOptions["StatusMeters"]["Show"] ) then
1017 CT_RAMetersFrame:Show();
1018 else
1019 CT_RAMetersFrame:Hide();
1020 end
1021 if ( tempOptions["ShowMonitor"] ) then
1022 CT_RA_ResFrame:Show();
1023 else
1024 CT_RA_ResFrame:Hide();
1025 end
1026 else
1027 CT_RA_ResFrame:Hide();
1028 CT_RAMetersFrame:Hide();
1029 end
1030 CT_RAOptions_Update();
1031 if ( CT_RA_NumRaidMembers ~= numRaidMembers ) then
1032 for i = 1, numRaidMembers, 1 do
1033 local uId = "raid" .. i;
1034 local uName = UnitName(uId);
1035 if ( uName and CT_RA_Stats[uName] ) then
1036 table.setn(CT_RA_Stats[uName]["Debuffs"], 0);
1037 end
1038 CT_RA_ScanPartyAuras(uId);
1039 end
1040 CT_RA_UpdateRaidGroup(0);
1041 if ( CT_RA_NumRaidMembers == 0 and CT_RA_Level >= 2 ) then
1042 local lootid = ( CT_RATab_DefaultLootMethod or -1 );
1043 if ( lootid == 1 ) then
1044 SetLootMethod("freeforall");
1045 elseif ( lootid == 2 ) then
1046 SetLootMethod("roundrobin");
1047 elseif ( lootid == 3 ) then
1048 SetLootMethod("master", playerName);
1049 elseif ( lootid == 4 ) then
1050 SetLootMethod("group");
1051 elseif ( lootid == 5 ) then
1052 SetLootMethod("needbeforegreed");
1053 end
1054 for i = 1, numRaidMembers, 1 do
1055 local name, rank = GetRaidRosterInfo(i);
1056 if ( name ~= playerName and rank < 1 and CT_RATab_AutoPromotions[name] ) then
1057 PromoteToAssistant(name);
1058 CT_RA_Print("<CTRaid> Auto-Promoted |c00FFFFFF" .. name .. "|r.", 1, 0.5, 0);
1059 end
1060 end
1061 end
1062 else
1063 CT_RA_UpdateRaidGroup(3);
1064 end
1065 CT_RA_NumRaidMembers = numRaidMembers;
1066 if ( not CT_RA_Channel and GetGuildInfo("player") ) then
1067 CT_RA_Channel = "CT" .. string.gsub(GetGuildInfo("player"), "[^%w]", "");
1068 end
1069 if ( event == "PLAYER_ENTERING_WORLD" ) then
1070 if ( CT_RA_RaidParticipant ) then
1071 if ( CT_RA_RaidParticipant ~= playerName ) then
1072 CT_RA_Stats = { { } };
1073 CT_RA_MainTanks = { };
1074 CT_RA_PTargets = { };
1075 CT_RATarget.MainTanks = { };
1076 CT_RA_ButtonIndexes = { };
1077 end
1078 end
1079 CT_RA_RaidParticipant = playerName;
1080 -- Add chat frame stuff
1081 local info = CT_RA_ChatInfo[playerName];
1082 local chatTypeInfo = ChatTypeInfo["CTRAID"];
1083 if ( not info ) then
1084 info = CT_RA_ChatInfo["Default"];
1085 end
1086 chatTypeInfo.r = info.r;
1087 chatTypeInfo.g = info.g;
1088 chatTypeInfo.b = info.b;
1089 end
1090 elseif ( event == "UNIT_HEALTH" or event == "UNIT_MAXHEALTH" ) then
1091 local _, _, id = string.find(arg1, "^raid(%d+)$");
1092 if ( id ) then
1093 local frame = getglobal("CT_RAMember" .. id);
1094 local name, hCurr, hMax = UnitName(arg1), UnitHealth(arg1), UnitHealthMax(arg1);
1095 local hpp = ( hCurr or 1 ) / ( hMax or 1 );
1096 local stats = CT_RA_Stats[name];
1097 if ( name ) then
1098 if ( not stats ) then
1099 CT_RA_Stats[name] = {
1100 ["Buffs"] = { },
1101 ["Debuffs"] = { },
1102 ["Position"] = { }
1103 };
1104 stats = CT_RA_Stats[name];
1105 end
1106 if ( UnitIsDead(arg1) or UnitIsGhost(arg1) ) then
1107 CT_RA_ScanPartyAuras(arg1);
1108 if ( not stats["Dead"] ) then
1109 stats["Dead"] = 1;
1110 end
1111 CT_RA_UpdateUnitDead(frame);
1112 elseif ( stats["Dead"] ) then
1113 if ( hCurr > 0 and not UnitIsGhost(arg1) ) then
1114 stats["Dead"] = nil;
1115 end
1116 CT_RA_UpdateUnitDead(frame);
1117 else
1118 stats["Dead"] = nil;
1119 if ( not frame.hpp or frame.hpp ~= floor(hpp*100) ) then
1120 CT_RA_UpdateUnitHealth(frame);
1121 end
1122 end
1123 if ( CT_RA_Emergency_Units[name] or ( not CT_RA_EmergencyFrame.maxPercent or hpp < CT_RA_EmergencyFrame.maxPercent ) ) then
1124 CT_RA_Emergency_UpdateHealth();
1125 end
1126 end
1127 elseif ( ( GetNumRaidMembers() == 0 and ( arg1 == "player" or string.find(arg1, "^party%d+$") ) ) ) then
1128 if ( CT_RA_Emergency_Units[UnitName(arg1)] or ( not CT_RA_EmergencyFrame.maxPercent or ( hpp and hpp < CT_RA_EmergencyFrame.maxPercent ) ) ) then
1129 CT_RA_Emergency_UpdateHealth();
1130 end
1131 end
1132 return;
1133 elseif ( event == "UNIT_AURA" and GetNumRaidMembers() > 0 ) then
1134 if ( string.find(arg1, "^raid%d+$") ) then
1135 CT_RA_ScanPartyAuras(arg1);
1136 end
1137 elseif ( event == "UNIT_MANA" or event == "UNIT_MAXMANA" or event == "UNIT_RAGE" or event == "UNIT_MAXRAGE" or event == "UNIT_ENERGY" or event == "UNIT_MAXENERGY" ) then
1138 local _, _, id = string.find(arg1, "^raid(%d+)$");
1139 if ( id ) then
1140 CT_RA_UpdateUnitMana(getglobal("CT_RAMember" .. id));
1141 end
1142 return;
1143 elseif ( event == "UI_ERROR_MESSAGE" or event == "UI_INFO_MESSAGE" ) then
1144 if ( CT_RA_LastCast and (GetTime()-CT_RA_LastCast) <= 0.1 ) then
1145 if ( CT_RA_LastCastType == "debuff" ) then
1146 tinsert(CT_RA_BuffsToCure, 1, CT_RA_LastCastSpell);
1147 else
1148 tinsert(CT_RA_BuffsToRecast, 1, CT_RA_LastCastSpell);
1149 end
1150 CT_RA_LastCast = nil;
1151 CT_RA_LastCastSpell = nil;
1152 end
1153 elseif ( event == "SPELLCAST_START" ) then
1154 CT_RA_CurrCastSpell = arg1;
1155 elseif ( event == "SPELLCAST_INTERRUPTED" or event == "SPELLCAST_FAILED" ) then
1156 CT_RA_CurrCastSpell = nil;
1157 elseif ( event == "SPELLCAST_STOP" and CT_RA_CurrCastSpell ) then
1158 if ( CT_RA_CurrCastSpell == CT_RA_REBIRTH ) then
1159 CT_RA_AddMessage("CD 1 30");
1160 elseif ( CT_RA_CurrCastSpell == CT_RA_SOULSTONERESURRECTION ) then
1161 CT_RA_AddMessage("CD 3 30");
1162 end
1163 CT_RA_CurrCastSpell = nil;
1164 elseif ( event == "PLAYER_TARGET_CHANGED" ) then
1165 CT_RA_UpdateResFrame();
1166 end
1167 end
1168  
1169 CT_RA_oldUseSoulstone = UseSoulstone;
1170 function CT_RA_newUseSoulstone()
1171 local text = HasSoulstone();
1172 if ( text and text == "Reincarnation" ) then
1173 local cooldown;
1174 for i = 1, GetNumTalentTabs(), 1 do
1175 for y = 1, GetNumTalents(i), 1 do
1176 local name, _, _, _, currRank = GetTalentInfo(i, y);
1177 if ( name == "Improved Reincarnation" ) then
1178 cooldown = 60 - (currRank*10);
1179 break;
1180 end
1181 end
1182 if ( cooldown ) then
1183 break;
1184 end
1185 end
1186 if ( not cooldown ) then
1187 cooldown = 60;
1188 end
1189 CT_RA_AddMessage("CD 2 " .. cooldown);
1190 end
1191 CT_RA_oldUseSoulstone();
1192 end
1193 UseSoulstone = CT_RA_newUseSoulstone;
1194  
1195 -----------------------------------------------------
1196 -- Update Functions --
1197 -----------------------------------------------------
1198  
1199 -- Update health
1200 function CT_RA_UpdateUnitHealth(frame)
1201 local tempOptions = CT_RAMenu_Options["temp"];
1202 if ( not frame.group or not tempOptions["ShowGroups"][frame.group.id] ) then
1203 return;
1204 end
1205 local id = "raid" .. frame.id;
1206 local maxHealth = UnitHealthMax(id);
1207 local percent = floor(UnitHealth(id) / maxHealth * 100);
1208 local name = UnitName(id);
1209 if ( not name and tempOptions["SORTTYPE"] == "virtual" ) then
1210 percent = 100;
1211 maxHealth = 100;
1212 name = "Virtual " .. frame.id;
1213 end
1214 frame.hpp = percent;
1215 local updateDead = frame.status;
1216 if ( percent and percent > 0 ) then
1217 -- Commonly used values
1218 local defaultAlpha = tempOptions.DefaultAlpha;
1219 if ( defaultAlpha and defaultAlpha < 1 ) then
1220 frame:SetAlpha(math.max(math.min(defaultAlpha+(1-(percent/100))*(1-defaultAlpha), 1), defaultAlpha));
1221 else
1222 frame:SetAlpha(1);
1223 end
1224 local showHP = tempOptions["ShowHP"];
1225 local memberHeight = tempOptions["MemberHeight"];
1226 local framePercent = frame.Percent;
1227 local frameHPBar = frame.HPBar;
1228 local stats = CT_RA_Stats[name];
1229  
1230 if ( stats and stats["Ressed"] ) then
1231 stats["Ressed"] = nil;
1232 updateDead = 1;
1233 end
1234 if ( percent > 100 ) then
1235 percent = 100;
1236 end
1237 frameHPBar:SetValue(percent);
1238 if ( showHP and showHP == 1 and maxHealth and memberHeight == 40 ) then
1239 framePercent:SetText(floor(percent/100*maxHealth) .. "/" .. maxHealth);
1240 elseif ( showHP and showHP == 2 and memberHeight == 40 ) then
1241 framePercent:SetText(percent .. "%");
1242 elseif ( showHP and showHP == 3 and memberHeight == 40 ) then
1243 if ( maxHealth ) then
1244 local diff = floor(percent/100*maxHealth)-maxHealth;
1245 if ( diff == 0 ) then diff = ""; end
1246 framePercent:SetText(diff);
1247 else
1248 framePercent:SetText(percent-100 .. "%");
1249 end
1250 else
1251 framePercent:Hide();
1252 end
1253 local hppercent = percent/100;
1254 local r, g;
1255 if ( hppercent > 0.5 and hppercent <= 1) then
1256 g = 1;
1257 r = (1.0 - hppercent) * 2;
1258 elseif ( hppercent >= 0 and hppercent <= 0.5 ) then
1259 r = 1.0;
1260 g = hppercent * 2;
1261 else
1262 r = 0;
1263 g = 1;
1264 end
1265 frameHPBar:SetStatusBarColor(r, g, 0);
1266 frame.HPBG:SetVertexColor(r, g, 0, tempOptions["BGOpacity"]);
1267 end
1268 local isDead;
1269 if ( updateDead ) then
1270 CT_RA_UpdateUnitDead(frame, 1);
1271 end
1272 end
1273  
1274 -- Update status
1275  
1276 function CT_RA_UpdateUnitStatus(frame)
1277 local tempOptions = CT_RAMenu_Options["temp"];
1278 if ( not frame.group or not tempOptions["ShowGroups"][frame.group.id] ) then
1279 return;
1280 end
1281 local frameName = frame.name;
1282 local id = frame.id;
1283 local castFrame = frame.CastFrame;
1284  
1285 local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(id);
1286 if ( not name and tempOptions["SORTTYPE"] == "virtual" ) then
1287 name, rank, subgroup, level, class, fileName, zone, online, isDead = "Virtual " .. id, 0, floor((id-1)/5)+1, 60, CT_RA_PRIEST, "PRIEST", "Emerald Dream", 1, nil;
1288 end
1289 local height = tempOptions["MemberHeight"];
1290 if ( ( ( class == CT_RA_WARRIOR or class == CT_RA_ROGUE ) and tempOptions["HideRP"] ) or ( class ~= CT_RA_WARRIOR and class ~= CT_RA_ROGUE and tempOptions["HideMP"] ) ) then
1291 height = height - 4;
1292 end
1293 if ( tempOptions["HideBorder"] ) then
1294 if ( height == 28 ) then
1295 frame.BuffButton1:SetPoint("TOPRIGHT", frameName, "TOPRIGHT", -5, -5);
1296 frame.DebuffButton1:SetPoint("TOPRIGHT", frameName, "TOPRIGHT", -5, -5);
1297 else
1298 frame.BuffButton1:SetPoint("TOPRIGHT", frameName, "TOPRIGHT", -5, -3);
1299 frame.DebuffButton1:SetPoint("TOPRIGHT", frameName, "TOPRIGHT", -5, -3);
1300 end
1301 frame:SetBackdropBorderColor(1, 1, 1, 0);
1302  
1303 frame.Percent:SetPoint("TOP", frameName, "TOP", 2, -16);
1304 frame.HPBar:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -19);
1305 frame.HPBG:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -19);
1306 castFrame:SetWidth(85);
1307 if ( not online ) then
1308 frame:SetHeight(37);
1309 castFrame:SetHeight(37);
1310 else
1311 frame:SetHeight(height-3);
1312 castFrame:SetHeight(height-3);
1313 end
1314 else
1315 frame:SetBackdropBorderColor(1, 1, 1, 1);
1316 frame.BuffButton1:SetPoint("TOPRIGHT", frameName, "TOPRIGHT", -5, -5);
1317 frame.DebuffButton1:SetPoint("TOPRIGHT", frameName, "TOPRIGHT", -5, -5);
1318 frame.HPBar:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -22);
1319 frame.HPBG:SetPoint("TOPLEFT",frameName, "TOPLEFT", 10, -22);
1320 frame.Percent:SetPoint("TOP", frameName, "TOP", 2, -18);
1321 castFrame:SetWidth(90);
1322 if ( not online ) then
1323 frame:SetHeight(40);
1324 castFrame:SetHeight(40);
1325 else
1326 frame:SetHeight(height);
1327 castFrame:SetHeight(height);
1328 end
1329 end
1330 if ( height == 32 or height == 28 ) then
1331 frame.HPBar:Hide();
1332 frame.HPBG:Hide();
1333 frame.Percent:Hide();
1334 else
1335 frame.HPBar:Show();
1336 frame.HPBG:Show();
1337 end
1338 stats = CT_RA_Stats[name];
1339 if ( frame.group and tempOptions["ShowGroups"][frame.group.id] ) then
1340 frame:Show();
1341 end
1342 frame.Name:SetText(name);
1343 CT_RA_UpdateUnitDead(frame);
1344 if ( stats ) then
1345 CT_RA_UpdateUnitBuffs(stats["Buffs"], frame, name);
1346 end
1347 if ( online ) then
1348 CT_RA_UpdateUnitHealth(frame, 1);
1349 CT_RA_UpdateUnitMana(frame);
1350 if ( stats ) then
1351 CT_RA_UpdateUnitBuffs(stats["Buffs"], frame, name);
1352 end
1353 end
1354 end
1355  
1356 function CT_RA_CanShowInfo(id)
1357 local tempOptions = CT_RAMenu_Options["temp"];
1358 local stats = CT_RA_Stats[UnitName(id)];
1359 local showHP, hasFD, isRessed, isNotReady, showAFK, isDead;
1360 local hp = tempOptions["ShowHP"];
1361  
1362 showHP = ( hp and hp <= 3 );
1363 hasFD = ( stats and stats["FD"] );
1364 isRessed = ( stats and stats["Ressed"] );
1365 isNotReady = ( stats and stats["notready"] );
1366 showAFK = ( tempOptions["ShowAFK"] and stats and stats["AFK"] );
1367 isDead = ( ( stats and stats["Dead"] ) or UnitIsDead(id) or UnitIsGhost(id) );
1368 if ( showHP and not hasFD and not isRessed and not isNotReady and not showAFK and not isDead ) then
1369 return true;
1370 else
1371 return nil;
1372 end
1373 end
1374 -- Update mana
1375 function CT_RA_UpdateUnitMana(frame)
1376 local tempOptions = CT_RAMenu_Options["temp"];
1377 if ( not frame.group or not tempOptions["ShowGroups"][frame.group.id] ) then
1378 return;
1379 end
1380 local id = "raid" .. frame.id;
1381 local percent;
1382 if ( not UnitExists(id) and tempOptions["SORTTYPE"] == "virtual" ) then
1383 percent = 100;
1384 else
1385 percent = floor(UnitMana(id) / UnitManaMax(id) * 100);
1386 end
1387 frame.MPBar:SetValue(percent);
1388 end
1389  
1390 -- Update buffs
1391 function CT_RA_UpdateUnitBuffs(buffs, frame, nick)
1392 local tempOptions = CT_RAMenu_Options["temp"];
1393 if ( not frame.group or not tempOptions["ShowGroups"][frame.group.id] ) then
1394 return;
1395 end
1396 local num = 1;
1397 if ( buffs ) then
1398 if ( not tempOptions["ShowDebuffs"] or tempOptions["ShowBuffsDebuffed"] ) then
1399 for key, val in tempOptions["BuffArray"] do
1400 local name;
1401 if ( type(val["name"]) == "table" ) then
1402 if ( buffs[val["name"][1]] ) then
1403 name = val["name"][1];
1404 elseif ( buffs[val["name"][2]] ) then
1405 name = val["name"][2];
1406 end
1407 elseif ( buffs[val["name"]] ) then
1408 name = val["name"];
1409 end
1410 if ( name ) then
1411 if ( num <= 4 and val["show"] ~= -1 ) then -- Change 4 to number of buffs
1412 local button = frame["BuffButton"..num];
1413 frameCache[button].Icon:SetTexture("Interface\\Icons\\" .. CT_RA_BuffTextures[name][1]);
1414 button.name = name;
1415 button.owner = nick;
1416 button.texture = CT_RA_BuffTextures[name][1];
1417 button:Show();
1418 num = num + 1;
1419 end
1420 end
1421 end
1422 end
1423 end
1424 for i = num, 4, 1 do -- Change 4 to number of buffs
1425 frame["BuffButton"..i]:Hide();
1426 end
1427 local stats = CT_RA_Stats[nick];
1428 if ( stats ) then
1429 CT_RA_UpdateUnitDebuffs(stats["Debuffs"], frame);
1430 end
1431 end
1432  
1433 function CT_RA_UpdateUnitDead(frame, didUpdateHealth)
1434 local tempOptions = CT_RAMenu_Options["temp"];
1435 if ( not frame.group or not tempOptions["ShowGroups"][frame.group.id] ) then
1436 return;
1437 end
1438 local raidid = "raid" .. frame.id;
1439 local name, rank, subgroup, level, class, fileName, zone, online, dead = GetRaidRosterInfo(frame.id);
1440 if ( not name and tempOptions["SORTTYPE"] == "virtual" ) then
1441 name, rank, subgroup, level, class, fileName, zone, online, isDead = "Virtual " .. frame.id, 0, floor((frame.id-1)/5)+1, 60, CT_RA_PRIEST, "PRIEST", "Emerald Dream", 1, nil;
1442 end
1443 local color = RAID_CLASS_COLORS[fileName];
1444 if ( color ) then
1445 frame.Name:SetTextColor(color.r, color.g, color.b);
1446 end
1447 local stats, isFD, isDead = CT_RA_Stats[name], false, false;
1448 if ( UnitIsGhost(raidid) or UnitIsDead(raidid) ) then
1449 isFD = CT_RA_CheckFD(name, raidid)
1450 if ( isFD == 0 ) then
1451 isDead = 1;
1452 -- Scan buffs&debuffs on death
1453 CT_RA_ScanPartyAuras(raidid);
1454 end
1455 end
1456 local height = tempOptions["MemberHeight"];
1457 if ( ( ( class == CT_RA_WARRIOR or class == CT_RA_ROGUE ) and tempOptions["HideRP"] ) or ( class ~= CT_RA_WARRIOR and class ~= CT_RA_ROGUE and tempOptions["HideMP"] ) ) then
1458 height = height - 4;
1459 end
1460 if ( not online ) then
1461 if ( tempOptions["HideOffline"] ) then
1462 frame:Hide();
1463 end
1464 for i = 1, 4, 1 do
1465 if ( i <= 2 ) then
1466 frame["DebuffButton"..i]:Hide();
1467 end
1468 frame["BuffButton"..i]:Hide();
1469 end
1470 frame:SetBackdropColor(0.3, 0.3, 0.3, 1);
1471 if ( tempOptions["HideBorder"] ) then
1472 frame:SetHeight(37);
1473 else
1474 frame:SetHeight(40);
1475 end
1476 if ( name ) then
1477 if ( not stats ) then
1478 CT_RA_Stats[name] = {
1479 ["Buffs"] = { },
1480 ["Debuffs"] = { },
1481 ["Position"] = { },
1482 };
1483 stats = CT_RA_Stats[name];
1484 end
1485 if ( not stats["Offline"] ) then
1486 stats["Offline"] = 1;
1487 end
1488 end
1489 frame.status = "offline";
1490 frame.Status:SetText("OFFLINE");
1491 frame.Status:Show();
1492 frame.HPBar:Hide();
1493 frame.HPBG:Hide();
1494 frame.Percent:Hide();
1495 frame.MPBar:Hide();
1496 frame.MPBG:Hide();
1497 frame:SetAlpha(1);
1498 return;
1499 elseif ( stats and stats["notready"] ) then
1500 frame.Status:Show();
1501 if ( tempOptions["HideBorder"] ) then
1502 frame:SetHeight(37);
1503 else
1504 frame:SetHeight(40);
1505 end
1506  
1507 if ( stats["notready"] == 1 ) then
1508 frame.status = "noreply";
1509 frame.Status:SetText("No Reply");
1510 frame:SetBackdropColor(0.45, 0.45, 0.45, 1);
1511 else
1512 frame.status = "notready";
1513 frame.Status:SetText("Not Ready");
1514 frame:SetBackdropColor(0.8, 0.45, 0.45, 1);
1515 end
1516  
1517 frame.HPBar:Hide();
1518 frame.HPBG:Hide();
1519 frame.Percent:Hide();
1520 frame.MPBar:Hide();
1521 frame.MPBG:Hide();
1522 frame:SetAlpha(1);
1523 elseif ( isFD == 1 ) then
1524 frame.status = "feigndeath";
1525 frame.Status:Show();
1526 frame.Status:SetText("Feign Death");
1527 frame:SetBackdropColor(0.3, 0.3, 0.3, 1);
1528 if ( tempOptions["HideBorder"] and ( ( ( class == CT_RA_WARRIOR or class == CT_RA_ROGUE ) and tempOptions["HideRP"] ) or ( class ~= CT_RA_WARRIOR and class ~= CT_RA_ROGUE and tempOptions["HideMP"] ) ) ) then
1529 frame:SetHeight(height+3);
1530 end
1531 frame.HPBar:Hide();
1532 frame.HPBG:Hide();
1533 frame.Percent:Hide();
1534 frame.MPBar:Hide();
1535 frame.MPBG:Hide();
1536 frame:SetAlpha(1);
1537 elseif ( isFD == 2 ) then
1538 frame.status = "spiritofredemption";
1539 frame.Status:Show();
1540 frame.Status:SetText("SoR");
1541 frame:SetBackdropColor(0.3, 0.3, 0.3, 1);
1542 if ( tempOptions["HideBorder"] and ( ( ( class == CT_RA_WARRIOR or class == CT_RA_ROGUE ) and tempOptions["HideRP"] ) or ( class ~= CT_RA_WARRIOR and class ~= CT_RA_ROGUE and tempOptions["HideMP"] ) ) ) then
1543 frame:SetHeight(height+3);
1544 end
1545 frame.HPBar:Hide();
1546 frame.HPBG:Hide();
1547 frame.Percent:Hide();
1548 frame.MPBar:Hide();
1549 frame.MPBG:Hide();
1550 frame:SetAlpha(1);
1551 elseif ( stats and stats["Ressed"] ) then
1552 frame.status = "resurrected";
1553 frame.Status:Show();
1554 frame:SetBackdropColor(0.3, 0.3, 0.3, 1);
1555 if ( tempOptions["HideBorder"] ) then
1556 frame:SetHeight(37);
1557 else
1558 frame:SetHeight(40);
1559 end
1560 if ( stats["Ressed"] == 1 ) then
1561 frame.Status:SetText("Resurrected");
1562 elseif ( stats["Ressed"] == 2 ) then
1563 frame.Status:SetText("SS Available");
1564 end
1565 frame.HPBar:Hide();
1566 frame.HPBG:Hide();
1567 frame.Percent:Hide();
1568 frame.MPBar:Hide();
1569 frame.MPBG:Hide();
1570 frame:SetAlpha(1);
1571 elseif ( isDead ) then
1572 frame.status = "dead";
1573 for i = 1, 4, 1 do
1574 if ( i <= 2 ) then
1575 frame["DebuffButton"..i]:Hide();
1576 end
1577 frame["BuffButton"..i]:Hide();
1578 end
1579 frame.Status:Show();
1580 frame:SetBackdropColor(0.3, 0.3, 0.3, 1);
1581 if ( tempOptions["HideBorder"] ) then
1582 frame:SetHeight(37);
1583 else
1584 frame:SetHeight(40);
1585 end
1586 frame.Status:SetText("DEAD");
1587 frame.HPBar:Hide();
1588 frame.HPBG:Hide();
1589  
1590 frame.Percent:Hide();
1591 frame.MPBar:Hide();
1592 frame.MPBG:Hide();
1593 frame:SetAlpha(1);
1594 elseif ( stats and stats["AFK"] and tempOptions["ShowAFK"] ) then
1595 frame.status = "afk";
1596 frame.Status:Show();
1597 frame:SetBackdropColor(0.3, 0.3, 0.3, 1);
1598 if ( tempOptions["HideBorder"] ) then
1599 frame:SetHeight(37);
1600 else
1601 frame:SetHeight(40);
1602 end
1603  
1604 frame.Status:SetText("AFK");
1605 frame.HPBar:Hide();
1606 frame.HPBG:Hide();
1607 frame.Percent:Hide();
1608 frame.MPBar:Hide();
1609 frame.MPBG:Hide();
1610 frame:SetAlpha(1);
1611 else
1612 if ( frame.status and not didUpdateHealth ) then
1613 CT_RA_UpdateUnitHealth(frame);
1614 end
1615 local canShowInfo = CT_RA_CanShowInfo("raid"..frame.id);
1616 frame.status = nil;
1617 frame:SetBackdropColor(tempOptions["DefaultColor"].r, tempOptions["DefaultColor"].g, tempOptions["DefaultColor"].b, tempOptions["DefaultColor"].a);
1618 if ( tempOptions["MemberHeight"] == 40 ) then
1619 frame.HPBar:Show();
1620 frame.HPBG:Show();
1621 if ( canShowInfo ) then
1622 frame.Percent:Show();
1623 else
1624 frame.Percent:Hide();
1625 end
1626 end
1627 if ( tempOptions["HideBorder"] ) then
1628 frame:SetHeight(height-3);
1629 else
1630 frame:SetHeight(height);
1631 end
1632 if ( class == CT_RA_WARRIOR ) then
1633 frame.MPBar:SetStatusBarColor(1, 0, 0);
1634 frame.MPBG:SetVertexColor(1, 0, 0, tempOptions["BGOpacity"]);
1635 elseif ( class == CT_RA_ROGUE ) then
1636 frame.MPBar:SetStatusBarColor(1, 1, 0);
1637 frame.MPBG:SetVertexColor(1, 1, 0, tempOptions["BGOpacity"]);
1638 else
1639 frame.MPBar:SetStatusBarColor(0, 0, 1);
1640 frame.MPBG:SetVertexColor(0, 0, 1, tempOptions["BGOpacity"]);
1641 end
1642 frame.Status:Hide();
1643 if ( ( ( class == CT_RA_WARRIOR or class == CT_RA_ROGUE ) and not tempOptions["HideRP"] ) or ( class ~= CT_RA_WARRIOR and class ~= CT_RA_ROGUE and not tempOptions["HideMP"] ) ) then
1644 frame.MPBar:Show();
1645 frame.MPBG:Show();
1646 if ( canShowInfo ) then
1647 frame.Percent:Show();
1648 else
1649 frame.Percent:Hide();
1650 end
1651 else
1652 frame.MPBar:Hide();
1653 frame.MPBG:Hide();
1654 end
1655 end
1656 if ( stats ) then
1657 stats["Offline"] = nil;
1658 end
1659 end
1660  
1661 -- Update debuffs
1662 function CT_RA_UpdateUnitDebuffs(debuffs, frame)
1663 local tempOptions = CT_RAMenu_Options["temp"];
1664 if ( not frame.group or not tempOptions["ShowGroups"][frame.group.id] ) then
1665 return;
1666 end
1667 local num = 1;
1668 if ( tempOptions["ShowBuffsDebuffed"] ) then
1669 num = 2;
1670 end
1671 local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(frame.id);
1672 local stats, setbg = CT_RA_Stats[name], 0;
1673 if ( name and stats and online and not UnitIsGhost("raid" .. frame.id) and ( not UnitIsDead("raid" .. frame.id) or stats["FD"] ) ) then
1674 if ( not frame.status ) then
1675 local defaultColors = tempOptions["DefaultColor"];
1676 frame:SetBackdropColor(defaultColors.r, defaultColors.g, defaultColors.b, defaultColors.a);
1677 end
1678 if ( debuffs ) then
1679 for key, val in tempOptions["DebuffColors"] do
1680 for k, v in debuffs do
1681 local en, de, fr;
1682 if ( type(val["type"]) == "table" ) then
1683 en = val["type"]["en"];
1684 de = val["type"]["de"];
1685 fr = val["type"]["fr"];
1686 else
1687 en = val["type"];
1688 end
1689 if ( ( ( en and en == v[1] ) or ( de and de == v[1] ) or ( fr and fr == v[1] ) ) and val["id"] ~= -1 ) then
1690 if ( tempOptions["ShowBuffsDebuffed"] and num >= 1 ) then
1691 local button = frame["DebuffButton"..num];
1692 frameCache[button].Icon:SetTexture("Interface\\Icons\\" ..v[3]);
1693 button.name = k;
1694 button.owner = name;
1695 button.texture = v[3];
1696 button:Show();
1697 num = num - 1;
1698 elseif ( not tempOptions["ShowBuffsDebuffed"] and tempOptions["ShowDebuffs"] and num <= 2 ) then
1699 local button = frame["DebuffButton"..num];
1700 frameCache[button].Icon:SetTexture("Interface\\Icons\\" ..v[3]);
1701 button.name = k;
1702 button.owner = name;
1703 button.texture = v[3];
1704 button:Show();
1705 num = num + 1;
1706 end
1707 if ( setbg == 0 and not frame.status ) then
1708 frame:SetBackdropColor(val.r, val.g, val.b, val.a);
1709 setbg = 1;
1710 end
1711 end
1712 end
1713 end
1714 end
1715 if ( tempOptions["ShowBuffsDebuffed"] ) then
1716 if ( num < 1 ) then
1717 for i = 1, 4, 1 do
1718 frame["BuffButton"..i]:Hide();
1719 end
1720 end
1721 for i = num, 1, -1 do
1722 frame["DebuffButton"..i]:Hide();
1723 end
1724 else
1725 for i = num, 2, 1 do
1726 frame["DebuffButton"..i]:Hide();
1727 end
1728 end
1729 end
1730 end
1731  
1732 -- Get info
1733  
1734 function CT_RA_SortClassArray(arr)
1735  
1736 local classValues = {
1737 [CT_RA_WARRIOR] = 8,
1738 [CT_RA_PALADIN] = 7,
1739 [CT_RA_DRUID] = 6,
1740 [CT_RA_MAGE] = 5,
1741 [CT_RA_WARLOCK] = 4,
1742 [CT_RA_ROGUE] = 3,
1743 [CT_RA_HUNTER] = 2,
1744 [CT_RA_PRIEST] = 1,
1745 [CT_RA_SHAMAN] = 0
1746 };
1747  
1748 local limit, st, j, temp, swapped;
1749 limit = getn(arr);
1750 st = 0;
1751 while ( st < limit ) do
1752 swapped = false;
1753 st = st + 1;
1754 limit = limit - 1;
1755 local val, val1;
1756  
1757 for j = st, limit, 1 do
1758 if ( arr[j]["class"] ) then
1759 val = classValues[arr[j]["class"]];
1760 else
1761 val = 0;
1762 end
1763 if ( arr[j+1]["class"] ) then
1764 val1 = classValues[arr[j+1]["class"]];
1765 else
1766 val1 = 0;
1767 end
1768 if ( val < val1 ) then
1769 temp = arr[j];
1770 arr[j] = arr[j+1];
1771 arr[j+1] = temp;
1772 swapped = true;
1773 end
1774 end
1775 if ( not swapped ) then return arr; end
1776  
1777 swapped = false;
1778 for j=limit, st, -1 do
1779 if ( arr[j]["class"] ) then
1780 val = classValues[arr[j]["class"]];
1781 else
1782 val = 0;
1783 end
1784 if ( arr[j+1]["class"] ) then
1785 val1 = classValues[arr[j+1]["class"]];
1786 else
1787 val1 = 0;
1788 end
1789  
1790 if ( val < val1 ) then
1791 temp = arr[j];
1792 arr[j] = arr[j+1];
1793 arr[j+1] = temp;
1794 swapped = true;
1795 end
1796 end
1797 if ( not swapped ) then return arr; end
1798 end
1799 return arr;
1800 end
1801  
1802 function CT_RA_UpdateMT(raidid, mtid, frame, height, key, val)
1803 local tempOptions = CT_RAMenu_Options["temp"];
1804 local framecast = frame.CastFrame;
1805 local frameName = frame.name;
1806 if ( not tempOptions["ShowMTTT"] or ( UnitIsUnit(mtid, raidid .. "target") or tempOptions["HideColorChange"] ) ) then
1807 local defaultColors = tempOptions.DefaultColor;
1808 frame:SetBackdropColor(defaultColors.r, defaultColors.g, defaultColors.b, defaultColors.a);
1809 else
1810 frame:SetBackdropColor(1, 0, 0, 1);
1811 end
1812 if ( tempOptions["HideBorder"] ) then
1813 frame.Percent:SetPoint("TOP", frameName, "TOPLEFT", 47, -16);
1814 frame:SetBackdropBorderColor(1, 1, 1, 0);
1815 frame.HPBar:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -19);
1816 frame.HPBG:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -19);
1817 frame:SetHeight(height-3);
1818 frame.height = height-3;
1819 framecast:SetHeight(height-3);
1820 framecast:SetWidth(85);
1821 else
1822 frame:SetBackdropBorderColor(1, 1, 1, 1);
1823 frame.HPBar:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -22);
1824 frame.HPBG:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -22);
1825 frame.Percent:SetPoint("TOP", frameName, "TOPLEFT", 47, -18);
1826 frame:SetHeight(height);
1827 frame.height = height;
1828 framecast:SetHeight(height);
1829 framecast:SetWidth(90);
1830 end
1831 if ( raidid and UnitExists(raidid) and strlen(UnitName(raidid) or "") > 0 ) then
1832 local health, healthmax, mana, manamax = UnitHealth(raidid), UnitHealthMax(raidid), UnitMana(raidid), UnitManaMax(raidid);
1833 frame.Name:SetHeight(15);
1834 frame.Status:Hide();
1835 frame.HPBar:Show();
1836 frame.HPBG:Show();
1837 frame.MPBar:Show();
1838 frame.MPBG:Show();
1839 frame.Name:Show();
1840 local manaType = UnitPowerType(raidid);
1841 if ( ( manaType == 0 and not tempOptions["HideMP"] ) or ( manaType > 0 and not tempOptions["HideRP"] and UnitIsPlayer(raidid) ) ) then
1842 local manaTbl = ManaBarColor[manaType];
1843 frame.MPBar:SetStatusBarColor(manaTbl.r, manaTbl.g, manaTbl.b);
1844 frame.MPBG:SetVertexColor(manaTbl.r, manaTbl.g, manaTbl.b, tempOptions["BGOpacity"]);
1845 if ( tempOptions["HideBorder"] ) then
1846 frame:SetHeight(37);
1847 frame.height = 37;
1848 framecast:SetHeight(37);
1849 else
1850 frame:SetHeight(40);
1851 frame.height = 40;
1852 framecast:SetHeight(40);
1853 end
1854 frame.MPBar:SetMinMaxValues(0, manamax);
1855 frame.MPBar:SetValue(mana);
1856 else
1857 frame.MPBar:Hide();
1858 frame.MPBG:Hide();
1859 if ( tempOptions["HideBorder"] ) then
1860 frame:SetHeight(33);
1861 frame.height = 33;
1862 framecast:SetHeight(33);
1863 else
1864 frame:SetHeight(36);
1865 frame.height = 36;
1866 framecast:SetHeight(36);
1867 end
1868 end
1869 if ( health and healthmax and not UnitIsDead(raidid) and not UnitIsGhost(raidid) ) then
1870 if ( tempOptions["ShowHP"] and tempOptions["ShowHP"] <= 4 ) then
1871 frame.Percent:Show();
1872 else
1873 frame.Percent:Hide();
1874 end
1875  
1876 frame.HPBar:SetMinMaxValues(0, healthmax);
1877 frame.HPBar:SetValue(health);
1878  
1879 frame.Percent:SetText(floor(health/healthmax*100+0.5) .. "%");
1880 local percent = health/healthmax;
1881 if ( percent >= 0 and percent <= 1 ) then
1882 local r, g;
1883 if ( percent > 0.5 ) then
1884 g = 1;
1885 r = (1.0 - percent) * 2;
1886 else
1887 r = 1;
1888 g = percent * 2;
1889 end
1890 frame.HPBar:SetStatusBarColor(r, g, 0);
1891 frame.HPBG:SetVertexColor(r, g, 0, tempOptions["BGOpacity"]);
1892 end
1893 elseif ( UnitIsDead(raidid) or UnitIsGhost(raidid) ) then
1894 frame.HPBar:Hide();
1895 frame.HPBG:Hide();
1896 frame.Percent:Hide();
1897 frame.MPBar:Hide();
1898 frame.MPBG:Hide();
1899 frame.Status:Show();
1900 frame.Status:SetText("DEAD");
1901 else
1902 frame.HPBar:Hide();
1903 frame.HPBG:Hide();
1904 end
1905 frame.Name:SetText(UnitName(raidid));
1906 if ( UnitCanAttack("player", raidid) ) then
1907 frame.Name:SetTextColor(1, 0.5, 0);
1908 else
1909 frame.Name:SetTextColor(0.5, 1, 0);
1910 end
1911 frame.CastFrame.unitName = UnitName(raidid);
1912 else
1913 frame.Percent:Hide();
1914 frame.HPBar:Hide();
1915 frame.HPBG:Hide();
1916 frame.MPBar:Hide();
1917 frame.MPBG:Hide();
1918 frame.Status:Hide();
1919 frame.Name:SetText(val .. "'s Target");
1920 frame.Name:SetHeight(30);
1921 frame.Name:SetTextColor(1, 0.82, 0);
1922 end
1923 end
1924  
1925 function CT_RA_UpdateMTs()
1926 local tempOptions = CT_RAMenu_Options["temp"];
1927 CT_RAMTGroupGroupName:SetText("MT Targets");
1928 CT_RAMTGroup:Hide();
1929 CT_RAMTGroupGroupName:Hide();
1930 for i = 1, 10, 1 do
1931 local mem = getglobal("CT_RAMTGroupMember" .. i);
1932 mem:Hide();
1933 mem:ClearAllPoints();
1934 if ( i > 1 ) then
1935 local above = "CT_RAMTGroupMember" .. (i-1);
1936 if ( tempOptions["HideBorder"] ) then
1937 if ( tempOptions["HideSpace"] ) then
1938 if ( tempOptions["ShowReversed"] ) then
1939 mem:SetPoint("BOTTOMLEFT", above, "TOPLEFT", 0, -10);
1940 else
1941 mem:SetPoint("TOPLEFT", above, "BOTTOMLEFT", 0, 10);
1942 end
1943 else
1944 if ( tempOptions["ShowReversed"] ) then
1945 mem:SetPoint("BOTTOMLEFT", above, "TOPLEFT", 0, -7);
1946 else
1947 mem:SetPoint("TOPLEFT", above, "BOTTOMLEFT", 0, 7);
1948 end
1949 end
1950 else
1951 if ( tempOptions["ShowReversed"] ) then
1952 mem:SetPoint("BOTTOMLEFT", above, "TOPLEFT", 0, -5);
1953 else
1954 mem:SetPoint("TOPLEFT", above, "BOTTOMLEFT", 0, 4);
1955 end
1956 end
1957 else
1958 if ( tempOptions["ShowReversed"] ) then
1959 mem:SetPoint("BOTTOMLEFT", "CT_RAMTGroup", "TOPLEFT", 0, -15);
1960 else
1961 mem:SetPoint("TOPLEFT", "CT_RAMTGroup", "TOPLEFT", 0, -20);
1962 end
1963 end
1964 end
1965 if ( GetNumRaidMembers() == 0 or tempOptions["HideMTs"] ) then
1966 CT_RAMTGroupDrag:Hide();
1967 return;
1968 end
1969 local hide = true;
1970 for key, val in CT_RA_MainTanks do
1971 if ( key <= ( tempOptions["ShowNumMTs"] or 10 ) ) then
1972 local height = tempOptions["MemberHeight"];
1973 if ( tempOptions["HideMP"] ) then
1974 height = height - 4;
1975 end
1976 local frame = getglobal("CT_RAMTGroupMember" .. key);
1977 local frameParent = frame.frameParent;
1978 local raidid, mtid;
1979 for i = 1, GetNumRaidMembers(), 1 do
1980 if ( UnitName("raid" .. i) == CT_RA_MainTanks[key] ) then
1981 raidid = "raid" .. i .. "target";
1982 mtid = "raid" .. i;
1983 break;
1984 end
1985 end
1986 if ( raidid and mtid ) then
1987 local name, hppercent, mppercent = UnitName(raidid), UnitHealth(raidid)/UnitHealthMax(raidid), UnitMana(raidid)/UnitManaMax(raidid);
1988 if ( name ~= ( frame.unitName or "" ) or hppercent ~= ( frame.hppercent or -1 ) or mppercent ~= ( frame.mppercent or -1 ) or not UnitIsConnected(raidid) ) then
1989 if ( not UnitIsConnected(raidid) ) then
1990 frame.unitName = nil; frame.hppercent = nil; frame.mppercent = nil;
1991 else
1992 frame.unitName = name; frame.hppercent = hppercent; frame.mppercent = mppercent;
1993 end
1994 CT_RA_UpdateMT(raidid, mtid, frame, height, key, val);
1995 end
1996 frame:Show();
1997 frameParent:Show();
1998 end
1999 if ( not tempOptions["HideNames"] ) then
2000 frameCache[frameParent].GroupName:Show();
2001 else
2002 frameCache[frameParent].GroupName:Hide();
2003 end
2004 if ( not tempOptions["LockGroups"] ) then
2005 hide = false;
2006 CT_RAMTGroupDrag:Show();
2007 end
2008 end
2009 end
2010 if ( hide ) then
2011 CT_RAMTGroupDrag:Hide();
2012 end
2013 CT_RA_UpdateMTTTs();
2014 end
2015  
2016 function CT_RA_UpdatePT(raidid, frame, height, key, val)
2017 local tempOptions = CT_RAMenu_Options["temp"];
2018 local framecast = getglobal("CT_RAPTGroupMember" .. key .. "CastFrame");
2019 local frameName = frame.name;
2020 frame:SetBackdropColor(tempOptions["DefaultColor"]["r"], tempOptions["DefaultColor"]["g"], tempOptions["DefaultColor"]["b"], tempOptions["DefaultColor"]["a"]);
2021 if ( tempOptions["HideBorder"] ) then
2022 frame.Percent:SetPoint("TOP", frameName, "TOPLEFT", 47, -16);
2023 frame:SetBackdropBorderColor(1, 1, 1, 0);
2024 frame.HPBar:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -19);
2025 frame.HPBG:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -19);
2026 frame:SetHeight(height-3);
2027 frame.height = height-3;
2028 framecast:SetHeight(height-3);
2029 framecast:SetWidth(85);
2030 else
2031 frame:SetBackdropBorderColor(1, 1, 1, 1);
2032 frame.HPBar:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -22);
2033 frame.HPBG:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -22);
2034 frame.Percent:SetPoint("TOP", frameName, "TOPLEFT", 47, -18);
2035 frame:SetHeight(height);
2036 frame.height = height;
2037 framecast:SetHeight(height);
2038 framecast:SetWidth(90);
2039 end
2040 if ( raidid and UnitExists(raidid) and strlen(UnitName(raidid) or "") > 0 ) then
2041 local health, healthmax, mana, manamax = UnitHealth(raidid), UnitHealthMax(raidid), UnitMana(raidid), UnitManaMax(raidid);
2042 frame.Name:SetHeight(15);
2043 frame.Status:Hide();
2044 frame.HPBar:Show();
2045 frame.HPBG:Show();
2046 frame.MPBar:Show();
2047 frame.MPBG:Show();
2048 frame.Name:Show();
2049 local manaType = UnitPowerType(raidid);
2050 if ( ( manaType == 0 and not tempOptions["HideMP"] ) or ( manaType > 0 and not tempOptions["HideRP"] and UnitIsPlayer(raidid) ) ) then
2051 local manaTbl = ManaBarColor[manaType];
2052 getglobal(frame:GetName() .. "MPBar"):SetStatusBarColor(manaTbl.r, manaTbl.g, manaTbl.b);
2053 getglobal(frame:GetName() .. "MPBG"):SetVertexColor(manaTbl.r, manaTbl.g, manaTbl.b, tempOptions["BGOpacity"]);
2054 if ( tempOptions["HideBorder"] ) then
2055 frame:SetHeight(37);
2056 frame.height = 37;
2057 framecast:SetHeight(37);
2058 else
2059 frame:SetHeight(40);
2060 frame.height = 40;
2061 framecast:SetHeight(40);
2062 end
2063 frame.MPBar:SetMinMaxValues(0, manamax);
2064 frame.MPBar:SetValue(mana);
2065 else
2066 frame.MPBar:Hide();
2067 frame.MPBG:Hide();
2068 if ( tempOptions["HideBorder"] ) then
2069 frame:SetHeight(33);
2070 frame.height = 33
2071 framecast:SetHeight(33);
2072 else
2073 frame:SetHeight(36);
2074 frame.height = 36;
2075 framecast:SetHeight(36);
2076 end
2077 end
2078 if ( health and healthmax and not UnitIsDead(raidid) and not UnitIsGhost(raidid) and UnitIsConnected(raidid) ) then
2079 if ( tempOptions["ShowHP"] and tempOptions["ShowHP"] <= 4 ) then
2080 frame.Percent:Show();
2081 else
2082 frame.Percent:Hide();
2083 end
2084  
2085 frame.HPBar:SetMinMaxValues(0, healthmax);
2086 frame.HPBar:SetValue(health);
2087  
2088 frame.Percent:SetText(floor(health/healthmax*100+0.5) .. "%");
2089 local percent = health/healthmax;
2090 if ( percent >= 0 and percent <= 1 ) then
2091 local r, g;
2092 if ( percent > 0.5 ) then
2093 g = 1;
2094 r = (1.0 - percent) * 2;
2095 else
2096 r = 1;
2097 g = percent * 2;
2098 end
2099 frame.HPBar:SetStatusBarColor(r, g, 0);
2100 frame.HPBG:SetVertexColor(r, g, 0, tempOptions["BGOpacity"]);
2101 end
2102 elseif ( not UnitIsConnected(raidid) ) then
2103 frame.HPBar:Hide();
2104 frame.HPBG:Hide();
2105 frame.Percent:Hide();
2106 frame.MPBar:Hide();
2107 frame.MPBG:Hide();
2108 frame.Status:Show();
2109 frame.Status:SetText("OFFLINE");
2110 elseif ( UnitIsDead(raidid) or UnitIsGhost(raidid) ) then
2111 frame.HPBar:Hide();
2112 frame.HPBG:Hide();
2113 frame.Percent:Hide();
2114 frame.MPBar:Hide();
2115 frame.MPBG:Hide();
2116 frame.Status:Show();
2117 local isFD = CT_RA_CheckFD(UnitName(raidid), raidid);
2118 if ( isFD == 1 ) then
2119 frame.Status:SetText("Feign Death");
2120 elseif ( isFD == 2 ) then
2121 frame.Status:SetText("SoR");
2122 else
2123 frame.Status:SetText("DEAD");
2124 end
2125 else
2126 frame.HPBar:Hide();
2127 frame.HPBG:Hide();
2128 end
2129 frame.Name:SetText(UnitName(raidid));
2130 frame.Name:SetTextColor(0.5, 1, 0);
2131 frame.CastFrame.unitName = UnitName(raidid);
2132 else
2133 frame.Percent:Hide();
2134 frame.HPBar:Hide();
2135 frame.HPBG:Hide();
2136 frame.MPBar:Hide();
2137 frame.MPBG:Hide();
2138 frame.Status:Hide();
2139 frame.Name:SetText(val);
2140 frame.Name:SetHeight(30);
2141 frame.Name:SetTextColor(1, 0.82, 0);
2142 end
2143 end
2144  
2145 function CT_RA_UpdatePTs()
2146 local tempOptions = CT_RAMenu_Options["temp"];
2147 CT_RAPTGroupGroupName:SetText("PTargets");
2148 CT_RAPTGroup:Hide();
2149 CT_RAPTGroupGroupName:Hide();
2150 for i = 1, 10, 1 do
2151 local mem = getglobal("CT_RAPTGroupMember" .. i);
2152 mem:Hide();
2153 mem:ClearAllPoints();
2154 if ( i > 1 ) then
2155 local above = "CT_RAPTGroupMember" .. (i-1);
2156 if ( tempOptions["HideBorder"] ) then
2157 if ( tempOptions["HideSpace"] ) then
2158 if ( tempOptions["ShowReversed"] ) then
2159 mem:SetPoint("BOTTOMLEFT", above, "TOPLEFT", 0, -10);
2160 else
2161 mem:SetPoint("TOPLEFT", above, "BOTTOMLEFT", 0, 10);
2162 end
2163 else
2164 if ( tempOptions["ShowReversed"] ) then
2165 mem:SetPoint("BOTTOMLEFT", above, "TOPLEFT", 0, -7);
2166 else
2167 mem:SetPoint("TOPLEFT", above, "BOTTOMLEFT", 0, 7);
2168 end
2169 end
2170 else
2171 if ( tempOptions["ShowReversed"] ) then
2172 mem:SetPoint("BOTTOMLEFT", above, "TOPLEFT", 0, -5);
2173 else
2174 mem:SetPoint("TOPLEFT", above, "BOTTOMLEFT", 0, 4);
2175 end
2176 end
2177 else
2178 if ( tempOptions["ShowReversed"] ) then
2179 mem:SetPoint("BOTTOMLEFT", "CT_RAPTGroup", "TOPLEFT", 0, -15);
2180 else
2181 mem:SetPoint("TOPLEFT", "CT_RAPTGroup", "TOPLEFT", 0, -20);
2182 end
2183 end
2184 end
2185 if ( GetNumRaidMembers() == 0 or not CT_RA_PTargets ) then
2186 CT_RAPTGroupDrag:Hide();
2187 return;
2188 end
2189 local hide = true;
2190 for key, val in CT_RA_PTargets do
2191 if ( key <= 10 ) then
2192 local height = tempOptions["MemberHeight"];
2193 if ( tempOptions["HideMP"] ) then
2194 height = height - 4;
2195 end
2196 local frame = getglobal("CT_RAPTGroupMember" .. key);
2197 local frameParent = frame.frameParent;
2198 local raidid;
2199 for i = 1, GetNumRaidMembers(), 1 do
2200 if ( UnitName("raid" .. i) == CT_RA_PTargets[key] ) then
2201 raidid = "raid" .. i;
2202 break;
2203 end
2204 end
2205 if ( raidid ) then
2206 local name, hppercent, mppercent = UnitName(raidid), UnitHealth(raidid)/UnitHealthMax(raidid), UnitMana(raidid)/UnitManaMax(raidid);
2207 if ( name ~= ( frame.unitName or "" ) or hppercent ~= ( frame.hppercent or -1 ) or mppercent ~= ( frame.mppercent or -1 ) or not UnitIsConnected(raidid) ) then
2208 if ( not UnitIsConnected(raidid) ) then
2209 frame.unitName = nil; frame.hppercent = nil; frame.mppercent = nil;
2210 else
2211 frame.unitName = name; frame.hppercent = hppercent; frame.mppercent = mppercent;
2212 end
2213 CT_RA_UpdatePT(raidid, frame, height, key, val);
2214 end
2215 frame:Show();
2216 frame:GetParent():Show();
2217 end
2218 if ( not tempOptions["HideNames"] ) then
2219 frameCache[frameParent].GroupName:Show();
2220 else
2221 frameCache[frameParent].GroupName:Hide();
2222 end
2223 if ( not tempOptions["LockGroups"] ) then
2224 hide = false;
2225 CT_RAPTGroupDrag:Show();
2226 end
2227 end
2228 end
2229 if ( hide ) then
2230 CT_RAPTGroupDrag:Hide();
2231 end
2232 CT_RA_UpdatePTTs();
2233 end
2234  
2235 function CT_RA_UpdatePTT(raidid, frame, height, key, val)
2236 local tempOptions = CT_RAMenu_Options["temp"];
2237 local frameParent = frame.frameParent;
2238 local currHeight = frameParent:GetHeight();
2239 local frameName = frame.name;
2240 if ( tempOptions["HideBorder"] ) then
2241 frame.Percent:SetPoint("TOP", frameName, "TOPLEFT", 47, -16);
2242 frame.HPBar:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -19);
2243 frame.HPBG:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -19);
2244 frame:SetHeight(height-3);
2245 frame.theight = height-3;
2246 else
2247 frame.Percent:SetPoint("TOP", frameName, "TOPLEFT", 47, -18);
2248 frame:SetHeight(height);
2249 frame.theight = height;
2250 end
2251 if ( raidid and UnitExists(raidid) and UnitIsConnected(raidid) ) then
2252 frameParent:SetBackdropColor(tempOptions["DefaultColor"].r, tempOptions["DefaultColor"].g, tempOptions["DefaultColor"].b, tempOptions["DefaultColor"].a);
2253 local health, healthmax, mana, manamax = UnitHealth(raidid), UnitHealthMax(raidid), UnitMana(raidid), UnitManaMax(raidid);
2254 frame.CastFrame.id = raidid;
2255 frame.Name:SetHeight(12);
2256 frame.Status:Hide();
2257 frame.HPBar:Show();
2258 frame.HPBG:Show();
2259 frame.MPBar:Show();
2260 frame.MPBG:Show();
2261 frame.Name:Show();
2262 local manaType = UnitPowerType(raidid);
2263 if ( ( manaType == 0 and not tempOptions["HideMP"] ) or ( manaType > 0 and not tempOptions["HideRP"] and UnitIsPlayer(raidid) ) ) then
2264 local manaTbl = ManaBarColor[manaType];
2265 getglobal(frame:GetName() .. "MPBar"):SetStatusBarColor(manaTbl.r, manaTbl.g, manaTbl.b);
2266 getglobal(frame:GetName() .. "MPBG"):SetVertexColor(manaTbl.r, manaTbl.g, manaTbl.b, tempOptions["BGOpacity"]);
2267 if ( tempOptions["HideBorder"] ) then
2268 frame:SetHeight(37);
2269 frame.theight = 37;
2270 frame.CastFrame:SetHeight(37);
2271 else
2272 frame:SetHeight(40);
2273 frame.theight = 37;
2274 frame.CastFrame:SetHeight(40);
2275 end
2276 frame.MPBar:SetMinMaxValues(0, manamax);
2277 frame.MPBar:SetValue(mana);
2278 else
2279 frame.MPBar:Hide();
2280 frame.MPBG:Hide();
2281 if ( tempOptions["HideBorder"] ) then
2282 frame:SetHeight(33);
2283 frame.theight = 33;
2284 frame.CastFrame:SetHeight(33);
2285 else
2286 frame:SetHeight(36);
2287 frame.theight = 36;
2288 frame.CastFrame:SetHeight(36);
2289 end
2290 end
2291 if ( health and healthmax and not UnitIsDead(raidid) and not UnitIsGhost(raidid) ) then
2292 if ( tempOptions["ShowHP"] and tempOptions["ShowHP"] <= 4 ) then
2293 frame.Percent:Show();
2294 else
2295 frame.Percent:Hide();
2296 end
2297 frame.HPBar:SetMinMaxValues(0, healthmax);
2298 frame.HPBar:SetValue(health);
2299 frame.Percent:SetText(floor(health/healthmax*100+0.5) .. "%");
2300 local percent = health/healthmax;
2301 if ( percent >= 0 and percent <= 1 ) then
2302 local r, g;
2303 if ( percent > 0.5 ) then
2304 g = 1;
2305 r = (1.0 - percent) * 2;
2306 else
2307 r = 1;
2308 g = percent * 2;
2309 end
2310 frame.HPBar:SetStatusBarColor(r, g, 0);
2311 frame.HPBG:SetVertexColor(r, g, 0, tempOptions["BGOpacity"]);
2312 end
2313 elseif ( UnitIsDead(raidid) or UnitIsGhost(raidid) ) then
2314 frame.HPBar:Hide();
2315 frame.HPBG:Hide();
2316 frame.Percent:Hide();
2317 frame.MPBar:Hide();
2318 frame.MPBG:Hide();
2319 frame.Status:Show();
2320 frame.Status:SetText("DEAD");
2321 else
2322 frame.HPBar:Hide();
2323 frame.HPBG:Hide();
2324 end
2325 frame.Name:SetText(UnitName(raidid));
2326 if ( UnitCanAttack("player", raidid) ) then
2327 frame.Name:SetTextColor(1, 0.5, 0);
2328 else
2329 frame.Name:SetTextColor(0.5, 1, 0);
2330 end
2331 if ( frame:GetHeight() > currHeight ) then
2332 frame:GetParent():SetHeight(frame:GetHeight());
2333 frameParent.CastFrame:SetHeight(frame:GetHeight());
2334 end
2335 else
2336 local defaultColors = tempOptions["DefaultColor"];
2337 frameParent:SetBackdropColor(defaultColors.r, defaultColors.g, defaultColors.b, defaultColors.a);
2338 frame:SetBackdropColor(defaultColors.r, defaultColors.g, defaultColors.b, defaultColors.a);
2339 frame.Percent:Hide();
2340 frame.HPBar:Hide();
2341 frame.HPBG:Hide();
2342 frame.MPBar:Hide();
2343 frame.MPBG:Hide();
2344 frame.Status:Hide();
2345 frame.Name:SetText("<No Target>");
2346 frame.Name:SetTextColor(1, 0.82, 0);
2347 frame.Name:SetHeight(30);
2348 end
2349 end
2350  
2351 function CT_RA_UpdatePTTs()
2352 local tempOptions = CT_RAMenu_Options["temp"];
2353 for key, val in CT_RA_PTargets do
2354 if ( key <= 10 ) then
2355 local height = tempOptions["MemberHeight"];
2356 if ( tempOptions["HideMP"] ) then
2357 height = height - 4;
2358 end
2359 local frameParent = getglobal("CT_RAPTGroupMember"..key);
2360 local frame = frameParent.MTTT;
2361 if ( tempOptions["ShowPTT"] ) then
2362 local raidid;
2363 for i = 1, GetNumRaidMembers(), 1 do
2364 if ( UnitName("raid" .. i) == CT_RA_PTargets[key] ) then
2365 raidid = "raid" .. i .. "target";
2366 break;
2367 end
2368 end
2369 if ( raidid ) then
2370 frame:Show();
2371 local name, hppercent, mppercent = UnitName(raidid), UnitHealth(raidid)/UnitHealthMax(raidid), UnitMana(raidid)/UnitManaMax(raidid);
2372 if ( frame.theight and frame.theight > ( frameParent.height or 0 ) and name ) then
2373 frameParent:SetHeight(frame.theight);
2374 elseif ( not frame.theight ) then
2375 name = nil; -- Force an update
2376 end
2377 if ( name ~= ( frame.unitName or "" ) or hppercent ~= ( frame.hppercent or -1 ) or mppercent ~= ( frame.mppercent or -1 ) or not UnitIsConnected(raidid) ) then
2378 if ( not UnitIsConnected(raidid) ) then
2379 frame.unitName = nil; frame.hppercent = nil; frame.mppercent = nil;
2380 else
2381 frame.unitName = name; frame.hppercent = hppercent; frame.mppercent = mppercent;
2382 end
2383 CT_RA_UpdatePTT(raidid, frame, height, key, val);
2384 end
2385 end
2386 frameParent:SetWidth(165);
2387 CT_RAPTGroupMember1:ClearAllPoints();
2388 if ( tempOptions["ShowReversed"] ) then
2389 CT_RAPTGroupMember1:SetPoint("BOTTOMLEFT", "CT_RAPTGroup", "TOPLEFT", -35, -15);
2390 else
2391 CT_RAPTGroupMember1:SetPoint("TOPLEFT", "CT_RAPTGroup", "TOPLEFT", -35, -20);
2392 end
2393 else
2394 frame:Hide();
2395 frameParent:SetWidth(90);
2396 CT_RAPTGroupMember1:ClearAllPoints();
2397 if ( tempOptions["ShowReversed"] ) then
2398 CT_RAPTGroupMember1:SetPoint("BOTTOMLEFT", "CT_RAPTGroup", "TOPLEFT", 0, -15);
2399 else
2400 CT_RAPTGroupMember1:SetPoint("TOPLEFT", "CT_RAPTGroup", "TOPLEFT", 0, -20);
2401 end
2402 end
2403 end
2404 end
2405 end
2406  
2407 function CT_RA_AssistMTTT(button)
2408 local id = this.id;
2409 if ( not id ) then
2410 return;
2411 end
2412 local stopDefaultBehaviour;
2413 if ( type(CT_RA_CustomOnClickFunction) == "function" ) then
2414 stopDefaultBehaviour = CT_RA_CustomOnClickFunction(button, id);
2415 end
2416 if ( not stopDefaultBehaviour ) then
2417 if ( SpellIsTargeting() ) then
2418 SpellTargetUnit(id);
2419 else
2420 TargetUnit(id);
2421 end
2422 end
2423 end
2424  
2425 function CT_RA_UpdateMTTT(raidid, mtid, frame, height, key, val)
2426 local tempOptions = CT_RAMenu_Options["temp"];
2427 local frameParent = frame.frameParent;
2428 local currHeight = frameParent:GetHeight();
2429 local frameName = frame.name;
2430 if ( tempOptions["HideBorder"] ) then
2431 frame.Percent:SetPoint("TOP", frameName, "TOPLEFT", 47, -16);
2432 frame.HPBar:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -19);
2433 frame.HPBG:SetPoint("TOPLEFT", frameName, "TOPLEFT", 10, -19);
2434 frame:SetHeight(height-3);
2435 frame.theight = height-3;
2436 else
2437 frame.Percent:SetPoint("TOP", frameName, "TOPLEFT", 47, -18);
2438 frame:SetHeight(height);
2439 frame.height = height;
2440 end
2441 if ( raidid and UnitExists(raidid) ) then
2442 if ( not UnitIsUnit(mtid, raidid) and not tempOptions["HideColorChange"] ) then
2443 frame:GetParent():SetBackdropColor(1, 0, 0, 1);
2444 else
2445 local defaultColors = tempOptions.DefaultColor;
2446 frame:GetParent():SetBackdropColor(defaultColors.r, defaultColors.g, defaultColors.b, defaultColors.a);
2447 end
2448 local health, healthmax, mana, manamax = UnitHealth(raidid), UnitHealthMax(raidid), UnitMana(raidid), UnitManaMax(raidid);
2449 frame.CastFrame.id = raidid;
2450 frame.Name:SetHeight(12);
2451 frame.Status:Hide();
2452 frame.HPBar:Show();
2453 frame.HPBG:Show();
2454 frame.MPBar:Show();
2455 frame.MPBG:Show();
2456 frame.Name:Show();
2457 local manaType = UnitPowerType(raidid);
2458 if ( ( manaType == 0 and not tempOptions["HideMP"] ) or ( manaType > 0 and not tempOptions["HideRP"] and UnitIsPlayer(raidid) ) ) then
2459 local manaTbl = ManaBarColor[manaType];
2460 getglobal(frame:GetName() .. "MPBar"):SetStatusBarColor(manaTbl.r, manaTbl.g, manaTbl.b);
2461 getglobal(frame:GetName() .. "MPBG"):SetVertexColor(manaTbl.r, manaTbl.g, manaTbl.b, tempOptions["BGOpacity"]);
2462 if ( tempOptions["HideBorder"] ) then
2463 frame:SetHeight(37);
2464 frame.theight = 37;
2465 frame.CastFrame:SetHeight(37);
2466 else
2467 frame:SetHeight(40);
2468 frame.theight = 40;
2469 frame.CastFrame:SetHeight(40);
2470 end
2471 frame.MPBar:SetMinMaxValues(0, manamax);
2472 frame.MPBar:SetValue(mana);
2473 else
2474 frame.MPBar:Hide();
2475 frame.MPBG:Hide();
2476 if ( tempOptions["HideBorder"] ) then
2477 frame:SetHeight(33);
2478 frame.theight = 33;
2479 frame.CastFrame:SetHeight(33);
2480 else
2481 frame:SetHeight(36);
2482 frame.theight = 36;
2483 frame.CastFrame:SetHeight(36);
2484 end
2485 end
2486 if ( health and healthmax and not UnitIsDead(raidid) and not UnitIsGhost(raidid) ) then
2487 if ( tempOptions["ShowHP"] and tempOptions["ShowHP"] <= 4 ) then
2488 frame.Percent:Show();
2489 else
2490 frame.Percent:Hide();
2491 end
2492 frame.HPBar:SetMinMaxValues(0, healthmax);
2493 frame.HPBar:SetValue(health);
2494 frame.Percent:SetText(floor(health/healthmax*100+0.5) .. "%");
2495 local percent = health/healthmax;
2496 if ( percent >= 0 and percent <= 1 ) then
2497 local r, g;
2498 if ( percent > 0.5 ) then
2499 g = 1;
2500 r = (1.0 - percent) * 2;
2501 else
2502 r = 1;
2503 g = percent * 2;
2504 end
2505 frame.HPBar:SetStatusBarColor(r, g, 0);
2506 frame.HPBG:SetVertexColor(r, g, 0, tempOptions["BGOpacity"]);
2507 end
2508 elseif ( UnitIsDead(raidid) or UnitIsGhost(raidid) ) then
2509 frame.HPBar:Hide();
2510 frame.HPBG:Hide();
2511 frame.Percent:Hide();
2512 frame.MPBar:Hide();
2513 frame.MPBG:Hide();
2514 frame.Status:Show();
2515 frame.Status:SetText("DEAD");
2516 else
2517 frame.HPBar:Hide();
2518 frame.HPBG:Hide();
2519 end
2520 frame.Name:SetText(UnitName(raidid));
2521 if ( UnitCanAttack("player", raidid) ) then
2522 frame.Name:SetTextColor(1, 0.5, 0);
2523 else
2524 getglobal(frame:GetName() .. "Name"):SetTextColor(0.5, 1, 0);
2525 end
2526 if ( frame:GetHeight() > currHeight ) then
2527 frameParent:SetHeight(frame:GetHeight());
2528 frameParent.CastFrame:SetHeight(frame:GetHeight());
2529 end
2530 else
2531 local defaultColors = tempOptions.DefaultColor;
2532 frame:GetParent():SetBackdropColor(defaultColors.r, defaultColors.g, defaultColors.b, defaultColors.a);
2533 frame:SetBackdropColor(defaultColors.r, defaultColors.g, defaultColors.b, defaultColors.a);
2534 frame.Percent:Hide();
2535 frame.HPBar:Hide();
2536 frame.HPBG:Hide();
2537 frame.MPBar:Hide();
2538 frame.MPBG:Hide();
2539 frame.Status:Hide();
2540 frame.Name:SetText("<No Target>");
2541 frame.Name:SetTextColor(1, 0.82, 0);
2542 frame.Name:SetHeight(30);
2543 end
2544 end
2545  
2546 function CT_RA_UpdateMTTTs()
2547 local tempOptions = CT_RAMenu_Options["temp"];
2548 for key, val in CT_RA_MainTanks do
2549 if ( key <= ( tempOptions["ShowNumMTs"] or 10 ) ) then
2550 local height = tempOptions["MemberHeight"];
2551 if ( tempOptions["HideMP"] ) then
2552 height = height - 4;
2553 end
2554 local frameParent = getglobal("CT_RAMTGroupMember"..key);
2555 local frame = frameParent.MTTT
2556 if ( tempOptions["ShowMTTT"] and not tempOptions["HideMTs"] ) then
2557 if ( CT_RA_MainTanks[key] ) then
2558 local raidid, mtid;
2559 for i = 1, GetNumRaidMembers(), 1 do
2560 if ( UnitName("raid" .. i) == CT_RA_MainTanks[key] ) then
2561 raidid = "raid" .. i .. "targettarget";
2562 mtid = "raid" .. i;
2563 break;
2564 end
2565 end
2566 if ( raidid and mtid ) then
2567 frame:Show();
2568 local name, hppercent, mppercent = UnitName(raidid), UnitHealth(raidid)/UnitHealthMax(raidid), UnitMana(raidid)/UnitManaMax(raidid);
2569 if ( frame.theight and frame.theight > ( frameParent.height or 0 ) and name ) then
2570 frameParent:SetHeight(frame.theight);
2571 elseif ( not frame.theight ) then
2572 name = nil; -- Force an update
2573 end
2574 if ( name ~= ( frame.unitName or "" ) or hppercent ~= ( frame.hppercent or -1 ) or mppercent ~= ( frame.mppercent or -1 ) or not UnitIsConnected(raidid) ) then
2575 if ( not UnitIsConnected(raidid) ) then
2576 frame.unitName = nil; frame.hppercent = nil; frame.mppercent = nil;
2577 else
2578 frame.unitName = name; frame.hppercent = hppercent; frame.mppercent = mppercent;
2579 end
2580 if ( name == UnitName("player") and not UnitIsPlayer(mtid .. "target") ) then
2581 local isMT;
2582 for k, v in CT_RA_MainTanks do
2583 if ( v == UnitName("player") ) then
2584 isMT = 1;
2585 break;
2586 end
2587 end
2588 if ( not isMT and not CT_RA_UpdateFrame.hasAggroAlert and tempOptions["AggroNotifier"] ) then
2589 CT_RA_UpdateFrame.hasAggroAlert = 15;
2590 CT_RA_WarningFrame:AddMessage("AGGRO FROM " .. UnitName(mtid .. "target") .. "!", 1, 0, 0, 1, UIERRORS_HOLD_TIME);
2591 if ( tempOptions["AggroNotifierSound"] ) then
2592 PlaySoundFile("Sound\\Spells\\PVPFlagTakenHorde.wav");
2593 end
2594 end
2595 end
2596 CT_RA_UpdateMTTT(raidid, mtid, frame, height, key, val);
2597 end
2598 end
2599 end
2600 frameParent:SetWidth(165);
2601 CT_RAMTGroupMember1:ClearAllPoints();
2602 if ( tempOptions["ShowReversed"] ) then
2603 CT_RAMTGroupMember1:SetPoint("BOTTOMLEFT", "CT_RAMTGroup", "TOPLEFT", -35, -15);
2604 else
2605 CT_RAMTGroupMember1:SetPoint("TOPLEFT", "CT_RAMTGroup", "TOPLEFT", -35, -20);
2606 end
2607 else
2608 frame:Hide();
2609 frameParent:SetWidth(90);
2610 CT_RAMTGroupMember1:ClearAllPoints();
2611 if ( tempOptions["ShowReversed"] ) then
2612 CT_RAMTGroupMember1:SetPoint("BOTTOMLEFT", "CT_RAMTGroup", "TOPLEFT", 0, -15);
2613 else
2614 CT_RAMTGroupMember1:SetPoint("TOPLEFT", "CT_RAMTGroup", "TOPLEFT", 0, -20);
2615 end
2616 end
2617 end
2618 end
2619 end
2620  
2621 function CT_RA_UpdateGroupVisibility(num, noStatusUpdate)
2622 local tempOptions = CT_RAMenu_Options["temp"];
2623 local group = getglobal("CT_RAGroup" .. num);
2624 local drag = getglobal("CT_RAGroupDrag" .. num);
2625 if ( not tempOptions["ShowGroups"] or not tempOptions["ShowGroups"][num] or ( GetNumRaidMembers() == 0 and tempOptions["SORTTYPE"] ~= "virtual" ) or not group.next ) then
2626 group:Hide();
2627 drag:Hide();
2628 elseif ( group.next ) then
2629 if ( tempOptions["LockGroups"] ) then
2630 drag:Hide();
2631 else
2632 drag:Show();
2633 end
2634 if ( tempOptions["HideNames"] ) then
2635 frameCache[group].GroupName:Hide();
2636 else
2637 frameCache[group].GroupName:Show();
2638 end
2639 group:Show();
2640 end
2641 while ( group.next ) do
2642 if ( tempOptions["ShowGroups"] and tempOptions["ShowGroups"][num] ) then
2643 if ( not noStatusUpdate ) then
2644 CT_RA_UpdateUnitStatus(group.next);
2645 end
2646 group.next:Show();
2647 else
2648 group.next:Hide();
2649 end
2650 group = group.next;
2651 end
2652 end
2653  
2654 function CT_RA_UpdateVisibility(noStatusUpdate)
2655 for i = 1, 8, 1 do
2656 CT_RA_UpdateGroupVisibility(i, noStatusUpdate);
2657 end
2658 if ( CT_RA_MainTanks ) then
2659 CT_RA_UpdateMTs();
2660 end
2661 if ( CT_RA_PTargets ) then
2662 CT_RA_UpdatePTs();
2663 end
2664 end
2665  
2666 function CT_RA_UpdateRaidGroup(updateType)
2667 local tempOptions = CT_RAMenu_Options["temp"];
2668 local sortType = tempOptions["SORTTYPE"];
2669 if ( sortType == "group" ) then
2670 CT_RA_SortByGroup();
2671 elseif ( sortType == "custom" ) then
2672 CT_RA_SortByCustom();
2673 elseif ( sortType == "class" ) then
2674 CT_RA_SortByClass();
2675 elseif ( sortType == "virtual" ) then
2676 CT_RA_SortByVirtual(1);
2677 end
2678 local numRaidMembers = GetNumRaidMembers();
2679 local name, rank, subgroup, level, class, fileName, zone, online, isDead;
2680  
2681 for i=1, MAX_RAID_MEMBERS do
2682 if ( i <= numRaidMembers or sortType == "virtual" ) then
2683 local unitid = "raid" .. i;
2684 name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(i);
2685 if ( not name and sortType == "virtual" ) then
2686 name, rank, subgroup, level, class, fileName, zone, online, isDead = "Virtual " .. i, 0, floor((i-1)/5)+1, 60, CT_RA_PRIEST, "PRIEST", "Emerald Dream", 1, nil;
2687 end
2688 if ( UnitIsDead(unitid) or UnitIsGhost(unitid) ) then
2689 isDead = 1;
2690 end
2691 -- Set Rank
2692 if ( name == UnitName("player") ) then
2693 if ( rank >= 2 and CT_RA_Level and CT_RA_Level < 2 ) then
2694 -- Check if we have to auto-promote people
2695 for j = 1, numRaidMembers, 1 do
2696 local pName, pRank = GetRaidRosterInfo(j);
2697 if ( pRank < 1 and pName and CT_RATab_AutoPromotions and CT_RATab_AutoPromotions[pName] ) then
2698 PromoteToAssistant(pName);
2699 CT_RA_Print("<CTRaid> Auto-Promoted |c00FFFFFF" .. pName .. "|r.", 1, 0.5, 0);
2700 end
2701 end
2702 end
2703 CT_RA_Level = rank;
2704 end
2705 local button = getglobal("CT_RAMember" .. i);
2706 local buttoncast = button.CastFrame;
2707 local group = button.group;
2708 if ( group ) then
2709 if ( tempOptions["ShowGroups"] and tempOptions["ShowGroups"][group.id] ) then
2710 button.Name:SetText(name);
2711 button.CastFrame.unitName = name;
2712 if ( sortType ~= "virtual" or not updateType or updateType == 0 ) then
2713 if ( button.update or updateType == 0 ) then
2714 CT_RA_UpdateUnitStatus(button);
2715 else
2716 CT_RA_UpdateUnitDead(button);
2717 local stats = CT_RA_Stats[name];
2718 if ( updateType == 2 and stats ) then
2719 CT_RA_UpdateUnitBuffs(stats["Buffs"], button, name);
2720 end
2721 end
2722 button.update = nil;
2723 else
2724 CT_RA_UpdateUnitDead(button);
2725 end
2726 end
2727 end
2728 else
2729 local btn = getglobal("CT_RAMember"..i);
2730 btn:Hide();
2731 btn.next = nil;
2732 end
2733 end
2734 CT_RA_UpdateVisibility(1);
2735 end
2736  
2737 function CT_RA_MemberFrame_OnEnter()
2738 local tempOptions = CT_RAMenu_Options["temp"];
2739 if ( SpellIsTargeting() ) then
2740 SetCursor("CAST_CURSOR");
2741 end
2742 local parent = this.frameParent;
2743 local id = parent.id;
2744 if ( strsub(parent.name, 1, 12) == "CT_RAMTGroup" ) then
2745 local name;
2746 if ( CT_RA_MainTanks[id] ) then
2747 name = CT_RA_MainTanks[id];
2748 end
2749 for i = 1, GetNumRaidMembers(), 1 do
2750 local memberName = GetRaidRosterInfo(i);
2751 if ( name == memberName ) then
2752 id = i;
2753 break;
2754 end
2755 end
2756 elseif ( strsub(parent.name, 1, 12) == "CT_RAPTGroup" ) then
2757 local name;
2758 if ( CT_RA_PTargets[id] ) then
2759 name = CT_RA_PTargets[id];
2760 end
2761 for i = 1, GetNumRaidMembers(), 1 do
2762 local memberName = GetRaidRosterInfo(i);
2763 if ( name == memberName ) then
2764 id = i;
2765 break;
2766 end
2767 end
2768 end
2769 local unitid = "raid"..id;
2770 if ( SpellIsTargeting() and not SpellCanTargetUnit(unitid) ) then
2771 SetCursor("CAST_ERROR_CURSOR");
2772 end
2773 if ( tempOptions["HideTooltip"] ) then
2774 return;
2775 end
2776 local xp = "LEFT";
2777 local yp = "BOTTOM";
2778 local xthis, ythis = this:GetCenter();
2779 local xui, yui = UIParent:GetCenter();
2780 if ( xthis < xui ) then
2781 xp = "RIGHT";
2782 end
2783 if ( ythis < yui ) then
2784 yp = "TOP";
2785 end
2786 GameTooltip:SetOwner(this, "ANCHOR_" .. yp .. xp);
2787 local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(id);
2788 local stats = CT_RA_Stats[name];
2789 local isVirtual;
2790 if ( not name and tempOptions["SORTTYPE"] == "virtual" ) then
2791 isVirtual = 1;
2792 name, level = "Virtual " .. id, 60;
2793 end
2794 local version = stats;
2795 if ( version ) then
2796 version = version["Version"];
2797 end
2798 if ( name == UnitName("player") ) then
2799 zone = GetRealZoneText();
2800 version = CT_RA_VersionNumber;
2801 end
2802 local color = RAID_CLASS_COLORS[fileName];
2803 if ( not color ) then
2804 color = { ["r"] = 1, ["g"] = 1, ["b"] = 1 };
2805 end
2806 GameTooltip:AddDoubleLine(name, level, color.r, color.g, color.b, 1, 1, 1);
2807 if ( UnitRace(unitid) and class ) then
2808 GameTooltip:AddLine(UnitRace(unitid) .. " " .. class, 1, 1, 1);
2809 end
2810 GameTooltip:AddLine(zone, 1, 1, 1);
2811  
2812 if ( not version and not isVirtual ) then
2813 if ( not stats or not stats["Reporting"] ) then
2814 GameTooltip:AddLine("No CTRA Found", 0.7, 0.7, 0.7);
2815 else
2816 GameTooltip:AddLine("CTRA <1.077", 1, 1, 1);
2817 end
2818 elseif ( not isVirtual ) then
2819 GameTooltip:AddLine("CTRA " .. version, 1, 1, 1);
2820 end
2821  
2822 if ( stats and stats["AFK"] ) then
2823 if ( type(stats["AFK"][1]) == "string" ) then
2824 GameTooltip:AddLine("AFK: " .. stats["AFK"][1]);
2825 end
2826 GameTooltip:AddLine("AFK for " .. CT_RA_FormatTime(stats["AFK"][2]));
2827 elseif ( CT_RA_Stats[name] and stats["DND"] ) then
2828 if ( type(stats["DND"][1]) == "string" ) then
2829 GameTooltip:AddLine("DND: " .. stats["DND"][1]);
2830 end
2831 GameTooltip:AddLine("DND for " .. CT_RA_FormatTime(stats["DND"][2]));
2832 end
2833 if ( stats and stats["Offline"] ) then
2834 GameTooltip:AddLine("Offline for " .. CT_RA_FormatTime(stats["Offline"]));
2835 elseif ( stats and stats["FD"] ) then
2836 if ( stats["FD"] < 360 ) then
2837 GameTooltip:AddLine("Dying in " .. CT_RA_FormatTime(360-stats["FD"]));
2838 end
2839 elseif ( stats and stats["Dead"] ) then
2840 if ( stats["Dead"] < 360 and not UnitIsGhost(unitid) ) then
2841 GameTooltip:AddLine("Releasing in " .. CT_RA_FormatTime(360-stats["Dead"]));
2842 else
2843 GameTooltip:AddLine("Dead for " .. CT_RA_FormatTime(stats["Dead"]));
2844 end
2845 end
2846 if ( stats and stats["Rebirth"] and stats["Rebirth"] > 0 ) then
2847 GameTooltip:AddLine("Rebirth up in: " .. CT_RA_FormatTime(stats["Rebirth"]));
2848 elseif ( stats and stats["Reincarnation"] and stats["Reincarnation"] > 0 ) then
2849 GameTooltip:AddLine("Ankh up in: " .. CT_RA_FormatTime(stats["Reincarnation"]));
2850 elseif ( stats and stats["Soulstone"] and stats["Soulstone"] > 0 ) then
2851 GameTooltip:AddLine("Soulstone up in: " .. CT_RA_FormatTime(stats["Soulstone"]));
2852 end
2853 GameTooltip:Show();
2854 CT_RA_CurrentMemberFrame = this;
2855 end
2856  
2857 function CT_RA_FormatTime(num)
2858 num = floor(num + 0.5);
2859 local hour, min, sec, str = 0, 0, 0, "";
2860  
2861 hour = floor(num/3600);
2862 min = floor(mod(num, 3600)/60);
2863 sec = mod(num, 60);
2864  
2865 if ( hour > 0 ) then
2866 str = hour .. "h";
2867 end
2868  
2869 if ( min > 0 ) then
2870 if ( strlen(str) > 0 ) then
2871 str = str .. ", ";
2872 end
2873 str = str .. min .. "m";
2874 end
2875  
2876 if ( sec > 0 or strlen(str) == 0 ) then
2877 if ( strlen(str) > 0 ) then
2878 str = str .. ", ";
2879 end
2880 str = str .. sec .. "s";
2881 end
2882 return str;
2883  
2884 end
2885  
2886  
2887 function CT_RA_Drag_OnEnter()
2888 CT_RAMenuHelp_SetTooltip();
2889 GameTooltip:SetText("Click to drag");
2890 end
2891  
2892 function CT_RA_RecastBuffButton()
2893 if ( this.owner and this.name and this.type == "BUFF" ) then
2894 local spell = CT_RA_ClassSpells[this.name];
2895 if ( spell ) then
2896 local targetName = UnitName("target");
2897 for i = 1, GetNumRaidMembers(), 1 do
2898 local uId = "raid"..i;
2899 if ( UnitName(uId) == this.owner ) then
2900 TargetUnit(uId);
2901 break;
2902 end
2903 end
2904 local newTargetName = UnitName("target");
2905 if ( newTargetName == this.owner ) then
2906 CastSpell(spell["spell"], spell["tab"]+1);
2907 end
2908 if ( newTargetName ~= targetName ) then
2909 TargetLastTarget();
2910 end
2911 end
2912 return;
2913 elseif ( this.owner and this.name and this.type == "DEBUFF" ) then
2914 local stats = CT_RA_Stats[this.owner];
2915 if ( stats ) then
2916 local debuff = stats["Debuffs"][this.name];
2917 if ( debuff ) then
2918 for i = 1, GetNumRaidMembers(), 1 do
2919 if ( UnitName("raid" .. i) == this.owner ) then
2920 CT_RADebuff_CureTarget(debuff[1], this.name, "raid" .. i);
2921 return;
2922 end
2923 end
2924 end
2925 end
2926 end
2927 end
2928  
2929 function CT_RA_BuffButton_OnEnter()
2930 if ( CT_RA_LockPosition ) then return; end
2931 CT_RAMenuHelp_SetTooltip();
2932 local left, secure;
2933 local stats = CT_RA_Stats[this.owner];
2934 if ( stats and stats["Buffs"][this.name] and stats["Buffs"][this.name][2] ) then
2935 left = stats["Buffs"][this.name][2];
2936 if ( stats["Reporting"] and ( stats["Version"] or 0 ) >= 1.38 ) then
2937 secure = 1;
2938 end
2939 end
2940 if ( this.name and left ) then
2941 local str;
2942 if ( left >= 60 ) then
2943 secs = mod(left, 60);
2944 mins = (left-secs)/60;
2945 else
2946 mins = 0;
2947 secs = left;
2948 end
2949 if ( mins < 0 ) then mins = "00"; elseif ( mins < 10 ) then mins = "0" .. mins; end
2950 if ( secs < 0 ) then secs = "00"; elseif ( secs < 10 ) then secs = "0" .. secs; end
2951 if ( not secure ) then
2952 GameTooltip:SetText(this.name .. " (" .. mins .. ":" .. secs .. "?)");
2953 else
2954 GameTooltip:SetText(this.name .. " (" .. mins .. ":" .. secs .. ")");
2955 end
2956 elseif ( this.name ) then
2957 GameTooltip:SetText(this.name);
2958 end
2959 end
2960  
2961 function CT_RA_AssistMT(id)
2962 if ( CT_RA_MainTanks[id] ) then
2963 for i = 1, GetNumRaidMembers(), 1 do
2964 local uId = "raid" .. i;
2965 if ( UnitName(uId) == CT_RA_MainTanks[id] ) then
2966 AssistUnit(uId);
2967 return;
2968 end
2969 end
2970 end
2971 end
2972  
2973 function CT_RA_TargetMT(id)
2974 if ( CT_RA_MainTanks[id] ) then
2975 for i = 1, GetNumRaidMembers(), 1 do
2976 local uId = "raid" .. i;
2977 if ( UnitName(uId) == CT_RA_MainTanks[id] ) then
2978 TargetUnit(uId);
2979 return;
2980 end
2981 end
2982 end
2983 end
2984  
2985 function CT_RA_AssistPT(id)
2986 if ( CT_RA_PTargets[id] ) then
2987 for i = 1, GetNumRaidMembers(), 1 do
2988 local uId = "raid" .. i;
2989 if ( UnitName(uId) == CT_RA_PTargets[id] ) then
2990 AssistUnit(uId);
2991 return;
2992 end
2993 end
2994 end
2995 end
2996  
2997 function CT_RA_TargetPT(id)
2998 if ( CT_RA_PTargets[id] ) then
2999 for i = 1, GetNumRaidMembers(), 1 do
3000 local uId = "raid" .. i;
3001 if ( UnitName(uId) == CT_RA_PTargets[id] ) then
3002 TargetUnit(uId);
3003 return;
3004 end
3005 end
3006 end
3007 end
3008  
3009 function CT_RA_MemberFrame_OnClick(button)
3010 local parent = this.frameParent;
3011 local id = parent.id;
3012 local unitid = "raid" .. id;
3013 if ( strsub(parent.name, 1, 12) == "CT_RAMTGroup" ) then
3014 for i = 1, GetNumRaidMembers(), 1 do
3015 local uId = "raid" .. i;
3016 if ( UnitName(uId) == CT_RA_MainTanks[id] ) then
3017 AssistUnit(uId);
3018 return;
3019 end
3020 end
3021 elseif ( strsub(parent.name, 1, 12) == "CT_RAPTGroup" ) then
3022 for i = 1, GetNumRaidMembers(), 1 do
3023 local uId = "raid" .. i;
3024 if ( UnitName(uId) == CT_RA_PTargets[id] ) then
3025 TargetUnit(uId);
3026 return;
3027 end
3028 end
3029 end
3030  
3031 local stopDefaultBehaviour;
3032 if ( type(CT_RA_CustomOnClickFunction) == "function" ) then
3033 stopDefaultBehaviour = CT_RA_CustomOnClickFunction(button, unitid);
3034 end
3035 if ( not stopDefaultBehaviour ) then
3036 if ( SpellIsTargeting() ) then
3037 SpellTargetUnit(unitid);
3038 else
3039 TargetUnit(unitid);
3040 end
3041 end
3042 end
3043  
3044 function CT_RA_SendStatus()
3045 CT_RA_Auras = {
3046 ["buffs"] = { },
3047 ["debuffs"] = { }
3048 }; -- Reset everything so every buff & debuff is treated as new
3049 CT_RA_AddMessage("V " .. CT_RA_VersionNumber);
3050 end
3051  
3052 function CT_RA_AddToQueue(type, nick, name)
3053 tinsert(CT_RA_BuffsToCure, { ["type"] = type, ["nick"] = nick, ["name"] = name });
3054 end
3055  
3056 function CT_RA_GetDebuff()
3057 return tremove(CT_RA_BuffsToCure);
3058 end
3059  
3060 function CT_RA_GetCure(school)
3061 local arr = {
3062 [CT_RA_PRIEST] = { [CT_RA_MAGIC] = CT_RA_DISPELMAGIC, [CT_RA_DISEASE] = { CT_RA_CUREDISEASE, CT_RA_ABOLISHDISEASE } },
3063 [CT_RA_SHAMAN] = { [CT_RA_DISEASE] = CT_RA_CUREDISEASE, [CT_RA_POISON] = CT_RA_CUREPOISON },
3064 [CT_RA_DRUID] = { [CT_RA_CURSE] = CT_RA_REMOVECURSE, [CT_RA_POISON] = { CT_RA_CUREPOISON, CT_RA_ABOLISHPOISON } },
3065 [CT_RA_MAGE] = { [CT_RA_CURSE] = CT_RA_REMOVELESSERCURSE },
3066 [CT_RA_PALADIN] = { [CT_RA_MAGIC] = CT_RA_CLEANSE, [CT_RA_POISON] = { CT_RA_PURIFY, CT_RA_CLEANSE }, [CT_RA_DISEASE] = { CT_RA_PURIFY, CT_RA_CLEANSE } }
3067 };
3068 local playerArr = arr[UnitClass("player")];
3069 if ( playerArr and playerArr[school] ) then
3070 local tmp = playerArr[school];
3071 if ( type(tmp) == "table" ) then
3072 for i = getn(tmp), 1, -1 do
3073 if ( CT_RA_ClassSpells[tmp[i]] ) then
3074 return tmp[i];
3075 end
3076 end
3077 return nil;
3078 else
3079 if ( CT_RA_ClassSpells[tmp] ) then
3080 return tmp;
3081 else
3082 return nil;
3083 end
3084 end
3085 end
3086 return nil;
3087 end
3088  
3089 function CT_RA_UpdateRaidGroupColors()
3090 local tempOptions = CT_RAMenu_Options["temp"];
3091 local defaultColors = tempOptions["DefaultColor"];
3092 local r, g, b, a = defaultColors.r, defaultColors.g, defaultColors.b, defaultColors.a;
3093 for y = 1, 40, 1 do
3094 local frame = getglobal("CT_RAMember" .. y);
3095 if ( y <= 5 ) then
3096 local mt = getglobal("CT_RAMTGroupMember" .. y);
3097 mt:SetBackdropColor(r, g, b, a);
3098 mt.Percent:SetTextColor(r, g, b);
3099 mt = getglobal("CT_RAPTGroupMember" .. y);
3100 mt:SetBackdropColor(r, g, b, a);
3101 mt.Percent:SetTextColor(r, g, b);
3102 end
3103 if ( not frame.status ) then
3104 frame:SetBackdropColor(r, g, b, a);
3105 end
3106 frame.Percent:SetTextColor(r, g, b);
3107 local name = UnitName("raid"..y);
3108 if ( CT_RA_Stats[name] ) then
3109 CT_RA_UpdateUnitBuffs(CT_RA_Stats[name]["Buffs"], frame, name);
3110 end
3111 end
3112 end
3113 function CT_RA_UpdateRaidGroupColors()
3114 local tempOptions = CT_RAMenu_Options["temp"];
3115 for y = 1, 40, 1 do
3116 if ( y <= 5 ) then
3117 getglobal("CT_RAMTGroupMember" .. y):SetBackdropColor(tempOptions["DefaultColor"].r, tempOptions["DefaultColor"].g, tempOptions["DefaultColor"].b, tempOptions["DefaultColor"].a);
3118 getglobal("CT_RAMTGroupMember" .. y .. "Percent"):SetTextColor(tempOptions["PercentColor"].r, tempOptions["PercentColor"].g, tempOptions["PercentColor"].b);
3119 end
3120 if ( not getglobal("CT_RAMember" .. y).status ) then
3121 getglobal("CT_RAMember" .. y):SetBackdropColor(tempOptions["DefaultColor"].r, tempOptions["DefaultColor"].g, tempOptions["DefaultColor"].b, tempOptions["DefaultColor"].a);
3122 end
3123 getglobal("CT_RAMember" .. y .. "Percent"):SetTextColor(tempOptions["PercentColor"].r, tempOptions["PercentColor"].g, tempOptions["PercentColor"].b);
3124 if ( CT_RA_Stats[UnitName("raid"..y)] ) then
3125 CT_RA_UpdateUnitBuffs(CT_RA_Stats[UnitName("raid"..y)]["Buffs"], getglobal("CT_RAMember"..y), UnitName("raid"..y));
3126 end
3127 end
3128 end
3129  
3130 function CT_RA_UpdateRaidMovability()
3131 local tempOptions = CT_RAMenu_Options["temp"];
3132 for i = 1, 8, 1 do
3133 if ( tempOptions["LockGroups"] or not tempOptions["ShowGroups"] or not tempOptions["ShowGroups"][i] ) then
3134 getglobal("CT_RAGroupDrag" .. i):Hide();
3135 else
3136 if ( getglobal("CT_RAGroup" .. i).next ) then
3137 getglobal("CT_RAGroupDrag" .. i):Show();
3138 end
3139 end
3140 end
3141 if ( tempOptions["LockGroups"] or not tempOptions["ShowMTs"] or tempOptions["HideMTs"] ) then
3142 getglobal("CT_RAMTGroupDrag"):Hide();
3143 else
3144 for i = 1, 10, 1 do
3145 if ( CT_RA_MainTanks[i] ) then
3146 CT_RAMTGroupDrag:Show();
3147 break;
3148 else
3149 CT_RAMTGroupDrag:Hide();
3150 end
3151 end
3152 end
3153 end
3154  
3155 function CT_RA_AddToBuffQueue(name, nick)
3156 tinsert(CT_RA_BuffsToRecast, { ["name"] = name, ["nick"] = nick });
3157 end
3158  
3159 function CT_RA_GetBuff()
3160 return tremove(CT_RA_BuffsToRecast);
3161 end
3162  
3163 function CT_RA_RecastLastBuff()
3164 local tempOptions = CT_RAMenu_Options["temp"];
3165 local buff = CT_RA_GetBuff();
3166  
3167 while ( buff ) do
3168 if ( CT_RA_Stats[UnitName(buff["nick"])] and CT_RA_Stats[UnitName(buff["nick"])]["Buffs"][buff["name"]] ) then
3169 buff = CT_RA_GetBuff();
3170 else
3171 CT_RA_LastCastSpell = buff;
3172 CT_RA_LastCast = GetTime();
3173 CT_RA_LastCastType = "buff";
3174 local couldNotCast;
3175 local i, targetunit, targetname;
3176 if ( tempOptions["MaintainTarget"] ) then
3177 -- Check parties
3178 if ( UnitExists("target") ) then
3179 for i = 1, 40, 1 do
3180 if ( UnitIsUnit("raid" ..i, "target") ) then
3181 targetunit = "raid" .. i;
3182 break;
3183 end
3184 end
3185 if ( UnitIsUnit("target", "pet" ) ) then
3186 targetunit = "pet";
3187 elseif ( UnitIsUnit("target", "player" ) ) then
3188 targetunit = "player";
3189 elseif ( not UnitCanAttack("player", "target") ) then
3190 targetunit = "friend";
3191 targetname = UnitName("target");
3192 else
3193 targetunit = "lastenemy";
3194 end
3195 end
3196 TargetUnit(buff["nick"]);
3197 if ( not UnitIsUnit("target", buff["nick"]) ) then
3198 if ( targetunit ) then
3199 if ( targetunit == "lastenemy" ) then
3200 TargetLastEnemy();
3201 elseif ( targetunit == "friend" ) then
3202 TargetByName(targetname);
3203 else
3204 TargetUnit(targetunit);
3205 end
3206 else
3207 ClearTarget();
3208 end
3209 return;
3210 end
3211 else
3212 TargetUnit(buff["nick"]);
3213 end
3214 if ( buff["name"] and CT_RA_ClassSpells[buff["name"]] ) then
3215 if ( UnitIsUnit("target", buff["nick"]) ) then
3216 CastSpell(CT_RA_ClassSpells[buff["name"]]["spell"], CT_RA_ClassSpells[buff["name"]]["tab"]+1);
3217 end
3218 if ( SpellIsTargeting() and not SpellCanTargetUnit(buff["nick"]) ) then
3219 SpellStopTargeting();
3220 couldNotCast = 1;
3221 elseif ( SpellIsTargeting() and SpellCanTargetUnit(buff["nick"]) ) then
3222 SpellStopTargeting();
3223 tinsert(CT_RA_BuffsToRecast, 1, buff);
3224 end
3225 end
3226 if ( targetunit and tempOptions["MaintainTarget"] ) then
3227 if ( targetunit == "lastenemy" ) then
3228 TargetLastEnemy();
3229 elseif ( targetunit == "friend" ) then
3230 TargetByName(targetname);
3231 else
3232 TargetUnit(targetunit);
3233 end
3234 elseif ( tempOptions["MaintainTarget"] ) then
3235 ClearTarget();
3236 end
3237 break;
3238 end
3239 buff = couldNotCast;
3240 end
3241 end
3242  
3243 function CT_RA_Print(msg, r, g, b)
3244 if ( SIMPLE_CHAT == "1" ) then
3245 DEFAULT_CHAT_FRAME:AddMessage(msg, r, g, b);
3246 else
3247 local oldArgs = {
3248 event, this, arg1, arg2, arg3, arg4, arg6
3249 };
3250 event = "CHAT_MSG_CTRAID";
3251 arg1 = msg;
3252 arg2, arg3, arg4, arg6 = "", "", "", "";
3253 local info = CT_RA_ChatInfo[UnitName("player")];
3254  
3255 if ( not info ) then
3256 info = CT_RA_ChatInfo["Default"];
3257 end
3258 for i = 1, 7, 1 do
3259 for k, v in info["show"] do
3260 local frameName = "ChatFrame" .. i;
3261 if ( v == frameName ) then
3262 this = getglobal(frameName);
3263 CT_RA_oldChatFrame_OnEvent(event);
3264 break;
3265 end
3266 end
3267 end
3268 event, this, arg1, arg2, arg3, arg4, arg6 = oldArgs[1], oldArgs[2], oldArgs[3], oldArgs[4], oldArgs[5], oldArgs[6], oldArgs[7];
3269 end
3270 end
3271  
3272 function CT_RA_SubSortByName()
3273 local tempOptions = CT_RAMenu_Options["temp"];
3274 -- Sort the name of the players in the raid.
3275 -- Returns an array containing raid roster numbers in player name sequence, followed by unfilled player slots.
3276 -- Thanks to Dargen of Eternal Keggers for this function
3277 local temp;
3278 local subsort = {};
3279 local count;
3280 local name;
3281 count = GetNumRaidMembers();
3282 if ( not tempOptions["SubSortByName"] ) then
3283 for i = 1, MAX_RAID_MEMBERS, 1 do
3284 subsort[i] = {};
3285 subsort[i][1] = i;
3286 end
3287 return subsort;
3288 end
3289 local playerName = UnitName("player");
3290 for i = 1, MAX_RAID_MEMBERS, 1 do
3291 subsort[i] = {};
3292 subsort[i][1] = i;
3293 if ( i <= count ) then
3294 name = UnitName("raid" .. i);
3295 if ( not name ) then name = playerName; end
3296 if ((name == nil) or (name == UNKNOWNOBJECT) or (name == UKNOWNBEING)) then name = ""; end
3297 subsort[i][2] = name;
3298 else
3299 subsort[i][2] = "";
3300 end
3301 end
3302 local swap;
3303 for j = 1, count - 1, 1 do
3304 swap = false;
3305 for i = 1, count - j, 1 do
3306 if ( subsort[i][2] > subsort[i+1][2] ) then
3307 -- Swap
3308 temp = subsort[i];
3309 subsort[i] = subsort[i+1];
3310 subsort[i+1] = temp;
3311 swap = true;
3312 end
3313 end
3314 if ( not swap ) then
3315 break;
3316 end
3317 end
3318 return subsort;
3319 end
3320  
3321 function CT_RA_SortByClass()
3322 local tempOptions = CT_RAMenu_Options["temp"];
3323 CT_RA_SetSortType("class");
3324 CT_RA_ButtonIndexes = { };
3325 CT_RA_CurrPositions = { };
3326 local groupnum = 1;
3327 local membernum = 1;
3328  
3329 for k, v in CT_RA_ClassPositions do
3330 if ( k ~= CT_RA_SHAMAN or ( UnitFactionGroup("player") and UnitFactionGroup("player") == "Horde" ) ) then
3331 getglobal("CT_RAOptionsGroup" .. v .. "Label"):SetText(k);
3332 end
3333 end
3334 for i = 1, 40, 1 do
3335 if ( i <= 8 ) then
3336 getglobal("CT_RAGroup" .. i).next = nil;
3337 getglobal("CT_RAGroup" .. i).num = 0;
3338 end
3339 getglobal("CT_RAMember" .. i).next = nil;
3340 end
3341 local subsort = CT_RA_SubSortByName();
3342 for j = 1, GetNumRaidMembers(), 1 do
3343 i = subsort[j][1];
3344 local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(i);
3345 if ( class and CT_RA_ClassPositions[class] ) then
3346 local group = getglobal("CT_RAGroup" .. CT_RA_ClassPositions[class]);
3347 if ( name ) then
3348 CT_RA_CurrPositions[name] = { CT_RA_ClassPositions[class], i };
3349 end
3350 local button = getglobal("CT_RAMember" .. i);
3351 getglobal(group:GetName() .. "GroupName"):SetText(class);
3352 local modifier = 0.5;
3353 if ( not online ) then
3354 modifier = 0.3;
3355 end
3356 getglobal("CT_RAOptionsGroupButton" .. i .."Texture"):SetVertexColor(modifier, modifier, modifier);
3357 getglobal("CT_RAOptionsGroupButton" .. i .."Rank"):SetTextColor(modifier, modifier, modifier);
3358 getglobal("CT_RAOptionsGroupButton" .. i .."Name"):SetTextColor(modifier, modifier, modifier);
3359 getglobal("CT_RAOptionsGroupButton" .. i .."Level"):SetTextColor(modifier, modifier, modifier);
3360 getglobal("CT_RAOptionsGroupButton" .. i .."Class"):SetTextColor(modifier, modifier, modifier);
3361 if ( not tempOptions["HideOffline"] or online ) then
3362 button:ClearAllPoints();
3363 local new, newName;
3364 if ( group.next and group.next ~= button ) then
3365 new = group;
3366 while ( new.next ) do
3367 if ( new.next ) then
3368 new = new.next;
3369 end
3370 end
3371 newName = new.name;
3372 group.num = group.num + 1;
3373 if ( tempOptions["ShowHorizontal"] ) then
3374 if ( tempOptions["HideBorder"] ) then
3375 if ( tempOptions["HideSpace"] ) then
3376 button:SetPoint("LEFT", newName, "RIGHT", -10, 0);
3377 else
3378 button:SetPoint("LEFT", newName, "RIGHT", -8, 0);
3379 end
3380 else
3381 button:SetPoint("LEFT", newName, "RIGHT", -2, 0);
3382 end
3383 else
3384 if ( tempOptions["HideBorder"] ) then
3385 if ( tempOptions["HideSpace"] ) then
3386 if ( tempOptions["ShowReversed"] ) then
3387 button:SetPoint("BOTTOMLEFT", newName, "TOPLEFT", 0, -10);
3388 else
3389 button:SetPoint("TOPLEFT", newName, "BOTTOMLEFT", 0, 10);
3390 end
3391 else
3392 if ( tempOptions["ShowReversed"] ) then
3393 button:SetPoint("BOTTOMLEFT", newName, "TOPLEFT", 0, -7);
3394 else
3395 button:SetPoint("TOPLEFT", newName, "BOTTOMLEFT", 0, 7);
3396 end
3397 end
3398 else
3399 if ( tempOptions["ShowReversed"] ) then
3400 button:SetPoint("BOTTOMLEFT", newName, "TOPLEFT", 0, -5);
3401 else
3402 button:SetPoint("TOPLEFT", newName, "BOTTOMLEFT", 0, 4);
3403 end
3404 end
3405 end
3406 else
3407 group.num = 1;
3408 new = group;
3409 button:ClearAllPoints();
3410 if ( tempOptions["ShowReversed"] ) then
3411 button:SetPoint("BOTTOMLEFT", group:GetName(), "TOPLEFT", 0, -15);
3412 else
3413 button:SetPoint("TOPLEFT", group:GetName(), "TOPLEFT", 0, -20);
3414 end
3415 end
3416 new.next = button;
3417 button.group = group;
3418 end
3419 end
3420 end
3421 end
3422  
3423 function CT_RA_SortByGroup()
3424 local tempOptions = CT_RAMenu_Options["temp"];
3425 CT_RA_SetSortType("group");
3426 CT_RA_ButtonIndexes = { };
3427 CT_RA_CurrPositions = { };
3428 local groupnum = 1;
3429 local membernum = 1;
3430 for i = 1, 40, 1 do
3431 if ( i <= 8 ) then
3432 local group = getglobal("CT_RAGroup"..i);
3433 group.next = nil;
3434 group.num = 0;
3435 local label = getglobal("CT_RAOptionsGroup" .. i .. "Label");
3436 if ( label ) then
3437 label:SetText("Group " .. i);
3438 end
3439 end
3440 getglobal("CT_RAMember" .. i).next = nil;
3441 end
3442 local subsort = CT_RA_SubSortByName();
3443 for j = 1, GetNumRaidMembers(), 1 do
3444 i = subsort[j][1];
3445 local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(i);
3446 if ( ( not tempOptions["HideOffline"] or online ) and ( CT_RA_Stats[name] or not tempOptions["HideNA"] ) ) then
3447 local groupid = subgroup;
3448 if ( name and CT_RA_CurrPositions[name] ) then
3449 groupid = CT_RA_CurrPositions[name][1];
3450 elseif ( name ) then
3451 CT_RA_CurrPositions[name] = { subgroup, j };
3452 end
3453 local group = getglobal("CT_RAGroup" .. groupid);
3454 frameCache[group].GroupName:SetText("Group " .. subgroup);
3455 local text = getglobal("CT_RAOptionsGroupButton" .. i .."Texture");
3456 if ( text ) then
3457 text:SetVertexColor(1.0, 1.0, 1.0);
3458 end
3459  
3460 local button = getglobal("CT_RAMember" .. i);
3461 local new, newName;
3462 button:ClearAllPoints();
3463 if ( group.next and group.next ~= button ) then
3464 new = group;
3465 while ( new.next ) do
3466 if ( new.next ) then
3467 new = new.next;
3468 end
3469 end
3470 newName = new.name;
3471 group.num = group.num + 1;
3472 if ( tempOptions["ShowHorizontal"] ) then
3473 if ( tempOptions["HideBorder"] ) then
3474 if ( tempOptions["HideSpace"] ) then
3475 button:SetPoint("LEFT", newName, "RIGHT", -10, 0);
3476 else
3477 button:SetPoint("LEFT", newName, "RIGHT", -8, 0);
3478 end
3479 else
3480 button:SetPoint("LEFT", newName, "RIGHT", -2, 0);
3481 end
3482 else
3483 if ( tempOptions["HideBorder"] ) then
3484 if ( tempOptions["HideSpace"] ) then
3485 if ( tempOptions["ShowReversed"] ) then
3486 button:SetPoint("BOTTOMLEFT", newName, "TOPLEFT", 0, -10);
3487 else
3488 button:SetPoint("TOPLEFT", newName, "BOTTOMLEFT", 0, 10);
3489 end
3490 else
3491 if ( tempOptions["ShowReversed"] ) then
3492 button:SetPoint("BOTTOMLEFT", newName, "TOPLEFT", 0, -7);
3493 else
3494 button:SetPoint("TOPLEFT", newName, "BOTTOMLEFT", 0, 7);
3495 end
3496 end
3497 else
3498 if ( tempOptions["ShowReversed"] ) then
3499 button:SetPoint("BOTTOMLEFT", newName, "TOPLEFT", 0, -5);
3500 else
3501 button:SetPoint("TOPLEFT", newName, "BOTTOMLEFT", 0, 4);
3502 end
3503 end
3504 end
3505 else
3506 group.num = 1;
3507 new = group;
3508 button:ClearAllPoints();
3509 if ( tempOptions["ShowReversed"] ) then
3510 button:SetPoint("BOTTOMLEFT", group.name, "TOPLEFT", 0, -15);
3511 else
3512 button:SetPoint("TOPLEFT", group.name, "TOPLEFT", 0, -20);
3513 end
3514 end
3515 new.next = button;
3516 button.group = group;
3517 end
3518 end
3519 end
3520  
3521 function CT_RA_SortByVirtual(updateStatus)
3522 local tempOptions = CT_RAMenu_Options["temp"];
3523 CT_RA_SetSortType("virtual");
3524 local groupnum = 1;
3525 local membernum = 1;
3526 local availableSlots = {
3527 [1] = 0,
3528 [2] = 0,
3529 [3] = 0,
3530 [4] = 0,
3531 [5] = 0,
3532 [6] = 0,
3533 [7] = 0,
3534 [8] = 0
3535 };
3536 for i = 1, 40, 1 do
3537 if ( i <= GetNumRaidMembers() ) then
3538 local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(i);
3539 availableSlots[subgroup] = availableSlots[subgroup] + 1;
3540 end
3541 if ( i <= 8 ) then
3542 local group = getglobal("CT_RAGroup"..i);
3543 group.next = nil;
3544 group.num = 0;
3545 local label = getglobal("CT_RAOptionsGroup" .. i .. "Label");
3546 if ( label ) then
3547 label:SetText("Virtual " .. i);
3548 end
3549 end
3550 getglobal("CT_RAMember" .. i).next = nil;
3551 end
3552 local subsort = CT_RA_SubSortByName();
3553 for j = 1, 40, 1 do
3554 local i = subsort[j][1];
3555 local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(i);
3556 local isVirtual;
3557 if ( not name ) then
3558 isVirtual = 1;
3559 name, rank, level, class, fileName, zone, online, isDead = "Virtual " .. i, 0, 60, CT_RA_PRIEST, "PRIEST", "Emerald Dream", 1, nil;
3560 for i = 1, 8, 1 do
3561 if ( availableSlots[i] < 5 ) then
3562 availableSlots[i] = availableSlots[i] + 1;
3563 subgroup = i;
3564 break;
3565 end
3566 end
3567 end
3568 local groupid = subgroup;
3569 local group = getglobal("CT_RAGroup" .. groupid);
3570 frameCache[group].GroupName:SetText("Virtual " .. subgroup);
3571 local text = getglobal("CT_RAOptionsGroupButton" .. i .."Texture");
3572 if ( text ) then
3573 text:SetVertexColor(1.0, 1.0, 1.0);
3574 end
3575  
3576 local button = getglobal("CT_RAMember" .. i);
3577 local new, newName;
3578 if ( group.next and group.next ~= button ) then
3579 new = group;
3580 while ( new.next ) do
3581 new = new.next;
3582 end
3583 newName = new.name;
3584 group.num = group.num + 1;
3585 button:ClearAllPoints();
3586 if ( tempOptions["ShowHorizontal"] ) then
3587 if ( tempOptions["HideBorder"] ) then
3588 if ( tempOptions["HideSpace"] ) then
3589 button:SetPoint("LEFT", newName, "RIGHT", -10, 0);
3590 else
3591 button:SetPoint("LEFT", newName, "RIGHT", -8, 0);
3592 end
3593 else
3594 button:SetPoint("LEFT", newName, "RIGHT", -2, 0);
3595 end
3596 else
3597 if ( tempOptions["HideBorder"] ) then
3598 if ( tempOptions["HideSpace"] ) then
3599 if ( tempOptions["ShowReversed"] ) then
3600 button:SetPoint("BOTTOMLEFT", newName, "TOPLEFT", 0, -10);
3601 else
3602 button:SetPoint("TOPLEFT", newName, "BOTTOMLEFT", 0, 10);
3603 end
3604 else
3605 if ( tempOptions["ShowReversed"] ) then
3606 button:SetPoint("BOTTOMLEFT", newName, "TOPLEFT", 0, -7);
3607 else
3608 button:SetPoint("TOPLEFT", newName, "BOTTOMLEFT", 0, 7);
3609 end
3610 end
3611 else
3612 if ( tempOptions["ShowReversed"] ) then
3613 button:SetPoint("BOTTOMLEFT", newName, "TOPLEFT", 0, -5);
3614 else
3615 button:SetPoint("TOPLEFT", newName, "BOTTOMLEFT", 0, 4);
3616 end
3617 end
3618 end
3619 else
3620 group.num = 1;
3621 new = group;
3622 button:ClearAllPoints();
3623 if ( tempOptions["ShowReversed"] ) then
3624 button:SetPoint("BOTTOMLEFT", group.name, "TOPLEFT", 0, -15);
3625 else
3626 button:SetPoint("TOPLEFT", group.name, "TOPLEFT", 0, -20);
3627 end
3628 end
3629 new.next = button;
3630 button.group = group;
3631 group:Show();
3632 CT_RA_UpdateGroupVisibility(groupid, 1);
3633 if ( not updateStatus ) then
3634 CT_RA_UpdateUnitStatus(button);
3635 end
3636 end
3637 end
3638  
3639 function CT_RA_SortByCustom()
3640 local tempOptions = CT_RAMenu_Options["temp"];
3641 tempOptions["SORTTYPE"] = "custom";
3642 local groupnum = 1;
3643 local membernum = 1;
3644 for i = 1, 40, 1 do
3645 if ( i <= 8 ) then
3646 local group = getglobal("CT_RAGroup" .. i);
3647 group.next = nil;
3648 group.num = 0;
3649 local label = getglobal("CT_RAOptionsGroup" .. i .. "Label");
3650 if ( label ) then
3651 label:SetText("Custom " .. i);
3652 end
3653 end
3654 getglobal("CT_RAMember" .. i).next = nil;
3655 end
3656 local subsort = CT_RA_SubSortByName();
3657 for j = 1, GetNumRaidMembers(), 1 do
3658 local i = subsort[j][1];
3659 local name, rank, subgroup, level, class, fileName, zone, online, isDead = GetRaidRosterInfo(i);
3660 local text = getglobal("CT_RAOptionsGroupButton" .. i .."Texture");
3661 if ( text ) then
3662 text:SetVertexColor(1.0, 1.0, 1.0);
3663 end
3664 if ( ( not tempOptions["HideOffline"] or online ) and ( CT_RA_Stats[name] or not tempOptions["HideNA"] ) ) then
3665 if ( name and CT_RA_CurrPositions[name] ) then
3666 subgroup = CT_RA_CurrPositions[name][1];
3667 elseif ( name ) then
3668 for y = 1, 8, 1 do
3669 local group = getglobal("CT_RAGroup" .. y);
3670 if ( not group.num or group.num < 5 ) then
3671 subgroup = y;
3672 CT_RA_CurrPositions[name] = { y, j };
3673 break;
3674 end
3675 end
3676 end
3677 if ( name ) then
3678 local group = getglobal("CT_RAGroup" .. subgroup);
3679 local button = getglobal("CT_RAMember" .. i);
3680 frameCache[group].GroupName:SetText("Custom " .. subgroup);
3681 button:ClearAllPoints();
3682 local new, newName;
3683 if ( group.next and group.next ~= button ) then
3684 new = group;
3685 while ( new.next ) do
3686 if ( new.next ) then
3687 new = new.next;
3688 end
3689 end
3690 newName = new.name;
3691 group.num = group.num + 1;
3692 button:ClearAllPoints();
3693 if ( tempOptions["ShowHorizontal"] ) then
3694 if ( tempOptions["HideBorder"] ) then
3695 if ( tempOptions["HideSpace"] ) then
3696 button:SetPoint("LEFT", newName, "RIGHT", -10, 0);
3697 else
3698 button:SetPoint("LEFT", newName, "RIGHT", -8, 0);
3699 end
3700 else
3701 button:SetPoint("LEFT", newName, "RIGHT", -2, 0);
3702 end
3703 else
3704 if ( tempOptions["HideBorder"] ) then
3705 if ( tempOptions["HideSpace"] ) then
3706 if ( tempOptions["ShowReversed"] ) then
3707 button:SetPoint("BOTTOMLEFT", newName, "TOPLEFT", 0, -10);
3708 else
3709 button:SetPoint("TOPLEFT", newName, "BOTTOMLEFT", 0, 10);
3710 end
3711 else
3712 if ( tempOptions["ShowReversed"] ) then
3713 button:SetPoint("BOTTOMLEFT", newName, "TOPLEFT", 0, -7);
3714 else
3715 button:SetPoint("TOPLEFT", newName, "BOTTOMLEFT", 0, 7);
3716 end
3717 end
3718 else
3719 if ( tempOptions["ShowReversed"] ) then
3720 button:SetPoint("BOTTOMLEFT", newName, "TOPLEFT", 0, -5);
3721 else
3722 button:SetPoint("TOPLEFT", newName, "BOTTOMLEFT", 0, 4);
3723 end
3724 end
3725 end
3726 else
3727 group.num = 1;
3728 new = group;
3729 button:ClearAllPoints();
3730 if ( tempOptions["ShowReversed"] ) then
3731 button:SetPoint("BOTTOMLEFT", group.name, "TOPLEFT", 0, -15);
3732 else
3733 button:SetPoint("TOPLEFT", group.name, "TOPLEFT", 0, -20);
3734 end
3735 end
3736 new.next = button;
3737 button.group = group;
3738 end
3739 end
3740 end
3741 end
3742  
3743 function CT_RA_LinkDrag(frame, drag, point, relative, x, y)
3744 frame:ClearAllPoints();
3745 frame:SetPoint(point, drag:GetName(), relative, x, y);
3746 end
3747  
3748 CT_RA_ConvertedRaid = 1;
3749 CT_RA_HasInvited = { };
3750  
3751 local CT_RA_GameTooltip_ClearMoney;
3752  
3753 local function CT_RA_MoneyToggle()
3754 if( CT_RA_GameTooltip_ClearMoney ) then
3755 GameTooltip_ClearMoney = CT_RA_GameTooltip_ClearMoney;
3756 CT_RA_GameTooltip_ClearMoney = nil;
3757 else
3758 CT_RA_GameTooltip_ClearMoney = GameTooltip_ClearMoney;
3759 GameTooltip_ClearMoney = CT_RA_GameTooltipFunc_ClearMoney;
3760 end
3761 end
3762  
3763 function CT_RA_GameTooltipFunc_ClearMoney()
3764  
3765 end
3766  
3767 function CT_RA_GetBuffIndex(name, filter)
3768 local i = 0;
3769 local buffIndex, untilCancelled = GetPlayerBuff(i, filter);
3770 while ( buffIndex ~= -1 ) do
3771 CT_RA_MoneyToggle();
3772 CT_RATooltip:SetPlayerBuff(buffIndex);
3773 CT_RA_MoneyToggle();
3774 local tooltipName = CT_RATooltipTextLeft1:GetText();
3775 if ( tooltipName and name == tooltipName ) then
3776 return buffIndex;
3777 end
3778 i = i + 1;
3779 buffIndex, untilCancelled = GetPlayerBuff(i, filter);
3780 end
3781 return nil;
3782 end
3783  
3784  
3785 function CT_RA_UpdateFrame_OnUpdate(elapsed)
3786 if ( this.showDialog ) then
3787 this.showDialog = this.showDialog - elapsed;
3788 if ( this.showDialog <= 0 ) then
3789 if ( CT_RAChanges_DisplayDialog ) then
3790 CT_RAChanges_DisplayDialog();
3791 end
3792 this.showDialog = nil;
3793 end
3794 end
3795  
3796 if ( this.lastInvite ) then
3797 this.lastInvite = this.lastInvite - elapsed;
3798 if ( this.lastInvite <= 0 ) then
3799 this.lastInvite = nil;
3800 this.inviteName = nil;
3801 end
3802 end
3803 if ( this.invite ) then
3804 this.invite = this.invite - elapsed;
3805 if ( this.invite <= 0 ) then
3806 if ( not CT_RA_ConvertedRaid ) then
3807 GuildRoster();
3808 CT_RA_ConvertedRaid = 1;
3809 ConvertToRaid();
3810 this.invite = 3;
3811 else
3812 CT_RA_InviteGuild(CT_RA_MinLevel, CT_RA_MaxLevel);
3813 this.invite = nil;
3814 end
3815 end
3816 end
3817 if ( this.startinviting ) then
3818 this.startinviting = this.startinviting - elapsed;
3819 if ( this.startinviting <= 0 ) then
3820 this.startinviting = nil;
3821 CT_RA_HasInvited = { };
3822 if ( GetNumRaidMembers() == 0 ) then
3823 CT_RA_ConvertedRaid = nil;
3824 else
3825 CT_RA_ConvertedRaid = 1;
3826 end
3827 local inZone = "";
3828 if ( CT_RA_ZoneInvite ) then
3829 inZone = " from " .. GetRealZoneText();
3830 end
3831 local numInvites = CT_RA_InviteGuild(CT_RA_MinLevel, CT_RA_MaxLevel);
3832 if ( CT_RA_MinLevel == CT_RA_MaxLevel ) then
3833 CT_RA_Print("<CTRaid> " .. numInvites .. " Guild Members of level |c00FFFFFF" .. CT_RA_MinLevel .. "|r have been invited" .. inZone .. ".", 1, 0.5, 0);
3834 else
3835 CT_RA_Print("<CTRaid> " .. numInvites .. " Guild Members of levels |c00FFFFFF" .. CT_RA_MinLevel .. "|r to |c00FFFFFF" .. CT_RA_MaxLevel .. "|r have been invited" .. inZone .. ".", 1, 0.5, 0);
3836 end
3837 end
3838 end
3839 if ( this.closeroster ) then
3840 this.closeroster = this.closeroster - elapsed;
3841 if ( this.closeroster <= 0 ) then
3842 HideUIPanel(FriendsFrame);
3843 this.closeroster = nil;
3844 end
3845 end
3846 if ( this.joinchan ) then
3847 this.joinchan = this.joinchan - elapsed;
3848 if ( this.joinchan <= 0 ) then
3849 CT_RA_Channel = this.newchan;
3850 CT_RA_Join(CT_RA_Channel);
3851 this.joinchan = nil;
3852 this.newchan = nil;
3853 end
3854 end
3855  
3856 -- Only run the ones below if we're in a raid.
3857 if ( CT_RA_NumRaidMembers == 0 ) then
3858 return;
3859 end
3860  
3861 this.mouseOverUpdate = this.mouseOverUpdate - elapsed;
3862 if ( this.mouseOverUpdate <= 0 ) then
3863 this.mouseOverUpdate = 0.1;
3864 if ( CT_RA_CurrentMemberFrame ) then
3865 local parent = CT_RA_CurrentMemberFrame.frameParent;
3866 if ( SpellIsTargeting() and ( strsub(parent.name, 1, 12) == "CT_RAMTGroup" or SpellCanTargetUnit("raid" .. parent.id) ) ) then
3867 SetCursor("CAST_CURSOR");
3868 elseif ( SpellIsTargeting() ) then
3869 SetCursor("CAST_ERROR_CURSOR");
3870 end
3871 end
3872 end
3873  
3874 if ( this.hasAggroAlert ) then
3875 this.hasAggroAlert = this.hasAggroAlert - elapsed;
3876 if ( this.hasAggroAlert <= 0 ) then
3877 this.hasAggroAlert = nil;
3878 end
3879 end
3880 this.updateAFK = this.updateAFK + elapsed;
3881 if ( this.updateAFK >= 1 ) then
3882 this.updateAFK = this.updateAFK - 1;
3883 for k, v in CT_RA_Stats do
3884 if ( v["AFK"] ) then
3885 v["AFK"][2] = v["AFK"][2] + 1;
3886 end
3887 if ( v["DND"] ) then
3888 v["DND"][2] = v["DND"][2] + 1;
3889 end
3890 if ( v["Dead"] ) then
3891 v["Dead"] = v["Dead"] + 1;
3892 end
3893 if ( v["Offline"] ) then
3894 v["Offline"] = v["Offline"] + 1;
3895 end
3896 if ( v["FD"] ) then
3897 v["FD"] = v["FD"] + 1;
3898 end
3899 if ( v["Rebirth"] ) then
3900 v["Rebirth"] = v["Rebirth"] - 1;
3901 end
3902 if ( v["Reincarnation"] ) then
3903 v["Reincarnation"] = v["Reincarnation"] - 1;
3904 end
3905 if ( v["Soulstone"] ) then
3906 v["Soulstone"] = v["Soulstone"] - 1;
3907 end
3908 end
3909 end
3910  
3911 this.update = this.update + elapsed;
3912 if ( this.update >= 1 ) then
3913 for k, v in CT_RA_BuffTimeLeft do
3914 local buffIndex, buffTimeLeft, buffName;
3915 buffIndex = CT_RA_GetBuffIndex(k, "HELPFUL");
3916 if ( buffIndex ) then
3917 buffTimeLeft = GetPlayerBuffTimeLeft(buffIndex);
3918 if ( buffTimeLeft ) then
3919 if ( abs(CT_RA_BuffTimeLeft[k]-buffTimeLeft) >= 2 ) then
3920 local index, num;
3921 for key, val in CT_RAMenu_Options["temp"]["BuffArray"] do
3922 if ( type(val["name"]) == "table" ) then
3923 if ( k == val["name"][1] ) then
3924 buffName = k;
3925 index, num = key, 1;
3926 break;
3927 elseif ( k == val["name"][2] ) then
3928 buffName = k;
3929 index, num = key, 2;
3930 break;
3931 end
3932 elseif ( val["name"] == k ) then
3933 buffName = k;
3934 index, num = key, 0;
3935 break;
3936 end
3937 end
3938 if ( not index and not num ) then
3939 if ( k == CT_RA_FEIGNDEATH[CT_RA_GetLocale()] ) then
3940 buffName = CT_RA_FEIGNDEATH[CT_RA_GetLocale()];
3941 index, num = 0, 0;
3942 end
3943 end
3944 if ( index and num ) then
3945 local playerName = UnitName("player");
3946 local stats = CT_RA_Stats[playerName];
3947 if ( not stats ) then
3948 CT_RA_Stats[playerName] = {
3949 ["Buffs"] = { },
3950 ["Debuffs"] = { },
3951 ["Position"] = { }
3952 };
3953 stats = CT_RA_Stats[playerName];
3954 end
3955 stats["Buffs"][buffName] = { string.find(GetPlayerBuffTexture(buffIndex), "([%w_&]+)$"), floor(buffTimeLeft+0.5) };
3956 CT_RA_AddMessage("RN " .. floor(buffTimeLeft+0.5) .. " " .. index .. " " .. num);
3957 end
3958 end
3959 CT_RA_BuffTimeLeft[k] = buffTimeLeft;
3960 end
3961 end
3962 end
3963 for k, v in CT_RA_Stats do
3964 if ( v["Buffs"] ) then
3965 for key, val in v["Buffs"] do
3966 if ( type(val) == "table" and val[2] ) then
3967 val[2] = val[2] - 1;
3968 end
3969 end
3970 end
3971 end
3972 this.update = this.update - 1;
3973 end
3974 if ( this.time ) then
3975 this.time = this.time - elapsed;
3976 if ( this.time <= 0 ) then
3977 if ( CT_RA_Channel ) then
3978 this.time = nil;
3979 CT_RA_AddMessage("SR");
3980 if ( CT_RA_VersionNumber ) then
3981 CT_RA_AddMessage("V " .. CT_RA_VersionNumber);
3982 end
3983 else
3984 this.time = 5;
3985 end
3986 end
3987 if ( this.SS ) then
3988 this.SS = nil;
3989 end
3990 end
3991  
3992 if ( this.SS ) then
3993 this.SS = this.SS - elapsed;
3994 if ( this.SS <= 0 ) then
3995 if ( CT_RA_Channel ) then
3996 this.SS = nil;
3997 CT_RA_AddMessage("SR");
3998 if ( CT_RA_VersionNumber ) then
3999 CT_RA_AddMessage("V " .. CT_RA_VersionNumber);
4000 end
4001 else
4002 this.SS = 5;
4003 end
4004 end
4005 end
4006 if ( this.scheduleUpdate ) then
4007 this.scheduleUpdate = this.scheduleUpdate - elapsed;
4008 if ( this.scheduleUpdate <= 0 ) then
4009 if ( CT_RA_InCombat ) then
4010 this.scheduleUpdate = 1;
4011 else
4012 this.scheduleUpdate = nil;
4013 for i = 1, GetNumRaidMembers(), 1 do
4014 if ( UnitIsUnit("raid" .. i, "player") ) then
4015 local useless, useless, subgroup = GetRaidRosterInfo(i);
4016 this.updateDelay = subgroup;
4017 return;
4018 end
4019 end
4020 end
4021 end
4022 end
4023 if ( this.scheduleMTUpdate ) then
4024 this.scheduleMTUpdate = this.scheduleMTUpdate - elapsed;
4025 if ( this.scheduleMTUpdate <= 0 ) then
4026 this.scheduleMTUpdate = nil;
4027 if ( CT_RA_IsSendingWithVersion(1.08) ) then
4028 for k, v in CT_RA_MainTanks do
4029 CT_RA_AddMessage("SET " .. k .. " " .. v);
4030 end
4031 end
4032 end
4033 end
4034 if ( this.updateDelay ) then
4035 this.updateDelay = this.updateDelay - elapsed;
4036 if ( this.updateDelay <= 0 ) then
4037 this.updateDelay = nil;
4038 CT_RA_SendStatus();
4039 CT_RA_UpdateRaidGroup(1);
4040 end
4041 end
4042 if ( this.voteTimer ) then
4043 this.voteTimer = this.voteTimer - elapsed;
4044 if ( this.voteTimer <= 0 ) then
4045 if ( CT_RA_VotePerson ) then
4046 local numCount = 0;
4047 for i = 1, GetNumRaidMembers(), 1 do
4048 if ( UnitIsConnected("raid" .. i) ) then
4049 numCount = numCount + 1;
4050 end
4051 end
4052 local noVotes = numCount-(CT_RA_VotePerson[2]+CT_RA_VotePerson[3]+1);
4053 local yesPercent, noPercent, noVotePercent = 0, 0, 0;
4054 if ( CT_RA_VotePerson[2] > 0 ) then
4055 yesPercent = floor(CT_RA_VotePerson[2]/(CT_RA_VotePerson[2]+CT_RA_VotePerson[3]+noVotes)*100+0.5);
4056 end
4057 if ( CT_RA_VotePerson[3] > 0 ) then
4058 noPercent = floor(CT_RA_VotePerson[3]/(CT_RA_VotePerson[2]+CT_RA_VotePerson[3]+noVotes)*100+0.5);
4059 end
4060 if ( yesPercent+noPercent < 100 ) then
4061 noVotePercent = 100-(yesPercent+noPercent);
4062 end
4063 CT_RA_Print("<CTRaid> Vote results for \"|c00FFFFFF" .. CT_RA_VotePerson[4] .. "|r\": |c00FFFFFF" .. CT_RA_VotePerson[2] .. "|r (|c00FFFFFF" .. yesPercent .. "%|r) Yes / |c00FFFFFF" .. CT_RA_VotePerson[3] .. "|r (|c00FFFFFF" .. noPercent .. "%|r) No / |c00FFFFFF" .. noVotes .. "|r (|c00FFFFFF" .. noVotePercent .. "%|r) did not vote.", 1, 0.5, 0);
4064 SendChatMessage("<CTRaid> Vote results for \"" .. CT_RA_VotePerson[4] .. "\": " .. CT_RA_VotePerson[2] .. " (" .. yesPercent .. "%) Yes / " .. CT_RA_VotePerson[3] .. " (" .. noPercent .. "%) No / " .. noVotes .. " (" .. noVotePercent .. "%) did not vote.", "RAID");
4065 CT_RA_VotePerson = nil;
4066 end
4067 this.voteTimer = nil;
4068 end
4069 end
4070 if ( this.readyTimer ) then
4071 this.readyTimer = this.readyTimer - elapsed;
4072 if ( this.readyTimer <= 0 ) then
4073 CT_RA_CheckReady_Person = nil;
4074 this.readyTimer = nil;
4075 local numNotReady, numAfk = 0, 0
4076 local notReadyString, afkString = "", "";
4077 for k, v in CT_RA_Stats do
4078 if ( v["notready"] and v["notready"] == 2 ) then
4079 numNotReady = numNotReady + 1;
4080 if ( strlen(notReadyString) > 0 ) then
4081 notReadyString = notReadyString .. ", ";
4082 end
4083 notReadyString = notReadyString .. "|c00FFFFFF" .. k .. "|r";
4084 elseif ( v["notready"] and v["notready"] == 1 ) then
4085 numAfk = numAfk + 1;
4086 if ( strlen(afkString) > 0 ) then
4087 afkString = afkString .. ", ";
4088 end
4089 afkString = afkString .. "|c00FFFFFF" .. k .. "|r";
4090 end
4091 CT_RA_Stats[k]["notready"] = nil;
4092 end
4093 if ( numNotReady > 0 ) then
4094 if ( numNotReady == 1 ) then
4095 CT_RA_Print("<CTRaid> " .. notReadyString .. " is not ready.", 1, 1, 0);
4096 elseif ( numNotReady >= 8 ) then
4097 CT_RA_Print("<CTRaid> |c00FFFFFF" .. numNotReady .. "|r raid members are not ready.", 1, 1, 0);
4098 else
4099 CT_RA_Print("<CTRaid> |c00FFFFFF" .. numNotReady .. "|r raid members (" .. notReadyString .. ") are not ready.", 1, 1, 0);
4100 end
4101 CT_RA_UpdateRaidGroup(1);
4102 end
4103 if ( numAfk > 0 ) then
4104 if ( numAfk == 1 ) then
4105 CT_RA_Print("<CTRaid> " ..afkString .. " is away from keyboard.", 1, 1, 0);
4106 elseif ( numAfk >= 8 ) then
4107 CT_RA_Print("<CTRaid> |c00FFFFFF" .. numAfk.. "|r raid members are away from keyboard.", 1, 1, 0);
4108 else
4109 CT_RA_Print("<CTRaid> |c00FFFFFF" .. numAfk .. "|r raid members (" .. afkString .. ") are away from keyboard.", 1, 1, 0);
4110 end
4111 CT_RA_UpdateRaidGroup(1);
4112 end
4113 end
4114 end
4115 if ( this.rlyTimer ) then
4116 this.rlyTimer = this.rlyTimer - elapsed;
4117 if ( this.rlyTimer <= 0 ) then
4118 this.rlyTimer = nil;
4119 local numNotReady, numAfk = 0, 0
4120 local notReadyString, afkString = "", "";
4121 for k, v in CT_RA_Stats do
4122 if ( v["rly"] and v["rly"] == 2 ) then
4123 numNotReady = numNotReady + 1;
4124 if ( strlen(notReadyString) > 0 ) then
4125 notReadyString = notReadyString .. ", ";
4126 end
4127 notReadyString = notReadyString .. "|c00FFFFFF" .. k .. "|r";
4128 elseif ( v["rly"] and v["rly"] == 1 ) then
4129 numAfk = numAfk + 1;
4130 if ( strlen(afkString) > 0 ) then
4131 afkString = afkString .. ", ";
4132 end
4133 afkString = afkString .. "|c00FFFFFF" .. k .. "|r";
4134 end
4135 CT_RA_Stats[k]["rly"] = nil;
4136 end
4137 if ( numNotReady > 0 ) then
4138 if ( numNotReady == 1 ) then
4139 CT_RA_Print("<CTRaid> " .. notReadyString .. " says |c00FFFFFFNO WAI!|r.", 1, 1, 0);
4140 elseif ( numNotReady >= 8 ) then
4141 CT_RA_Print("<CTRaid> |c00FFFFFF" .. numNotReady .. "|r raid members say |c00FFFFFFNO WAI!|r.", 1, 1, 0);
4142 else
4143 CT_RA_Print("<CTRaid> |c00FFFFFF" .. numNotReady .. "|r raid members (" .. notReadyString .. ") say |c00FFFFFFNO WAI!|r.", 1, 1, 0);
4144 end
4145 CT_RA_UpdateRaidGroup(1);
4146 end
4147 if ( numAfk > 0 ) then
4148 if ( numAfk == 1 ) then
4149 CT_RA_Print("<CTRaid> " ..afkString .. " says nothing.", 1, 1, 0);
4150 elseif ( numAfk >= 8 ) then
4151 CT_RA_Print("<CTRaid> |c00FFFFFF" .. numAfk.. "|r raid members say nothing.", 1, 1, 0);
4152 else
4153 CT_RA_Print("<CTRaid> |c00FFFFFF" .. numAfk .. "|r raid members (" .. afkString .. ") say nothing.", 1, 1, 0);
4154 end
4155 CT_RA_UpdateRaidGroup(1);
4156 end
4157 end
4158 end
4159 if ( CT_RA_Squelch > 0 ) then
4160 CT_RA_Squelch = CT_RA_Squelch - elapsed;
4161 if ( CT_RA_Squelch <= 0 ) then
4162 CT_RA_Squelch = 0;
4163 CT_RA_Print("<CTRaid> Quiet Mode has been automatically disabled (timed out).", 1, 0.5, 0);
4164 end
4165 end
4166 if ( this.updateMT ) then
4167 this.updateMT = this.updateMT - elapsed;
4168 if ( this.updateMT <= 0 ) then
4169 this.updateMT = 0.25;
4170 CT_RA_UpdateMTs();
4171 CT_RA_UpdatePTs();
4172 end
4173 end
4174 for k, v in CT_RA_CurrDebuffs do
4175 CT_RA_CurrDebuffs[k][1] = CT_RA_CurrDebuffs[k][1] - elapsed;
4176 if ( CT_RA_CurrDebuffs[k][1] < 0 ) then
4177 local _, _, name, dType = string.find(k, "^([^@]+)@(.+)$");
4178 local msg = "";
4179 if ( GetBindingKey("CT_CUREDEBUFF") and CT_RA_GetCure(dType) ) then
4180 msg = " Press '|c00FFFFFF" .. GetBindingText(GetBindingKey("CT_CUREDEBUFF"), "KEY_") .. "|r' to cure";
4181 end
4182 if ( name == dType ) then
4183 dType = "";
4184 else
4185 dType = " (|c00FFFFFF" .. dType .. "|r)";
4186 end
4187 if ( CT_RA_CurrDebuffs[k][2] == 1 ) then
4188 CT_RA_Print("<CTRaid> |c00FFFFFF" .. CT_RA_CurrDebuffs[k][4] .. "|r has been debuffed by '|c00FFFFFF" .. name .. "|r'" .. dType .. msg .. ".", 1, 0.5, 0);
4189 else
4190 CT_RA_Print("<CTRaid> |c00FFFFFF" .. CT_RA_CurrDebuffs[k][2] .. "|r players have been debuffed by '|c00FFFFFF" .. name .. "|r'" .. dType .. msg .. ".", 1, 0.5, 0);
4191 end
4192 CT_RA_CurrDebuffs[k] = nil;
4193 end
4194 end
4195 end
4196 function CT_RA_UpdateFrame_OnEvent(event)
4197 if ( event == "PARTY_MEMBERS_CHANGED" ) then
4198 if ( not CT_RA_ConvertedRaid ) then
4199 this.invite = 3;
4200 end
4201 elseif ( event == "CHAT_MSG_SYSTEM" ) then
4202 local _, _, name = string.find(arg1, "^([^%s]+) is already in a group%.$");
4203 if ( name and this.inviteName and this.inviteName == name ) then
4204 this.inviteName = nil;
4205 this.lastInvite = nil;
4206 SendChatMessage("<CTRaid> You are already grouped.", "WHISPER", nil, name);
4207 end
4208 end
4209 end
4210  
4211 function CT_RA_InviteGuild(min, max)
4212 local offline = GetGuildRosterShowOffline();
4213 local selection = GetGuildRosterSelection();
4214 SetGuildRosterShowOffline(0);
4215 SetGuildRosterSelection(0);
4216 GetGuildRosterInfo(0);
4217 local inviteBeforeRaid = 4-GetNumPartyMembers();
4218 local numInvites = 0;
4219 local numGuildMembers = GetNumGuildMembers();
4220 CT_RA_UpdateFrame.closeroster = 2;
4221 local RealZoneText = GetRealZoneText();
4222 if (RealZoneText == nil) then RealZoneText = "?"; end
4223 local playerName = UnitName("player");
4224 for i = 1, numGuildMembers, 1 do
4225 local name, rank, rankIndex, level, class, zone, note, officernote, online, status = GetGuildRosterInfo(i);
4226 if ( level >= min and level <= max and name ~= playerName and not CT_RA_HasInvited[i] and online ) then
4227 if ( zone == nil ) then zone = "???"; end
4228 if ( not CT_RA_ZoneInvite or ( CT_RA_ZoneInvite and zone == RealZoneText ) ) then
4229 CT_RA_HasInvited[i] = 1;
4230 InviteByName(name);
4231 numInvites = numInvites + 1;
4232 if ( numInvites == inviteBeforeRaid and not CT_RA_ConvertedRaid ) then
4233 CT_RA_UpdateFrame.invite = 1.5;
4234 break;
4235 end
4236 end
4237 end
4238 end
4239 SetGuildRosterShowOffline(offline);
4240 SetGuildRosterSelection(selection);
4241 return numInvites;
4242 end
4243  
4244 function CT_RA_ProcessMessages(elapsed)
4245 if ( this.flush ) then
4246 this.flush = this.flush - elapsed;
4247 if ( this.flush <= 0 ) then
4248 this.flush = 1;
4249 this.numMessagesSent = 0;
4250 end
4251 end
4252 if ( this.elapsed ) then
4253 this.elapsed = this.elapsed - elapsed;
4254 if ( this.elapsed <= 0 ) then
4255 if ( getn(CT_RA_Comm_MessageQueue) > 0 and this.numMessagesSent < 4 ) then
4256 CT_RA_SendMessageQueue();
4257 end
4258 this.elapsed = 0.1;
4259 end
4260 end
4261 end
4262 function CT_RA_SendMessageQueue()
4263 local retstr = "";
4264 local numSent = 0;
4265  
4266 for key, val in CT_RA_Comm_MessageQueue do
4267 if ( strlen(retstr)+strlen(val)+1 > 255 ) then
4268 CT_RA_SendMessage(retstr, 1);
4269 this.numMessagesSent = this.numMessagesSent + 1;
4270 tremove(CT_RA_Comm_MessageQueue, key);
4271 if ( this.numMessagesSent == 4 ) then
4272 return;
4273 end
4274 retstr = "";
4275 end
4276 if ( retstr ~= "" ) then
4277 retstr = retstr .. "#";
4278 end
4279 retstr = retstr .. val;
4280 end
4281 if ( retstr ~= "" ) then
4282 CT_RA_SendMessage(retstr, 1);
4283 this.numMessagesSent = this.numMessagesSent + 1;
4284 end
4285 CT_RA_Comm_MessageQueue = { };
4286 end
4287  
4288 function CT_RA_Split(msg, char)
4289 local arr = { };
4290 while (string.find(msg, char) ) do
4291 local iStart, iEnd = string.find(msg, char);
4292 tinsert(arr, strsub(msg, 1, iStart-1));
4293 msg = strsub(msg, iEnd+1, strlen(msg));
4294 end
4295 if ( strlen(msg) > 0 ) then
4296 tinsert(arr, msg);
4297 end
4298 return arr;
4299 end
4300  
4301 function CT_RA_IsSendingWithVersion(version)
4302 local playerName = UnitName("player");
4303 local names = { };
4304 if ( not CT_RA_Level or CT_RA_Level < 1 ) then
4305 return nil;
4306 end
4307 for i = 1, GetNumRaidMembers(), 1 do
4308 local name, rank, subgroup, level, class, fileName = GetRaidRosterInfo(i);
4309 local stats = CT_RA_Stats[name];
4310 if ( rank >= 1 and name ~= playerName and stats and stats["Version"] and stats["Version"] >= version and name < playerName ) then
4311 return nil;
4312 end
4313 end
4314 return 1;
4315 end
4316  
4317 function CT_RA_ScanPartyAuras(unit)
4318 local name = UnitName(unit);
4319 if ( not name ) then
4320 return;
4321 end
4322 local id = string.gsub(unit, "^raid(%d+)$", "%1");
4323 local stats = CT_RA_Stats[name];
4324 if ( not stats ) then
4325 CT_RA_Stats[name] = {
4326 ["Buffs"] = { },
4327 ["Debuffs"] = { },
4328 ["Position"] = { }
4329 };
4330 stats = CT_RA_Stats[name];
4331 CT_RA_ScanUnitBuffs(unit, name, id);
4332 CT_RA_ScanUnitDebuffs(unit, name, id);
4333 CT_RA_UpdateUnitBuffs(CT_RA_Stats[name]["Buffs"], getglobal("CT_RAMember" .. id), name);
4334 else
4335 local num, numDebuffs, debuff = 0, 0, UnitDebuff(unit, 1);
4336 numDebuffs, debuff = 0, UnitDebuff(unit, 1);
4337 while ( debuff ) do
4338 numDebuffs = numDebuffs + 1;
4339 debuff = UnitDebuff(unit, numDebuffs+1);
4340 end
4341 if ( getn(CT_RA_Stats[name]["Debuffs"]) ~= numDebuffs ) then
4342 -- Debuffs
4343 CT_RA_ScanUnitDebuffs(unit, name, id);
4344 else
4345 CT_RA_ScanUnitBuffs(unit, name, id);
4346 local isFD = CT_RA_CheckFD(name, "raid" .. id);
4347 if ( isFD > 0 ) then
4348 CT_RA_UpdateUnitDead(getglobal("CT_RAMember" .. id));
4349 end
4350 end
4351 CT_RA_UpdateUnitBuffs(CT_RA_Stats[name]["Buffs"], getglobal("CT_RAMember" .. id), name);
4352 end
4353 end
4354  
4355 function CT_RA_CheckFD(name, unit)
4356 local class = UnitClass(unit);
4357 if ( class ~= CT_RA_HUNTER and class ~= CT_RA_PRIEST ) then
4358 return 0;
4359 end
4360 local hasFD = 0;
4361 local num, buff = 0, UnitBuff(unit, 1);
4362 while ( buff ) do
4363 if ( buff == "Interface\\Icons\\Ability_Rogue_FeignDeath" ) then
4364 hasFD = 1;
4365 break;
4366 elseif ( buff == "Interface\\Icons\\Spell_Holy_GreaterHeal" ) then
4367 hasFD = 2;
4368 break;
4369 end
4370 num = num + 1;
4371 buff = UnitBuff(unit, num+1);
4372 end
4373 return hasFD;
4374 end
4375  
4376 function CT_RA_ScanUnitBuffs(unit, name, id)
4377 local tempOptions = CT_RAMenu_Options["temp"];
4378 local oldAuras = { };
4379 local stats = CT_RA_Stats[name]["Buffs"];
4380 for k, v in stats do
4381 oldAuras[k] = 1;
4382 end
4383 table.setn(stats, 0);
4384 local num, buff = 0, UnitBuff(unit, 1);
4385 local duplicateTextures = {
4386 ["Interface\\Icons\\Spell_Nature_Regeneration"] = true,
4387 ["Interface\\Icons\\Spell_Nature_LightningShield"] = true
4388 };
4389 while ( buff ) do
4390 num = num + 1;
4391 local buffName;
4392 -- Only check matching if it's not used by anything else
4393 if ( not duplicateTextures[buff] ) then
4394 for k, v in CT_RA_BuffTextures do
4395 if ( "Interface\\Icons\\" .. v[1] == buff ) then
4396 buffName = k;
4397 break;
4398 end
4399 end
4400 else
4401 CT_RATooltip:SetOwner(WorldFrame, "ANCHOR_NONE");
4402 CT_RATooltipTextLeft1:SetText("");
4403 CT_RATooltip:SetUnitBuff(unit, num);
4404 local tooltipName = CT_RATooltipTextLeft1:GetText();
4405 if ( strlen(tooltipName or "") > 0 and CT_RA_BuffTextures[tooltipName] ) then
4406 buffName = tooltipName;
4407 end
4408 end
4409 if ( buffName ) then
4410 local buffT = CT_RA_BuffTextures[buffName];
4411 if ( not stats[buffName] ) then
4412 stats[buffName] = { buff, buffT[2] };
4413 if ( UnitIsUnit(unit, "player") ) then
4414 CT_RA_BuffTimeLeft[buffName] = buffT[2];
4415 end
4416 end
4417 table.setn(stats, getn(stats)+1);
4418 oldAuras[buffName] = nil;
4419 end
4420 buff = UnitBuff(unit, num+1);
4421 end
4422 for k, v in oldAuras do
4423 stats[k] = nil;
4424 local buffTbl;
4425 for key, val in tempOptions["BuffArray"] do
4426 if ( k == val["name"] ) then
4427 buffTbl = val;
4428 break;
4429 end
4430 end
4431 if ( buffTbl ) then
4432 local uId = "raid" .. id;
4433 if ( not UnitIsDead(uId) and UnitIsVisible(uId) and not tempOptions["NotifyDebuffs"]["hidebuffs"] and k ~= CT_RA_POWERWORDSHIELD and k ~= CT_RA_ADMIRALSHAT ) then
4434 if ( buffTbl["show"] ~= -1 ) then
4435 local currPos = CT_RA_CurrPositions[name];
4436 if ( currPos ) then
4437 if ( tempOptions["NotifyDebuffs"][currPos[1]] and tempOptions["NotifyDebuffsClass"][CT_RA_ClassPositions[UnitClass("raid" .. currPos[2])]] ) then
4438 if ( CT_RA_ClassSpells and CT_RA_ClassSpells[k] and GetBindingKey("CT_RECASTRAIDBUFF") ) then
4439 if ( GetBindingKey("CT_RECASTRAIDBUFF") ) then
4440 CT_RA_AddToBuffQueue(k, uId);
4441 CT_RA_Print("<CTRaid> '|c00FFFFFF" .. name .. "|r's '|c00FFFFFF" .. k .. "|r' has faded. Press '|c00FFFFFF" .. GetBindingText(GetBindingKey("CT_RECASTRAIDBUFF"), "KEY_") .. "|r' to recast.", 1, 0.5, 0);
4442 else
4443 CT_RA_Print("<CTRaid> '|c00FFFFFF" .. name .. "|r's '|c00FFFFFF" .. k .. "|r' has faded.", 1, 0.5, 0);
4444 end
4445 end
4446 end
4447 end
4448 end
4449 end
4450 end
4451 end
4452 end
4453  
4454 function CT_RA_ScanUnitDebuffs(unit, name, id)
4455 local tempOptions = CT_RAMenu_Options["temp"];
4456 local oldAuras = { };
4457 local stats = CT_RA_Stats[name]["Debuffs"];
4458 for k, v in stats do
4459 oldAuras[k] = 1;
4460 end
4461 table.setn(stats, 0);
4462 local num, debuff = 0, UnitDebuff(unit, 1);
4463 while ( debuff ) do
4464 table.setn(stats, getn(stats)+1);
4465 num = num + 1;
4466 local debuffName;
4467 CT_RATooltip:SetOwner(WorldFrame, "ANCHOR_NONE");
4468 CT_RATooltipTextLeft1:SetText("");
4469 CT_RATooltipTextRight1:SetText("");
4470 CT_RATooltip:SetUnitDebuff(unit, num);
4471 local tooltipName, dType = CT_RATooltipTextLeft1:GetText(), CT_RATooltipTextRight1:GetText();
4472 if ( tooltipName and strlen(tooltipName) > 0 ) then
4473 debuffName = tooltipName;
4474 end
4475 if ( debuffName ) then
4476 oldAuras[debuffName] = nil;
4477 if ( not stats[debuffName] ) then
4478 if ( debuffName == CT_RA_WEAKENEDSOUL ) then
4479 dType = CT_RA_WEAKENEDSOUL;
4480 elseif ( debuffName == CT_RA_RECENTLYBANDAGED ) then
4481 dType = CT_RA_RECENTLYBANDAGED;
4482 end
4483 local debuffType;
4484 for k, v in tempOptions["DebuffColors"] do
4485 if ( dType == v["type"] ) then
4486 debuffType = v;
4487 break;
4488 end
4489 end
4490 if ( debuffType ) then
4491 local uId = "raid" .. id;
4492 stats[debuffName] = { dType, 0, gsub(debuff, "^Interface\\Icons\\(.+)$", "%1") };
4493 if ( CastParty_AddDebuff ) then
4494 CastParty_AddDebuff(uId, dType);
4495 end
4496 if ( tempOptions["NotifyDebuffs"]["main"] and debuffName ~= CT_RA_RECENTLYBANDAGED and debuffName ~= CT_RA_MINDVISION and debuffType["id"] ~= -1 ) then
4497 local currPos = CT_RA_CurrPositions[name];
4498 if ( currPos ) then
4499 if ( tempOptions["NotifyDebuffs"][currPos[1]] and tempOptions["NotifyDebuffsClass"][CT_RA_ClassPositions[UnitClass(uId)]] ) then
4500 CT_RA_AddToQueue(dType, uId);
4501 CT_RA_AddDebuffMessage(debuffName, dType, name);
4502 end
4503 end
4504 end
4505 end
4506 end
4507 end
4508 debuff = UnitDebuff(unit, num+1);
4509 end
4510 for k, v in oldAuras do
4511 stats[k] = nil;
4512 end
4513 end
4514  
4515 function CT_RA_ShowHideDebuffs()
4516 local tempOptions = CT_RAMenu_Options["temp"];
4517 tempOptions["ShowDebuffs"] = not tempOptions["ShowDebuffs"];
4518 if ( tempOptions["ShowDebuffs"] ) then
4519 UIDropDownMenu_SetSelectedID(CT_RAMenuFrameBuffsBuffsDropDown, 2);
4520 CT_RAMenuFrameBuffsBuffsDropDownText:SetText("Show debuffs");
4521 elseif ( tempOptions["ShowBuffsDebuffed"] ) then
4522 UIDropDownMenu_SetSelectedID(CT_RAMenuFrameBuffsBuffsDropDown, 3);
4523 CT_RAMenuFrameBuffsBuffsDropDownText:SetText("Show buffs until debuffed");
4524 else
4525 UIDropDownMenu_SetSelectedID(CT_RAMenuFrameBuffsBuffsDropDown, 1);
4526 CT_RAMenuFrameBuffsBuffsDropDownText:SetText("Show buffs");
4527 end
4528 CT_RA_UpdateRaidGroup(2);
4529 end
4530  
4531 -- Thanks to Darco for the idea & some of the code
4532 CT_RA_OldChatFrame_OnEvent = ChatFrame_OnEvent;
4533 function CT_RA_NewChatFrame_OnEvent(event)
4534 if ( event == "CHAT_MSG_SYSTEM" ) then
4535 local iStart, iEnd, sName, iID, iDays, iHours, iMins, iSecs = string.find(arg1, "(.+) %(ID=(%w+)%): (%d+)d (%d+)h (%d+)m (%d+)s");
4536 if ( sName ) then
4537 local table = date("*t");
4538 table["sec"] = table["sec"] + (tonumber(iDays) * 86400) + (tonumber(iHours) * 3600) + (tonumber(iMins) * 60) + iSecs;
4539 arg1 = arg1 .. " ("..date("%A %b %d, %I:%M%p", time(table)) .. ")";
4540 end
4541 elseif ( event == "CHAT_MSG_WHISPER_INFORM" ) then
4542 if ( arg1 == "<CTRaid> You are already grouped." or string.find(arg1, "<CTRaid> Quiet mode is enabled in the raid%. Please be quiet%. %d+ seconds remaining%.") ) then
4543 return;
4544 end
4545 end
4546 CT_RA_OldChatFrame_OnEvent(event);
4547 end
4548  
4549 ChatFrame_OnEvent = CT_RA_NewChatFrame_OnEvent;
4550  
4551 local oldDialogs = { };
4552 oldDialogs["RESURRECTSHOW"] = StaticPopupDialogs["RESURRECT"].OnShow;
4553 oldDialogs["RESURRECT_NO_SICKNESSSHOW"] = StaticPopupDialogs["RESURRECT_NO_SICKNESS"].OnShow;
4554 oldDialogs["RESURRECT_NO_TIMERSHOW"] = StaticPopupDialogs["RESURRECT_NO_TIMER"].OnShow;
4555 oldDialogs["DEATHSHOW"] = StaticPopupDialogs["DEATH"].OnShow;
4556  
4557 StaticPopupDialogs["RESURRECT"].OnShow = function() oldDialogs["RESURRECTSHOW"]() CT_RA_AddMessage("RESSED") end;
4558 StaticPopupDialogs["RESURRECT_NO_SICKNESS"].OnShow = function() oldDialogs["RESURRECT_NO_SICKNESSSHOW"]() CT_RA_AddMessage("RESSED") end;
4559 StaticPopupDialogs["RESURRECT_NO_TIMER"].OnShow = function() oldDialogs["RESURRECT_NO_TIMERSHOW"]() CT_RA_AddMessage("RESSED") end;
4560 StaticPopupDialogs["RESURRECT"].OnHide = function() CT_RA_AddMessage("NORESSED") end;
4561 StaticPopupDialogs["RESURRECT_NO_SICKNESS"].OnHide = function() CT_RA_AddMessage("NORESSED") end;
4562 StaticPopupDialogs["RESURRECT_NO_TIMER"].OnHide = function() if ( not StaticPopup_FindVisible("DEATH") ) then CT_RA_AddMessage("NORESSED") end end;
4563 StaticPopupDialogs["DEATH"].OnShow = function() oldDialogs["DEATHSHOW"]() if ( HasSoulstone() ) then CT_RA_AddMessage("CANRES") end end;
4564  
4565 CT_RA_OldStaticPopup_OnShow = StaticPopup_OnShow;
4566 function CT_RA_NewStaticPopup_OnShow()
4567 if ( this.which and strsub(this.which, 1, 9) == "RESURRECT" ) then
4568 CT_RA_AddMessage("RESSED");
4569 end
4570 CT_RA_OldStaticPopup_OnShow();
4571 end
4572 StaticPopup_OnShow = CT_RA_NewStaticPopup_OnShow;
4573  
4574 function CT_RA_ResFrame_DropDown_OnClick()
4575 local tempOptions = CT_RAMenu_Options["temp"];
4576 if ( this.id == 2 ) then
4577 tempOptions["LockMonitor"] = not tempOptions["LockMonitor"];
4578 elseif ( this.id == 4 ) then
4579 tempOptions["ShowMonitor"] = nil;
4580 CT_RA_ResFrame:Hide();
4581 end
4582 end
4583  
4584 function CT_RA_ResFrame_InitButtons()
4585 local tempOptions = CT_RAMenu_Options["temp"];
4586 local dropdown, info;
4587 if ( UIDROPDOWNMENU_OPEN_MENU ) then
4588 dropdown = getglobal(UIDROPDOWNMENU_OPEN_MENU);
4589 else
4590 dropdown = this;
4591 end
4592  
4593 info = {};
4594 info.text = "Resurrection Monitor";
4595 info.isTitle = 1;
4596 info.justifyH = "CENTER";
4597 info.notCheckable = 1;
4598 UIDropDownMenu_AddButton(info);
4599  
4600 info = { };
4601 if ( tempOptions["LockMonitor"] ) then
4602 info.text = "Unlock Window";
4603 else
4604 info.text = "Lock Window";
4605 end
4606 info.notCheckable = 1;
4607 info.func = CT_RA_ResFrame_DropDown_OnClick;
4608 UIDropDownMenu_AddButton(info);
4609  
4610 info = { };
4611 info.text = "Background Color";
4612 info.hasColorSwatch = 1;
4613 info.hasOpacity = 1;
4614 if ( tempOptions["RMBG"] ) then
4615 info.r = ( tempOptions["RMBG"].r );
4616 info.g = ( tempOptions["RMBG"].g );
4617 info.b = ( tempOptions["RMBG"].b );
4618 info.opacity = ( tempOptions["RMBG"].a );
4619 else
4620 info.r = 0;
4621 info.g = 0;
4622 info.b = 1;
4623 info.opacity = 0.5;
4624 end
4625 info.notClickable = 1;
4626 info.swatchFunc = CT_RA_ResFrame_DropDown_SwatchFunc;
4627 info.opacityFunc = CT_RA_ResFrame_DropDown_OpacityFunc;
4628 info.cancelFunc = CT_RA_ResFrame_DropDown_CancelFunc;
4629 info.notCheckable = 1;
4630 UIDropDownMenu_AddButton(info);
4631  
4632 info = { };
4633 info.text = "Hide";
4634 info.notCheckable = 1;
4635 info.func = CT_RA_ResFrame_DropDown_OnClick;
4636 UIDropDownMenu_AddButton(info);
4637  
4638 end
4639  
4640 function CT_RA_ResFrame_DropDown_SwatchFunc()
4641 local tempOptions = CT_RAMenu_Options["temp"];
4642 local r, g, b = ColorPickerFrame:GetColorRGB();
4643 if ( not tempOptions["RMBG"] ) then
4644 tempOptions["RMBG"] = { ["r"] = r, ["g"] = g, ["b"] = b, ["a"] = 0 };
4645 else
4646 tempOptions["RMBG"]["r"] = r;
4647 tempOptions["RMBG"]["g"] = g;
4648 tempOptions["RMBG"]["b"] = b;
4649 end
4650 CT_RA_ResFrame:SetBackdropColor(r, g, b, tempOptions["RMBG"]["a"]);
4651 CT_RA_ResFrame:SetBackdropBorderColor(1, 1, 1, tempOptions["RMBG"]["a"]);
4652 end
4653  
4654 function CT_RA_ResFrame_DropDown_OpacityFunc()
4655 local tempOptions = CT_RAMenu_Options["temp"];
4656 local r, g, b = 1, 1, 1;
4657 if ( tempOptions["RMBG"] ) then
4658 r, g, b = tempOptions["RMBG"].r, tempOptions["RMBG"].g, tempOptions["RMBG"].b;
4659 end
4660 local a = OpacitySliderFrame:GetValue();
4661 tempOptions["RMBG"]["a"] = a;
4662 CT_RA_ResFrame:SetBackdropColor(r, g, b, a);
4663 CT_RA_ResFrame:SetBackdropBorderColor(1, 1, 1, a);
4664 end
4665  
4666 function CT_RA_ResFrame_DropDown_CancelFunc(val)
4667 local tempOptions = CT_RAMenu_Options["temp"];
4668 tempOptions["RMBG"] = {
4669 ["r"] = val.r,
4670 ["g"] = val.g,
4671 ["b"] = val.b,
4672 ["a"] = val.opacity
4673 };
4674 CT_RA_ResFrame:SetBackdropColor(val.r, val.g, val.b, val.opacity);
4675 CT_RA_ResFrame:SetBackdropBorderColor(1, 1, 1, val.opacity);
4676 end
4677  
4678 function CT_RA_ResFrame_OnLoad()
4679 UIDropDownMenu_Initialize(this, CT_RA_ResFrame_InitButtons, "MENU");
4680 end
4681  
4682 function CT_RA_SendReady()
4683 CT_RA_AddMessage("READY");
4684 end
4685  
4686 function CT_RA_SendNotReady()
4687 CT_RA_AddMessage("NOTREADY");
4688 end
4689  
4690 function CT_RA_SendYes()
4691 CT_RA_AddMessage("VOTEYES");
4692 end
4693  
4694 function CT_RA_SendNo()
4695 CT_RA_AddMessage("VOTENO");
4696 end
4697  
4698 function CT_RA_SendRly()
4699 CT_RA_AddMessage("YARLY");
4700 end
4701  
4702 function CT_RA_SendNoRly()
4703 CT_RA_AddMessage("NORLY");
4704 end
4705  
4706 function CT_RA_ReadyFrame_OnUpdate(elapsed)
4707 if ( this.hide ) then
4708 this.hide = this.hide - elapsed;
4709 if ( this.hide <= 0 ) then
4710 this:Hide();
4711 end
4712 end
4713 end
4714  
4715 function CT_RA_ToggleGroupSort(skipCustom)
4716 local tempOptions = CT_RAMenu_Options["temp"];
4717 if ( tempOptions["SORTTYPE"] == "group" ) then
4718 CT_RA_SetSortType("class");
4719 elseif ( tempOptions["SORTTYPE"] == "class" and not skipCustom ) then
4720 CT_RA_SetSortType("custom");
4721 else
4722 CT_RA_SetSortType("group");
4723 end
4724  
4725 CT_RA_UpdateRaidGroup(3);
4726 CT_RA_UpdateMTs();
4727 CT_RA_UpdatePTs();
4728 CT_RAOptions_Update();
4729 end
4730  
4731 function CT_RA_SetSortType(sort_type)
4732 local tempOptions = CT_RAMenu_Options["temp"];
4733 if ( sort_type == "class" ) then
4734 tempOptions["SORTTYPE"] = "class";
4735 if ( CT_RAMenuFrameGeneralMiscDropDown and CT_RAMenuFrame:IsVisible() ) then
4736 UIDropDownMenu_SetSelectedID(CT_RAMenuFrameGeneralMiscDropDown, 2);
4737 end
4738 if ( CT_RAMenuFrameGeneralMiscDropDownText ) then
4739 CT_RAMenuFrameGeneralMiscDropDownText:SetText("Class");
4740 end
4741 elseif ( sort_type == "custom" ) then
4742 tempOptions["SORTTYPE"] = "custom";
4743 if ( CT_RAMenuFrameGeneralMiscDropDown and CT_RAMenuFrame:IsVisible() ) then
4744 UIDropDownMenu_SetSelectedID(CT_RAMenuFrameGeneralMiscDropDown, 3);
4745 end
4746 if ( CT_RAMenuFrameGeneralMiscDropDownText ) then
4747 CT_RAMenuFrameGeneralMiscDropDownText:SetText("Custom");
4748 end
4749 elseif ( sort_type == "virtual" ) then
4750 tempOptions["SORTTYPE"] = "virtual";
4751 if ( CT_RAMenuFrameGeneralMiscDropDown and CT_RAMenuFrame:IsVisible() ) then
4752 UIDropDownMenu_SetSelectedID(CT_RAMenuFrameGeneralMiscDropDown, 4);
4753 end
4754 if ( CT_RAMenuFrameGeneralMiscDropDownText ) then
4755 CT_RAMenuFrameGeneralMiscDropDownText:SetText("Virtual");
4756 end
4757 else
4758 tempOptions["SORTTYPE"] = "group";
4759 if ( CT_RAMenuFrameGeneralMiscDropDown and CT_RAMenuFrame:IsVisible() ) then
4760 UIDropDownMenu_SetSelectedID(CT_RAMenuFrameGeneralMiscDropDown, 1);
4761 end
4762 if ( CT_RAMenuFrameGeneralMiscDropDownText ) then
4763 CT_RAMenuFrameGeneralMiscDropDownText:SetText("Group");
4764 end
4765 end
4766 end
4767  
4768 function CT_RA_DragAllWindows(start)
4769 local id = this:GetID();
4770 if ( start ) then
4771 local group = getglobal("CT_RAGroupDrag" .. id);
4772 local x, y = group:GetLeft(), group:GetTop();
4773  
4774 if ( not x or not y ) then
4775 return;
4776 end
4777 for i = 1, 8, 1 do
4778 if ( i ~= id ) then
4779 local oGroup = getglobal("CT_RAGroup" .. i);
4780 local oX, oY = oGroup:GetLeft(), oGroup:GetTop();
4781 if ( oX and oY ) then
4782 oGroup:ClearAllPoints();
4783 oGroup:SetPoint("TOPLEFT", "CT_RAGroupDrag" .. id, "TOPLEFT", oX-x, oY-y);
4784 end
4785 end
4786 end
4787 else
4788 for i = 1, 8, 1 do
4789 if ( i ~= id ) then
4790 local oGroup = getglobal("CT_RAGroupDrag" .. id);
4791 local oX, oY = oGroup:GetLeft(), oGroup:GetTop();
4792 if ( oX and oY ) then
4793 oGroup:ClearAllPoints();
4794 oGroup:SetPoint("TOPLEFT", "UIParent", "TOPLEFT", oX, oY-UIParent:GetTop());
4795 end
4796 end
4797 end
4798 end
4799 end
4800  
4801 function CT_RA_CheckGroups()
4802 if ( GetNumRaidMembers() == 0 ) then
4803 return;
4804 end
4805 local numPartyMembers = GetNumPartyMembers();
4806 if ( not CT_RA_PartyMembers ) then
4807 CT_RA_PartyMembers = { };
4808 if ( UnitName("party" .. numPartyMembers) ) then
4809 for i = 1, numPartyMembers, 1 do
4810 CT_RA_PartyMembers[UnitName("party"..i)] = i;
4811 end
4812 end
4813 return;
4814 end
4815 local joined, left, numleft, numjoin = "", "", 0, 0;
4816 if ( not UnitName("party" .. numPartyMembers) and numPartyMembers > 0 ) then
4817 CT_RA_PartyMembers = { };
4818 return;
4819 end
4820 for i = 1, numPartyMembers, 1 do
4821 local uName = UnitName("party" .. i);
4822 if ( uName and not CT_RA_PartyMembers[uName] ) then
4823 if ( numjoin > 0 ) then
4824 joined = joined .. "|r, |c00FFFFFF";
4825 end
4826 joined = joined .. uName;
4827 numjoin = numjoin + 1;
4828 end
4829 CT_RA_PartyMembers[uName] = nil;
4830 end
4831  
4832 for k, v in CT_RA_PartyMembers do
4833 if ( numleft > 0 ) then
4834 left = left .. "|r, |c00FFFFFF";
4835 end
4836 left = left .. k;
4837 numleft = numleft + 1;
4838 end
4839 local tempOptions = CT_RAMenu_Options["temp"];
4840 if ( tempOptions["NotifyGroupChange"] and ( numjoin > 0 or numleft > 0 ) ) then
4841 if ( tempOptions["NotifyGroupChangeSound"] ) then
4842 PlaySoundFile("Sound\\Spells\\Thorns.wav");
4843 end
4844 if ( numjoin > 1 ) then
4845 CT_RA_Print("<CTRaid> |c00FFFFFF" .. joined .. "|r have joined your party.", 1, 0.5, 0);
4846 elseif ( numjoin == 1 ) then
4847 CT_RA_Print("<CTRaid> |c00FFFFFF" .. joined .. "|r has joined your party.", 1, 0.5, 0);
4848 end
4849 if ( numleft > 1 ) then
4850 CT_RA_Print("<CTRaid> |c00FFFFFF" .. left .. "|r have left your party.", 1, 0.5, 0);
4851 elseif ( numleft == 1 ) then
4852 CT_RA_Print("<CTRaid> |c00FFFFFF" .. left .. "|r has left your party.", 1, 0.5, 0);
4853 end
4854 end
4855 CT_RA_PartyMembers = { };
4856 for i = 1, numPartyMembers, 1 do
4857 local uName = UnitName("party" .. i);
4858 if ( uName ) then
4859 CT_RA_PartyMembers[uName] = 1;
4860 end
4861 end
4862 end
4863  
4864 function CT_RA_Emergency_UpdateHealth()
4865 local tempOptions = CT_RAMenu_Options["temp"];
4866 local numRaidMembers = GetNumRaidMembers();
4867 if ( not tempOptions["ShowEmergency"] or ( numRaidMembers == 0 and not tempOptions["ShowEmergencyOutsideRaid"] ) ) then
4868 CT_RA_EmergencyFrame:Hide();
4869 return;
4870 else
4871 CT_RA_EmergencyFrame:Show();
4872 end
4873 for i = 1, 5, 1 do
4874 CT_RA_EmergencyFrame["frame"..i]:Hide();
4875 end
4876 CT_RA_EmergencyFrame.maxPercent = nil;
4877 local healthThreshold = tempOptions["EMThreshold"];
4878 if ( not healthThreshold ) then
4879 healthThreshold = 0.9;
4880 end
4881 CT_RA_Emergency_Units = { };
4882 local health;
4883 if ( not tempOptions["ShowEmergencyParty"] and GetNumRaidMembers() > 0 ) then
4884 health = CT_RA_Emergency_RaidHealth;
4885 health = { };
4886 local numMembers = GetNumRaidMembers();
4887 for i = 1, numMembers, 1 do
4888 local uId = "raid" .. i;
4889 local curr, max = UnitHealth(uId), UnitHealthMax(uId);
4890 if ( curr and max and curr/max <= healthThreshold ) then
4891 tinsert(health, { curr, max, uId, i, curr/max });
4892 end
4893 end
4894 else
4895 health = { };
4896 for i = 1, GetNumPartyMembers(), 1 do
4897 local uId = "party" .. i;
4898 local curr, max = UnitHealth(uId), UnitHealthMax(uId);
4899 if ( curr and max and curr/max <= healthThreshold) then
4900 tinsert(health, { curr, max, uId, nil, curr/max });
4901 end
4902 end
4903 local curr, max = UnitHealth("player"), UnitHealthMax("player");
4904 if ( curr/max <= healthThreshold ) then
4905 tinsert(health, { curr, max, "player", nil, curr/max });
4906 end
4907 end
4908  
4909 table.sort(
4910 health,
4911 function(v1, v2)
4912 return v1[5] < v2[5];
4913 end
4914 );
4915 CT_RA_EmergencyFrameTitle:Show();
4916 CT_RA_EmergencyFrameDrag:Show();
4917 local nextFrame = 0;
4918 for k, v in health do
4919 if ( not UnitIsDead(v[3]) and not UnitIsGhost(v[3]) and UnitIsConnected(v[3]) and UnitIsVisible(v[3]) and ( not CT_RA_Stats[UnitName(v[3])] or not CT_RA_Stats[UnitName(v[3])]["Dead"] ) and ( not tempOptions["EMClasses"] or not tempOptions["EMClasses"][UnitClass(v[3])] ) ) then
4920 local name, rank, subgroup, level, class, fileName;
4921 local obj = CT_RA_EmergencyFrame["frame" .. (nextFrame+1)];
4922 if ( GetNumRaidMembers() > 0 and not tempOptions["ShowEmergencyParty"] and v[4] ) then
4923 name, rank, subgroup, level, class, fileName = GetRaidRosterInfo(v[4]);
4924 local colors = RAID_CLASS_COLORS[fileName];
4925 if ( colors ) then
4926 obj.Name:SetTextColor(colors.r, colors.g, colors.b);
4927 end
4928 else
4929 obj.Name:SetTextColor(1, 1, 1);
4930 end
4931 if ( not subgroup or not tempOptions["EMGroups"] or not tempOptions["EMGroups"][subgroup] ) then
4932 nextFrame = nextFrame + 1;
4933 obj:Show();
4934 CT_RA_EmergencyFrame.maxPercent = v[5];
4935 CT_RA_Emergency_Units[UnitName(v[3])] = 1;
4936 obj.ClickFrame.unitid = v[3];
4937 obj.HPBar:SetMinMaxValues(0, v[2]);
4938 obj.HPBar:SetValue(v[1]);
4939 obj.Name:SetText(UnitName(v[3]));
4940 obj.Deficit:SetText(v[1]-v[2]);
4941  
4942 if ( UnitIsUnit(v[3], "player") ) then
4943 obj.HPBar:SetStatusBarColor(1, 0, 0);
4944 obj.HPBG:SetVertexColor(1, 0, 0, tempOptions["BGOpacity"]);
4945 elseif ( UnitInParty(v[3]) ) then
4946 obj.HPBar:SetStatusBarColor(0, 1, 1);
4947 obj.HPBG:SetVertexColor(0, 1, 1, tempOptions["BGOpacity"]);
4948 else
4949 obj.HPBar:SetStatusBarColor(0, 1, 0);
4950 obj.HPBG:SetVertexColor(0, 1, 0, tempOptions["BGOpacity"]);
4951 end
4952 end
4953 end
4954 if ( nextFrame == 5 ) then
4955 break;
4956 end
4957 end
4958 end
4959  
4960 function CT_RA_Emergency_TargetMember(num)
4961 local obj = CT_RA_EmergencyFrame["frame"..num];
4962 if ( obj:IsVisible() and obj.ClickFrame.unitid ) then
4963 TargetUnit(obj.ClickFrame.unitid);
4964 end
4965 end
4966  
4967 function CT_RA_Emergency_OnEnter()
4968 if ( SpellIsTargeting() ) then
4969 SetCursor("CAST_CURSOR");
4970 elseif ( not SpellCanTargetUnit(this.unitid) and SpellIsTargeting() ) then
4971 SetCursor("CAST_ERROR_CURSOR");
4972 end
4973 end
4974  
4975 function CT_RA_Emergency_OnUpdate(elapsed)
4976 this.update = this.update - elapsed;
4977 if ( this.update <= 0 ) then
4978 this.update = 0.1;
4979 if ( this.cursor ) then
4980 if ( SpellIsTargeting() and SpellCanTargetUnit(this.unitid) ) then
4981 SetCursor("CAST_CURSOR");
4982 elseif ( SpellIsTargeting() ) then
4983 SetCursor("CAST_ERROR_CURSOR");
4984 end
4985 end
4986 end
4987 end
4988  
4989 function CT_RA_Emergency_DropDown_OnLoad()
4990 UIDropDownMenu_Initialize(this, CT_RA_Emergency_DropDown_Initialize, "MENU");
4991 end
4992  
4993 function CT_RA_Emergency_DropDown_Initialize()
4994 local tempOptions = CT_RAMenu_Options["temp"];
4995 local dropdown, info;
4996 if ( UIDROPDOWNMENU_OPEN_MENU ) then
4997 dropdown = getglobal(UIDROPDOWNMENU_OPEN_MENU);
4998 else
4999 dropdown = this;
5000 end
5001 if ( UIDROPDOWNMENU_MENU_VALUE == "Classes" ) then
5002 info = {};
5003 info.text = "Classes";
5004 info.isTitle = 1;
5005 info.notCheckable = 1;
5006 UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
5007 for k, v in CT_RA_ClassPositions do
5008 if ( ( k ~= CT_RA_SHAMAN or ( UnitFactionGroup("player") and UnitFactionGroup("player") == "Horde" ) ) and ( k ~= CT_RA_PALADIN or ( UnitFactionGroup("player") and UnitFactionGroup("player") == "Alliance" ) ) ) then
5009 info = {};
5010 info.text = k;
5011 info.value = k;
5012 info.func = CT_RA_Emergency_DropDown_OnClick;
5013 info.checked = ( not tempOptions["EMClasses"] or not tempOptions["EMClasses"][k] );
5014 info.keepShownOnClick = 1;
5015 info.tooltipTitle = "Toggle Class";
5016 info.tooltipText = "Toggles displaying the selected class, allowing you to hide certain classes from the Emergency Monitor.";
5017 UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
5018 end
5019 end
5020 return;
5021 end
5022  
5023 if ( UIDROPDOWNMENU_MENU_VALUE == "Groups" ) then
5024 info = {};
5025 info.text = "Groups";
5026 info.isTitle = 1;
5027 info.notCheckable = 1;
5028 UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
5029 for i = 1, 8, 1 do
5030 info = {};
5031 info.text = "Group " .. i;
5032 info.value = i;
5033 info.func = CT_RA_Emergency_DropDown_OnClick;
5034 info.checked = ( not tempOptions["EMGroups"] or not tempOptions["EMGroups"][i] );
5035 info.keepShownOnClick = 1;
5036 info.tooltipTitle = "Toggle Group";
5037 info.tooltipText = "Toggles displaying the selected group, allowing you to hide certain groups from the Emergency Monitor.";
5038 UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
5039 end
5040 return;
5041 end
5042 info = {};
5043 info.text = "Emergency Monitor";
5044 info.isTitle = 1;
5045 info.notCheckable = 1;
5046 UIDropDownMenu_AddButton(info);
5047  
5048 info = {};
5049 info.text = "Classes";
5050 info.hasArrow = 1;
5051 info.notCheckable = 1;
5052 UIDropDownMenu_AddButton(info);
5053  
5054 info = {};
5055 info.text = "Groups";
5056 info.hasArrow = 1;
5057 info.notCheckable = 1;
5058 UIDropDownMenu_AddButton(info);
5059  
5060 info = { };
5061 info.text = "Background Color";
5062 info.hasColorSwatch = 1;
5063 info.hasOpacity = 1;
5064 if ( tempOptions["EMBG"] ) then
5065 info.r = ( tempOptions["EMBG"].r );
5066 info.g = ( tempOptions["EMBG"].g );
5067 info.b = ( tempOptions["EMBG"].b );
5068 info.opacity = ( tempOptions["EMBG"].a );
5069 else
5070 info.r = 0;
5071 info.g = 0;
5072 info.b = 1;
5073 info.opacity = 0;
5074 end
5075 info.notClickable = 1;
5076 info.swatchFunc = CT_RA_Emergency_DropDown_SwatchFunc;
5077 info.opacityFunc = CT_RA_Emergency_DropDown_OpacityFunc;
5078 info.cancelFunc = CT_RA_Emergency_DropDown_CancelFunc;
5079 info.notCheckable = 1;
5080 UIDropDownMenu_AddButton(info);
5081 end
5082  
5083 function CT_RA_Emergency_DropDown_SwatchFunc()
5084 local tempOptions = CT_RAMenu_Options["temp"];
5085 local r, g, b = ColorPickerFrame:GetColorRGB();
5086 if ( not tempOptions["EMBG"] ) then
5087 tempOptions["EMBG"] = { ["r"] = r, ["g"] = g, ["b"] = b, ["a"] = 0 };
5088 else
5089 tempOptions["EMBG"]["r"] = r;
5090 tempOptions["EMBG"]["g"] = g;
5091 tempOptions["EMBG"]["b"] = b;
5092 end
5093 CT_RA_EmergencyFrame:SetBackdropColor(r, g, b, tempOptions["EMBG"]["a"]);
5094 CT_RA_EmergencyFrame:SetBackdropBorderColor(1, 1, 1, tempOptions["EMBG"]["a"]);
5095 end
5096  
5097 function CT_RA_Emergency_DropDown_OpacityFunc()
5098 local tempOptions = CT_RAMenu_Options["temp"];
5099 local r, g, b = 1, 1, 1;
5100 if ( tempOptions["EMBG"] ) then
5101 r, g, b = tempOptions["EMBG"].r, tempOptions["EMBG"].g, tempOptions["EMBG"].b;
5102 end
5103 local a = OpacitySliderFrame:GetValue();
5104 tempOptions["EMBG"]["a"] = a;
5105 CT_RA_EmergencyFrame:SetBackdropColor(r, g, b, a);
5106 CT_RA_EmergencyFrame:SetBackdropBorderColor(1, 1, 1, a);
5107 end
5108  
5109 function CT_RA_Emergency_DropDown_CancelFunc(val)
5110 local tempOptions = CT_RAMenu_Options["temp"];
5111 tempOptions["EMBG"] = {
5112 ["r"] = val.r,
5113 ["g"] = val.g,
5114 ["b"] = val.b,
5115 ["a"] = val.opacity
5116 };
5117 CT_RA_EmergencyFrame:SetBackdropColor(val.r, val.g, val.b, val.opacity);
5118 CT_RA_EmergencyFrame:SetBackdropBorderColor(1, 1, 1, val.opacity);
5119 end
5120  
5121 function CT_RA_Emergency_DropDown_OnClick()
5122 local tempOptions = CT_RAMenu_Options["temp"];
5123 if ( UIDROPDOWNMENU_MENU_VALUE == "Classes" ) then
5124 if ( not tempOptions["EMClasses"] ) then
5125 tempOptions["EMClasses"] = { };
5126 end
5127 tempOptions["EMClasses"][this.value] = not tempOptions["EMClasses"][this.value];
5128 CT_RA_Emergency_UpdateHealth();
5129 elseif ( UIDROPDOWNMENU_MENU_VALUE == "Groups" ) then
5130 if ( not tempOptions["EMGroups"] ) then
5131 tempOptions["EMGroups"] = { };
5132 end
5133 tempOptions["EMGroups"][this.value] = not tempOptions["EMGroups"][this.value];
5134 CT_RA_Emergency_UpdateHealth();
5135 end
5136 end
5137  
5138 function CT_RA_Emergency_ToggleDropDown()
5139 local left, top = this:GetCenter();
5140 local uileft, uitop = UIParent:GetCenter();
5141 if ( left > uileft ) then
5142 CT_RA_EmergencyFrameDropDown.point = "TOPRIGHT";
5143 CT_RA_EmergencyFrameDropDown.relativePoint = "BOTTOMLEFT";
5144 else
5145 CT_RA_EmergencyFrameDropDown.point = "TOPLEFT";
5146 CT_RA_EmergencyFrameDropDown.relativePoint = "BOTTOMRIGHT";
5147 end
5148 CT_RA_EmergencyFrameDropDown.relativeTo = this:GetName();
5149 ToggleDropDownMenu(1, nil, CT_RA_EmergencyFrameDropDown);
5150 end
5151  
5152 -- RADurability stuff
5153 function CT_RADurability_GetDurability()
5154 local currDur, maxDur, brokenItems = 0, 0, 0;
5155 local itemIds = {
5156 1, 2, 3, 5, 6, 7, 8, 9, 10, 16, 17, 18
5157 };
5158 for k, v in itemIds do
5159 CT_RADurationTooltip:ClearLines();
5160 CT_RADurationTooltip:SetInventoryItem("player", v);
5161 for i = 1, CT_RADurationTooltip:NumLines(), 1 do
5162 local useless, useless, sMin, sMax = string.find(getglobal("CT_RADurationTooltipTextLeft" .. i):GetText() or "", CT_RA_DURABILITY);
5163 if ( sMin and sMax ) then
5164 local iMin, iMax = tonumber(sMin), tonumber(sMax);
5165 if ( iMin == 0 ) then
5166 brokenItems = brokenItems + 1;
5167 end
5168 currDur = currDur + iMin;
5169 maxDur = maxDur + iMax;
5170 break;
5171 end
5172 end
5173 end
5174 return currDur, maxDur, brokenItems;
5175 end
5176  
5177 function CT_RAReagents_GetReagents()
5178 local numItems = 0;
5179 local classes = {
5180 [CT_RA_PRIEST] = {CT_REG_PRIEST , CT_REG_PRIEST_SPELL},
5181 [CT_RA_MAGE] = { CT_REG_MAGE , CT_REG_MAGE_SPELL },
5182 [CT_RA_DRUID] = { CT_REG_DRUID ,CT_REG_DRUID_SPELL },
5183 [CT_RA_WARLOCK] = { CT_REG_WARLOCK },
5184 [CT_RA_PALADIN] = { CT_REG_PALADIN, CT_REG_PALADIN_SPELL },
5185 [CT_RA_SHAMAN] = { CT_REG_SHAMAN, CT_REG_SHAMAN_SPELL }
5186 };
5187 local plClass = classes[UnitClass("player")];
5188 if ( not plClass or ( plClass[2] and not CT_RA_ClassSpells[plClass[2]] ) ) then
5189 return;
5190 end
5191 for i = 0, 4, 1 do
5192 for y = 1, MAX_CONTAINER_ITEMS, 1 do
5193 local link = GetContainerItemLink(i, y);
5194 if ( link ) then
5195 local _, _, name = string.find(link, "%[(.+)%]");
5196 if ( name ) then
5197 if ( plClass and plClass[1] == name ) then
5198 local texture, itemCount, locked, quality, readable = GetContainerItemInfo(i,y);
5199 numItems = numItems + itemCount;
5200 end
5201 end
5202 end
5203 end
5204 end
5205 return numItems;
5206 end
5207  
5208 function CT_RAItem_GetItems(itemName)
5209 local numItems = 0;
5210 for i = 0, 4, 1 do
5211 for y = 1, MAX_CONTAINER_ITEMS, 1 do
5212 local link = GetContainerItemLink(i, y);
5213 if ( link ) then
5214 local _, _, name = string.find(link, "%[(.+)%]");
5215 if ( name == itemName ) then
5216 local texture, itemCount, locked, quality, readable = GetContainerItemInfo(i,y);
5217 numItems = numItems + itemCount;
5218 end
5219 end
5220 end
5221 end
5222 return numItems;
5223 end
5224  
5225 CT_RADurability_Shown = { };
5226 CT_RADurability_Sorting = {
5227 ["curr"] = 4,
5228 [3] = { "a", "a" },
5229 [4] = { "a", "a" }
5230 };
5231 tinsert(UISpecialFrames, "CT_RA_DurabilityFrame");
5232  
5233  
5234 function CT_RADurability_Add(name, info, fileName, ...)
5235 local tbl = { name, info, fileName };
5236 for i = 1, arg.n, 1 do
5237 tinsert(tbl, ( tonumber(arg[i]) or arg[i] ));
5238 end
5239 tinsert(CT_RADurability_Shown, tbl);
5240 CT_RADurability_Sort(CT_RADurability_Sorting["curr"], 1);
5241 CT_RADurability_Update();
5242 end
5243  
5244 function CT_RADurability_Sort(sortBy, maintain)
5245 if ( CT_RADurability_Sorting["curr"] ~= sortBy ) then
5246 CT_RADurability_Sorting[sortBy][1] = CT_RADurability_Sorting[sortBy][2];
5247 end
5248 CT_RADurability_Sorting["curr"] = sortBy;
5249 if ( CT_RADurability_Sorting[sortBy][1] == "a" ) then
5250 if ( not maintain ) then
5251 CT_RADurability_Sorting[sortBy][1] = "b";
5252 end
5253 else
5254 if ( not maintain ) then
5255 CT_RADurability_Sorting[sortBy][1] = "a";
5256 end
5257 end
5258 if ( CT_RADurability_Sorting[sortBy][1] == "b" ) then
5259 table.sort(CT_RADurability_Shown,
5260 function(t1, t2)
5261 if (t1[sortBy] == t2[sortBy] ) then
5262 if ( t1[3] == t2[3] ) then
5263 return t1[1] < t2[1]
5264 else
5265 return t1[3] < t2[3]
5266 end
5267 else
5268 return t1[sortBy] < t2[sortBy]
5269 end
5270 end
5271 );
5272 else
5273 table.sort(CT_RADurability_Shown,
5274 function(t1, t2)
5275 if (t1[sortBy] == t2[sortBy] ) then
5276 if ( t1[3] == t2[3] ) then
5277 return t1[1] < t2[1]
5278 else
5279 return t1[3] < t2[3]
5280 end
5281 else
5282 return t1[sortBy] > t2[sortBy]
5283 end
5284 end
5285 );
5286 end
5287 CT_RADurability_Update();
5288 end
5289  
5290 function CT_RADurability_Update()
5291 local numEntries = getn(CT_RADurability_Shown);
5292 FauxScrollFrame_Update(CT_RA_DurabilityFrameScrollFrame, numEntries, 19, 20);
5293  
5294 for i = 1, 19, 1 do
5295 local button = getglobal("CT_RA_DurabilityFramePlayer" .. i);
5296 local index = i + FauxScrollFrame_GetOffset(CT_RA_DurabilityFrameScrollFrame);
5297 if ( index <= numEntries ) then
5298 if ( numEntries <= 19 ) then
5299 button:SetWidth(275);
5300 else
5301 button:SetWidth(253);
5302 end
5303 if ( CT_RA_DurabilityFrame.type ~= "RARST" or numEntries <= 19 ) then
5304 CT_RA_DurabilityFrameScrollFrame:SetPoint("TOPLEFT", "CT_RA_DurabilityFrame", "TOPLEFT", 19, -27);
5305 getglobal(button:GetName() .. "Resist1"):SetPoint("LEFT", button:GetName(), "LEFT", 127, 0);
5306 CT_RA_DurabilityFrameNameTab:SetWidth(135);
5307 else
5308 CT_RA_DurabilityFrameScrollFrame:SetPoint("TOPLEFT", "CT_RA_DurabilityFrame", "TOPLEFT", 19, -32);
5309 getglobal(button:GetName() .. "Resist1"):SetPoint("LEFT", button:GetName(), "LEFT", 110, 0);
5310 CT_RA_DurabilityFrameNameTab:SetWidth(118);
5311 end
5312 button:Show();
5313 getglobal(button:GetName() .. "Name"):SetText(CT_RADurability_Shown[index][1]);
5314 local color = RAID_CLASS_COLORS[CT_RADurability_Shown[index][3]];
5315 if ( color ) then
5316 getglobal(button:GetName() .. "Name"):SetTextColor(color.r, color.g, color.b);
5317 end
5318 getglobal(button:GetName() .. "Info"):SetText(CT_RADurability_Shown[index][2]);
5319 for i = 1, 5, 1 do
5320 if ( CT_RA_DurabilityFrame.type == "RARST" and CT_RADurability_Shown[index][3+i] ~= -1 ) then
5321 getglobal(button:GetName() .. "Resist" .. i):SetText(CT_RADurability_Shown[index][3+i]);
5322 getglobal(button:GetName() .. "Resist" .. i):Show();
5323 else
5324 getglobal(button:GetName() .. "Resist" .. i):Hide();
5325 end
5326 end
5327 else
5328 button:Hide();
5329 end
5330 end
5331  
5332 end
5333  
5334 CT_RA_CurrDebuffs = { };
5335  
5336 function CT_RA_AddDebuffMessage(name, dType, player)
5337 if ( not dType ) then
5338 return;
5339 end
5340 if ( CT_RADebuff_IgnoreDebuffs[name] ) then
5341 return;
5342 end
5343 if ( CT_RA_CurrDebuffs[name .. "@" .. dType] ) then
5344 if ( not CT_RA_CurrDebuffs[name .. "@" .. dType][3][player] ) then
5345 CT_RA_CurrDebuffs[name .. "@" .. dType][3][player] = 1;
5346 CT_RA_CurrDebuffs[name .. "@" .. dType][2] = CT_RA_CurrDebuffs[name .. "@" .. dType][2] + 1;
5347 CT_RA_CurrDebuffs[name .. "@" .. dType][1] = 0.4;
5348 end
5349 else
5350 CT_RA_CurrDebuffs[name .. "@" .. dType] = {
5351 0.4, 1, {
5352 [player] = 1
5353 },
5354 player
5355 };
5356 end
5357 end
5358  
5359 function CT_RA_RGBToHex(r, g, b)
5360 return format("%.2x%.2x%.2x", floor(r*255), floor(g*255), floor(b*255));
5361 end
5362  
5363 CT_RA_oldRaidFrame_LoadUI = RaidFrame_LoadUI;
5364 function RaidFrame_LoadUI()
5365 CT_RA_oldRaidFrame_LoadUI();
5366 RaidFrameDropDown_Initialize = CT_RATab_newRaidFrameDropDown_Initialize;
5367 end