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