c23b2d1 - Move some standard blizzard frames
[wowui.git] / OmaAB / TellMeWhen.lua
1 -- TellMeWhen.lua
2 local _;
3 local pairs = pairs;
4 local GetSpecialization = GetSpecialization;
5 local UnitExists = UnitExists;
6 local UnitAura = UnitAura;
7
8 -- character specific frames
9 local chars = {
10     ["Stormreaver"] = {
11         ["Vildan"] = {
12             {
13                 unit = "target",
14                 spec = 3, -- Retribution
15                 auras = {"Judgment"},
16                 auraFilter = "PLAYER HARMFUL",
17                 x = 570, -- placed over Innervate frame
18                 y = 440,
19                 width = 80,
20                 height = 80,
21             },
22             {
23                 unit = "player",
24                 spec = 3, -- Retribution
25                 auras = {"Divine Purpose"},
26                 auraFilter = "PLAYER HELPFUL",
27                 x = 570,
28                 y = 530,
29                 width = 80,
30                 height = 80,
31             },
32             {
33                 unit = "player",
34                 spec = 2, -- Protection
35                 auras = {"Shield of the Righteous"},
36                 auraFilter = "PLAYER HELPFUL",
37                 x = 570,
38                 y = 440,
39                 width = 80,
40                 height = 80,
41             },
42             {
43                 unit = "player",
44                 auras = {"Divine Shield"},
45                 auraFilter = "PLAYER HELPFUL",
46                 x = 660,
47                 y = 440,
48                 width = 80,
49                 height = 80,
50             },
51         },
52     },
53 };
54
55 -- settings entry:
56 -- unit = unitID where to check auras, not required for totem checkers
57 -- spec = player spec index to show frame, if nil show always
58 -- auras = list of auras to track, in priority order
59 -- auraFilter = filter for UnitAura
60 -- totems = list of totem slots to track, in priority order, only checked if auras is nil
61 -- x = x position relative to UIParent bottom left
62 -- y = y position relative to UIParent bottom left
63 -- width = width
64 -- height = height
65
66 -- global frames' settings
67 local settings = {
68     {
69         unit = "player",
70         auras = {"Innervate"},
71         auraFilter = "HELPFUL",
72         x = 570,
73         y = 440,
74         width = 80,
75         height = 80,
76     },
77     {
78         unit = "player",
79         auras = {
80             "Delusions", "Entropic Blast", "Necrotic Embrace", "Flametouched", "Shadowtouched",
81             "Blazing Eruption", "Shattering Scream", "Consuming Hunger", "Unstable Soul",
82             "Time Bomb", "Broken Shard",
83         },
84         auraFilter = "HARMFUL",
85         x = 660,
86         y = 530,
87         width = 80,
88         height = 80,
89     },
90 };
91
92 local frames = {};
93 local units = {}; -- mapping from unitID to frames
94 local totems = {}; -- mapping to frames with totems
95 local bosses = {};
96 for i = 1, MAX_BOSS_FRAMES do
97     bosses[i] = "boss"..i;
98 end
99 local currentSpec = 0; -- 0 is invalid
100
101 local Indicators = CreateFrame("Frame", "OmaTMW", UIParent);
102
103 local function updateAuraFrame(frame)
104     local unit = frame.unit;
105     if UnitExists(unit) and (not frame.spec or frame.spec == currentSpec) then
106         local name, icon, count, duration, expires;
107         for _, aura in pairs(frame.auras) do
108             name, _, icon, count, _, duration, expires =  UnitAura(unit, aura, nil, frame.auraFilter);
109             if name then
110                 if count > 0 then
111                     frame.stack:SetText(count);
112                     frame.stack:Show();
113                 else
114                     frame.stack:Hide();
115                 end
116                 if expires > 0 then
117                     frame.cd:SetCooldown(expires - duration, duration);
118                     frame.cd:Show();
119                 else
120                     frame.cd:Hide();
121                 end
122                 frame.icon:SetTexture(icon);
123                 frame:Show();
124                 return;
125             end
126         end
127     end
128     frame:Hide();
129 end
130
131 local function updateAuras(unit)
132     if units[unit] then
133         for _, i in pairs(units[unit]) do
134             updateAuraFrame(frames[i]);
135         end
136     end
137 end
138
139 local function updateTotemFrame(frame)
140     print("totem frame not implemented");
141 end
142
143 local function updateTotems(slot)
144     if totems[slot] then
145         for _, i in pairs(totems[slot]) do
146             updateTotemFrame(frames[i]);
147         end
148     end
149 end
150
151 local function createTMW(name, config, parent)
152     local frame = CreateFrame("Frame", name, parent);
153     frame:SetPoint("TOPLEFT", parent, "BOTTOMLEFT", config.x, config.y+config.height);
154     frame:SetPoint("BOTTOMRIGHT", parent, "BOTTOMLEFT", config.x+config.width, config.y);
155     frame.unit = config.unit;
156     frame.spec = config.spec;
157     frame.auras = config.auras;
158     frame.auraFilter = config.auraFilter;
159     frame.totems = config.totems;
160     frame:Hide();
161     frame.base = frame:CreateTexture(nil, "BACKGROUND");
162     frame.base:SetAllPoints();
163     frame.base:SetColorTexture(0, 0, 0, 0.6);
164     frame.icon = frame:CreateTexture(nil, "ARTWORK");
165     frame.icon:SetPoint("TOPLEFT", frame.base, "TOPLEFT", 1, -1);
166     frame.icon:SetPoint("BOTTOMRIGHT", frame.base, "BOTTOMRIGHT", -1, 1);
167     frame.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93);
168     frame.stack = frame:CreateFontString(nil, "OVERLAY", "NumberFontNormalLarge");
169     frame.stack:SetPoint("TOPLEFT");
170     frame.cd = CreateFrame("Cooldown", name.."CD", frame, "CooldownFrameTemplate");
171     frame.cd:SetReverse(true);
172     frame.cd:SetAllPoints();
173     return frame;
174 end
175
176 local function initialize()
177     Indicators:SetFrameStrata("LOW");
178     Indicators:SetPoint("BOTTOMLEFT");
179     Indicators:SetWidth(1);
180     Indicators:SetHeight(1);
181     currentSpec = GetSpecialization();
182     local name, realm = UnitFullName("player");
183     if chars[realm] and chars[realm][name] then
184         for _, config in pairs(chars[realm][name]) do
185             table.insert(settings, config)
186         end
187     end
188     for i, config in pairs(settings) do
189         if config.unit then
190             if not units[config.unit] then units[config.unit] = {} end
191             table.insert(units[config.unit], i);
192         end
193         if config.totems then
194             for _, slot in pairs(config.totems) do
195                 if not totems[slot] then totems[slot] = {} end
196                 table.insert(totems[slot], i);
197             end
198         end
199         frames[i] = createTMW("OmaTMW"..i, config, Indicators);
200     end
201
202     for _, frame in pairs(frames) do
203         if frame.auras then updateAuraFrame(frame) end
204         if frame.totems then updateTotemFrame(frame) end
205     end
206 end
207
208 Indicators:RegisterEvent("UNIT_AURA");
209 Indicators:RegisterEvent("PLAYER_TARGET_CHANGED");
210 Indicators:RegisterEvent("PLAYER_TOTEM_UPDATE");
211 Indicators:RegisterEvent("INSTANCE_ENCOUNTER_ENGAGE_UNIT");
212 Indicators:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED");
213 Indicators:RegisterEvent("PLAYER_LOGIN");
214 Indicators:SetScript("OnEvent", function(self, event, arg1)
215     if event == "UNIT_AURA" then
216         updateAuras(arg1);
217     elseif event == "PLAYER_TARGET_CHANGED" then
218         updateAuras("target");
219     elseif event == "PLAYER_TOTEM_UPDATE" then
220         updateTotems(arg1);
221     elseif event == "INSTANCE_ENCOUNTER_ENGAGE_UNIT" then
222         for _, boss in pairs(bosses) do
223             updateAuras(boss);
224         end
225     elseif event == "PLAYER_SPECIALIZATION_CHANGED" then
226         currentSpec = GetSpecialization();
227         for _, frame in pairs(frames) do
228             if frame.auras then updateAuraFrame(frame) end
229             if frame.totems then updateTotemFrame(frame) end
230         end
231     elseif event == "PLAYER_LOGIN" then
232         initialize();
233     end
234 end);