3 local unpack, pairs, rawget = unpack, pairs, rawget;
4 local format = string.format;
5 local UnitHealthMax, UnitPowerMax = UnitHealthMax, UnitPowerMax;
6 local UnitInRange = UnitInRange;
7 local InCombatLockdown = InCombatLockdown;
8 local CreateFrame, RegisterStateDriver, RegisterUnitWatch = CreateFrame, RegisterStateDriver, RegisterUnitWatch;
9 local STANDARD_TEXT_FONT = STANDARD_TEXT_FONT;
10 local GameTooltip = nil;
11 local GameTooltip_SetDefaultAnchor = nil;
13 local registerEvents = OmaRFEvents.RegisterEvents;
14 local unitEvent = OmaRFEvents.UnitEvent;
16 local Settings = OmaRFSettings;
17 local indSize = Settings.IndSize;
18 local baseColor = Settings.BaseColor;
19 local bgColor = Settings.BgColor;
20 local healthColor = Settings.HealthColor;
21 local shieldColor = Settings.ShieldColor;
22 local shieldhlColor = Settings.ShieldhlColor;
23 local healpredColor = Settings.HealpredColor;
24 local healabsorbColor = Settings.HealabsorbColor;
25 -- placeholders with visible values when error happens
27 local width, height = 10, 10;
28 local anchorX, anchorY = 10, 10;
29 local attributes = {};
31 local CFrame = CreateFrame("Frame", "OmaRFFrame", UIParent);
32 local inheritedFrames = "SecureUnitButtonTemplate,SecureHandlerStateTemplate";
39 local function setupIndicators(frame)
40 frame.inds = CreateFrame("Frame", nil, frame);
41 frame.inds:SetAllPoints();
43 for _, pos in pairs(positions) do
44 frame.inds[pos] = frame.inds:CreateTexture(nil, "OVERLAY");
45 frame.inds[pos]:SetPoint(pos, frame.inds, pos);
46 frame.inds[pos]:SetWidth(indSize);
47 frame.inds[pos]:SetHeight(indSize);
48 frame.inds[pos]:SetTexture("Interface\\AddOns\\OmaRF\\images\\rhomb");
49 frame.inds[pos]:SetVertexColor(1, 0, 0);
50 frame.inds[pos]:Hide();
51 frame.inds[pos].text = frame.inds:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
52 frame.inds[pos].text:SetPoint("BOTTOMRIGHT", frame.inds[pos], "BOTTOMRIGHT");
53 frame.inds[pos].text:Hide();
55 frame.major = CreateFrame("Frame", nil, frame);
56 frame.major:SetPoint("TOPLEFT", frame, "TOPLEFT", 4, -indSize + 4);
57 frame.major:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT");
59 frame.major[i] = frame.major:CreateTexture(nil, "OVERLAY");
61 frame.major[i]:SetPoint("TOPLEFT", frame.major, "TOPLEFT");
63 frame.major[i]:SetPoint("TOPLEFT", frame.major[i-1], "TOPRIGHT");
65 frame.major[i]:SetWidth(indSize*2);
66 frame.major[i]:SetHeight(indSize*2);
67 frame.major[i]:Hide();
68 frame.major[i].text = frame.major:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
69 frame.major[i].text:SetPoint("BOTTOMRIGHT", frame.major[i], "BOTTOMRIGHT");
70 frame.major[i].text:Hide();
71 frame.major[i].stack = frame.major:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
72 frame.major[i].stack:SetPoint("TOPLEFT", frame.major[i], "TOPLEFT");
73 frame.major[i].stack:Hide();
77 local function unitUpdate(self, elapsed)
78 -- there's no in/out of range event, have to check each frame
79 -- from FrameXML/CompactUnitFrame.lua
80 local inRange, checked = UnitInRange(self.displayed);
81 if checked and not inRange then
88 local function frameShow(frame)
89 frame:RegisterEvent("PARTY_MEMBER_ENABLE");
90 frame:RegisterEvent("PARTY_MEMBER_DISABLE");
91 frame:RegisterEvent("UNIT_ENTERED_VEHICLE");
92 frame:RegisterEvent("UNIT_EXITED_VEHICLE");
93 frame:RegisterEvent("UNIT_PET");
94 frame:RegisterEvent("PLAYER_ROLES_ASSIGNED");
95 frame:RegisterEvent("GROUP_ROSTER_UPDATE");
96 frame:RegisterEvent("PLAYER_ENTERING_WORLD");
97 frame:RegisterEvent("READY_CHECK");
98 frame:RegisterEvent("READY_CHECK_CONFIRM");
99 frame:RegisterEvent("READY_CHECK_FINISHED");
100 if frame.unit == "focus" then frame:RegisterEvent("PLAYER_FOCUS_CHANGED") end
101 registerEvents(frame);
102 frame:SetScript("OnUpdate", unitUpdate);
103 unitEvent(frame, "UPDATE_ALL_BARS", frame.displayed);
106 local function frameHide(frame)
107 frame:UnregisterAllEvents();
108 frame:SetScript("OnUpdate", nil);
111 local function showTooltip(frame)
112 GameTooltip_SetDefaultAnchor(GameTooltip, PlayerFrame);
113 GameTooltip:SetUnit(frame:GetAttribute("unit"));
116 local function hideTooltip(frame)
117 GameTooltip:FadeOut();
120 local function setupFrame(frame, secure, unit)
121 secure:SetAttribute("unit", unit);
122 frame:SetAttribute("unit", unit);
124 frame.displayed = unit;
125 -- hide frame to get initial frameShow call
127 if unit == "player" then
128 frame.vehicle = "vehicle";
130 frame.vehicle = unit.."pet";
133 secure:SetWidth(width+2);
134 secure:SetHeight(height+2);
135 frame:SetWidth(width+2);
136 frame:SetHeight(height+2);
137 frame.base = frame:CreateTexture(nil, "BACKGROUND");
138 frame.base:SetAllPoints();
139 frame.base:SetColorTexture(1, 1, 1);
140 frame.base:SetVertexColor(unpack(baseColor));
141 frame.background = frame:CreateTexture(nil, "BACKGROUND", nil, 1);
142 frame.background:SetPoint("TOPLEFT", frame, "TOPLEFT", 1, -1);
143 frame.background:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -1, 1);
144 frame.background:SetColorTexture(unpack(bgColor));
145 frame.health = frame:CreateTexture(nil, "BORDER");
146 frame.health:SetTexture("Interface\\RaidFrame\\Raid-Bar-Hp-Fill");
147 frame.health:SetPoint("TOPLEFT", frame.background, "TOPLEFT");
148 frame.health:SetPoint("BOTTOMLEFT", frame.background, "BOTTOMLEFT", 0, 2);
149 frame.health:SetVertexColor(unpack(healthColor));
150 frame.health:SetWidth(width);
151 frame.health.max = UnitHealthMax(unit);
152 frame.mana = frame:CreateTexture(nil, "BORDER");
153 frame.mana:SetPoint("TOPLEFT", frame.background, "BOTTOMLEFT", 0, 2);
154 frame.mana:SetPoint("BOTTOMLEFT", frame.background, "BOTTOMLEFT");
155 frame.mana:SetColorTexture(1, 1, 1);
156 frame.mana:SetWidth(width);
157 frame.mana.max = UnitPowerMax(unit);
158 frame.shield = frame:CreateTexture(nil, "BORDER");
159 frame.shield:SetPoint("TOPLEFT", frame.health, "TOPRIGHT");
160 frame.shield:SetPoint("BOTTOMLEFT", frame.health, "BOTTOMRIGHT");
161 frame.shield:SetColorTexture(unpack(shieldColor));
163 frame.shieldhl = frame:CreateTexture(nil, "ARTWORK");
164 frame.shieldhl:SetPoint("TOPLEFT", frame.background, "TOPRIGHT", -1, 0);
165 frame.shieldhl:SetPoint("BOTTOMRIGHT", frame.background, "BOTTOMRIGHT", 1, 0);
166 frame.shieldhl:SetColorTexture(unpack(shieldhlColor));
167 frame.shieldhl:Hide();
168 frame.healpred = frame:CreateTexture(nil, "ARTWORK");
169 frame.healpred:SetPoint("TOPLEFT", frame.health, "TOPRIGHT");
170 frame.healpred:SetPoint("BOTTOMLEFT", frame.health, "BOTTOMRIGHT");
171 frame.healpred:SetColorTexture(unpack(healpredColor));
172 frame.healpred:Hide();
173 frame.healabsorb = frame:CreateTexture(nil, "ARTWORK");
174 frame.healabsorb:SetPoint("TOPRIGHT", frame.health, "TOPRIGHT");
175 frame.healabsorb:SetPoint("BOTTOMRIGHT", frame.health, "BOTTOMRIGHT");
176 frame.healabsorb:SetColorTexture(unpack(healabsorbColor));
177 frame.healabsorb:Hide();
178 frame.role = frame:CreateTexture(nil, "ARTWORK");
179 frame.role:SetPoint("BOTTOMRIGHT", frame.background, "BOTTOMRIGHT", -2, 2);
180 frame.role:SetPoint("TOPLEFT", frame.background, "BOTTOMRIGHT", -14, 14);
181 frame.role:SetTexCoord(0.75, 1, 0, 1);
182 frame.role:SetTexture("Interface\\LFGFRAME\\LFGROLE");
184 frame.overlay = frame:CreateTexture(nil, "ARTWORK", nil, 1);
185 frame.overlay:SetPoint("TOPLEFT", frame.background, "TOPLEFT");
186 frame.overlay:SetPoint("BOTTOMRIGHT", frame.background, "BOTTOMRIGHT", 0, 2);
187 frame.overlay:SetColorTexture(1, 1, 1);
188 frame.overlay:Hide();
189 frame.name = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
190 frame.name:SetPoint("CENTER", frame.background, "CENTER", 0, 11);
191 frame.text = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight");
192 frame.text:SetFont(STANDARD_TEXT_FONT, 13);
193 frame.text:SetPoint("CENTER", frame.background, "CENTER", 0, -1);
195 frame.rez = frame:CreateTexture(nil, "OVERLAY");
196 frame.rez:SetPoint("TOPLEFT", frame.background, "CENTER", -12, 12);
197 frame.rez:SetPoint("BOTTOMRIGHT", frame.background, "CENTER", 12, -12);
198 frame.rez:SetTexture("Interface\\RaidFrame\\Raid-Icon-Rez");
200 frame.ready = frame:CreateTexture(nil, "OVERLAY");
201 frame.ready:SetPoint("TOPLEFT", frame.background, "BOTTOMLEFT", 0, 12);
202 frame.ready:SetPoint("BOTTOMRIGHT", frame.background, "BOTTOMLEFT", 12, 0);
205 setupIndicators(frame);
207 frame:SetScript("OnShow", frameShow);
208 frame:SetScript("OnHide", frameHide);
209 frame:SetScript("OnEvent", unitEvent);
210 -- let other addons hook these to anchor tooltip elsewhere
211 GameTooltip = _G["GameTooltip"];
212 GameTooltip_SetDefaultAnchor = _G["GameTooltip_SetDefaultAnchor"];
213 secure:SetScript("OnEnter", showTooltip);
214 secure:SetScript("OnLeave", hideTooltip);
216 secure:RegisterForClicks("AnyDown");
217 for attr, val in pairs(attributes) do
218 secure:SetAttribute(attr, val);
220 -- rest give target and menu
221 secure:SetAttribute("*type1", "target");
222 secure:SetAttribute("*type2", "togglemenu");
225 -- vehicle toggle from Shadowed Unit Frames
226 local vehicletoggle = [=[
227 local unit = self:GetAttribute("unit");
228 if unit and newstate == "vehicle" and not UnitTargetsVehicleInRaidUI(unit) then
229 self:SetAttribute("toggleForVehicle", false);
231 self:SetAttribute("toggleForVehicle", true);
235 local function initializeParty(parent)
236 local secure = CreateFrame("Button", "OmaPartySecure0", parent, inheritedFrames);
237 local frame = CreateFrame("Frame", "OmaParty0", parent);
238 local unit = "player";
239 secure:SetPoint("TOPLEFT", parent, "TOPLEFT");
240 frame:SetPoint("TOPLEFT", parent, "TOPLEFT");
241 setupFrame(frame, secure, unit);
242 RegisterStateDriver(frame, "visibility", "[@player,group:raid] hide; show");
243 RegisterStateDriver(secure, "visibility", "[@player,group:raid] hide; show");
244 RegisterStateDriver(secure, "vehicleui", "[vehicleui] vehicle; no");
245 secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
246 party[0] = {secure=secure, frame=frame};
248 local secure = CreateFrame("Button", "OmaPartySecure"..i, parent, inheritedFrames);
249 local frame = CreateFrame("Frame", "OmaParty"..i, parent);
250 local unit = "party"..i;
251 secure:SetPoint("TOPLEFT", party[i-1].secure, "TOPRIGHT");
252 frame:SetPoint("TOPLEFT", party[i-1].frame, "TOPRIGHT");
253 setupFrame(frame, secure, unit);
254 local visible = format("[@%s,exists,group:raid] hide; [@%s,exists] show; hide", unit, unit);
255 local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
256 RegisterStateDriver(frame, "visibility", visible);
257 RegisterStateDriver(secure, "visibility", visible);
258 RegisterStateDriver(secure, "vehicleui", vehicle);
259 secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
260 party[i] = {secure=secure, frame=frame};
264 local function initializeRaid(parent)
265 local secure = CreateFrame("Button", "OmaRaidSecure1", parent, inheritedFrames);
266 local frame = CreateFrame("Frame", "OmaRaid1", parent);
267 local unit = "raid1";
268 secure:SetPoint("TOPLEFT", parent, "TOPLEFT");
269 frame:SetPoint("TOPLEFT", parent, "TOPLEFT");
270 setupFrame(frame, secure, unit);
271 RegisterUnitWatch(frame);
272 RegisterUnitWatch(secure);
273 local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
274 RegisterStateDriver(secure, "vehicleui", vehicle);
275 secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
276 raid[1] = {secure=secure, frame=frame};
279 local secure = CreateFrame("Button", "OmaRaidSecure"..i, parent, inheritedFrames);
280 local frame = CreateFrame("Frame", "OmaRaid"..i, parent);
281 local unit = "raid"..i;
282 secure:SetPoint("TOPLEFT", raid[i-5].secure, "BOTTOMLEFT");
283 frame:SetPoint("TOPLEFT", raid[i-5].frame, "BOTTOMLEFT");
284 setupFrame(frame, secure, unit);
285 RegisterUnitWatch(frame);
286 RegisterUnitWatch(secure);
287 local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
288 RegisterStateDriver(secure, "vehicleui", vehicle);
289 secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
290 raid[i] = {secure=secure, frame=frame};
295 local secure = CreateFrame("Button", "OmaRaidSecure"..i, parent, inheritedFrames);
296 local frame = CreateFrame("Frame", "OmaRaid"..i, parent);
297 local unit = "raid"..i;
298 secure:SetPoint("TOPLEFT", raid[i-1].secure, "TOPRIGHT");
299 frame:SetPoint("TOPLEFT", raid[i-1].frame, "TOPRIGHT");
300 setupFrame(frame, secure, unit);
301 RegisterUnitWatch(frame);
302 RegisterUnitWatch(secure);
303 local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
304 RegisterStateDriver(secure, "vehicleui", vehicle);
305 secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
306 raid[i] = {secure=secure, frame=frame};
311 local function initializeFocus(parent)
312 local secure = CreateFrame("Button", "OmaFocusSecure", parent, inheritedFrames);
313 local frame = CreateFrame("Frame", "OmaFocus", parent);
314 local unit = "focus";
315 secure:SetPoint("BOTTOMLEFT", parent, "TOPLEFT");
316 frame:SetPoint("BOTTOMLEFT", parent, "TOPLEFT");
317 setupFrame(frame, secure, unit);
318 RegisterUnitWatch(frame);
319 RegisterUnitWatch(secure);
320 local vehicle = format("[@%s,unithasvehicleui] vehicle; no", unit);
321 RegisterStateDriver(secure, "vehicleui", vehicle);
322 secure:SetAttribute("_onstate-vehicleui", vehicletoggle);
325 local function initialize()
326 CFrame:SetPoint("CENTER", nil, "CENTER", anchorX, anchorY);
327 CFrame:SetHeight((height+2)*8);
328 CFrame:SetWidth((width+2)*5+1);
329 initializeParty(CFrame);
330 initializeRaid(CFrame);
331 initializeFocus(CFrame);
334 local function loadCharSettings()
335 width, height = Settings.Character.Width, Settings.Character.Height;
336 anchorX, anchorY = Settings.Character.AnchorX, Settings.Character.AnchorY;
337 attributes = Settings.Character.Clickheal;
338 positions = Settings.Character.Positions;
341 -- hiding Blizzard frames somewhat based on ShadowedUF
342 local function hideBlizzardRaidButton()
343 if InCombatLockdown() then return end
344 local manager = CompactRaidFrameManager;
345 -- remove show and unlock buttons from manager
346 manager.displayFrame.hiddenModeToggle:Hide();
347 manager.displayFrame.lockedModeToggle:Hide();
350 local hidden = false;
351 local function hideBlizzardRaid()
352 if hidden then return end
354 local function hide()
355 if InCombatLockdown() then return end
356 CompactRaidFrameContainer:Hide();
357 local shown = CompactRaidFrameManager_GetSetting("IsShown");
358 if shown and shown ~= "0" then
359 CompactRaidFrameManager_SetSetting("IsShown", "0");
363 CompactRaidFrameContainer:UnregisterAllEvents();
364 -- there may still be frames created at startup getting events
365 for i=1,MAX_RAID_MEMBERS do
366 local frame = _G["CompactRaidFrame"..i];
367 if not frame then break end
368 frame:UnregisterAllEvents();
370 hooksecurefunc("CompactRaidFrameManager_UpdateShown", hide);
372 CompactRaidFrameContainer:HookScript("OnShow", hide);
373 hooksecurefunc("CompactRaidFrameManager_UpdateOptionsFlowContainer", hideBlizzardRaidButton);
374 hideBlizzardRaidButton();
377 for _, frame in pairs({FocusFrame, FocusFrameToT}) do
378 frame:UnregisterAllEvents();
379 frame.healthbar:UnregisterAllEvents();
380 frame.manabar:UnregisterAllEvents();
381 if frame.spellbar then frame.spellbar:UnregisterAllEvents() end
382 if frame.powerBarAlt then frame.powerBarAlt:UnregisterAllEvents() end
387 CFrame:RegisterEvent("ADDON_LOADED");
388 CFrame:RegisterEvent("PLAYER_LOGIN");
389 CFrame:RegisterEvent("PLAYER_REGEN_ENABLED");
390 CFrame:SetScript("OnEvent", function(self, event, addon)
391 if event == "PLAYER_LOGIN" then
394 elseif event == "ADDON_LOADED" and addon == "Blizzard_CompactRaidFrames" then
395 -- never really happening unless load order changes
397 elseif event == "PLAYER_REGEN_ENABLED" then
398 -- if CompactRaidFrameManager_UpdateOptionsFlowContainer was called in combat
399 -- couldn't hide the button
400 hideBlizzardRaidButton();
401 elseif event == "ADDON_LOADED" and addon == "OmaRF" then
404 OmaRFEvents.LoadChar();
405 OmaRFIndicators.LoadChar();