annotate RaidBuffTray.lua @ 7:5301c68f28d8

TrackerBlock - use IsModifiedClick function to determine appropriate OnClick actions - handle 'CHATLINK' modifier - handle 'TOGGLEQUESTWATCH' modifier TrackerBlockObjectives - use a generic framework to manage frame creation for various criteria tracker types: - ProgressBar when Blizzard flag data indicates so - skip when Blizzard flag data indicates so - DynamicText otherwise - events related to the criteria are registered in the criteria frame, and unregistered when the frame is hidden, either by destruction of its parent or completion
author Nenue
date Fri, 01 Apr 2016 12:27:05 -0400
parents 3dbcad2b387d
children
rev   line source
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