annotate BuffFrame/RaidBuffTray.lua @ 48:9837069e366a

move BuffFrame-specific things out of Veneer.lua straighten out table hierarchy for BuffFrame module
author Nenue
date Thu, 28 Apr 2016 06:58:13 -0400
parents 1a322b92dbfa
children 16465f3fd919
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@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