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