Nenue@0
|
1 --- ${PACKAGE_NAME}
|
Nenue@0
|
2 -- @file-author@
|
Nenue@0
|
3 -- @project-revision@ @project-hash@
|
Nenue@0
|
4 -- @file-revision@ @file-hash@
|
Nenue@0
|
5 -- Created: 3/20/2016 10:00 PM
|
Nenue@0
|
6
|
Nenue@0
|
7 local _, A = ...
|
Nenue@0
|
8 local B = A.frame
|
Nenue@0
|
9 local MODULE = 'BuffFrame'
|
Nenue@0
|
10 local M = B:RegisterModule(MODULE)
|
Nenue@0
|
11 local displays = B.displays
|
Nenue@0
|
12
|
Nenue@0
|
13 local parentAnchor, parentFrame, raidbuffsFrame
|
Nenue@0
|
14 local band, lshift, CreateFrame = bit.band, bit.lshift, CreateFrame
|
Nenue@0
|
15 local raidBuffs = {}
|
Nenue@0
|
16 local raidBuffSymbols = {'St', 'HP', 'AP', 'Ha', 'SP', 'Cr', 'Ma', 'MS', 'V' }
|
Nenue@0
|
17 local missingBuffs = {}
|
Nenue@0
|
18 local playerBuffing, playerCurrentBuff
|
Nenue@0
|
19 local playerBuffs = {}
|
Nenue@0
|
20 local c, ac, frameSize, frameSpacing, framePosition
|
Nenue@0
|
21 local fprint = B.fprint
|
Nenue@0
|
22 local NUM_LE_MISSING_RAID_BUFFS = 0
|
Nenue@0
|
23 local missingBuffsAnchor
|
Nenue@0
|
24
|
Nenue@0
|
25
|
Nenue@0
|
26 --- Takes a given icon texture and calls the pre-defined function set
|
Nenue@0
|
27 M.UpdateBuffStyle = function(buff, style, path)
|
Nenue@0
|
28 local print = fprint()
|
Nenue@0
|
29 local icon = buff.icon
|
Nenue@0
|
30 local symbol = buff.symbol
|
Nenue@0
|
31 path = path or icon.iconPath
|
Nenue@0
|
32 --print(style, icon.iconStyle)
|
Nenue@0
|
33
|
Nenue@0
|
34 if style ~= buff.iconStyle or path ~= buff.iconPath then
|
Nenue@0
|
35 print('|cFF0088FFUpdateBuffStyle(|r', icon:GetName(), style, path)
|
Nenue@0
|
36 icon.iconStyle = style
|
Nenue@0
|
37 icon.iconPath = path
|
Nenue@0
|
38 else
|
Nenue@0
|
39 --print('|cFF00FF88UpdateBuffStyle(|r', icon:GetName(), style, path, ') same values, ignore')
|
Nenue@0
|
40 return
|
Nenue@0
|
41 end
|
Nenue@0
|
42 local styleset = B.BuffStyles[style]
|
Nenue@0
|
43 if not path or path == '' then
|
Nenue@0
|
44 print('path is nil/empty')
|
Nenue@0
|
45 icon:SetTexture(1, 1, 1, 1)
|
Nenue@0
|
46 icon:SetVertexColor(unpack(styleset.Color))
|
Nenue@0
|
47 else
|
Nenue@0
|
48 icon:SetTexture(path or icon:GetTexture())
|
Nenue@0
|
49 icon:SetVertexColor(unpack(styleset.Color))
|
Nenue@0
|
50 end
|
Nenue@0
|
51
|
Nenue@0
|
52 if symbol and symbol.GetText then
|
Nenue@0
|
53 symbol:SetTextColor(unpack(styleset.TextColor))
|
Nenue@0
|
54 symbol:SetText(buff.symbolName or 'NaW')
|
Nenue@0
|
55 end
|
Nenue@0
|
56
|
Nenue@0
|
57 icon:SetBlendMode(styleset.SetBlendMode)
|
Nenue@0
|
58 icon:SetDesaturated(styleset.SetDesaturated)
|
Nenue@0
|
59 end
|
Nenue@0
|
60
|
Nenue@0
|
61 --- Populates a list of targets needing a buff, fired by a handler
|
Nenue@0
|
62 local PlayerBuffTodo ={}
|
Nenue@48
|
63 local PlayerBuffStatus = {}
|
Nenue@48
|
64 local UnitClass, IsInGroup, GetNumGroupMembers, UnitAura = UnitClass, IsInGroup, GetNumGroupMembers, UnitAura
|
Nenue@48
|
65 local GetTalentInfoByID, GetActiveSpecGroup, GetStablePetInfo, GetSpecialization = GetTalentInfoByID, GetActiveSpecGroup, GetStablePetInfo, GetSpecialization
|
Nenue@0
|
66 M.UpdateBuffStatus = function(aura, filters)
|
Nenue@0
|
67 if not PlayerBuffStatus[aura] then
|
Nenue@0
|
68 PlayerBuffStatus[aura] = {}
|
Nenue@0
|
69 end
|
Nenue@0
|
70
|
Nenue@0
|
71
|
Nenue@0
|
72 print(UnitClass('player'))
|
Nenue@0
|
73 if IsInGroup() then
|
Nenue@0
|
74 local numBuffed = 0
|
Nenue@0
|
75 local partySize = GetNumGroupMembers()
|
Nenue@0
|
76 local missing = {}
|
Nenue@0
|
77 for i = 1, partySize do
|
Nenue@0
|
78 local unit = 'raid'..i
|
Nenue@0
|
79 if UnitAura(unit, aura, nil, filters) then
|
Nenue@0
|
80 numBuffed = numBuffed + 1
|
Nenue@0
|
81 else
|
Nenue@0
|
82 tinsert(missing, unit)
|
Nenue@0
|
83 end
|
Nenue@0
|
84 end
|
Nenue@0
|
85
|
Nenue@0
|
86 PlayerBuffTodo[aura] = missing
|
Nenue@0
|
87
|
Nenue@0
|
88 end
|
Nenue@0
|
89 end
|
Nenue@0
|
90
|
Nenue@0
|
91 --- Evaluates buff availability criteria
|
Nenue@0
|
92 -- Uses hard returns to avoid over-iterating conditionals, particularly pet family
|
Nenue@0
|
93 local function IsBuffAvailable(criteria)
|
Nenue@0
|
94 local available, active = false, false
|
Nenue@0
|
95 local result
|
Nenue@0
|
96 for _, test in ipairs(criteria) do
|
Nenue@0
|
97 if test == true then
|
Nenue@0
|
98 -- it's a passive effect that is always on
|
Nenue@0
|
99 return true, true
|
Nenue@0
|
100 else
|
Nenue@0
|
101 if c.spec then
|
Nenue@0
|
102 if not (result and c.spec == B.PlayerSpec) then
|
Nenue@0
|
103 return false
|
Nenue@0
|
104 end
|
Nenue@0
|
105 end
|
Nenue@0
|
106
|
Nenue@0
|
107 if c.talent then
|
Nenue@0
|
108 local talentID, name, texture, selected, available = GetTalentInfoByID(c.talent, GetActiveSpecGroup())
|
Nenue@0
|
109 if not (result and selected) then
|
Nenue@0
|
110 return false
|
Nenue@0
|
111 end
|
Nenue@0
|
112 end
|
Nenue@0
|
113
|
Nenue@0
|
114 if c.petFamily then
|
Nenue@0
|
115 local lim = min(5, NUM_PET_STABLE_SLOTS) -- to avoid volatile loop condition
|
Nenue@0
|
116 for p = 1, lim do
|
Nenue@0
|
117 local hasPet = false
|
Nenue@0
|
118 local icon, name, level, family, talent = GetStablePetInfo(p)
|
Nenue@0
|
119 if family == c.petFamily then
|
Nenue@0
|
120 hasPet = true
|
Nenue@0
|
121 end
|
Nenue@0
|
122 if not (result and hasPet) then
|
Nenue@0
|
123 return false
|
Nenue@0
|
124 end
|
Nenue@0
|
125 end
|
Nenue@0
|
126 end
|
Nenue@0
|
127
|
Nenue@0
|
128 end
|
Nenue@0
|
129 end
|
Nenue@0
|
130 return true, false
|
Nenue@0
|
131 end
|
Nenue@0
|
132
|
Nenue@0
|
133 --- events: PLAYER_SPECIALIZATION_CHANGED
|
Nenue@0
|
134 function M:UpdateBuffsTodo (unit)
|
Nenue@0
|
135 -- buffs vs. auras
|
Nenue@0
|
136 if unit ~= 'player' then
|
Nenue@0
|
137 -- look for changes in the GIST manifest and sort them out
|
Nenue@0
|
138 return
|
Nenue@0
|
139 end
|
Nenue@0
|
140
|
Nenue@0
|
141 local class = UnitClass('player')
|
Nenue@0
|
142 local spec = GetSpecialization()
|
Nenue@0
|
143 if not class or
|
Nenue@0
|
144 not spec or
|
Nenue@0
|
145 not IsInGroup() or
|
Nenue@0
|
146 not B.PlayerBuffStatus[class] then
|
Nenue@0
|
147 -- if just logging in, info won't be available for several seconds
|
Nenue@0
|
148 -- if not grouped, don't calc
|
Nenue@0
|
149 -- hide frame
|
Nenue@0
|
150 B.PlayerBuffsActive = function() return false end
|
Nenue@0
|
151 return
|
Nenue@0
|
152 end
|
Nenue@0
|
153
|
Nenue@0
|
154 -- verify change
|
Nenue@0
|
155 if B.PlayerCurrentSpec == spec or B.PlayerClass == class then
|
Nenue@0
|
156 return
|
Nenue@0
|
157 end
|
Nenue@0
|
158 B.PlayerCurrentSpec = spec
|
Nenue@0
|
159 B.PlayerClass = class
|
Nenue@0
|
160
|
Nenue@0
|
161 local test = B.ClassRaidBuffs
|
Nenue@0
|
162 local buffTypes = {}
|
Nenue@0
|
163 local auraTypes = {}
|
Nenue@0
|
164 for i = 1, NUM_LE_RAID_BUFF_TYPES do
|
Nenue@0
|
165 local name, filters
|
Nenue@0
|
166 if test[i] and test[i][class] then
|
Nenue@0
|
167 playerBuffs[i], name, filters = IsBuffAvailable(test[i][class])
|
Nenue@0
|
168 else
|
Nenue@0
|
169 playerBuffs[i] = nil
|
Nenue@0
|
170 end
|
Nenue@0
|
171
|
Nenue@0
|
172 if name then
|
Nenue@0
|
173 B.UpdateBuffStatus(name, filters)
|
Nenue@0
|
174 end
|
Nenue@0
|
175 end
|
Nenue@0
|
176 end
|
Nenue@0
|
177
|
Nenue@0
|
178 -- Called once to setup the ConsolidatedBuffs stencil
|
Nenue@0
|
179 local consolidatedBuffsLoaded
|
Nenue@0
|
180 M.SetConsolidatedBuffs = function()
|
Nenue@48
|
181 local displays = M.displays
|
Nenue@0
|
182 local print = fprint()
|
Nenue@0
|
183 c = displays.ConsolidatedBuff.conf
|
Nenue@48
|
184 parentFrame = M.guides[c.Parent][c.Position]
|
Nenue@48
|
185 raidbuffsFrame = M.anchors.ConsolidatedBuff
|
Nenue@0
|
186
|
Nenue@0
|
187 B.SetConfigLayers(raidbuffsFrame)
|
Nenue@0
|
188 consolidatedBuffsLoaded = true
|
Nenue@0
|
189 ConsolidatedBuffs:ClearAllPoints()
|
Nenue@0
|
190 ConsolidatedBuffs:SetAllPoints(parentFrame.icon)
|
Nenue@0
|
191 if c.Icon then
|
Nenue@0
|
192 ConsolidatedBuffsIcon:SetAllPoints(parentFrame.icon)
|
Nenue@0
|
193 ConsolidatedBuffsIcon:SetTexCoord(0.609,0.89,0.215,0.78)
|
Nenue@0
|
194 else
|
Nenue@0
|
195 ConsolidatedBuffsIcon:Hide()
|
Nenue@0
|
196 end
|
Nenue@0
|
197
|
Nenue@0
|
198 ConsolidatedBuffsCount:Hide()
|
Nenue@0
|
199 end
|
Nenue@0
|
200
|
Nenue@0
|
201 local missingTypes = {}
|
Nenue@0
|
202 local raidBuffsInitialized
|
Nenue@0
|
203 M.UpdateRaidBuffs = function()
|
Nenue@0
|
204 local print = fprint()
|
Nenue@0
|
205 if not consolidatedBuffsLoaded then
|
Nenue@0
|
206 M.SetConsolidatedBuffs()
|
Nenue@0
|
207 end
|
Nenue@0
|
208
|
Nenue@0
|
209 if not M.ShowConsolidated or not parentFrame.contains then
|
Nenue@0
|
210 print(' hiding raid buffs square')
|
Nenue@0
|
211 if raidBuffsInitialized then
|
Nenue@0
|
212 for i = 1, 9 do
|
Nenue@0
|
213 if raidBuffs[i] then
|
Nenue@0
|
214 raidBuffs[i]:Hide()
|
Nenue@0
|
215 end
|
Nenue@0
|
216 end
|
Nenue@0
|
217 raidBuffsInitialized = nil
|
Nenue@0
|
218 end
|
Nenue@0
|
219 if parentFrame then
|
Nenue@0
|
220 print(c.Parent, c.Position)
|
Nenue@0
|
221 print('de-flagging parent')
|
Nenue@0
|
222 parentFrame.contains = nil
|
Nenue@0
|
223 end
|
Nenue@0
|
224 raidbuffsFrame:Hide()
|
Nenue@0
|
225 return
|
Nenue@0
|
226 end
|
Nenue@0
|
227
|
Nenue@0
|
228 local c = B.displays.ConsolidatedBuff.conf
|
Nenue@0
|
229 if parentFrame and not parentFrame.contains then
|
Nenue@0
|
230 raidBuffsInitialized = true
|
Nenue@0
|
231 print('re-flagging parent', parentFrame:GetName())
|
Nenue@0
|
232 parentFrame.contains = parentFrame
|
Nenue@0
|
233 B.decors[c.Parent][c.Position]:Hide()
|
Nenue@0
|
234 raidbuffsFrame:Show()
|
Nenue@0
|
235
|
Nenue@0
|
236 -- make sure parent icon is updated
|
Nenue@0
|
237 local w = c.Size*c.PerRow+c.Spacing*(c.PerRow-1)+c.Border*2
|
Nenue@0
|
238 parentFrame:SetSize(w, w)
|
Nenue@0
|
239 parentFrame.icon:SetSize(w - c.Border*2, w - c.Border*2)
|
Nenue@0
|
240 parentFrame.contains = raidbuffsFrame
|
Nenue@0
|
241
|
Nenue@0
|
242 M.UpdateBuffs(c.Parent)
|
Nenue@0
|
243 end
|
Nenue@0
|
244
|
Nenue@0
|
245 -- have to loop again due to tainting restrictions
|
Nenue@0
|
246 -- could compare the tooltip font object pointers, but that may change
|
Nenue@0
|
247 local buffStack = GetRaidBuffInfo()
|
Nenue@0
|
248 print(GetRaidBuffInfo())
|
Nenue@0
|
249 local guides = B.guides.ConsolidatedBuff
|
Nenue@0
|
250 local numBuffs = 0
|
Nenue@0
|
251 local numAvailable = 0
|
Nenue@0
|
252 local mask = 1
|
Nenue@0
|
253 if buffStack == nil then
|
Nenue@0
|
254 return -- discard
|
Nenue@0
|
255 end
|
Nenue@0
|
256
|
Nenue@0
|
257
|
Nenue@0
|
258 for i = 1, NUM_LE_RAID_BUFF_TYPES do
|
Nenue@0
|
259 local available = (band(buffStack, mask) > 0)
|
Nenue@0
|
260 local name, _, icon, start, duration, spellID, slot = GetRaidBuffTrayAuraInfo(i)
|
Nenue@0
|
261 print(i, name, icon, available)
|
Nenue@0
|
262
|
Nenue@0
|
263 raidBuffs[i] = raidBuffs[i] or CreateFrame('Frame', 'VeneerRaidBuff' .. i, raidbuffsFrame, 'VeneerRaidBuffTemplate')
|
Nenue@0
|
264 local buff = raidBuffs[i]
|
Nenue@0
|
265 if not raidBuffs[i].stylized then
|
Nenue@0
|
266 print(' setting style', i)
|
Nenue@0
|
267 buff.stylized = true
|
Nenue@0
|
268 buff.symbol:SetText(raidBuffSymbols[i])
|
Nenue@0
|
269 buff.symbol:SetFont("Fonts\\FRIZQT__.TTF", 10, 'OUTLINE')
|
Nenue@0
|
270 buff:SetSize(parentFrame.icon:GetWidth()/c.PerRow,parentFrame.icon:GetWidth()/c.PerRow)
|
Nenue@0
|
271 buff.symbolName = raidBuffSymbols[i]
|
Nenue@0
|
272
|
Nenue@0
|
273 buff.icon:SetAllPoints(guides[i].icon)
|
Nenue@0
|
274 buff:SetAllPoints(guides[i])
|
Nenue@0
|
275 raidbuffsFrame.Zoom(buff.icon)
|
Nenue@0
|
276 end
|
Nenue@0
|
277
|
Nenue@0
|
278 buff:Show()
|
Nenue@0
|
279 local buffStyle = 'missing'
|
Nenue@0
|
280 if name then
|
Nenue@0
|
281 buff:Show()
|
Nenue@0
|
282 buff.symbol:Hide()
|
Nenue@0
|
283 missingTypes[i] = nil
|
Nenue@0
|
284 numBuffs = numBuffs + 1
|
Nenue@0
|
285 numAvailable = numAvailable + 1
|
Nenue@0
|
286 buffStyle = 'active'
|
Nenue@0
|
287 else
|
Nenue@0
|
288 buff.symbol:Show()
|
Nenue@0
|
289 if band(buffStack, mask) > 0 then
|
Nenue@0
|
290 buffStyle = 'available'
|
Nenue@0
|
291 numAvailable = numAvailable + 1
|
Nenue@0
|
292 else
|
Nenue@0
|
293 buffStyle = 'missing'
|
Nenue@0
|
294 icon = ''
|
Nenue@0
|
295 end
|
Nenue@0
|
296 end
|
Nenue@0
|
297 mask = lshift(mask, 1)
|
Nenue@0
|
298
|
Nenue@0
|
299 M.UpdateBuffStyle(buff, buffStyle, icon)
|
Nenue@0
|
300 end
|
Nenue@0
|
301
|
Nenue@0
|
302 -- todo: filter by castable and suppress for non-overlapping auras
|
Nenue@0
|
303
|
Nenue@0
|
304 raidbuffsFrame.label:SetText(numBuffs..'/'..numAvailable)
|
Nenue@0
|
305 print(parentFrame:GetName(), parentFrame:GetSize())
|
Nenue@0
|
306
|
Nenue@0
|
307 if B.ShowMissingBuffs then
|
Nenue@0
|
308 B.UpdateMissingBuffs()
|
Nenue@0
|
309 elseif missingBuffsAnchor and missingBuffsAnchor:IsVisible() then
|
Nenue@0
|
310 for i = 1, NUM_LE_MISSING_RAID_BUFFS do
|
Nenue@0
|
311 missingBuffs[i]:Hide()
|
Nenue@0
|
312 end
|
Nenue@0
|
313 end
|
Nenue@0
|
314 end
|
Nenue@0
|
315
|
Nenue@0
|
316 B.UpdateMissingBuffs = function()
|
Nenue@0
|
317 local print = B.fprint()
|
Nenue@0
|
318 local numMissing = 0
|
Nenue@0
|
319
|
Nenue@0
|
320 local firstMissing, lastMissing
|
Nenue@0
|
321 for i = 1, NUM_LE_RAID_BUFF_TYPES do
|
Nenue@0
|
322 local name, _, icon, start, duration, spellID, slot = GetRaidBuffTrayAuraInfo(i)
|
Nenue@0
|
323
|
Nenue@0
|
324 if not name then
|
Nenue@0
|
325 numMissing = numMissing + 1
|
Nenue@0
|
326
|
Nenue@0
|
327 print('missing buff', i, numMissing)
|
Nenue@0
|
328 B.UpdateBuffStyle(raidBuffs[i].icon, 'missing', "")
|
Nenue@0
|
329
|
Nenue@0
|
330 missingBuffs[numMissing] = missingBuffs[numMissing] or CreateFrame('Button', 'VeneerMissingBuff' .. numMissing, raidbuffsFrame, 'VeneerMissingBuffTemplate')
|
Nenue@0
|
331
|
Nenue@0
|
332 local missing = missingBuffs[numMissing]
|
Nenue@0
|
333
|
Nenue@0
|
334 missing:Show()
|
Nenue@0
|
335 missing:SetSize(c.Size*c.PerRow, c.Size)
|
Nenue@0
|
336 if numMissing == 1 then
|
Nenue@0
|
337 firstMissing = missing
|
Nenue@0
|
338 else
|
Nenue@0
|
339 missing:SetPoint('TOP', lastMissing, 'BOTTOM', 0, -c.Spacing)
|
Nenue@0
|
340 end
|
Nenue@0
|
341
|
Nenue@0
|
342 missing.label:SetText(_G['RAID_BUFF_'.. i])
|
Nenue@0
|
343 lastMissing = missing
|
Nenue@0
|
344
|
Nenue@0
|
345 end
|
Nenue@0
|
346 end
|
Nenue@0
|
347
|
Nenue@0
|
348 if firstMissing then
|
Nenue@0
|
349 print(firstMissing:GetName(), raidbuffsFrame)
|
Nenue@0
|
350 firstMissing:SetPoint('TOPRIGHT', raidbuffsFrame.label, 'BOTTOMRIGHT', 0, c.Spacing)
|
Nenue@0
|
351 missingBuffsAnchor = firstMissing
|
Nenue@0
|
352 end
|
Nenue@0
|
353
|
Nenue@0
|
354 for i = numMissing +1, NUM_LE_MISSING_RAID_BUFFS do
|
Nenue@0
|
355 missingBuffs[i]:Hide()
|
Nenue@0
|
356 end
|
Nenue@0
|
357 NUM_LE_MISSING_RAID_BUFFS = numMissing
|
Nenue@0
|
358 end |