annotate SkeletonStats/DamageMeter.lua @ 4:a30285f8191e

Units: make sure unit frames are SecureUnitButton derivatives remove of unnecessary target/focus events Stats: resolve GUID after event handlers have fired keep frame manipulation in uf.ui, get needed values from wrapper functions
author Nenue
date Tue, 21 Jun 2016 11:56:14 -0400
parents 07293831dd7b
children
rev   line source
Nenue@0 1 --------------------------------------------
Nenue@0 2 -- KrakTool
Nenue@0 3 -- DamageMeter
Nenue@0 4 -- @project-revision@ @project-hash@
Nenue@0 5 -- @file-revision@ @file-hash@
Nenue@0 6 -- Created: 6/19/2016 10:43 AM
Nenue@0 7 --------------------------------------------
Nenue@0 8 -- dm
Nenue@0 9 -- {...} = actor ( name, guid ) -- returns actor table
Nenue@0 10 -- .showbar (bar ) -- toggle row
Nenue@0 11 -- .hidebar ( bar ) --
Nenue@0 12 -- .ui () -- update chart
Nenue@1 13 local KT = LibKT.register(DamageMeter)
Nenue@0 14 local dm = DamageMeter
Nenue@1 15 local db
Nenue@0 16
Nenue@4 17 local addon, core = ...
Nenue@4 18 core.segments = {}
Nenue@4 19 core.actors = {}
Nenue@4 20 core.pets = {}
Nenue@4 21 core.ordered = {}
Nenue@4 22 core.actorsOrdered = {}
Nenue@4 23 core.current = {}
Nenue@4 24 core.prototypes = {}
Nenue@4 25
Nenue@4 26 local GROUP_SIZE = 4
Nenue@4 27 local GROUP_TOKEN = 'party'
Nenue@4 28 local myGUID
Nenue@4 29 local segments, actors, pets, ordered = core.segments, core.actors, core.pets, core.ordered
Nenue@4 30 local prototypes = core.prototypes
Nenue@0 31 local segmentUID
Nenue@0 32 local viewPos
Nenue@0 33 local handler
Nenue@0 34 local viewType = 'damageDone'
Nenue@0 35 local meterWidth = 230
Nenue@0 36
Nenue@0 37 dm.init = function()
Nenue@0 38 dm:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED')
Nenue@1 39 dm:RegisterEvent('PLAYER_REGEN_DISABLED')
Nenue@0 40 dm:RegisterEvent('ENCOUNTER_START')
Nenue@0 41 dm.bars = dm.bars or {}
Nenue@0 42 dm.headings = dm.headings or {}
Nenue@0 43 end
Nenue@0 44
Nenue@0 45 dm.ENCOUNTER_START = function()
Nenue@0 46 dm.new()
Nenue@0 47 end
Nenue@0 48
Nenue@0 49 dm.variables = function()
Nenue@1 50 SkeletonStatsDB = SkeletonStatsDB or {}
Nenue@1 51 db = SkeletonStatsDB
Nenue@1 52 db.segments = db.segments or {}
Nenue@1 53 db.currentSegment = db.currentSegment or 0
Nenue@1 54 db.actors = db.actors or {}
Nenue@1 55 db.viewType = db.viewType or 'damageDone'
Nenue@0 56
Nenue@4 57
Nenue@4 58
Nenue@4 59 myGUID = UnitGUID('player')
Nenue@4 60 core.actor(myGUID)
Nenue@4 61 segments = db.segments
Nenue@4 62 viewPos = db.currentSegment
Nenue@4 63 viewType = prototypes[viewType] and viewType or 'damageDone'
Nenue@4 64
Nenue@4 65 if not segments[#segments] then
Nenue@4 66 dm.new()
Nenue@4 67 end
Nenue@0 68
Nenue@0 69 dm.handler(viewType)
Nenue@4 70 dm.view(viewPos)
Nenue@0 71
Nenue@0 72 dm.ui()
Nenue@0 73 end
Nenue@0 74
Nenue@0 75 dm.handler = function (viewType)
Nenue@0 76 handler = prototypes[viewType]
Nenue@0 77 dm.header:SetText(handler.header)
Nenue@0 78 end
Nenue@0 79
Nenue@0 80 dm.new = function()
Nenue@4 81 if core.active then
Nenue@4 82 core.active.finish = GetTime()
Nenue@4 83 end
Nenue@4 84
Nenue@1 85 segmentUID = (db.segUID or 0) + 1
Nenue@1 86 db.segUID = segmentUID
Nenue@4 87
Nenue@4 88 local segPos = #segments+1
Nenue@4 89 core.segments[segPos] = {
Nenue@4 90 view = {},
Nenue@4 91 start = GetTime(),
Nenue@4 92 uid = segmentUID
Nenue@4 93 }
Nenue@4 94 core.active = core.segments[viewPos].view
Nenue@4 95 print('Starting new segment #', segPos, 'UID', segmentUID, core.active, core.segments[viewPos])
Nenue@4 96
Nenue@4 97 dm.view(segPos)
Nenue@4 98
Nenue@0 99 return viewPos
Nenue@0 100 end
Nenue@4 101
Nenue@4 102 dm.view = function(pos)
Nenue@4 103 if not segments[pos] then
Nenue@4 104 pos = 1
Nenue@4 105 end
Nenue@4 106 core.current = segments[pos]
Nenue@4 107 core.current.view = core.current.view or {}
Nenue@4 108 end
Nenue@4 109
Nenue@0 110 local dummyColor = {
Nenue@0 111 r = 0,
Nenue@0 112 g = 0.5,
Nenue@0 113 b = 0
Nenue@0 114 }
Nenue@0 115 local dummyActor = {
Nenue@0 116 name = 'Unknown',
Nenue@0 117 flags = 0,
Nenue@0 118 class = 'NA',
Nenue@0 119 classFilename = '',
Nenue@0 120 race = 'Unknown',
Nenue@0 121 raceFilename = '',
Nenue@0 122 sex = 1,
Nenue@0 123 realm = ''
Nenue@0 124 }
Nenue@0 125
Nenue@4 126 local UNKNOWN_ACTOR = {
Nenue@4 127 name = 'Unknown',
Nenue@4 128 flags = 0,
Nenue@4 129 class = 'NADA'
Nenue@4 130 }
Nenue@4 131 --- Pull stored actor info if possible
Nenue@4 132 core.actor = function (guid, name, flags)
Nenue@4 133 local class, classFilename, race, raceFilename, sex, name, realm
Nenue@4 134 local actor = UNKNOWN_ACTOR
Nenue@4 135 if actors[guid] then
Nenue@4 136 print('cached GUID', guid)
Nenue@4 137 return actors[guid]
Nenue@4 138 end
Nenue@0 139
Nenue@4 140 if guid:match('^Player') then
Nenue@4 141 if db.actors[guid] then
Nenue@4 142 actor = db.actors[guid]
Nenue@4 143 print('using saved player GUID')
Nenue@4 144 else
Nenue@4 145
Nenue@4 146 class, classFilename, race, raceFilename, sex, name, realm = GetPlayerInfoByGUID(guid)
Nenue@4 147 actor = {
Nenue@4 148 name = name,
Nenue@4 149 flags = flags,
Nenue@4 150 class = class,
Nenue@4 151 classFilename = classFilename,
Nenue@4 152 race = race,
Nenue@4 153 raceFilename = raceFilename,
Nenue@4 154 sex = sex,
Nenue@4 155 realm = realm
Nenue@4 156 }
Nenue@4 157 print('saving player GUID')
Nenue@4 158 db.actors[guid] = actor
Nenue@4 159
Nenue@4 160 end
Nenue@4 161
Nenue@4 162 actors[guid] = actor
Nenue@4 163 elseif guid:match('^Pet') then
Nenue@4 164 print('analyzing pet GUID')
Nenue@4 165 actor = {
Nenue@0 166 name = name,
Nenue@4 167 class = 'PET',
Nenue@0 168 }
Nenue@4 169 if not pets[guid] then
Nenue@4 170 if bit.band(flags, COMBATLOG_OBJECT_AFFILIATION_MINE) > 0 then
Nenue@4 171 pets[guid] = myGUID
Nenue@4 172 actors[myGUID].pets = actors[myGUID].pets or {}
Nenue@4 173 actors[myGUID].pets[guid] = actor
Nenue@4 174 elseif bit.band(flags, COMBATLOG_OBJECT_AFFILIATION_PARTY+COMBATLOG_OBJECT_AFFILIATION_RAID > 0) then
Nenue@4 175 -- todo: handle party/raid pets
Nenue@4 176 end
Nenue@4 177 end
Nenue@4 178 actors[guid] = actor
Nenue@4 179 end
Nenue@4 180 return actor
Nenue@0 181 end
Nenue@0 182
Nenue@1 183 dm.PLAYER_REGEN_DISABLED = function()
Nenue@1 184 dm.new()
Nenue@1 185 end
Nenue@1 186
Nenue@0 187 dm.COMBAT_LOG_EVENT_UNFILTERED = function(self, event, timeStemp, subEvent, u1, ...)
Nenue@0 188 local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags = ...
Nenue@0 189
Nenue@4 190 local storeActor = false
Nenue@0 191 local args = {...}
Nenue@0 192 for key, prototype in pairs(prototypes) do
Nenue@0 193 --print(subEvent)
Nenue@0 194 if prototype[subEvent] then
Nenue@4 195 local result = prototype[subEvent](subEvent, ...)
Nenue@4 196 storeActor = (storeActor or result)
Nenue@3 197 --print('|cFFFFFF00' .. key .. '|r.|cFF00FFFF'..subEvent, '|r', ...)
Nenue@0 198 end
Nenue@0 199 end
Nenue@0 200
Nenue@4 201 if storeActor then
Nenue@4 202 core.actor(sourceGUID, sourceName, sourceFlags)
Nenue@4 203 core.actor(destGUID, destName, destFlags)
Nenue@4 204 end
Nenue@4 205
Nenue@0 206 dm.ui()
Nenue@0 207 return true
Nenue@0 208 end
Nenue@0 209
Nenue@0 210 --- [name]
Nenue@0 211 -- .COMBAT_EVENT = function(event, ...)
Nenue@0 212 -- .init = function()
Nenue@0 213 -- .calculate = function(bar, data, actor)
Nenue@0 214 -- .refresh = function(bar, data, actor
Nenue@0 215
Nenue@0 216 dm.showbar = function(bar)
Nenue@0 217 bar:Show()
Nenue@0 218 bar.icon:Show()
Nenue@0 219 bar.header:Show()
Nenue@0 220 bar.headerRight:Show()
Nenue@0 221 end
Nenue@0 222
Nenue@0 223 dm.hidebar = function(bar)
Nenue@0 224 bar:Hide()
Nenue@0 225 bar.icon:Hide()
Nenue@0 226 bar.header:Hide()
Nenue@0 227 bar.headerRight:Hide()
Nenue@0 228 end
Nenue@0 229
Nenue@0 230 dm.ui = function()
Nenue@0 231 --table.sort(view, sortType)
Nenue@4 232 local view = core.current.view
Nenue@0 233
Nenue@0 234 table.wipe(ordered)
Nenue@0 235 for k,v in pairs(view) do
Nenue@0 236 if type(v) ~= 'table' then
Nenue@0 237 view[k] = nil
Nenue@0 238 else
Nenue@0 239 tinsert(ordered, v)
Nenue@0 240 end
Nenue@0 241 end
Nenue@0 242 table.sort(ordered, handler.sort)
Nenue@0 243
Nenue@0 244 handler.init()
Nenue@0 245
Nenue@0 246 for i = 1, 12 do
Nenue@0 247 if ordered[i] then
Nenue@0 248 if not dm.bars[i] then
Nenue@0 249 dm.bars[i] = dm:CreateTexture('MeterBar'..i, 'BORDER')
Nenue@0 250 dm.bars[i]:SetHeight(24)
Nenue@0 251 dm.bars[i]:SetPoint('TOPLEFT', dm, 0, i * -24)
Nenue@0 252 dm.bars[i].icon = dm:CreateTexture('MeterIcon' .. i, 'OVERLAY')
Nenue@0 253 dm.bars[i].icon:SetSize(24,24)
Nenue@0 254 dm.bars[i].icon:SetPoint('TOPLEFT', dm.bars[i], 'TOPLEFT', -12, 0)
Nenue@0 255
Nenue@0 256 dm.bars[i].header = dm:CreateFontString('MeterHeader'..i, 'OVERLAY', 'MeterHeaderLeft')
Nenue@0 257 dm.bars[i].header:SetPoint('LEFT', dm.bars[i], 'LEFT', 22, 0)
Nenue@0 258
Nenue@0 259 dm.bars[i].headerRight = dm:CreateFontString('MeterHeaderRight'..i, 'OVERLAY', 'MeterHeaderRight')
Nenue@0 260 dm.bars[i].headerRight:SetPoint('TOP', dm.bars[i], 'TOP', 0, -6)
Nenue@0 261 end
Nenue@4 262
Nenue@4 263 local actor = actors[ordered[i].guid] or UNKNOWN_ACTOR
Nenue@4 264 handler.calculate(dm.bars[i], ordered[i], ordered[i], actor)
Nenue@0 265 end
Nenue@0 266 end
Nenue@0 267
Nenue@0 268 for i, bar in ipairs(dm.bars) do
Nenue@0 269 if ordered[i] then
Nenue@4 270
Nenue@4 271 local actor = actors[ordered[i].guid] or UNKNOWN_ACTOR
Nenue@4 272 local icon, textLeft, textRight, r, g, b, a, percent = handler.refresh(bar, ordered[i], actor)
Nenue@4 273
Nenue@4 274 bar:SetColorTexture(r, g, b, a)
Nenue@4 275
Nenue@4 276 if icon then
Nenue@4 277 bar.icon:Show()
Nenue@4 278 bar.icon:SetTexture(icon[1])
Nenue@4 279 if icon[2] then
Nenue@4 280 bar.icon:SetTexCoord(unpack(icon[2]))
Nenue@4 281 else
Nenue@4 282 bar.icon:SetTexCoord(1,0,1,0)
Nenue@4 283 end
Nenue@4 284 else
Nenue@4 285 bar.icon:Hide()
Nenue@4 286 end
Nenue@4 287
Nenue@4 288 if textLeft then
Nenue@4 289 bar.header:Show()
Nenue@4 290 bar.header:SetText(textLeft)
Nenue@4 291 else
Nenue@4 292 bar.header:Hide()
Nenue@4 293 end
Nenue@4 294 if textRight then
Nenue@4 295 bar.headerRight:Show()
Nenue@4 296 bar.headerRight:SetText(textRight)
Nenue@4 297 else
Nenue@4 298 bar.headerRight:Hide()
Nenue@4 299 end
Nenue@4 300
Nenue@4 301 bar:SetWidth(meterWidth*percent)
Nenue@4 302 bar:Show()
Nenue@0 303 else
Nenue@0 304 dm.hidebar(bar)
Nenue@0 305 end
Nenue@0 306 end
Nenue@0 307 dm:SetHeight((#ordered + 1) * 24)
Nenue@0 308 dm:SetWidth(meterWidth)
Nenue@0 309 end
Nenue@0 310 ---------------------------------------------------------
Nenue@0 311 -- DAMAGE DONE
Nenue@0 312
Nenue@0 313
Nenue@0 314 ---------------------------------------------------------
Nenue@0 315 -- HEALING DONE