vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 XPerl_MainTanks = {}
2 MainTankCount = 0
3 local MainTanks = {}
4 local Events = {}
5 local XUnits = {}
6 local XOtherUnits = {}
7 local XFreeUnits = {}
8 local OtherTargetOwners = {}
9 local UpdateTime = 0
10 local FrameExpanded = false
11 local XOtherRows = 0
12 local XGaps = 0
13 local XTitle
14 local MainAssist = nil
15 local XFind = nil
16 local bigwigsSlowDown = 0
17  
18 -- Dup colours used to show which tanks have the same target
19 local MTdupColours = { {r = "0.8", g = "0.2", b = "0.2"},
20 {r = "0.2", g = "0.2", b = "0.8"},
21 {r = "0.8", g = "0.2", b = "0.8"},
22 {r = "0.2", g = "0.8", b = "0.2"},
23 {r = "0.2", g = "0.8", b = "0.8"}}
24  
25 local MAX_UNITS = 50
26 local MAX_OTHER_ROWS = 10
27 local GAP_SPACING = 10
28 XPERL_UNIT_HEIGHT_MIN = 17
29 XPERL_UNIT_HEIGHT_MAX = 30
30 XPERL_UNIT_WIDTH_MIN = 50
31 XPERL_UNIT_WIDTH_MAX = 125
32  
33 if (not XPerlColourTable) then
34 local function MashXX(class)
35 local c = RAID_CLASS_COLORS[class]
36 XPerlColourTable[class] = string.format("|c00%02X%02X%02X", 255 * c.r, 255 * c.g, 255 * c.b)
37 end
38 XPerlColourTable = {}
39 MashXX("HUNTER")
40 MashXX("WARLOCK")
41 MashXX("PRIEST")
42 MashXX("PALADIN")
43 MashXX("MAGE")
44 MashXX("ROGUE")
45 MashXX("DRUID")
46 MashXX("SHAMAN")
47 MashXX("WARRIOR")
48 end
49  
50 -- Although your own "target" is updated immediately, any reference to ourself via our raid id is updated via the server
51 -- So, to cure the slow response times, we check if anything is 'me'. Only direct targets are updated immedately,
52 -- so we don't bother with target's target onwards.
53 local function SpecialCaseUnit(unit)
54 if (unit.unit and (unit.type == "MTT" or unit.type == "OT") and UnitIsUnit("player", unit.unit)) then
55 return "target"
56 else
57 return unit.partyid
58 end
59 end
60  
61 ----------------------------
62 ------- DISPLAY ------------
63 ----------------------------
64 local function UpdateUnit(unit,forcedUpdate)
65  
66 if (forcedUpdate) then
67 local time = GetTime()
68 if (unit.update and time < unit.update + 0.2) then
69 -- Since we catch UNIT_HEALTH changes, we don't need to update always
70 return
71 end
72 end
73  
74 unit.update = GetTime()
75  
76 local xunit = SpecialCaseUnit(unit)
77  
78 local name = UnitName(xunit)
79 local text = getglobal(unit:GetName().."_Name")
80 local bar = getglobal(unit:GetName().."_HealthBar")
81 local percent = getglobal(unit:GetName().."_HealthBarText")
82 local barBG = getglobal(unit:GetName().."_HealthBarBG")
83 local combat = getglobal(unit:GetName().."_Combat")
84 local warning = getglobal(unit:GetName().."_Warning")
85 local raidIcon = getglobal(unit:GetName().."_RaidIcon")
86 local percBar
87  
88 barBG:Show()
89  
90 if (name and name ~= UNKNOWNOBJECT) then
91 -- Name
92 text:SetText(name)
93 text:SetPoint("BOTTOMRIGHT", unit, "TOPRIGHT", 0, -12)
94  
95 local remCount = 1
96 while ((text:GetStringWidth() >= (unit:GetWidth() - 2)) and (string.len(name) > remCount)) do
97 name = string.sub(name, 1, string.len(name) - remCount)..".."
98 remCount = 3
99 text:SetText(name)
100 end
101  
102 if (UnitPlayerControlled(xunit)) then
103 XPerl_ColourFriendlyUnit(text, xunit)
104 else
105 XPerl_SetUnitNameColor(xunit, text)
106 end
107  
108 -- Health
109 local healthMax = UnitHealthMax(xunit)
110 local health = UnitHealth(xunit)
111 percBar = health / healthMax
112 local perc = percBar * 100
113  
114 bar:SetMinMaxValues(0, healthMax)
115 bar:SetValue(health)
116  
117 if (UnitIsDead(xunit)) then
118 percent:SetText(XPERL_LOC_DEAD)
119 else
120 percent:SetText(math.floor(perc + 0.5).."%")
121 end
122 if (XPerlConfigHelper.UnitHeight < 23) then
123 percent:Hide()
124 else
125 percent:Show()
126 end
127  
128 if (unit.type == "MTT" or unit.type == "OT") then
129 if (BigWigsTargetMonitor) then
130 if (bigwigsSlowDown == 0) then
131 BigWigsTargetMonitor:TargetCheck(xunit)
132 end
133 end
134  
135 local index = GetRaidTargetIndex(xunit)
136 if (index) then
137 SetRaidTargetIconTexture(raidIcon, index)
138 raidIcon:Show()
139 else
140 raidIcon:Hide()
141 end
142 else
143 raidIcon:Hide()
144 end
145 else
146 text:SetPoint("BOTTOMRIGHT", -2, 1)
147  
148 if (unit.type == "MTT") then
149 name = UnitName(unit.unit)
150  
151 if (name) then
152 XPerl_ColourFriendlyUnit(text, unit.unit)
153 text:SetText(string.format(XPERL_XS_TARGET, name))
154 barBG:Hide()
155 end
156 else
157 text:SetText(XPERL_NO_TARGET)
158 text:SetTextColor(0.5, 0.5, 0.5, 1)
159 end
160 bar:SetMinMaxValues(0, 1)
161 bar:SetValue(0)
162 percBar = 0
163 percent:Hide()
164 raidIcon:Hide()
165 end
166  
167 if (UnitAffectingCombat(xunit)) then
168 combat:Show()
169 else
170 combat:Hide()
171 end
172  
173 if (UnitIsCharmed(xunit)) then
174 warning:Show()
175 else
176 warning:Hide()
177 end
178  
179 XPerl_SetSmoothBarColor (bar, percBar)
180 end
181  
182 -- XPerl_RaidHelp_Show
183 function XPerl_RaidHelp_Show()
184 XPerlConfigHelper.RaidHelper = 1
185 XPerl_EnableDisable()
186 return true
187 end
188  
189 -- XPerl_OnClick
190 function XPerl_OnClick(button)
191 local unitid = this.partyid
192  
193 if (UnitName(unitid) or (button == "RightButton" and this.unit)) then
194 if (XPerl_OnClick_Handler) then
195 if (not XPerl_OnClick_Handler(button, unitid)) then
196 if (button == "RightButton" and this.unit) then
197 XPerl_OnClick_Handler("LeftButton", this.unit)
198 end
199 end
200 else
201 if (button == "RightButton" and this.unit and not SpellIsTargetting()) then
202 button = "LeftButton"
203 end
204  
205 if (button == "LeftButton") then
206 if (SpellIsTargeting()) then
207 SpellTargetUnit(unitid)
208 return true
209 elseif (CursorHasItem()) then
210 if (UnitIsUnit("player", unitid)) then
211 AutoEquipCursorItem()
212 else
213 DropItemOnUnit(unitid)
214 end
215 return true
216 else
217 TargetUnit(unitid)
218 return true
219 end
220  
221 elseif (button == "RightButton") then
222 if (SpellIsTargeting()) then
223 SpellStopTargeting()
224 return true
225 elseif (CursorHasItem()) then
226 ClearCursor()
227 return true
228 else
229 TargetUnit(this.unit)
230 end
231 end
232 end
233 end
234 end
235  
236 -- XPerl_OnEnter
237 function XPerl_OnEnter()
238  
239 local x = XPerl_Frame:GetCenter()
240 local a1, a2 = "ANCHOR_LEFT", "ANCHOR_TOPLEFT"
241 if ( x < (GetScreenWidth() / 2)) then
242 a1, a2 = "ANCHOR_RIGHT", "ANCHOR_TOPRIGHT"
243 end
244  
245 if (SpellIsTargeting()) then
246 if (SpellCanTargetUnit(this.partyid)) then
247 SetCursor("CAST_CURSOR")
248 else
249 SetCursor("CAST_ERROR_CURSOR")
250 end
251 end
252  
253 if (XPerlConfigHelper.Tooltips == 1) then
254 if (this.partyid and UnitName(this.partyid)) then
255 GameTooltip:SetOwner(this, a1)
256 GameTooltip:SetUnit(this.partyid)
257  
258 if (this.unit and (this.type == "MTT" or this.type == "OT")) then
259 local extra = 10
260 if (TinyTipExtrasExists) then
261 extra = 20
262 end
263  
264 XPerl_BottomTip:SetOwner(GameTooltip, a2, 0, extra)
265 XPerl_BottomTip:SetUnit(this.unit)
266 XPerl_BottomTip:SetBackdropColor(0.1, 0.4, 0.1, 0.75)
267 end
268 else
269 if (this.type == "MTT" or this.type == "OT") then
270 GameTooltip:SetOwner(this, a1)
271 GameTooltip:SetUnit(this.unit)
272 GameTooltip:SetBackdropColor(0.1, 0.4, 0.1, 0.75)
273 end
274 end
275 end
276 end
277  
278 -- ListChanged1
279 local function ListChanged1(list1, list2)
280 if (getn(list1) == getn(list2)) then
281 for k,v in pairs(list1) do
282 if (v == list2[k]) then
283 return true
284 end
285 end
286 return false
287 end
288 return true
289 end
290  
291 -- XPerl_SetupFrameSimple
292 function XPerl_SetupFrameSimple(argFrame, alpha)
293 argFrame:SetBackdropBorderColor(0.5, 0.5, 0.5, alpha or 0.8)
294 argFrame:SetBackdropColor(0, 0, 0, alpha or 0.8)
295 end
296  
297 -- AllocateUnit
298 local AllocateUnitNum = 0
299 local LastUnitWarning
300 local function AllocateUnit(list, parent)
301  
302 local unit = XFreeUnits[1]
303 if (unit) then
304 tremove(XFreeUnits, 1)
305 tinsert(list, unit)
306 unit:SetParent(parent)
307 else
308 if (AllocateUnitNum < MAX_UNITS) then
309 AllocateUnitNum = AllocateUnitNum + 1
310 unit = CreateFrame("Button", "XPerl_Unit"..AllocateUnitNum, parent, "XPerl_UnitTemplate")
311  
312 if (unit) then
313 XPerl_SetupFrameSimple(unit, XPerlConfigHelper.Background_Transparency)
314 unit:SetAlpha(XPerlConfigHelper.Targets_Transparency)
315 tinsert(list, unit)
316  
317 if (XPerl_RegisterHighlight) then
318 XPerl_RegisterHighlight(unit, 3)
319 else
320 local tex = unit:GetHighlightTexture()
321 tex:SetVertexColor(0.86, 0.82, 0.41)
322 end
323 else
324 XPerl_Notice("Error creating frame called 'XPerl_Unit"..AllocateUnitNum.."' from template 'XPerl_UnitTemplate'")
325 end
326 else
327 if (not LastUnitWarning or GetTime() > LastUnitWarning + 600) then
328 LastUnitWarning = GetTime()
329 XPerl_Notice("Maximum number of units reached ("..MAX_UNITS..")")
330 end
331 end
332 end
333  
334 if (unit) then
335 if (XPerl_GetBarTexture) then
336 local tex = XPerl_GetBarTexture()
337 getglobal(unit:GetName().."_HealthBarTex"):SetTexture(tex)
338  
339 if (XPerlConfig.BackgroundTextures == 1) then
340 getglobal(unit:GetName().."_HealthBarBG"):SetTexture(tex)
341 else
342 getglobal(unit:GetName().."_HealthBarBG"):SetTexture("Interface\\TargetingFrame\\UI-StatusBar")
343 end
344 end
345  
346 local t = getglobal(unit:GetName().."_HealthBarText"); t:Hide()
347 t = getglobal(unit:GetName().."_Label"); t:SetText(""); t:Hide()
348 t = getglobal(unit:GetName().."_Name"); t:Show()
349  
350 XPerl_SetupFrameSimple(unit, XPerlConfigHelper.Background_Transparency)
351  
352 unit:SetScale(1)
353 unit:SetWidth(XPerlConfigHelper.UnitWidth)
354 unit:SetHeight(XPerlConfigHelper.UnitHeight)
355  
356 local bar = getglobal(unit:GetName().."_HealthBar")
357 bar:ClearAllPoints()
358 if (XPerlConfigHelper.UnitHeight > 16) then
359 bar:SetPoint("TOPLEFT", 3, -14)
360 bar:SetPoint("BOTTOMRIGHT", -3, 2)
361 else
362 bar:SetPoint("TOPLEFT", 4, -4)
363 bar:SetPoint("BOTTOMRIGHT", -4, 4)
364 end
365  
366 unit:Show()
367 end
368  
369 return unit
370 end
371  
372 -- Remove units from list and place back into available unit pool
373 local function UnallocateUnits(list)
374  
375 while (getn(list) > 0) do
376 local unit = list[1]
377  
378 unit:ClearAllPoints()
379 unit:Hide()
380  
381 unit.partyid = nil
382 unit.unit = nil
383 unit.OtherTarget = nil
384 unit.collapseable = nil
385 unit.type = nil
386  
387 tremove(list, 1)
388 tinsert(XFreeUnits, unit)
389 end
390 end
391  
392 -- XPerl_HelperBarTextures
393 if (XPerl_GetBarTexture) then
394 function XPerl_HelperBarTextures(tex)
395 local function UnitTex(v, tex)
396 local f = getglobal(v:GetName().."_HealthBarTex")
397 f:SetTexture(tex)
398 f = getglobal(v:GetName().."_HealthBarBG")
399 if (XPerlConfig and XPerlConfig.BackgroundTextures == 1) then
400 f:SetTexture(tex)
401 else
402 f:SetTexture("Interface\\TargetingFrame\\UI-StatusBar")
403 end
404 end
405  
406 XPerl_MyThreatTex:SetTexture(tex)
407 XPerl_MyThreatBG:SetTexture(tex)
408  
409 for k,v in pairs(XUnits) do
410 UnitTex(v, tex)
411 end
412 for k,v in pairs(XOtherUnits) do
413 UnitTex(v, tex)
414 end
415 for k,v in pairs(XFreeUnits) do
416 UnitTex(v, tex)
417 end
418 end
419 end
420  
421 -- XPerl_SetMainAssist
422 function XPerl_SetMainAssist(msg, ma, quiet)
423  
424 if (ma == "broadcast") then
425 if (IsRaidOfficer()) then
426 SendAddonMessage(XPERL_COMMS_PREFIX, "MA "..UnitName("player").." "..UnitName(MainAssist.unit), "RAID")
427 else
428 XPerl_Message("You must be promoted to set the Main Assist")
429 end
430 else
431 if (not ma) then
432 ma = 0
433 end
434  
435 if (string.lower(ma) == "target") then
436 ma = UnitName(ma)
437 end
438  
439 if (ma) then
440 for i,tank in pairs(MainTanks) do
441 if (string.lower(UnitName("raid"..tank[1])) == string.lower(ma)) then
442 ma = i
443 break
444 end
445 end
446  
447 ma = tonumber(ma)
448  
449 if (MainTanks[ma]) then
450 local maUnit = "raid"..MainTanks[ma][1]
451 MainAssist = {unit = maUnit, name = UnitName(maUnit)}
452 local _, class = UnitClass(maUnit)
453 MainAssist.class = class
454 else
455 MainAssist = nil
456 end
457 else
458 MainAssist = nil
459 end
460  
461 if (MainAssist) then
462 XPerlConfigHelper.LastMainAssist = MainAssist.name
463 else
464 XPerlConfigHelper.LastMainAssist = nil
465 end
466  
467 if (not quiet) then
468 if (MainAssist) then
469 XPerl_Message("Main Assist set to "..XPerlColourTable[MainAssist.class]..MainAssist.name)
470 else
471 XPerl_Message("Main Assist |c00FF0000cleared!")
472 end
473 end
474 end
475  
476 return true
477 end
478  
479 -- RemoveDupMT
480 local function RemoveDupMT(name)
481 for k, v in pairs(XPerl_MainTanks) do
482 if (v[2] == name) then
483 XPerl_MainTanks[k] = nil
484 return true
485 end
486 end
487 end
488  
489 -- GetRaidIDByName
490 local function GetRaidIDByName(name)
491 for i = 1, GetNumRaidMembers() do
492 if (UnitName("raid"..i) == name) then
493 return i
494 end
495 end
496 end
497  
498 -- GetUnitRank
499 local function GetUnitRank(name)
500 local index = GetRaidIDByName(name)
501 if (index) then
502 local _, rank = GetRaidRosterInfo(index)
503 return rank
504 end
505 return 0
506 end
507  
508 -- ValidateTankList
509 -- Check the roster for any tanks that have left the raid
510 local function ValidateTankList()
511 for index,entry in pairs(XPerl_MainTanks) do
512 local found
513 for i = 1,GetNumRaidMembers() do
514 if (UnitName("raid"..i) == entry[2]) then
515 found = true
516 break
517 end
518 end
519  
520 if (not found) then
521 XPerl_MainTanks[index] = nil
522 end
523 end
524 end
525  
526 -- XPerl_MTRosterChanged()
527 function XPerl_MTRosterChanged()
528 ValidateTankList()
529  
530 MainTankCount = 0
531 for i in pairs(XPerl_MainTanks) do
532 MainTankCount = MainTankCount + 1
533 end
534  
535 if (MainTankCount == 0 or XPerlConfigHelper.UseCTRATargets == 0) then
536 -- If no defined tanks, then make a list from the warriors in raid
537 MainTanks = {}
538 MainTankCount = 0
539  
540 for i = 1,GetNumRaidMembers() do
541 local _, class = UnitClass("raid"..i)
542 if (class == "WARRIOR") then
543 tinsert(MainTanks, {i, UnitName("raid"..i)})
544 MainTankCount = MainTankCount + 1
545 end
546 end
547 else
548 MainTankCount = 0
549 for index,entry in pairs(XPerl_MainTanks) do
550 local raidid = GetRaidIDByName(entry[2])
551 if (raidid) then
552 MainTankCount = MainTankCount + 1
553 entry[1] = raidid
554 end
555 end
556  
557 MainTanks = XPerl_MainTanks
558 end
559  
560 XPerl_MakeTankList()
561  
562 if (XPerlConfigHelper.LastMainAssist) then
563 if (not MainAssist) then
564 XPerl_SetMainAssist("", XPerlConfigHelper.LastMainAssist, true)
565 if (not MainAssist) then
566 XPerlConfigHelper.LastMainAssist = nil
567 end
568 end
569 end
570 end
571  
572 -- CT_RA_IsSendingWithVersion override
573 -- Override this so that we get the MT list if there's only us in the raid with a CTRA version registered
574 local old_CT_RA_IsSendingWithVersion
575 if (CT_RA_IsSendingWithVersion) then
576 if (CT_RA_IsSendingWithVersion ~= XPerl_IsSendingWithVersion) then
577 old_CT_RA_IsSendingWithVersion = CT_RA_IsSendingWithVersion
578 CT_RA_IsSendingWithVersion = function(version)
579 if (version == 1.08) then
580 return 1
581 end
582 return old_CT_RA_IsSendingWithVersion(version)
583 end
584 end
585 end
586  
587 -- ProcessCTRAMessage
588 local function ProcessCTRAMessage(unitName, msg)
589  
590 local mtListUpdate
591  
592 if (strsub(msg, 1, 4) == "SET ") then
593 local rankSender = GetUnitRank(unitName)
594 if (rankSender < 1) then
595 return
596 end
597  
598 local useless, useless, num, name = strfind(msg, "^SET (%d+) (.+)$")
599 if (num and name) then
600 num = tonumber(num)
601 local mtID = 0
602 for i = 1, GetNumRaidMembers() do
603 if (UnitName("raid"..i) == name) then
604 mtID = i
605 break
606 end
607 end
608  
609 if (XPerl_MainTanks[num]) then
610 if (XPerl_MainTanks[num][1] == mtID and XPerl_MainTanks[num][2] == name) then
611 return -- No Change
612 end
613 end
614  
615 RemoveDupMT(name)
616  
617 XPerl_MainTanks[tonumber(num)] = {mtID, name}
618  
619 mtListUpdate = true
620 end
621  
622 elseif (strsub(msg, 1, 2) == "R ") then
623 local rankSender = GetUnitRank(unitName)
624 if (rankSender < 1) then
625 return
626 end
627  
628 local useless, useless, name = strfind(msg, "^R (.+)$")
629 if (name) then
630 mtListUpdate = RemoveDupMT(name)
631 end
632 end
633  
634 if (mtListUpdate) then
635 XPerl_MTRosterChanged()
636 end
637 end
638  
639 -- XPerl_SplitCTRAMessage
640 function XPerl_SplitCTRAMessage(msg, char)
641 local arr = { }
642 while (strfind(msg, char) ) do
643 local iStart, iEnd = strfind(msg, char)
644 tinsert(arr, strsub(msg, 1, iStart-1))
645 msg = strsub(msg, iEnd+1, strlen(msg))
646 end
647 if ( strlen(msg) > 0 ) then
648 tinsert(arr, msg)
649 end
650 return arr
651 end
652  
653 -- XPerl_ParseCTRA
654 function XPerl_ParseCTRA(nick, msg, func)
655 if (strfind(msg, "#")) then
656 local arr = XPerl_SplitCTRAMessage(msg, "#")
657 for i,subMsg in pairs(arr) do
658 func(nick, subMsg)
659 end
660 else
661 func(nick, msg)
662 end
663 end
664  
665 -- CHAT_MSG_ADDON
666 function Events:CHAT_MSG_ADDON()
667 if (arg1 == XPERL_COMMS_PREFIX and arg3 == "RAID") then
668 local msg = arg2
669 local cmds = {}
670 for x in string.gfind(msg, "[^ ]+") do
671 tinsert(cmds, x)
672 end
673  
674 if (cmds[1] == "MA") then
675 local from = cmds[2]
676 local newMA = cmds[3]
677 local fromID, maID
678  
679 -- Pick up raid id for sender and new MA
680 for i = 1,GetNumRaidMembers() do
681 local name, rank, group, level, classLocal, class = GetRaidRosterInfo(i)
682  
683 if (name == from) then
684 if (rank > 0) then -- Make sure someone who is promoted sent the message
685 fromID = "raid"..i
686 else
687 return
688 end
689 end
690 if (name == newMA) then
691 maID = "raid"..i
692 end
693 end
694  
695 if (fromID and maID) then
696 if (not UnitIsUnit(fromID, "player")) then
697 local _, fromClass = UnitClass(fromID)
698 local __, maClass = UnitClass(maID)
699  
700 MainAssist = {unit = maID, name = UnitName(maID), class = maClass}
701 XPerlConfigHelper.LastMainAssist = MainAssist.name
702 XPerl_Message(XPerlColourTable[fromClass]..from.." has assigned the Main Assist to be "..XPerlColourTable[maClass]..MainAssist.name)
703 end
704 end
705 end
706 elseif (arg1 == "CTRA" and arg3 == "RAID") then
707 XPerl_ParseCTRA(arg4, arg2, ProcessCTRAMessage)
708 end
709 end
710  
711 ----------------------------
712 ---------- EVENTS ----------
713 ----------------------------
714  
715 -- OnEvent
716 function XPerl_OnEvent()
717 local Event = Events[event]
718 if (Event) then
719 Event()
720 else
721 XPerl_ShowMessage("EXTRA EVENT")
722 end
723 end
724  
725 local function IsDPSClass(unit)
726 local _, class = UnitClass(unit)
727 return (class == "ROGUE" or class == "WARRIOR" or class == "MAGE" or class == "WARLOCK" or class == "HUNTER")
728 end
729  
730 local function IsMT1(unit)
731 if (MainAssist and UnitName(MainAssist.unit) == MainAssist.name) then
732 return UnitIsUnit(unit, MainAssist.unit)
733 elseif (MainTanks[1]) then
734 return UnitIsUnit(unit, "raid"..MainTanks[1][1])
735 end
736 end
737  
738 local function IsMT(unit)
739 for k, tank in pairs(MainTanks) do
740 if (UnitIsUnit(unit, "raid"..tank[1])) then
741 return true
742 end
743 end
744 end
745  
746 local function IsTanked(checkUnit)
747 for k, tank in pairs(MainTanks) do
748 if (UnitIsUnit("raid"..tank[1].."target", checkUnit)) then
749 return true
750 end
751 end
752 end
753  
754 -- ScanForTargets
755 local function ScanForTargets()
756  
757 if (XPerlConfigHelper.CollectOtherTargets == 0 or UnitIsCharmed("player")) then
758 return {}
759 end
760  
761 local NewList = {}
762  
763 local function FoundAlready(checkUnit)
764 for j, owner in pairs(NewList) do
765 if (UnitIsUnit(owner.."target", checkUnit.."target")) then
766 return true
767 end
768 end
769 end
770  
771 local function Check(unitid, doStats)
772 if (UnitLevel(unitid.."target") ~= 1 and (UnitReaction("player", unitid.."target") or 5) <= 4 and not UnitIsDeadOrGhost(unitid.."target")) then
773 if (not FoundAlready(unitid)) then
774 if (not IsTanked(unitid.."target")) then
775 tinsert(NewList, unitid)
776 end
777 end
778 end
779 end
780  
781 local doStats = XPerl_Stats:IsShown()
782  
783 if (doStats) then
784 XPerl_Stats_List.NoTarget = {}
785 XPerl_Stats_List.NotAssistingMT1 = {}
786 XPerl_Stats_List.NotAssistingAnyMT = {}
787 XPerl_Stats_List.HealersOnMT1 = {}
788 XPerl_Stats_List.HealersOnOtherMTs = {}
789 XPerl_Stats_List.HealersNotOnMTs = {}
790 end
791  
792 for i = 1,GetNumRaidMembers() do
793 local checkUnit = "raid"..i
794 if (doStats) then
795 if (UnitIsConnected(checkUnit) and UnitIsVisible(checkUnit) and not UnitIsDeadOrGhost(checkUnit)) then
796 if (not UnitName(checkUnit.."target") and UnitName(checkUnit.."target") ~= UNKNOWNOBJECT) then
797 -- No target, slacker
798 tinsert(XPerl_Stats_List.NoTarget, checkUnit)
799 else
800 if (IsDPSClass(checkUnit)) then
801 -- DPS statistics
802 --if (UnitCanAttack(checkUnit, checkUnit.."target")) then
803 if ((UnitReaction("player", checkUnit.."target") or 5) <= 4) then
804 if (not IsMT(checkUnit)) then
805 if (MainTanks[1] and not UnitIsUnit(checkUnit.."target", "raid"..MainTanks[1][1].."target")) then
806 -- They're not assisting MT1
807 tinsert(XPerl_Stats_List.NotAssistingMT1, checkUnit)
808 tinsert(XPerl_Stats_List.NotAssistingAnyMT, checkUnit)
809  
810 elseif (not IsTanked(checkUnit.."target")) then
811 -- They're not assisting any of the MTs
812 tinsert(XPerl_Stats_List.NotAssistingAnyMT, checkUnit)
813 end
814 end
815 else
816 -- DPS targetting friendly, count it as useless
817 tinsert(XPerl_Stats_List.NoTarget, checkUnit)
818 end
819 else
820 -- Healer statistics
821 if (IsMT1(checkUnit.."target")) then
822 -- Healer targetting MT1
823 tinsert(XPerl_Stats_List.HealersOnMT1, checkUnit)
824  
825 elseif (IsMT(checkUnit.."target")) then
826 -- Healer targetting another MT
827 tinsert(XPerl_Stats_List.HealersOnOtherMTs, checkUnit)
828  
829 else
830 tinsert(XPerl_Stats_List.HealersNotOnMTs, checkUnit)
831 end
832 end
833 end
834 end
835 end
836  
837 Check(checkUnit)
838 Check("raidpet"..i)
839 end
840  
841 if (doStats) then
842 local function Colour(num, good)
843 if (num > 10) then
844 if (good) then
845 return "|c0000FF00"..num.."|r"
846 else
847 return "|c00FF0000"..num.."|r"
848 end
849 elseif (num > 0) then
850 return "|c00FFFF00"..num.."|r"
851 else
852 if (good) then
853 return "|c00FF0000"..num.."|r"
854 else
855 return "|c0000FF00"..num.."|r"
856 end
857 end
858 end
859  
860 local MT1 = "MT1"
861 if (MainAssist and UnitName(MainAssist.unit) == MainAssist.name) then
862 MT1 = "MA"
863 end
864  
865 XPerl_Stats1:SetText(string.format(XPERL_STATS_NO_TARGET, Colour(getn(XPerl_Stats_List.NoTarget))))
866 XPerl_Stats2:SetText(string.format(XPERL_STATS_NOT_ASSIST_MT1, Colour(getn(XPerl_Stats_List.NotAssistingMT1)), MT1))
867 XPerl_Stats3:SetText(string.format(XPERL_STATS_NOT_ASSIST_ANY, Colour(getn(XPerl_Stats_List.NotAssistingAnyMT))))
868 XPerl_Stats4:SetText(string.format(XPERL_STATS_HEALERS_MT1, Colour(getn(XPerl_Stats_List.HealersOnMT1), true), MT1))
869 XPerl_Stats5:SetText(string.format(XPERL_STATS_HEALERS_ANY, Colour(getn(XPerl_Stats_List.HealersOnOtherMTs), true)))
870 XPerl_Stats6:SetText(string.format(XPERL_STATS_HEALERS_NON_MT, Colour(getn(XPerl_Stats_List.HealersNotOnMTs))))
871  
872 if (XPerl_Stats_List.shownStats ~= 0) then
873 XPerl_SetStatDetails()
874 end
875 end
876  
877 return NewList
878 end
879  
880 -- XPerl_GetUnit
881 local function XPerl_GetUnit(unit)
882 for i,search in pairs(XUnits) do
883 if (search.unit == unit) then
884 return search
885 end
886 end
887 end
888  
889 -- ScanForMTDups
890 -- Check MTs all have unique targets
891 local function ScanForMTDups()
892 local dup = 1
893 local dups = {}
894  
895 for i,unit in pairs(XUnits) do
896 XPerl_SetupFrameSimple(unit, XPerlConfigHelper.Background_Transparency)
897 end
898  
899 for i,t1 in pairs(MainTanks) do
900 local any = false
901  
902 if (UnitName("raid"..t1[1].."target") and UnitName("raid"..t1[1].."target") ~= UNKNOWNOBJECT and not UnitIsDeadOrGhost("raid"..t1[1])) then
903 for j,t2 in pairs(MainTanks) do
904 if (j > i and not dups["raid"..t2[1]]) then
905 if (UnitIsUnit("raid"..t1[1].."target", "raid"..t2[1].."target")) then
906 dups["raid"..t2[1]] = 1
907  
908 local unit1 = XPerl_GetUnit("raid"..t1[1])
909 local unit2 = XPerl_GetUnit("raid"..t2[1])
910  
911 if (unit1) then
912 unit1:SetBackdropBorderColor(MTdupColours[dup].r, MTdupColours[dup].g, MTdupColours[dup].b)
913 unit1:SetBackdropColor(MTdupColours[dup].r, MTdupColours[dup].g, MTdupColours[dup].b)
914 end
915 if (unit2) then
916 unit2:SetBackdropBorderColor(MTdupColours[dup].r, MTdupColours[dup].g, MTdupColours[dup].b)
917 unit2:SetBackdropColor(MTdupColours[dup].r, MTdupColours[dup].g, MTdupColours[dup].b)
918 end
919 any = true
920 end
921 end
922 end
923  
924 if (any and dup < 5) then
925 dup = dup + 1
926 end
927 end
928 end
929 end
930  
931 -- OnUpdate
932 local function OnUpdate()
933 UpdateTime = UpdateTime + arg1
934 if (UpdateTime > 0.2) then
935 UpdateTime = 0
936  
937 local doneArrow = false
938 local maDone = false
939 XPerl_MyTarget:ClearAllPoints()
940 XPerl_MyTarget:Hide()
941 XPerl_MainAssist:Hide()
942  
943 local arrowType = "MTT"
944 local arrowExtra = ""
945 if (XPerlConfigHelper.ShowMT == 1) then
946 arrowType = "MT"
947 arrowExtra = "target"
948 end
949  
950 for i,unit in pairs(XUnits) do
951 UpdateUnit(unit, true)
952  
953 local xunit = SpecialCaseUnit(unit)
954  
955 if (unit.type == arrowType and not doneArrow and UnitIsUnit("target", xunit..arrowExtra) and UnitExists("target")) then -- and not UnitIsPlayer(unit.partyid)) then
956 doneArrow = true
957 XPerl_MyTarget:SetParent(unit)
958 XPerl_MyTarget:SetPoint("RIGHT", unit, "LEFT", 2 - (XPerlConfigHelper.MTLabels * 10), 0)
959 XPerl_MyTarget:Show()
960 end
961  
962 if (not maDone and MainAssist and UnitIsUnit(unit.unit, MainAssist.unit) and UnitName(MainAssist.unit) == MainAssist.name) then
963 maDone = true
964 XPerl_MainAssist:SetParent(getglobal(unit:GetName().."_HealthBar"))
965 XPerl_MainAssist:ClearAllPoints()
966  
967 if (XPerlConfigHelper.MTLabels == 1) then
968 XPerl_MainAssist:SetPoint("BOTTOMRIGHT", unit, "BOTTOMLEFT", 1, 3)
969 else
970 XPerl_MainAssist:SetPoint("BOTTOMRIGHT", -1, 1)
971 end
972 XPerl_MainAssist:Show()
973 end
974 end
975  
976 local NewList = ScanForTargets()
977  
978 if (ListChanged1(OtherTargetOwners, NewList)) then
979 OtherTargetOwners = NewList
980 XPerl_MakeOtherTargetList()
981 else
982 for i,unit in pairs(XOtherUnits) do
983 UpdateUnit(unit, true)
984  
985 local xunit = SpecialCaseUnit(unit)
986  
987 if (unit.type == "OT" and unit:IsVisible() and not doneArrow and UnitIsUnit("target", xunit) and UnitExists("target") and not UnitIsPlayer(unit.partyid)) then
988 doneArrow = true
989 XPerl_MyTarget:SetParent(unit)
990 XPerl_MyTarget:SetPoint("RIGHT", unit, "LEFT", 2 - (XPerlConfigHelper.MTLabels * XPerlConfigHelper.OtherTargetTargets * 10) * unit:GetScale(), 0)
991 XPerl_MyTarget:Show()
992 end
993 end
994 end
995  
996 ScanForMTDups()
997  
998 bigwigsSlowDown = bigwigsSlowDown + 1
999 if (bigwigsSlowDown > 10) then
1000 bigwigsSlowDown = 0
1001 end
1002  
1003 --XPerl_Frame_Test:SetText(getn(XFreeUnits).." "..getn(XUnits).." "..getn(XOtherUnits))
1004 end
1005  
1006 if (FrameExpanded or XPerlConfigHelper.ExpandLock == 1) then
1007 local f = GetMouseFocus()
1008 if (f) then
1009 while (f:GetParent() and f:GetParent() ~= UIParent) do
1010 f = f:GetParent()
1011 end
1012  
1013 if (f ~= XPerl_Frame) then
1014 XPerl_CollapseOthers()
1015 end
1016 end
1017 end
1018 end
1019  
1020 -- VARIABLES_LOADED
1021 function Events:VARIABLES_LOADED()
1022 this:UnregisterEvent(event)
1023  
1024 if (type(XPerl_MainTanks) ~= "table") then
1025 XPerl_MainTanks = {}
1026 end
1027  
1028 XPerl_Startup()
1029 XPerl_EnableDisable()
1030 end
1031  
1032 -- Registration
1033 local function Registration()
1034 local list = { "UNIT_HEALTH",
1035 "UNIT_MAXHEALTH",
1036 "PLAYER_TARGET_CHANGED",
1037 "CHAT_MSG_ADDON"}
1038  
1039 for i,a in pairs(list) do
1040 if (GetNumRaidMembers() > 0 and XPerlConfigHelper.RaidHelper == 1) then
1041 XPerl_Frame:RegisterEvent(a)
1042 else
1043 XPerl_Frame:UnregisterEvent(a)
1044 end
1045 end
1046 end
1047  
1048 -- XPerl_EnableDisable
1049 function XPerl_EnableDisable()
1050 if (XPerlConfigHelper and XPerlConfigHelper.RaidHelper == 1 and GetNumRaidMembers() > 0) then
1051 XPerl_Frame:Show()
1052 XPerl_Frame:SetScript("OnUpdate", OnUpdate)
1053  
1054 if (CT_RAMenu_Options and CT_RA_UpdateVisibility) then
1055 XPerlConfigHelper.OldCTMTListHide = CT_RAMenu_Options["temp"]["HideMTs"]
1056 CT_RAMenu_Options["temp"]["HideMTs"] = true
1057 CT_RA_UpdateVisibility(1)
1058 end
1059 else
1060 XPerl_Frame:Hide()
1061 XPerl_Frame:SetScript("OnUpdate", nil)
1062  
1063 if (XPerlConfigHelper and XPerlConfigHelper.RaidHelper == 0 and CT_RAMenu_Options and CT_RA_UpdateVisibility) then
1064 if (XPerlConfigHelper.OldCTMTListHide ~= true) then
1065 XPerlConfigHelper.OldCTMTListHide = nil
1066 CT_RAMenu_Options["temp"]["HideMTs"] = false
1067 CT_RA_UpdateVisibility(1)
1068 end
1069 end
1070 end
1071  
1072 Registration()
1073 XPerl_MTRosterChanged()
1074 end
1075  
1076 -- RAID_ROSTER_UPDATE
1077 function Events:RAID_ROSTER_UPDATE()
1078 if (GetNumRaidMembers() == 0) then
1079 MainTanks = {}
1080 end
1081  
1082 XPerl_EnableDisable()
1083 end
1084  
1085 -- UNIT_HEALTH
1086 function Events:UNIT_HEALTH()
1087 -- scan for a unit we have
1088 for k,unit in pairs(XUnits) do
1089 if (UnitIsUnit(unit.partyid, arg1)) then
1090 UpdateUnit(unit)
1091 end
1092 end
1093  
1094 for k,unit in pairs(XOtherUnits) do
1095 if (UnitIsUnit(unit.partyid, arg1)) then
1096 UpdateUnit(unit)
1097 end
1098 end
1099 end
1100  
1101 Events.UNIT_MAXHEALTH = Events.UNIT_HEALTH
1102  
1103 function Events:PLAYER_TARGET_CHANGED()
1104 for i,unit in pairs(XUnits) do
1105 if (UnitIsUnit(unit.partyid, "player")) then
1106 UpdateUnit(unit)
1107 end
1108 end
1109 end
1110  
1111 -- The number of 'Other' colums that can be shown
1112 local function DisplayableColumns()
1113 local columnsTop = 1 + XPerlConfigHelper.ShowMT + XPerlConfigHelper.MTTargetTargets
1114 local columnsBottom = 1 + XPerlConfigHelper.OtherTargetTargets
1115  
1116 if (columnsTop == 1 and columnsBottom > 1) then
1117 if (XPerlConfigHelper.MTTargetTargets == 0) then
1118 if (XPerlConfigHelper.MTLabels == 1) then
1119 if (XPerlConfigHelper.OtherTargets_Scale > 0.52) then
1120 columnsTop = 2
1121 end
1122 else
1123 if (XPerlConfigHelper.OtherTargets_Scale > 0.49) then
1124 columnsTop = 2
1125 end
1126 end
1127 end
1128 end
1129  
1130 return columnsTop
1131 end
1132  
1133 -- XPerl_SetTitle
1134 function XPerl_SetTitle()
1135 if (DisplayableColumns() > 1 and XPerlConfigHelper.UnitWidth >= 70) then
1136 if (XPerl_MainTanks == MainTanks) then
1137 XPerl_Frame_Title:SetText(XPERL_TITLE_MT_LONG)
1138 else
1139 XPerl_Frame_Title:SetText(XPERL_TITLE_WARRIOR_LONG)
1140 end
1141 else
1142 if (XPerl_MainTanks == MainTanks) then
1143 XPerl_Frame_Title:SetText(XPERL_TITLE_MT_SHORT)
1144 else
1145 XPerl_Frame_Title:SetText(XPERL_TITLE_WARRIOR_SHORT)
1146 end
1147 end
1148 end
1149  
1150 -- XPerl_MakeTankList
1151 function XPerl_MakeTankList()
1152  
1153 if (not XPerlConfigHelper or XPerlConfigHelper.RaidHelper == 0 or GetNumRaidMembers() == 0) then
1154 XPerl_SetFrameSizes()
1155 return
1156 end
1157  
1158 XPerl_SetTitle()
1159  
1160 XPerl_MyTarget:Hide()
1161 XPerl_MainAssist:Hide()
1162  
1163 --MainTanks = NewTankList
1164  
1165 UnallocateUnits(XUnits)
1166  
1167 XGaps = 0
1168  
1169 local previousUnit
1170 local previousID = 0
1171 local first = true
1172 local foundMA = false
1173 local mainTanksDisplayed = 0
1174 for i,tank in pairs(MainTanks) do
1175 local unit = AllocateUnit(XUnits, XPerl_MTTargets)
1176 if (not unit) then
1177 break
1178 end
1179 unit.partyid = "raid"..tank[1].."target"
1180 unit.unit = "raid"..tank[1]; -- 1 == id, 2 == name
1181 unit.type = "MTT"
1182  
1183 mainTanksDisplayed = mainTanksDisplayed + 1
1184  
1185 local rowFrames = {}
1186 rowFrames[2] = unit
1187  
1188 -- Correct the Main Assist number in case people leave the raid
1189 if (MainAssist and UnitName("raid"..tank[1]) == MainAssist.name) then
1190 MainAssist.unit = "raid"..tank[1]
1191 foundMA = true
1192 end
1193  
1194 if (XPerlConfigHelper.ShowMT == 1) then
1195 local unitTank = AllocateUnit(XUnits, XPerl_MTTargets)
1196 if (unitTank) then
1197 unitTank.partyid = "raid"..tank[1]
1198 unitTank.unit = "raid"..tank[1]
1199 unitTank.type = "MT"
1200  
1201 rowFrames[1] = unitTank
1202 else
1203 break
1204 end
1205 end
1206  
1207 if (XPerlConfigHelper.MTTargetTargets == 1) then
1208 local unitTarget = AllocateUnit(XUnits, XPerl_MTTargets)
1209 if (unitTarget) then
1210 unitTarget.partyid = "raid"..tank[1].."targettarget"
1211 unitTarget.unit = "raid"..tank[1]
1212 unitTarget.type = "MTTT"
1213  
1214 rowFrames[3] = unitTarget
1215 else
1216 break
1217 end
1218 end
1219  
1220 local previousColumn
1221 for j,frame in pairs(rowFrames) do
1222 UpdateUnit(frame)
1223  
1224 if (not previousColumn) then
1225 if (first) then
1226 first = false
1227 frame:SetPoint("TOPLEFT", XPerl_MTTargets, "TOPLEFT", XPerlConfigHelper.MTLabels * 10, 0)
1228 else
1229 local gap = 0; -- Maintain a gap if not sequential numbers
1230 if (i > previousID + 1) then
1231 XGaps = XGaps + 1
1232 gap = -GAP_SPACING
1233 end
1234  
1235 frame:SetPoint("TOPLEFT", previousUnit, "BOTTOMLEFT", 0, gap)
1236 end
1237 else
1238 frame:SetPoint("TOPLEFT", previousColumn, "TOPRIGHT", 0, 0)
1239 end
1240  
1241 if (not previousColumn) then
1242 local label = getglobal(frame:GetName().."_Label")
1243 label:SetText(i)
1244 label:SetTextColor(1, 1, 1)
1245 if (XPerlConfigHelper.MTLabels == 1) then
1246 label:Show()
1247 end
1248  
1249 previousUnit = frame
1250 end
1251 previousColumn = frame
1252 end
1253  
1254 if (mainTanksDisplayed >= XPerlConfigHelper.MaxMainTanks) then
1255 break
1256 end
1257  
1258 previousID = i
1259 end
1260  
1261 if (MainAssist and not foundMA) then
1262 -- Main assist left the raid
1263 XPerl_Message("Main Assist "..XPerlColourTable[MainAssist.class]..MainAssist.name.."|r not found in tank list - removed!")
1264 MainAssist = nil
1265 end
1266  
1267 if (previousUnit) then
1268 XPerl_Frame:Show()
1269 else
1270 XPerl_Frame:Hide()
1271 end
1272  
1273 XPerl_SetFrameSizes()
1274 end
1275  
1276 -- XPerl_MakeOtherTargetList
1277 function XPerl_MakeOtherTargetList()
1278  
1279 UnallocateUnits(XOtherUnits)
1280  
1281 local mainWidth = XPerl_Frame:GetWidth()
1282  
1283 if (not IsTanked("target")) then
1284 XPerl_MyTarget:Hide()
1285 end
1286  
1287 XOtherRows = 0
1288  
1289 local previousUnit
1290 local rowStartUnit
1291 local rowSize = 0
1292 local firstRowSize
1293 for i,other in pairs(OtherTargetOwners) do
1294 if (XOtherRows >= MAX_OTHER_ROWS) then -- Well, gotta stop somewhere...
1295 break
1296 end
1297  
1298 local unit = AllocateUnit(XOtherUnits, XPerl_OtherTargets)
1299 if (not unit) then
1300 break
1301 end
1302  
1303 unit:SetScale(XPerlConfigHelper.OtherTargets_Scale)
1304 local otherWidth = unit:GetWidth() * unit:GetScale()
1305  
1306 unit.partyid = other.."target"
1307 unit.type = "OT"
1308  
1309 if (i == 1) then
1310 rowStartUnit = unit
1311 rowSize = otherWidth
1312 unit:SetPoint("TOPLEFT", XPerl_OtherTargets, "TOPLEFT", XPerlConfigHelper.MTLabels * XPerlConfigHelper.OtherTargetTargets * 10, 0)
1313 XOtherRows = XOtherRows + 1
1314 else
1315 if (XPerlConfigHelper.OtherTargetTargets == 1) then
1316 unit:SetPoint("TOPLEFT", previousUnit, "BOTTOMLEFT", 0, 0)
1317 XOtherRows = XOtherRows + 1
1318 else
1319 if (rowSize + otherWidth > mainWidth - 6) then
1320 if (XOtherRows == MAX_OTHER_ROWS) then
1321 break
1322 end
1323  
1324 if (not firstRowSize) then
1325 firstRowSize = i - 1
1326 end
1327  
1328 unit:SetPoint("TOPLEFT", rowStartUnit, "BOTTOMLEFT", 0, 0)
1329 rowStartUnit = unit
1330 rowSize = otherWidth
1331 XOtherRows = XOtherRows + 1
1332 else
1333 rowSize = rowSize + otherWidth
1334 unit:SetPoint("TOPLEFT", previousUnit, "TOPRIGHT", 0, 0)
1335 end
1336 end
1337 end
1338 UpdateUnit(unit)
1339  
1340 if (XOtherRows > 1) then
1341 unit.collapseable = true
1342 end
1343  
1344 if (XOtherRows > 1 and not FrameExpanded and XPerlConfigHelper.ExpandLock == 0) then
1345 unit:Hide()
1346 end
1347  
1348 local label = getglobal(unit:GetName().."_Label")
1349 label:SetText(i)
1350 label:SetTextColor(0.8, 0.2, 0.2)
1351 if (XPerlConfigHelper.OtherTargetTargets == 1) then
1352 if (XPerlConfigHelper.MTLabels == 1) then
1353 label:Show()
1354 end
1355  
1356 local newUnit = AllocateUnit(XOtherUnits, XPerl_OtherTargets)
1357 if (not newUnit) then
1358 break
1359 end
1360 newUnit:SetScale(XPerlConfigHelper.OtherTargets_Scale)
1361 newUnit.partyid = unit.partyid.."target"
1362 newUnit:SetPoint("TOPLEFT", unit, "TOPRIGHT", 0, 0)
1363 newUnit.type = "OTT"
1364  
1365 UpdateUnit(newUnit)
1366  
1367 if (XOtherRows > 1) then
1368 newUnit.collapseable = true
1369 end
1370 if (i > 1 and not FrameExpanded and XPerlConfigHelper.ExpandLock == 0) then
1371 unit.collapseable = true
1372 newUnit:Hide()
1373 end
1374  
1375 unit.OtherTarget = newUnit
1376 end
1377  
1378 previousUnit = unit
1379 end
1380  
1381 XPerl_SetFrameSizes()
1382  
1383 if (not firstRowSize) then
1384 firstRowSize = 1
1385 end
1386 XPerl_ExpandArrowFrame_Stats:SetText(string.format(XPERL_FOOTER_MORE, getn(OtherTargetOwners) - firstRowSize))
1387  
1388 local key = GetBindingText(GetBindingKey("TARGETFIRSTOTHER"), "KEY_")
1389 if (key) then
1390 XPerl_OtherTargets_Key:SetText(string.format(XPERL_TO_TARGET, "|c0000FF40"..key.."|r"))
1391 else
1392 XPerl_OtherTargets_Key:SetText("")
1393 end
1394 end
1395  
1396 -- XPerl_SetFrameSizes
1397 function XPerl_SetFrameSizes()
1398  
1399 local tanks = MainTankCount
1400 local unitHeight = 20
1401 local unitHeightOther = 20
1402  
1403 if (tanks > XPerlConfigHelper.MaxMainTanks) then
1404 tanks = XPerlConfigHelper.MaxMainTanks
1405 end
1406  
1407 if (XPerl_Unit1) then
1408 unitHeight = XPerl_Unit1:GetHeight()
1409 if (XOtherUnits[1]) then
1410 unitHeightOther = XOtherUnits[1]:GetHeight() * XOtherUnits[1]:GetScale()
1411 end
1412 end
1413  
1414 XPerl_MTTargets:SetHeight((unitHeight * tanks) + (XGaps * GAP_SPACING))
1415  
1416 local otherTargets = getn(OtherTargetOwners)
1417 local otherTargetsExtraHeight = 0
1418  
1419 if (otherTargets > 0) then
1420 otherTargetsExtraHeight = 10
1421 XPerl_OtherTargets:Show()
1422 else
1423 XPerl_OtherTargets:Hide()
1424 end
1425  
1426 if (XOtherRows < 2 or FrameExpanded or XPerlConfigHelper.ExpandLock == 1) then
1427 XPerl_ExpandArrowFrame:Hide()
1428 else
1429 if (otherTargets > 1) then
1430 otherTargets = 1
1431 otherTargetsExtraHeight = otherTargetsExtraHeight + 10
1432 XPerl_ExpandArrowFrame:Show()
1433 else
1434 XPerl_ExpandArrowFrame:Hide()
1435 end
1436 end
1437  
1438 local otherRows = XOtherRows
1439 if (otherRows > MAX_OTHER_ROWS) then
1440 otherRows = MAX_OTHER_ROWS
1441 end
1442 if (otherRows > 1 and not FrameExpanded and XPerlConfigHelper.ExpandLock == 0) then
1443 otherRows = 1
1444 end
1445 XPerl_Frame:SetHeight((unitHeight * tanks) + (XGaps * GAP_SPACING) + (unitHeightOther * otherRows) + 5 + XPerl_Frame_TitleBar:GetHeight() + otherTargetsExtraHeight)
1446  
1447 local ExtraWidth = (XPerlConfigHelper.MTLabels * 10); -- 0 for off, 10 for on
1448 XLastColumCount = DisplayableColumns()
1449 XPerl_Frame:SetWidth(XLastColumCount * XPerlConfigHelper.UnitWidth + 6 + ExtraWidth)
1450 end
1451  
1452 -- XPerl_ExpandOthers
1453 function XPerl_ExpandOthers()
1454 if (not FrameExpanded) then
1455 FrameExpanded = true
1456 XPerl_SetFrameSizes()
1457  
1458 for i,unit in pairs(XOtherUnits) do
1459 unit:Show()
1460 end
1461 end
1462 end
1463  
1464 -- XPerl_CollapseOthers
1465 function XPerl_CollapseOthers()
1466 if (FrameExpanded and XPerlConfigHelper.ExpandLock == 0) then
1467 FrameExpanded = false
1468 XPerl_SetFrameSizes()
1469  
1470 for i,unit in pairs(XOtherUnits) do
1471 if (unit.collapseable) then
1472 unit:Hide()
1473 end
1474 end
1475  
1476 if (XOtherUnits[1] and XOtherUnits[1].OtherTarget) then
1477 XOtherUnits[1].OtherTarget:Show()
1478 end
1479 end
1480 end
1481  
1482 -- XPerl_Toggle_Stats
1483 function XPerl_Toggle_Stats()
1484 if (XPerl_Stats:IsShown()) then
1485 XPerl_Stats:Hide()
1486 if (XPerl_Stats_List.shownStats ~= 0) then
1487 getglobal("XPerl_Stats"..XPerl_Stats_List.shownStats):UnlockHighlight()
1488 XPerl_Stats_List.shownStats = 0
1489 end
1490 XPerl_Stats_List:Hide()
1491 else
1492 XPerl_Stats1:SetText("")
1493 XPerl_Stats2:SetText("")
1494 XPerl_Stats3:SetText("")
1495 XPerl_Stats4:SetText("")
1496 XPerl_Stats5:SetText("")
1497  
1498 XPerl_Stats:Show()
1499 end
1500 end
1501  
1502 -- XPerl_TargetFirstOther
1503 function XPerl_TargetFirstOther()
1504 if (XOtherUnits[1]) then
1505 TargetUnit(XOtherUnits[1].partyid)
1506 end
1507 end
1508  
1509 -- XPerl_SmartAssist
1510 local XAssistSkipCount = 0
1511 function XPerl_SmartAssist()
1512  
1513 local function ValidTarget(unit)
1514 local minor
1515 if (UnitIsVisible(unit)) then
1516 if (UnitExists(unit) and not UnitIsDeadOrGhost(unit)) then
1517 if (UnitReaction("player", unit) <= 4) then
1518 if (UnitHealth(unit) <= 10) then
1519 return "minor"
1520 else
1521 return "valid"
1522 end
1523 end
1524 end
1525 end
1526 end
1527  
1528 local function XFindUnit()
1529 if (XFind) then
1530 TargetByName(XFind)
1531  
1532 if (ValidTarget("target") and strlower(strsub(UnitName("target"),1,strlen(XFind))) == strlower(XFind)) then
1533 XPerl_Message("Using FIND found suitable target. ('|c00007F00/xp find|r' to clear).")
1534 return true
1535 else
1536 local r = UnitReaction("player", "target")
1537 if (r and r > 4) then
1538 ClearTarget()
1539 end
1540 end
1541 end
1542 end
1543  
1544 if (not UnitName("target")) then
1545 if (XFindUnit()) then
1546 return
1547 end
1548 end
1549  
1550 if (not UnitExists("target")) then
1551 XAssistSkipCount = 0
1552 end
1553  
1554 local minorUnit
1555 local valid
1556 local isMT = IsMT("player")
1557 local targetCount = 0
1558  
1559 local function Skip()
1560 targetCount = targetCount + 1
1561 if (targetCount > XAssistSkipCount) then
1562 XAssistSkipCount = XAssistSkipCount + 1
1563 return false
1564 end
1565 return true
1566 end
1567  
1568 if (not isMT and MainAssist and UnitName(MainAssist.unit) == MainAssist.name) then
1569 valid = ValidTarget(MainAssist.unit.."target")
1570 if (valid and valid == "valid") then
1571 if (not Skip()) then
1572 TargetUnit(MainAssist.unit.."target")
1573 return
1574 end
1575 end
1576 end
1577  
1578 -- First scan the list of Main Tanks and pick one of their targets if it's health is greater than 10%
1579 for i,id in pairs(MainTanks) do
1580 local unit = "raid"..id[1]
1581  
1582 valid = ValidTarget(unit.."target")
1583  
1584 if (valid) then
1585 if (valid == "minor") then
1586 minorUnit = unit
1587 if (not Skip()) then
1588 break
1589 end
1590 else
1591 if (not isMT) then
1592 if (not Skip()) then
1593 TargetUnit(unit.."target")
1594 return
1595 end
1596 end
1597 end
1598 end
1599 end
1600  
1601 -- If we're not an MT, then pick one of the MT targets and assist
1602 if (minorUnit and not isMT) then
1603 if (not Skip()) then
1604 TargetUnit(minorUnit.."target")
1605 return
1606 end
1607 else
1608 -- Otherwise, we're a tank so look for something un-tanked
1609 for i,unit in pairs(OtherTargetOwners) do
1610 local valid = ValidTarget(unit.."target")
1611  
1612 if (valid) then
1613 if (valid == "minor") then
1614 minorUnit = unit
1615 if (not Skip()) then
1616 break
1617 end
1618 else
1619 if (not Skip()) then
1620 TargetUnit(unit.."target")
1621 return
1622 end
1623 end
1624 end
1625 end
1626 end
1627  
1628 XAssistSkipCount = 0; -- If we reached here, there was nothing else to find
1629 if (minorUnit) then
1630 TargetUnit(minorUnit.."target")
1631 else
1632 -- Nothing found so far, scan through party members in case we've pressed the button when not in a raid
1633 for i = 1,4 do
1634 local unit = "party"..i.."target"
1635  
1636 local valid = ValidTarget(unit)
1637  
1638 if (valid) then
1639 TargetUnit(unit.."target")
1640 break
1641 end
1642 end
1643 end
1644  
1645 XFindUnit()
1646  
1647 if (not UnitName("target")) then
1648 TargetNearestEnemy()
1649 end
1650 end
1651  
1652 -- XPerl_SetStatDetails
1653 function XPerl_SetStatDetails(id, event)
1654  
1655 if (id and XPerl_Stats_List.shownStats ~= 0) then
1656 getglobal("XPerl_Stats"..XPerl_Stats_List.shownStats):UnlockHighlight()
1657 end
1658  
1659 if (id and XPerl_Stats_List.shownStats == id) then
1660 XPerl_Stats_List.shownStats = 0
1661 XPerl_Stats_List:Hide()
1662 return
1663 end
1664  
1665 if (not id) then
1666 id = XPerl_Stats_List.shownStats
1667 end
1668  
1669 local list
1670 if (id == 1) then list = XPerl_Stats_List.NoTarget
1671 elseif (id == 2) then list = XPerl_Stats_List.NotAssistingMT1
1672 elseif (id == 3) then list = XPerl_Stats_List.NotAssistingAnyMT
1673 elseif (id == 4) then list = XPerl_Stats_List.HealersOnMT1
1674 elseif (id == 5) then list = XPerl_Stats_List.HealersOnOtherMTs
1675 elseif (id == 6) then list = XPerl_Stats_List.HealersNotOnMTs
1676 end
1677  
1678 local text = ""
1679 for i,unit in pairs(list) do
1680 local _, class = UnitClass(unit)
1681 local name = UnitName(unit)
1682 text = text..XPerlColourTable[class]..name.." "
1683 end
1684  
1685 getglobal("XPerl_Stats"..id):LockHighlight()
1686 XPerl_Stats_ListText:SetText(text)
1687  
1688 XPerl_Stats_List.shownStats = id
1689 XPerl_Stats_List:Show()
1690 end
1691  
1692 -- XPerl_Toggle_UseCTRATargets
1693 function XPerl_Toggle_UseCTRATargets()
1694 if (XPerlConfigHelper.UseCTRATargets == 1) then
1695 XPerlConfigHelper.UseCTRATargets = 0
1696 else
1697 XPerlConfigHelper.UseCTRATargets = 1
1698 end
1699  
1700 XPerl_MTRosterChanged()
1701 return true
1702 end
1703  
1704 -- XPerl_Toggle_OtherTargets
1705 function XPerl_Toggle_OtherTargets(noChange)
1706 if (not noChange) then
1707 if (XPerlConfigHelper.OtherTargetTargets == 1) then
1708 XPerlConfigHelper.OtherTargetTargets = 0
1709 else
1710 XPerlConfigHelper.OtherTargetTargets = 1
1711 end
1712 end
1713  
1714 XPerl_MakeTankList()
1715 XPerl_MakeOtherTargetList()
1716  
1717 XPerl_Frame_ToggleTargets:SetButtonTex()
1718 return true
1719 end
1720  
1721 function XPerl_Toggle_MTTargets(noChange)
1722 if (not noChange) then
1723 if (XPerlConfigHelper.MTTargetTargets == 1) then
1724 XPerlConfigHelper.MTTargetTargets = 0
1725 else
1726 XPerlConfigHelper.MTTargetTargets = 1
1727 end
1728 end
1729  
1730 XPerl_MakeTankList()
1731 XPerl_MakeOtherTargetList()
1732  
1733 XPerl_Frame_ToggleMTTargets:SetButtonTex()
1734 return true
1735 end
1736  
1737 -- XPerl_Toggle_ExpandLock
1738 function XPerl_Toggle_ExpandLock(noChange)
1739  
1740 if (not noChange) then
1741 if (XPerlConfigHelper.ExpandLock == 1) then
1742 XPerlConfigHelper.ExpandLock = 0
1743 else
1744 XPerlConfigHelper.ExpandLock = 1
1745 end
1746 end
1747  
1748 if (XPerlConfigHelper.ExpandLock == 1) then
1749 XPerl_ExpandOthers()
1750 else
1751 XPerl_CollapseOthers()
1752 end
1753  
1754 XPerl_Frame_ExpandLock:SetButtonTex()
1755 end
1756  
1757 -- XPerl_Toggle_ToggleLabels
1758 function XPerl_Toggle_ToggleLabels(noChange)
1759  
1760 if (not noChange) then
1761 if (XPerlConfigHelper.MTLabels == 1) then
1762 XPerlConfigHelper.MTLabels = 0
1763 else
1764 XPerlConfigHelper.MTLabels = 1
1765 end
1766 end
1767  
1768 XPerl_MakeTankList()
1769 XPerl_MakeOtherTargetList()
1770  
1771 XPerl_Frame_ToggleLabels:SetButtonTex()
1772  
1773 return true
1774 end
1775  
1776 function XPerl_Toggle_ShowMT(noChange)
1777 if (not noChange) then
1778 if (XPerlConfigHelper.ShowMT == 1) then
1779 XPerlConfigHelper.ShowMT = 0
1780 else
1781 XPerlConfigHelper.ShowMT = 1
1782 end
1783 end
1784  
1785 XPerl_MakeTankList()
1786 XPerl_MakeOtherTargetList()
1787  
1788 XPerl_Frame_ToggleShowMT:SetButtonTex()
1789  
1790 return true
1791 end
1792  
1793 -- XPerl_Toggle_CollectOtherTargets
1794 function XPerl_Toggle_CollectOtherTargets(noChange)
1795  
1796 if (not noChange) then
1797 if (XPerlConfigHelper.CollectOtherTargets == 1) then
1798 XPerlConfigHelper.CollectOtherTargets = 0
1799 else
1800 XPerlConfigHelper.CollectOtherTargets = 1
1801 end
1802 end
1803  
1804 XPerl_MakeOtherTargetList()
1805  
1806 return true
1807 end
1808  
1809 -- XPerl_SetFind
1810 function XPerl_SetFind(msg)
1811  
1812 local name = ""
1813 local any
1814 for x in string.gfind(msg, "[^ ]+") do
1815 if (any) then
1816 if (name ~= "") then
1817 name = name.." "
1818 end
1819 name = name..x
1820 end
1821 any = true
1822 end
1823  
1824 XFind = name
1825  
1826 if (XFind == "") then
1827 XFind = nil
1828 XPerl_Message("Find |c00FF0000cleared!|r")
1829 else
1830 XPerl_Message("Find set to |c0000FF00"..name.."|r. ('|c00007F00/xp find|r' to clear).")
1831 end
1832  
1833 return true
1834 end
1835  
1836 -- SmoothBarColor
1837 local function SmoothBarColor(bar, barBG)
1838 local barmin, barmax = bar:GetMinMaxValues()
1839 local percentage = (bar:GetValue()/(barmax-barmin))
1840  
1841 local r, g
1842 if (percentage < 0.5) then
1843 r = 2*percentage
1844 g = 1
1845 else
1846 r = 1
1847 g = 2*(1 - percentage)
1848 end
1849  
1850 if ((r>=0) and (g>=0) and (r<=1) and (g<=1)) then
1851 bar:SetStatusBarColor(r, g, 0)
1852 barBG:SetVertexColor(r, g, 0, 0.25)
1853 end
1854 end
1855  
1856 -- Redo some of this stuff. too much duplication and work on each frame
1857 local function SetBarToTitle(bar)
1858 local offset = XPerl_Frame_Title:GetStringWidth() + 25
1859 bar:SetScale(0.75); -- Scale it down for the font size
1860 bar:SetParent(XPerl_Frame_TitleBar)
1861 bar:Show()
1862 bar:ClearAllPoints()
1863 bar:SetPoint("TOPLEFT", XPerl_Frame_TitleBar, "TOPLEFT", offset / 0.75, -3)
1864 bar:SetPoint("BOTTOMRIGHT", XPerl_Frame_ToggleShowMT, "BOTTOMLEFT", -5, 2)
1865 end
1866  
1867 local function SetBarToFrame(bar)
1868 bar:SetScale(0.75)
1869 bar:SetParent(XPerl_Threat)
1870 bar:Show()
1871 bar:ClearAllPoints()
1872 bar:SetPoint("TOPLEFT", 3, -3)
1873 bar:SetPoint("BOTTOMRIGHT", -3, 3)
1874 end
1875  
1876 -- XPerl_UpdateThreat
1877 local lastThreat = -1
1878 local lastThreat100
1879 function XPerl_UpdateThreat()
1880  
1881 local data, playerCount, threat100 = KLHTM_GetRaidData()
1882 if (threat100 > 0) then
1883 local userThreat = klhtm.table.raiddata[UnitName("player")] or 0
1884  
1885 if (userThreat == lastThreat and threat100 == lastThreat100) then
1886 return
1887 else
1888 lastThreat = userThreat
1889 lastThreat100 = threat100
1890  
1891 if (data[1].name == "Aggro Gain") then
1892 playerCount = playerCount - 1
1893 end
1894  
1895 if (playerCount > 1) then
1896 local titleSpace = (XPerl_Frame_ToggleShowMT:GetLeft() - XPerl_Frame_Title:GetLeft()) - (XPerl_Frame_Title:GetStringWidth() + 25)
1897  
1898 XPerl_MyThreatText:SetText(userThreat - threat100) -- Show deficit threat value
1899  
1900 XPerl_MyThreat:SetMinMaxValues(0, threat100)
1901 XPerl_MyThreat:SetValue(userThreat)
1902  
1903 if (titleSpace >= 10) then
1904 SetBarToTitle(XPerl_MyThreat)
1905 XPerl_Threat:Hide()
1906 XPerl_Threat:SetHeight(2)
1907 else
1908 SetBarToFrame(XPerl_MyThreat)
1909 XPerl_Threat:Show()
1910 XPerl_Threat:SetHeight(12)
1911 end
1912  
1913 SmoothBarColor(XPerl_MyThreat, XPerl_MyThreatBG)
1914 return
1915 end
1916 end
1917 end
1918  
1919 if (lastThreat) then
1920 XPerl_Threat:Hide()
1921 XPerl_Threat:SetHeight(2)
1922 XPerl_MyThreat:Hide()
1923 lastThreat = nil
1924 lastThreat100 = nil
1925 end
1926 end