Blizzard_ArenaUI/Blizzard_ArenaUI.lua

Blizzard_ArenaUI/Blizzard_ArenaUI.lua (9.0.1.36372; unchanged since 9.0.1.36230)
  1. MAX_ARENA_ENEMIES = 5;
  2. function ArenaEnemyFrames_OnLoad(self)
  3. self:RegisterEvent("CVAR_UPDATE");
  4. self:RegisterEvent("VARIABLES_LOADED");
  5. self:RegisterEvent("PLAYER_ENTERING_WORLD");
  6. ArenaEnemyFrames_CheckEffectiveEnableState(self);
  7. local showCastbars = GetCVarBool("showArenaEnemyCastbar");
  8. local castFrame;
  9. for i = 1, MAX_ARENA_ENEMIES do
  10. castFrame = _G["ArenaEnemyFrame"..i.."CastingBar"];
  11. castFrame:SetPoint("RIGHT", _G["ArenaEnemyFrame"..i], "LEFT", -32, -3);
  12. castFrame.showCastbar = showCastbars;
  13. CastingBarFrame_UpdateIsShown(castFrame);
  14. end
  15. UpdateArenaEnemyBackground(GetCVarBool("showPartyBackground"));
  16. ArenaEnemyBackground_SetOpacity(tonumber(GetCVar("partyBackgroundOpacity")));
  17. ArenaEnemyFrames_UpdateVisible();
  18. ArenaEnemyFrames_ResetCrowdControlCooldownData();
  19. end
  20. function ArenaEnemyFrames_OnEvent(self, event, ...)
  21. local arg1, arg2 = ...;
  22. if ( (event == "CVAR_UPDATE") and (arg1 == "SHOW_ARENA_ENEMY_FRAMES_TEXT") ) then
  23. ArenaEnemyFrames_CheckEffectiveEnableState(self, arg2 == "1");
  24. elseif ( event == "VARIABLES_LOADED" ) then
  25. ArenaEnemyFrames_CheckEffectiveEnableState(self);
  26. local showCastbars = GetCVarBool("showArenaEnemyCastbar");
  27. local castFrame;
  28. for i = 1, MAX_ARENA_ENEMIES do
  29. castFrame = _G["ArenaEnemyFrame"..i.."CastingBar"];
  30. castFrame.showCastbar = showCastbars;
  31. CastingBarFrame_UpdateIsShown(castFrame);
  32. end
  33. for i=1, MAX_ARENA_ENEMIES do
  34. ArenaEnemyFrame_UpdatePet(_G["ArenaEnemyFrame"..i], i, true);
  35. end
  36. UpdateArenaEnemyBackground(GetCVarBool("showPartyBackground"));
  37. ArenaEnemyBackground_SetOpacity(tonumber(GetCVar("partyBackgroundOpacity")));
  38. elseif ( event == "PLAYER_ENTERING_WORLD" ) then
  39. ArenaEnemyFrames_CheckEffectiveEnableState(self);
  40. ArenaEnemyFrames_UpdateVisible();
  41. ArenaEnemyFrames_ResetCrowdControlCooldownData();
  42. end
  43. end
  44. function ArenaEnemyFrames_ResetCrowdControlCooldownData()
  45. for i=1, MAX_ARENA_ENEMIES do
  46. local frame = _G["ArenaEnemyFrame"..i];
  47. frame.CC.spellID = nil;
  48. frame.CC.Icon:SetTexture(nil);
  49. frame.CC.Cooldown:Clear();
  50. ArenaEnemyFrame_UpdateCrowdControl(frame);
  51. end
  52. end
  53. function ArenaEnemyFrames_OnShow(self)
  54. DurabilityFrame:SetAlerts();
  55. UIParent_ManageFramePositions();
  56. end
  57. function ArenaEnemyFrames_OnHide(self)
  58. DurabilityFrame:SetAlerts();
  59. UIParent_ManageFramePositions();
  60. end
  61. function ArenaEnemyFrames_CheckEffectiveEnableState(self, cvarUpdate)
  62. if (C_PvP.IsInBrawl()) then
  63. ArenaEnemyFrames_Disable(self);
  64. else
  65. if ( GetCVarBool("showArenaEnemyFrames") or cvarUpdate ) then
  66. ArenaEnemyFrames_Enable(self);
  67. else
  68. ArenaEnemyFrames_Disable(self);
  69. end
  70. end
  71. end
  72. function ArenaEnemyFrames_Enable(self)
  73. self.show = true;
  74. ArenaEnemyFrames_UpdateVisible();
  75. end
  76. function ArenaEnemyFrames_Disable(self)
  77. self.show = false;
  78. ArenaEnemyFrames_UpdateVisible();
  79. end
  80. function ArenaEnemyFrames_UpdateVisible()
  81. local _, instanceType = IsInInstance();
  82. if ( ArenaEnemyFrames.show and ((instanceType == "arena") or (GetNumArenaOpponents() > 0))) then
  83. ArenaEnemyFrames:Show();
  84. else
  85. ArenaEnemyFrames:Hide();
  86. end
  87. end
  88. function ArenaEnemyFrame_OnLoad(self)
  89. local id = self:GetID();
  90. self.debuffCountdown = 0;
  91. self.numDebuffs = 0;
  92. self.noTextPrefix = 1;
  93. local prefix = "ArenaEnemyFrame"..id;
  94. UnitFrame_Initialize(self, "arena"..id, _G[prefix.."Name"], nil,
  95. _G[prefix.."HealthBar"], _G[prefix.."HealthBarText"],
  96. _G[prefix.."ManaBar"], _G[prefix.."ManaBarText"], nil, nil, nil,
  97. _G[prefix.."MyHealPredictionBar"], _G[prefix.."OtherHealPredictionBar"],
  98. _G[prefix.."TotalAbsorbBar"], _G[prefix.."TotalAbsorbBarOverlay"], _G[prefix.."OverAbsorbGlow"],
  99. _G[prefix.."OverHealAbsorbGlow"], _G[prefix.."HealAbsorbBar"], _G[prefix.."HealAbsorbBarLeftShadow"],
  100. _G[prefix.."HealAbsorbBarRightShadow"]);
  101. SetTextStatusBarTextZeroText(_G[prefix.."HealthBar"], DEAD);
  102. self.statusCounter = 0;
  103. self.statusSign = -1;
  104. self.unitHPPercent = 1;
  105. self.classPortrait = _G[self:GetName().."ClassPortrait"];
  106. self.specPortrait = _G[self:GetName().."SpecPortrait"];
  107. self.specBorder = _G[self:GetName().."SpecBorder"];
  108. self.castBar = _G[self:GetName().."CastingBar"];
  109. ArenaEnemyFrame_UpdatePlayer(self, true);
  110. self:RegisterEvent("UNIT_PET");
  111. self:RegisterEvent("ARENA_OPPONENT_UPDATE");
  112. self:RegisterEvent("UNIT_NAME_UPDATE");
  113. self:RegisterEvent("ARENA_COOLDOWNS_UPDATE");
  114. self:RegisterEvent("ARENA_CROWD_CONTROL_SPELL_UPDATE");
  115. UIDropDownMenu_Initialize(self.DropDown, ArenaEnemyDropDown_Initialize, "MENU");
  116. local setfocus = function()
  117. FocusUnit("arena"..self:GetID());
  118. end
  119. SecureUnitButton_OnLoad(self, "arena"..self:GetID(), setfocus);
  120. local id = self:GetID();
  121. if ( UnitClass("arena"..id) and (not UnitExists("arena"..id))) then --It is possible for the unit itself to no longer exist on the client, but some of the information to remain (after reloading the UI)
  122. self:Show();
  123. ArenaEnemyFrame_Lock(self);
  124. elseif ( UnitExists("arenapet"..id) and ( not UnitClass("arena"..id) ) ) then --We use UnitClass because even if the unit doesn't exist on the client, we may still have enough info to populate the frame.
  125. ArenaEnemyFrame_SetMysteryPlayer(self);
  126. end
  127. end
  128. function ArenaEnemyFrame_UpdatePlayer(self, useCVars)--At some points, we need to use CVars instead of UVars even though UVars are faster.
  129. local id = self:GetID();
  130. if ( UnitGUID(self.unit) ) then --Use UnitGUID instead of UnitExists in case the unit is a remote update.
  131. self:Show();
  132. _G["ArenaPrepFrame"..id]:Hide();
  133. UnitFrame_Update(self);
  134. end
  135. local _, class = UnitClass(self.unit);
  136. if( class ) then
  137. self.classPortrait:SetTexture("Interface\\TargetingFrame\\UI-Classes-Circles");
  138. self.classPortrait:SetTexCoord(unpack(CLASS_ICON_TCOORDS[class]));
  139. end
  140. local specID = GetArenaOpponentSpec(id);
  141. if (specID and specID > 0) then
  142. local _, _, _, specIcon = GetSpecializationInfoByID(specID);
  143. self.specBorder:Show();
  144. SetPortraitToTexture(self.specPortrait, specIcon);
  145. else
  146. self.specPortrait:SetTexture(nil);
  147. self.specBorder:Hide();
  148. end
  149. -- When not in an arena, show their faction icon (these are really flag carriers, not arena opponents)
  150. local _, instanceType = IsInInstance();
  151. local factionGroup, factionName = UnitFactionGroup(self.unit);
  152. local pvpIcon = _G[self:GetName() .. "PVPIcon"];
  153. if ( factionGroup and factionGroup ~= "Neutral" and instanceType ~= "arena" ) then
  154. pvpIcon:SetTexture("Interface\\TargetingFrame\\UI-PVP-"..factionGroup);
  155. pvpIcon:Show();
  156. self:SetPoint("RIGHT", self:GetParent(), "RIGHT", -18, 0);
  157. else
  158. pvpIcon:Hide();
  159. self:SetPoint("RIGHT", self:GetParent(), "RIGHT", -2, 0);
  160. end
  161. CastingBarFrame_SetUnit(self.castBar, self.unit, false, true);
  162. ArenaEnemyFrames_UpdateVisible();
  163. end
  164. function ArenaEnemyFrame_Lock(self)
  165. self.healthbar:SetStatusBarColor(0.5, 0.5, 0.5);
  166. self.healthbar.lockColor = true;
  167. self.manabar:SetStatusBarColor(0.5, 0.5, 0.5);
  168. self.manabar.lockColor = true;
  169. self.hideStatusOnTooltip = true;
  170. end
  171. function ArenaEnemyFrame_Unlock(self)
  172. self.healthbar.lockColor = false;
  173. self.healthbar.forceHideText = false;
  174. self.manabar.lockColor = false;
  175. self.manabar.forceHideText = false;
  176. self.hideStatusOnTooltip = false;
  177. end
  178. function ArenaEnemyFrame_SetMysteryPlayer(self)
  179. self.healthbar:SetMinMaxValues(0,100);
  180. self.healthbar:SetValue(100);
  181. self.healthbar.forceHideText = true;
  182. self.manabar:SetMinMaxValues(0,100);
  183. self.manabar:SetValue(100);
  184. self.manabar.forceHideText = true;
  185. self.classPortrait:SetTexture("Interface\\CharacterFrame\\TempPortrait");
  186. self.classPortrait:SetTexCoord(0, 1, 0, 1);
  187. self.name:SetText("");
  188. ArenaEnemyFrame_Lock(self);
  189. self:Show();
  190. end
  191. function ArenaEnemyFrame_OnEvent(self, event, unit, ...)
  192. if ( unit == self.unit ) then
  193. if ( event == "ARENA_OPPONENT_UPDATE" ) then
  194. local unitEvent = ...;
  195. if ( unitEvent == "seen" or unitEvent == "destroyed") then
  196. ArenaEnemyFrame_Unlock(self);
  197. ArenaEnemyFrame_UpdatePlayer(self);
  198. if ( self.healthbar.frequentUpdates and GetCVarBool("predictedHealth") ) then
  199. self.healthbar:SetScript("OnUpdate", UnitFrameHealthBar_OnUpdate);
  200. self.healthbar:UnregisterEvent("UNIT_HEALTH");
  201. end
  202. if ( self.manabar.frequentUpdates ) then
  203. self.manabar:SetScript("OnUpdate", UnitFrameManaBar_OnUpdate);
  204. UnitFrameManaBar_UnregisterDefaultEvents(self.manabar);
  205. end
  206. ArenaEnemyFrame_UpdatePet(self);
  207. UpdateArenaEnemyBackground();
  208. UIParent_ManageFramePositions();
  209. elseif ( unitEvent == "unseen" ) then
  210. ArenaEnemyFrame_Lock(self);
  211. self.healthbar:RegisterEvent("UNIT_HEALTH");
  212. self.healthbar:SetScript("OnUpdate", nil);
  213. UnitFrameManaBar_RegisterDefaultEvents(self.manabar);
  214. self.manabar:SetScript("OnUpdate", nil);
  215. elseif ( unitEvent == "cleared" ) then
  216. ArenaEnemyFrame_Unlock(self);
  217. self:Hide();
  218. ArenaEnemyFrames_UpdateVisible();
  219. local _, instanceType = IsInInstance();
  220. if (instanceType ~= "arena") then
  221. ArenaPrepFrames:Hide()
  222. end
  223. end
  224. elseif ( event == "UNIT_PET" ) then
  225. ArenaEnemyFrame_UpdatePet(self);
  226. elseif ( event == "UNIT_NAME_UPDATE" ) then
  227. ArenaEnemyFrame_UpdatePlayer(self);
  228. elseif ( event == "UNIT_MAXHEALTH" or event == "UNIT_HEAL_PREDICTION" or event == "UNIT_ABSORB_AMOUNT_CHANGED" or event == "UNIT_HEAL_ABSORB_AMOUNT_CHANGED" ) then
  229. UnitFrameHealPredictionBars_Update(self);
  230. elseif ( event == "ARENA_COOLDOWNS_UPDATE" ) then
  231. ArenaEnemyFrame_UpdateCrowdControl(self);
  232. elseif ( event == "ARENA_CROWD_CONTROL_SPELL_UPDATE" ) then
  233. local spellID = ...;
  234. if (spellID ~= self.CC.spellID) then
  235. local spellTexture, spellTextureNoOverride = GetSpellTexture(spellID);
  236. self.CC.spellID = spellID;
  237. self.CC.Icon:SetTexture(spellTextureNoOverride);
  238. end
  239. end
  240. end
  241. end
  242. function ArenaEnemyFrame_UpdateCrowdControl(self)
  243. local spellID, startTime, duration = C_PvP.GetArenaCrowdControlInfo(self.unit);
  244. if (spellID) then
  245. if (spellID ~= self.CC.spellID) then
  246. local spellTexture, spellTextureNoOverride = GetSpellTexture(spellID);
  247. self.CC.spellID = spellID;
  248. self.CC.Icon:SetTexture(spellTextureNoOverride);
  249. end
  250. if (startTime ~= 0 and duration ~= 0) then
  251. self.CC.Cooldown:SetCooldown(startTime/1000.0, duration/1000.0);
  252. else
  253. self.CC.Cooldown:Clear();
  254. end
  255. end
  256. end
  257. function ArenaEnemyFrame_OnShow(self)
  258. self:SetFrameLevel(2);
  259. C_PvP.RequestCrowdControlSpell(self.unit);
  260. end
  261. function ArenaEnemyFrames_GetBestAnchorUnitFrameForOppponent(opponentNumber)
  262. return _G["ArenaEnemyFrame" .. math.min(opponentNumber, MAX_ARENA_ENEMIES)];
  263. end
  264. function ArenaEnemyFrame_UpdatePet(self, id, useCVars) --At some points, we need to use CVars instead of UVars even though UVars are faster.
  265. if ( not id ) then
  266. id = self:GetID();
  267. end
  268. local unitFrame = _G["ArenaEnemyFrame"..id];
  269. local petFrame = _G["ArenaEnemyFrame"..id.."PetFrame"];
  270. local showArenaEnemyPets = (SHOW_ARENA_ENEMY_PETS == "1");
  271. if ( useCVars ) then
  272. showArenaEnemyPets = GetCVarBool("showArenaEnemyPets");
  273. end
  274. if ( UnitGUID(petFrame.unit) and showArenaEnemyPets) then
  275. petFrame:Show();
  276. else
  277. petFrame:Hide();
  278. end
  279. UnitFrame_Update(petFrame);
  280. end
  281. function ArenaEnemyPetFrame_OnLoad(self)
  282. local id = self:GetParent():GetID();
  283. local prefix = "ArenaEnemyFrame"..id.."PetFrame";
  284. local unit = "arenapet"..id;
  285. UnitFrame_Initialize(self, unit, _G[prefix.."Name"], _G[prefix.."Portrait"],
  286. _G[prefix.."HealthBar"], _G[prefix.."HealthBarText"], _G[prefix.."ManaBar"], _G[prefix.."ManaBarText"]);
  287. SetTextStatusBarTextZeroText(_G[prefix.."HealthBar"], DEAD);
  288. _G[prefix.."Name"]:Hide();
  289. SecureUnitButton_OnLoad(self, unit);
  290. self:SetID(id);
  291. self:SetParent(ArenaEnemyFrames);
  292. ArenaEnemyFrame_UpdatePet(self, id, true);
  293. self:RegisterEvent("ARENA_OPPONENT_UPDATE");
  294. self:RegisterEvent("UNIT_CLASSIFICATION_CHANGED");
  295. UIDropDownMenu_Initialize(self.DropDown, ArenaEnemyPetDropDown_Initialize, "MENU");
  296. local setfocus = function()
  297. FocusUnit("arenapet"..self:GetID());
  298. end
  299. SecureUnitButton_OnLoad(self, "arenapet"..self:GetID(), setfocus);
  300. end
  301. function ArenaEnemyPetFrame_OnEvent(self, event, ...)
  302. local arg1, arg2 = ...;
  303. if ( event == "ARENA_OPPONENT_UPDATE" and arg1 == self.unit ) then
  304. if ( arg2 == "seen" or arg2 == "destroyed") then
  305. ArenaEnemyFrame_Unlock(self);
  306. ArenaEnemyFrame_UpdatePet(self);
  307. UpdateArenaEnemyBackground();
  308. local ownerFrame = _G["ArenaEnemyFrame"..self:GetID()];
  309. if ( not ownerFrame:IsShown() ) then
  310. ArenaEnemyFrame_SetMysteryPlayer(ownerFrame);
  311. ownerFrame:Show();
  312. end
  313. if ( self.healthbar.frequentUpdates and GetCVarBool("predictedHealth") ) then
  314. self.healthbar:SetScript("OnUpdate", UnitFrameHealthBar_OnUpdate);
  315. self.healthbar:UnregisterEvent("UNIT_HEALTH");
  316. end
  317. if ( self.manabar.frequentUpdates ) then
  318. self.manabar:SetScript("OnUpdate", UnitFrameManaBar_OnUpdate);
  319. UnitFrameManaBar_UnregisterDefaultEvents(self.manabar);
  320. end
  321. elseif ( arg2 == "unseen" ) then
  322. ArenaEnemyFrame_Lock(self);
  323. self.healthbar:RegisterEvent("UNIT_HEALTH");
  324. self.healthbar:SetScript("OnUpdate", nil);
  325. UnitFrameManaBar_RegisterDefaultEvents(self.manabar);
  326. self.manabar:SetScript("OnUpdate", nil);
  327. elseif ( arg2 == "cleared" ) then
  328. ArenaEnemyFrame_Unlock(self);
  329. self:Hide()
  330. end
  331. elseif ( event == "UNIT_CLASSIFICATION_CHANGED" and arg1 == self.unit ) then
  332. UnitFrame_Update(self);
  333. end
  334. UnitFrame_OnEvent(self, event, ...);
  335. end
  336. function ArenaEnemyDropDown_Initialize(self)
  337. UnitPopup_ShowMenu(self, "ARENAENEMY", "arena"..self:GetParent():GetID());
  338. end
  339. function ArenaEnemyPetDropDown_Initialize(self)
  340. UnitPopup_ShowMenu(self, "ARENAENEMY", "arenapet"..self:GetParent():GetID());
  341. end
  342. function UpdateArenaEnemyBackground(force)
  343. if ( (SHOW_PARTY_BACKGROUND == "1") or force ) then
  344. ArenaEnemyBackground:Show();
  345. local numOpps = min(GetNumArenaOpponents(), MAX_ARENA_ENEMIES);
  346. if ( numOpps > 0 ) then
  347. ArenaEnemyBackground:SetPoint("BOTTOMLEFT", "ArenaEnemyFrame"..numOpps.."PetFrame", "BOTTOMLEFT", -15, -10);
  348. else
  349. ArenaEnemyBackground:Hide();
  350. end
  351. else
  352. ArenaEnemyBackground:Hide();
  353. end
  354. end
  355. function ArenaEnemyBackground_SetOpacity(opacity)
  356. local alpha;
  357. if ( not opacity ) then
  358. alpha = 1.0 - OpacityFrameSlider:GetValue();
  359. else
  360. alpha = 1.0 - opacity;
  361. end
  362. ArenaEnemyBackground:SetAlpha(alpha);
  363. end
  364. -----------------------------------------------------------------------------
  365. --Arena preparation stuff, shows class and spec of opponents during countdown
  366. ------------------------------------------------------------------------------
  367. function ArenaPrepFrames_OnLoad(self)
  368. self:RegisterEvent("ARENA_PREP_OPPONENT_SPECIALIZATIONS");
  369. local numOpps = GetNumArenaOpponentSpecs();
  370. if (numOpps and numOpps > 0) then
  371. ArenaPrepFrames_OnEvent(self, "ARENA_PREP_OPPONENT_SPECIALIZATIONS");
  372. end
  373. end
  374. function ArenaPrepFrames_OnEvent(self, event, ...) --also called in OnLoad
  375. if (event == "ARENA_PREP_OPPONENT_SPECIALIZATIONS") then
  376. ArenaPrepFrames_UpdateFrames();
  377. self:Show()
  378. end
  379. end
  380. function ArenaPrepFrames_OnShow(self)
  381. DurabilityFrame:SetAlerts();
  382. UIParent_ManageFramePositions()
  383. end
  384. function ArenaPrepFrames_OnHide(self)
  385. DurabilityFrame:SetAlerts();
  386. UIParent_ManageFramePositions();
  387. end
  388. function ArenaPrepFrames_GetBestAnchorUnitFrameForOppponent(opponentNumber)
  389. return _G["ArenaPrepFrame" .. math.min(opponentNumber, MAX_ARENA_ENEMIES)];
  390. end
  391. function ArenaPrepFrames_UpdateFrames()
  392. local numOpps = GetNumArenaOpponentSpecs();
  393. for i=1, MAX_ARENA_ENEMIES do
  394. local prepFrame = _G["ArenaPrepFrame"..i];
  395. if (i <= numOpps) then
  396. prepFrame.specPortrait = _G["ArenaPrepFrame"..i.."SpecPortrait"];
  397. local specID, gender = GetArenaOpponentSpec(i);
  398. if (specID > 0) then
  399. local _, _, _, specIcon, _, class = GetSpecializationInfoByID(specID, gender);
  400. if( class ) then
  401. prepFrame.classPortrait:SetTexture("Interface\\TargetingFrame\\UI-Classes-Circles");
  402. prepFrame.classPortrait:SetTexCoord(unpack(CLASS_ICON_TCOORDS[strupper(class)]));
  403. end
  404. SetPortraitToTexture(prepFrame.specPortrait, specIcon);
  405. prepFrame:Show();
  406. else
  407. prepFrame:Hide();
  408. end
  409. else
  410. prepFrame:Hide();
  411. end
  412. end
  413. end
  414. function ArenaPrepFrames_UpdateBackground(force)
  415. if ( (SHOW_PARTY_BACKGROUND == "1") or force ) then
  416. ArenaPrepBackground:Show();
  417. local numOpps = GetNumArenaOpponents();
  418. if ( numOpps > 0 ) then
  419. ArenaPrepBackground:SetPoint("BOTTOMLEFT", "ArenaEnemyFrame"..numOpps.."PetFrame", "BOTTOMLEFT", -15, -10);
  420. else
  421. ArenaPrepBackground:Hide();
  422. end
  423. else
  424. ArenaPrepBackground:Hide();
  425. end
  426. end
  427. function ArenaPrepBackground_SetOpacity(opacity)
  428. local alpha;
  429. if ( not opacity ) then
  430. alpha = 1.0 - OpacityFrameSlider:GetValue();
  431. else
  432. alpha = 1.0 - opacity;
  433. end
  434. ArenaPrepBackground:SetAlpha(alpha);
  435. end