43157e6 - Add different alt power color for Warlock
[wowui.git] / OmaRF / RaidFrame.lua
1 -- RaidFrame.lua
2 local _;
3 local unpack, pairs = unpack, pairs;
4 local format = string.format;
5 local UnitInRange = UnitInRange;
6 local InCombatLockdown = InCombatLockdown;
7 local CreateFrame, RegisterStateDriver, RegisterUnitWatch = CreateFrame, RegisterStateDriver, RegisterUnitWatch;
8 local CTimerAfter = C_Timer.After;
9 local STANDARD_TEXT_FONT = STANDARD_TEXT_FONT;
10 local GameTooltip = GameTooltip;
11 local GameTooltip_SetDefaultAnchor = GameTooltip_SetDefaultAnchor;
12
13 local registerEvents = OmaRFEvents.RegisterEvents;
14 local registerUnitEvents = OmaRFEvents.RegisterUnitEvents;
15 local unitEvent = OmaRFEvents.UnitEvent;
16 local setupIndicators = OmaRFIndicators.SetupIndicators;
17
18 local Settings = OmaRFSettings;
19 local baseColor = Settings.BaseColor;
20 local bgColor = Settings.BgColor;
21 local healthColor = Settings.HealthColor;
22 local shieldColor = Settings.ShieldColor;
23 local shieldhlColor = Settings.ShieldhlColor;
24 local healpredColor = Settings.HealpredColor;
25 local healabsorbColor = Settings.HealabsorbColor;
26 local width, height = Settings.Width, Settings.Height;
27 -- placeholders with visible values when error happens
28 local anchorX, anchorY = 10, 10;
29 local attributes = {};
30
31 local CFrame = CreateFrame("Frame", "OmaRFFrame", UIParent);
32 local inheritedFrames = "SecureUnitButtonTemplate,SecureHandlerStateTemplate";
33 local barTexture = "Interface\\AddOns\\OmaRF\\images\\minimalist";
34 local class = nil;
35 local party = {};
36 local raid = {};
37 local updaters = {};
38
39 local M = {};
40 OmaRaidFrame = M;
41
42 local function unitUpdate(frame)
43     -- there's no in/out of range event, have to check each frame
44     -- from FrameXML/CompactUnitFrame.lua
45     if frame.updating then
46         local inRange, checked = UnitInRange(frame.displayed);
47         if checked and not inRange then
48             frame:SetAlpha(0.55);
49         else
50             frame:SetAlpha(1);
51         end
52         CTimerAfter(0.25, updaters[frame]);
53     end
54 end
55
56 local function frameShow(frame)
57     registerEvents(frame);
58     registerUnitEvents(frame);
59     frame.updating = true;
60     CTimerAfter(0.25, updaters[frame]);
61     unitEvent(frame, "UPDATE_ALL_BARS");
62 end
63
64 local function frameHide(frame)
65     frame:UnregisterAllEvents();
66     frame.updating = nil;
67 end
68
69 local function showTooltip(secure)
70     -- only show raid frame tooltips out of combat
71     if not InCombatLockdown() then
72         GameTooltip_SetDefaultAnchor(GameTooltip, secure);
73         GameTooltip:SetUnit(secure:GetAttribute("unit"));
74     end
75 end
76
77 local function hideTooltip(secure)
78     if GameTooltip:IsOwned(secure) then GameTooltip:FadeOut() end
79 end
80
81 local function setupFrame(frame, secure, unit)
82     secure:SetAttribute("unit", unit);
83     frame:SetAttribute("unit", unit);
84     frame.unit = unit;
85     frame.displayed = unit;
86     -- hide frame to get initial frameShow call
87     frame:Hide();
88     if unit == "player" then frame.vehicle = "vehicle"
89     else frame.vehicle = unit.."pet" end
90     -- create visuals
91     secure:SetWidth(width+2);
92     secure:SetHeight(height+2);
93     frame:SetWidth(width+2);
94     frame:SetHeight(height+2);
95     frame.base = frame:CreateTexture(nil, "BACKGROUND");
96     frame.base:SetAllPoints();
97     frame.base:SetColorTexture(1, 1, 1);
98     frame.base:SetVertexColor(unpack(baseColor));
99     frame.background = frame:CreateTexture(nil, "BACKGROUND", nil, 1);
100     frame.background:SetPoint("TOPLEFT", frame, "TOPLEFT", 1, -1);
101     frame.background:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -1, 1);
102     frame.background:SetColorTexture(unpack(bgColor));
103     frame.health = frame:CreateTexture(nil, "BORDER");
104     frame.health:SetTexture(barTexture);
105     frame.health:SetPoint("TOPLEFT", frame.background, "TOPLEFT");
106     frame.health:SetPoint("BOTTOMLEFT", frame.background, "BOTTOMLEFT");
107     frame.health:SetVertexColor(unpack(healthColor));
108     frame.shield = frame:CreateTexture(nil, "BORDER");
109     frame.shield:SetPoint("TOPLEFT", frame.health, "TOPRIGHT");
110     frame.shield:SetPoint("BOTTOMLEFT", frame.health, "BOTTOMRIGHT");
111     frame.shield:SetTexture(barTexture);
112     frame.shield:SetVertexColor(unpack(shieldColor));
113     frame.shield:Hide();
114     frame.shieldhl = frame:CreateTexture(nil, "ARTWORK");
115     frame.shieldhl:SetPoint("TOPLEFT", frame.background, "TOPRIGHT", -1, 0);
116     frame.shieldhl:SetPoint("BOTTOMRIGHT", frame.background, "BOTTOMRIGHT", 1, 0);
117     frame.shieldhl:SetColorTexture(unpack(shieldhlColor));
118     frame.shieldhl:Hide();
119     frame.healpred = frame:CreateTexture(nil, "ARTWORK");
120     frame.healpred:SetPoint("TOPLEFT", frame.health, "TOPRIGHT");
121     frame.healpred:SetPoint("BOTTOMLEFT", frame.health, "BOTTOMRIGHT");
122     frame.healpred:SetColorTexture(unpack(healpredColor));
123     frame.healpred:Hide();
124     frame.healabsorb = frame:CreateTexture(nil, "ARTWORK");
125     frame.healabsorb:SetPoint("TOPRIGHT", frame.health, "TOPRIGHT");
126     frame.healabsorb:SetPoint("BOTTOMRIGHT", frame.health, "BOTTOMRIGHT");
127     frame.healabsorb:SetColorTexture(unpack(healabsorbColor));
128     frame.healabsorb:Hide();
129     frame.overlay = frame:CreateTexture(nil, "ARTWORK", nil, 1);
130     frame.overlay:SetPoint("TOPLEFT", frame.background, "TOPLEFT");
131     frame.overlay:SetPoint("BOTTOMRIGHT", frame.background, "BOTTOMRIGHT");
132     frame.overlay:SetColorTexture(1, 1, 1);
133     frame.overlay:Hide();
134     frame.role = frame:CreateTexture(nil, "ARTWORK", nil, 2);
135     frame.role:SetPoint("BOTTOMRIGHT", frame.background, "BOTTOMRIGHT", -2, 2);
136     frame.role:SetPoint("TOPLEFT", frame.background, "BOTTOMRIGHT", -14, 14);
137     frame.role:SetTexture("Interface\\LFGFRAME\\LFGROLE");
138     frame.role:Hide();
139     frame.name = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
140     frame.name:SetPoint("CENTER", frame.background, "CENTER", 0, 11);
141     frame.text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
142     frame.text:SetFont(STANDARD_TEXT_FONT, 13);
143     frame.text:SetPoint("CENTER", frame.background, "CENTER", 0, -1);
144     frame.text:Hide();
145     frame.ready = frame:CreateTexture(nil, "OVERLAY");
146     frame.ready:SetPoint("TOPLEFT", frame.background, "BOTTOMLEFT", 0, 14);
147     frame.ready:SetPoint("BOTTOMRIGHT", frame.background, "BOTTOMLEFT", 14, 0);
148     frame.ready:Hide();
149     frame.targeticon = frame:CreateTexture(nil, "OVERLAY");
150     frame.targeticon:SetPoint("CENTER", frame.background, "TOP");
151     frame.targeticon:SetWidth(12);
152     frame.targeticon:SetHeight(12);
153     frame.targeticon:SetTexture("Interface\\TARGETINGFRAME\\UI-RaidTargetingIcons");
154     frame.targeticon:Hide();
155     -- set up indicators
156     setupIndicators(frame, class);
157     -- set scripts
158     frame:SetScript("OnShow", frameShow);
159     frame:SetScript("OnHide", frameHide);
160     frame:SetScript("OnEvent", unitEvent);
161     secure:SetScript("OnEnter", showTooltip);
162     secure:SetScript("OnLeave", hideTooltip);
163     -- set up periodic updates
164     updaters[frame] = function() return unitUpdate(frame) end
165     -- set attributes
166     secure:RegisterForClicks("AnyDown");
167     for attr, val in pairs(attributes) do
168         secure:SetAttribute(attr, val);
169     end
170     -- rest give target and menu
171     secure:SetAttribute("*type1", "target");
172     secure:SetAttribute("*type2", "togglemenu");
173 end
174
175 -- vehicle toggle from Shadowed Unit Frames
176 local vehicletoggle = [=[
177     local unit = self:GetAttribute("unit");
178     if unit and newstate == "vehicle" and not UnitTargetsVehicleInRaidUI(unit) then
179         self:SetAttribute("toggleForVehicle", false);
180     else
181         self:SetAttribute("toggleForVehicle", true);
182     end
183 ]=]
184
185 local function initializeParty(parent)
186     local secure = CreateFrame("Button", "OmaPartySecure0", parent, inheritedFrames);
187     local frame = CreateFrame("Frame", "OmaParty0", parent);
188     local unit = "player";
189     secure:SetPoint("TOPLEFT", parent, "TOPLEFT");
190     frame:SetPoint("TOPLEFT", parent, "TOPLEFT");
191     setupFrame(frame, secure, unit);
192     RegisterStateDriver(frame, "visibility", "[@player,group:raid] hide; show");
193     RegisterStateDriver(secure, "visibility", "[@player,group:raid] hide; show");
194     RegisterStateDriver(secure, "vehicleui", "[vehicleui] vehicle; no");
195     secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
196     party[0] = {secure=secure, frame=frame};
197     for i = 1,4 do
198         local secure = CreateFrame("Button", "OmaPartySecure"..i, parent, inheritedFrames);
199         local frame = CreateFrame("Frame", "OmaParty"..i, parent);
200         local unit = "party"..i;
201         secure:SetPoint("TOPLEFT", party[i-1].secure, "TOPRIGHT");
202         frame:SetPoint("TOPLEFT", party[i-1].frame, "TOPRIGHT");
203         setupFrame(frame, secure, unit);
204         local visible = format("[@%s,exists,group:raid] hide; [@%s,exists] show; hide", unit, unit);
205         local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
206         RegisterStateDriver(frame, "visibility", visible);
207         RegisterStateDriver(secure, "visibility", visible);
208         RegisterStateDriver(secure, "vehicleui", vehicle);
209         secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
210         party[i] = {secure=secure, frame=frame};
211     end
212 end
213
214 local function initializeRaid(parent)
215     local secure = CreateFrame("Button", "OmaRaidSecure1", parent, inheritedFrames);
216     local frame = CreateFrame("Frame", "OmaRaid1", parent);
217     local unit = "raid1";
218     secure:SetPoint("TOPLEFT", parent, "TOPLEFT");
219     frame:SetPoint("TOPLEFT", parent, "TOPLEFT");
220     setupFrame(frame, secure, unit);
221     RegisterUnitWatch(frame);
222     RegisterUnitWatch(secure);
223     local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
224     RegisterStateDriver(secure, "vehicleui", vehicle);
225     secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
226     raid[1] = {secure=secure, frame=frame};
227     for y = 1,7 do
228         local i = y*5+1;
229         local secure = CreateFrame("Button", "OmaRaidSecure"..i, parent, inheritedFrames);
230         local frame = CreateFrame("Frame", "OmaRaid"..i, parent);
231         local unit = "raid"..i;
232         secure:SetPoint("TOPLEFT", raid[i-5].secure, "BOTTOMLEFT");
233         frame:SetPoint("TOPLEFT", raid[i-5].frame, "BOTTOMLEFT");
234         setupFrame(frame, secure, unit);
235         RegisterUnitWatch(frame);
236         RegisterUnitWatch(secure);
237         local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
238         RegisterStateDriver(secure, "vehicleui", vehicle);
239         secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
240         raid[i] = {secure=secure, frame=frame};
241     end
242     for y = 0,7 do
243         for x = 1,4 do
244             local i = y*5+x+1;
245             local secure = CreateFrame("Button", "OmaRaidSecure"..i, parent, inheritedFrames);
246             local frame = CreateFrame("Frame", "OmaRaid"..i, parent);
247             local unit = "raid"..i;
248             secure:SetPoint("TOPLEFT", raid[i-1].secure, "TOPRIGHT");
249             frame:SetPoint("TOPLEFT", raid[i-1].frame, "TOPRIGHT");
250             setupFrame(frame, secure, unit);
251             RegisterUnitWatch(frame);
252             RegisterUnitWatch(secure);
253             local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
254             RegisterStateDriver(secure, "vehicleui", vehicle);
255             secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
256             raid[i] = {secure=secure, frame=frame};
257         end
258     end
259 end
260
261 local function initializeFocus(parent)
262     local secure = CreateFrame("Button", "OmaFocusSecure", parent, inheritedFrames);
263     local frame = CreateFrame("Frame", "OmaFocus", parent);
264     local unit = "focus";
265     secure:SetPoint("BOTTOMLEFT", parent, "TOPLEFT");
266     frame:SetPoint("BOTTOMLEFT", parent, "TOPLEFT");
267     setupFrame(frame, secure, unit);
268     RegisterUnitWatch(frame);
269     RegisterUnitWatch(secure);
270     local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
271     RegisterStateDriver(secure, "vehicleui", vehicle);
272     secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
273 end
274
275 local function initialize()
276     _, class = UnitClass("player");
277     anchorX, anchorY = Settings.Character.AnchorX, Settings.Character.AnchorY;
278     attributes = Settings.Character.Clickheal;
279     CFrame:SetFrameStrata("LOW");
280     CFrame:SetPoint("CENTER", nil, "CENTER", anchorX, anchorY);
281     CFrame:SetHeight((height+2)*8);
282     CFrame:SetWidth((width+2)*5);
283     initializeParty(CFrame);
284     initializeRaid(CFrame);
285     initializeFocus(CFrame);
286 end
287
288 -- hiding Blizzard frames somewhat based on ShadowedUF
289 local function hideBlizzardRaidButton()
290     if InCombatLockdown() then return end
291     local manager = CompactRaidFrameManager;
292     -- remove show and unlock buttons from manager
293     manager.displayFrame.hiddenModeToggle:Hide();
294     manager.displayFrame.lockedModeToggle:Hide();
295 end
296
297 local hidden = false;
298 local function hideBlizzardRaid()
299     if hidden then return end
300     hidden = true;
301     local function hide()
302         if InCombatLockdown() then return end
303         CompactRaidFrameContainer:Hide();
304         local shown = CompactRaidFrameManager_GetSetting("IsShown");
305         if shown and shown ~= "0" then
306             CompactRaidFrameManager_SetSetting("IsShown", "0");
307         end
308     end
309
310     CompactRaidFrameContainer:UnregisterAllEvents();
311     -- there may still be frames created at startup getting events
312     for i=1,MAX_RAID_MEMBERS do
313         local frame = _G["CompactRaidFrame"..i];
314         if not frame then break end
315         frame:UnregisterAllEvents();
316     end
317     hooksecurefunc("CompactRaidFrameManager_UpdateShown", hide);
318     hide();
319     CompactRaidFrameContainer:HookScript("OnShow", hide);
320     hooksecurefunc("CompactRaidFrameManager_UpdateOptionsFlowContainer", hideBlizzardRaidButton);
321     hideBlizzardRaidButton();
322
323     -- hide focus frame
324     for _, frame in pairs({FocusFrame, FocusFrameToT, FocusFrameSpellBar}) do
325         frame:UnregisterAllEvents();
326         if frame.healthbar then frame.healthbar:UnregisterAllEvents() end
327         if frame.manabar then frame.manabar:UnregisterAllEvents() end
328         if frame.spellbar then frame.spellbar:UnregisterAllEvents() end
329         if frame.powerBarAlt then frame.powerBarAlt:UnregisterAllEvents() end
330         frame:Hide();
331     end
332 end
333
334 CFrame:RegisterEvent("PLAYER_LOGIN");
335 CFrame:RegisterEvent("PLAYER_REGEN_ENABLED");
336 CFrame:SetScript("OnEvent", function(self, event, addon)
337     if event == "PLAYER_REGEN_ENABLED" then
338         -- if CompactRaidFrameManager_UpdateOptionsFlowContainer was called in combat
339         -- couldn't hide the button
340         hideBlizzardRaidButton();
341     elseif event == "PLAYER_LOGIN" then
342         OmaRFLoadChar();
343         hideBlizzardRaid();
344         initialize();
345     end
346 end);