Mercurial > wow > skeletonkey
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 3:07293831dd7b | 4:a30285f8191e |
|---|---|
| 11 -- .hidebar ( bar ) -- | 11 -- .hidebar ( bar ) -- |
| 12 -- .ui () -- update chart | 12 -- .ui () -- update chart |
| 13 local KT = LibKT.register(DamageMeter) | 13 local KT = LibKT.register(DamageMeter) |
| 14 local dm = DamageMeter | 14 local dm = DamageMeter |
| 15 local db | 15 local db |
| 16 local segments = {} | 16 |
| 17 local actors = {} | 17 local addon, core = ... |
| 18 local ordered = {} | 18 core.segments = {} |
| 19 local actorsOrdered = {} | 19 core.actors = {} |
| 20 local prototypes = {} | 20 core.pets = {} |
| 21 | 21 core.ordered = {} |
| 22 core.actorsOrdered = {} | |
| 23 core.current = {} | |
| 24 core.prototypes = {} | |
| 25 | |
| 26 local GROUP_SIZE = 4 | |
| 27 local GROUP_TOKEN = 'party' | |
| 28 local myGUID | |
| 29 local segments, actors, pets, ordered = core.segments, core.actors, core.pets, core.ordered | |
| 30 local prototypes = core.prototypes | |
| 22 local segmentUID | 31 local segmentUID |
| 23 local viewPos | 32 local viewPos |
| 24 local view | |
| 25 local handler | 33 local handler |
| 26 local viewType = 'damageDone' | 34 local viewType = 'damageDone' |
| 27 local sortType | |
| 28 local meterWidth = 230 | 35 local meterWidth = 230 |
| 29 | |
| 30 local SortByDamage = function(a, b) | |
| 31 end | |
| 32 | 36 |
| 33 dm.init = function() | 37 dm.init = function() |
| 34 dm:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED') | 38 dm:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED') |
| 35 dm:RegisterEvent('PLAYER_REGEN_DISABLED') | 39 dm:RegisterEvent('PLAYER_REGEN_DISABLED') |
| 36 dm:RegisterEvent('ENCOUNTER_START') | 40 dm:RegisterEvent('ENCOUNTER_START') |
| 48 db.segments = db.segments or {} | 52 db.segments = db.segments or {} |
| 49 db.currentSegment = db.currentSegment or 0 | 53 db.currentSegment = db.currentSegment or 0 |
| 50 db.actors = db.actors or {} | 54 db.actors = db.actors or {} |
| 51 db.viewType = db.viewType or 'damageDone' | 55 db.viewType = db.viewType or 'damageDone' |
| 52 | 56 |
| 53 actors = db.actors | 57 |
| 54 segments = db.segments | 58 |
| 55 viewPos = db.currentSegment | 59 myGUID = UnitGUID('player') |
| 56 viewType = prototypes[viewType] and viewType or 'damageDone' | 60 core.actor(myGUID) |
| 61 segments = db.segments | |
| 62 viewPos = db.currentSegment | |
| 63 viewType = prototypes[viewType] and viewType or 'damageDone' | |
| 64 | |
| 65 if not segments[#segments] then | |
| 66 dm.new() | |
| 67 end | |
| 57 | 68 |
| 58 dm.handler(viewType) | 69 dm.handler(viewType) |
| 59 | 70 dm.view(viewPos) |
| 60 -- resolve segment | |
| 61 if not segments[viewPos] then | |
| 62 viewPos = dm.new() | |
| 63 else | |
| 64 view = segments[viewPos] | |
| 65 print('Using segment #', viewPos) | |
| 66 end | |
| 67 db.currentSegment = viewPos | |
| 68 | 71 |
| 69 dm.ui() | 72 dm.ui() |
| 70 end | 73 end |
| 71 | 74 |
| 72 dm.handler = function (viewType) | 75 dm.handler = function (viewType) |
| 73 handler = prototypes[viewType] | 76 handler = prototypes[viewType] |
| 74 dm.header:SetText(handler.header) | 77 dm.header:SetText(handler.header) |
| 75 end | 78 end |
| 76 | 79 |
| 77 dm.new = function() | 80 dm.new = function() |
| 81 if core.active then | |
| 82 core.active.finish = GetTime() | |
| 83 end | |
| 84 | |
| 78 segmentUID = (db.segUID or 0) + 1 | 85 segmentUID = (db.segUID or 0) + 1 |
| 79 db.segUID = segmentUID | 86 db.segUID = segmentUID |
| 80 view = {} | 87 |
| 81 viewPos = #segments+1 | 88 local segPos = #segments+1 |
| 82 segments[viewPos] = view | 89 core.segments[segPos] = { |
| 83 db.currentSegment = viewPos | 90 view = {}, |
| 84 print('Starting new segment #', viewPos) | 91 start = GetTime(), |
| 92 uid = segmentUID | |
| 93 } | |
| 94 core.active = core.segments[viewPos].view | |
| 95 print('Starting new segment #', segPos, 'UID', segmentUID, core.active, core.segments[viewPos]) | |
| 96 | |
| 97 dm.view(segPos) | |
| 98 | |
| 85 return viewPos | 99 return viewPos |
| 86 end | 100 end |
| 101 | |
| 102 dm.view = function(pos) | |
| 103 if not segments[pos] then | |
| 104 pos = 1 | |
| 105 end | |
| 106 core.current = segments[pos] | |
| 107 core.current.view = core.current.view or {} | |
| 108 end | |
| 109 | |
| 87 local dummyColor = { | 110 local dummyColor = { |
| 88 r = 0, | 111 r = 0, |
| 89 g = 0.5, | 112 g = 0.5, |
| 90 b = 0 | 113 b = 0 |
| 91 } | 114 } |
| 98 raceFilename = '', | 121 raceFilename = '', |
| 99 sex = 1, | 122 sex = 1, |
| 100 realm = '' | 123 realm = '' |
| 101 } | 124 } |
| 102 | 125 |
| 103 dm.actor = function (guid, name, flags) | 126 local UNKNOWN_ACTOR = { |
| 104 --if not actors[guid] then | 127 name = 'Unknown', |
| 105 local class, classFilename, race, raceFilename, sex, name, realm = GetPlayerInfoByGUID(guid) | 128 flags = 0, |
| 106 | 129 class = 'NADA' |
| 107 --print('|cFFFFFF00guid|r =', name, flags, 'class', class, classFilename) | 130 } |
| 108 actors[guid] = { | 131 --- Pull stored actor info if possible |
| 132 core.actor = function (guid, name, flags) | |
| 133 local class, classFilename, race, raceFilename, sex, name, realm | |
| 134 local actor = UNKNOWN_ACTOR | |
| 135 if actors[guid] then | |
| 136 print('cached GUID', guid) | |
| 137 return actors[guid] | |
| 138 end | |
| 139 | |
| 140 if guid:match('^Player') then | |
| 141 if db.actors[guid] then | |
| 142 actor = db.actors[guid] | |
| 143 print('using saved player GUID') | |
| 144 else | |
| 145 | |
| 146 class, classFilename, race, raceFilename, sex, name, realm = GetPlayerInfoByGUID(guid) | |
| 147 actor = { | |
| 148 name = name, | |
| 149 flags = flags, | |
| 150 class = class, | |
| 151 classFilename = classFilename, | |
| 152 race = race, | |
| 153 raceFilename = raceFilename, | |
| 154 sex = sex, | |
| 155 realm = realm | |
| 156 } | |
| 157 print('saving player GUID') | |
| 158 db.actors[guid] = actor | |
| 159 | |
| 160 end | |
| 161 | |
| 162 actors[guid] = actor | |
| 163 elseif guid:match('^Pet') then | |
| 164 print('analyzing pet GUID') | |
| 165 actor = { | |
| 109 name = name, | 166 name = name, |
| 110 flags = flags, | 167 class = 'PET', |
| 111 class = class, | |
| 112 classFilename = classFilename, | |
| 113 race = race, | |
| 114 raceFilename = raceFilename, | |
| 115 sex = sex, | |
| 116 realm = realm | |
| 117 } | 168 } |
| 118 --end | 169 if not pets[guid] then |
| 119 return actors[guid] | 170 if bit.band(flags, COMBATLOG_OBJECT_AFFILIATION_MINE) > 0 then |
| 120 end | 171 pets[guid] = myGUID |
| 121 | 172 actors[myGUID].pets = actors[myGUID].pets or {} |
| 122 | 173 actors[myGUID].pets[guid] = actor |
| 123 prototypes.damageDone = { | 174 elseif bit.band(flags, COMBATLOG_OBJECT_AFFILIATION_PARTY+COMBATLOG_OBJECT_AFFILIATION_RAID > 0) then |
| 124 header = 'Damage Done', | 175 -- todo: handle party/raid pets |
| 125 } | 176 end |
| 177 end | |
| 178 actors[guid] = actor | |
| 179 end | |
| 180 return actor | |
| 181 end | |
| 126 | 182 |
| 127 dm.PLAYER_REGEN_DISABLED = function() | 183 dm.PLAYER_REGEN_DISABLED = function() |
| 128 dm.new() | 184 dm.new() |
| 129 end | 185 end |
| 130 | 186 |
| 131 dm.COMBAT_LOG_EVENT_UNFILTERED = function(self, event, timeStemp, subEvent, u1, ...) | 187 dm.COMBAT_LOG_EVENT_UNFILTERED = function(self, event, timeStemp, subEvent, u1, ...) |
| 132 local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags = ... | 188 local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags = ... |
| 133 | 189 |
| 134 | 190 local storeActor = false |
| 135 local args = {...} | 191 local args = {...} |
| 136 for key, prototype in pairs(prototypes) do | 192 for key, prototype in pairs(prototypes) do |
| 137 --print(subEvent) | 193 --print(subEvent) |
| 138 if prototype[subEvent] then | 194 if prototype[subEvent] then |
| 139 prototype[subEvent](subEvent, ...) | 195 local result = prototype[subEvent](subEvent, ...) |
| 196 storeActor = (storeActor or result) | |
| 140 --print('|cFFFFFF00' .. key .. '|r.|cFF00FFFF'..subEvent, '|r', ...) | 197 --print('|cFFFFFF00' .. key .. '|r.|cFF00FFFF'..subEvent, '|r', ...) |
| 141 end | 198 end |
| 199 end | |
| 200 | |
| 201 if storeActor then | |
| 202 core.actor(sourceGUID, sourceName, sourceFlags) | |
| 203 core.actor(destGUID, destName, destFlags) | |
| 142 end | 204 end |
| 143 | 205 |
| 144 dm.ui() | 206 dm.ui() |
| 145 return true | 207 return true |
| 146 end | 208 end |
| 165 bar.headerRight:Hide() | 227 bar.headerRight:Hide() |
| 166 end | 228 end |
| 167 | 229 |
| 168 dm.ui = function() | 230 dm.ui = function() |
| 169 --table.sort(view, sortType) | 231 --table.sort(view, sortType) |
| 170 | 232 local view = core.current.view |
| 171 | 233 |
| 172 table.wipe(ordered) | 234 table.wipe(ordered) |
| 173 for k,v in pairs(view) do | 235 for k,v in pairs(view) do |
| 174 if type(v) ~= 'table' then | 236 if type(v) ~= 'table' then |
| 175 view[k] = nil | 237 view[k] = nil |
| 195 dm.bars[i].header:SetPoint('LEFT', dm.bars[i], 'LEFT', 22, 0) | 257 dm.bars[i].header:SetPoint('LEFT', dm.bars[i], 'LEFT', 22, 0) |
| 196 | 258 |
| 197 dm.bars[i].headerRight = dm:CreateFontString('MeterHeaderRight'..i, 'OVERLAY', 'MeterHeaderRight') | 259 dm.bars[i].headerRight = dm:CreateFontString('MeterHeaderRight'..i, 'OVERLAY', 'MeterHeaderRight') |
| 198 dm.bars[i].headerRight:SetPoint('TOP', dm.bars[i], 'TOP', 0, -6) | 260 dm.bars[i].headerRight:SetPoint('TOP', dm.bars[i], 'TOP', 0, -6) |
| 199 end | 261 end |
| 200 handler.calculate(dm.bars[i], ordered[i], ordered[i].actor) | 262 |
| 263 local actor = actors[ordered[i].guid] or UNKNOWN_ACTOR | |
| 264 handler.calculate(dm.bars[i], ordered[i], ordered[i], actor) | |
| 201 end | 265 end |
| 202 end | 266 end |
| 203 | 267 |
| 204 for i, bar in ipairs(dm.bars) do | 268 for i, bar in ipairs(dm.bars) do |
| 205 if ordered[i] then | 269 if ordered[i] then |
| 206 handler.refresh(bar, ordered[i], ordered[i].actor) | 270 |
| 207 dm.showbar(bar) | 271 local actor = actors[ordered[i].guid] or UNKNOWN_ACTOR |
| 272 local icon, textLeft, textRight, r, g, b, a, percent = handler.refresh(bar, ordered[i], actor) | |
| 273 | |
| 274 bar:SetColorTexture(r, g, b, a) | |
| 275 | |
| 276 if icon then | |
| 277 bar.icon:Show() | |
| 278 bar.icon:SetTexture(icon[1]) | |
| 279 if icon[2] then | |
| 280 bar.icon:SetTexCoord(unpack(icon[2])) | |
| 281 else | |
| 282 bar.icon:SetTexCoord(1,0,1,0) | |
| 283 end | |
| 284 else | |
| 285 bar.icon:Hide() | |
| 286 end | |
| 287 | |
| 288 if textLeft then | |
| 289 bar.header:Show() | |
| 290 bar.header:SetText(textLeft) | |
| 291 else | |
| 292 bar.header:Hide() | |
| 293 end | |
| 294 if textRight then | |
| 295 bar.headerRight:Show() | |
| 296 bar.headerRight:SetText(textRight) | |
| 297 else | |
| 298 bar.headerRight:Hide() | |
| 299 end | |
| 300 | |
| 301 bar:SetWidth(meterWidth*percent) | |
| 302 bar:Show() | |
| 208 else | 303 else |
| 209 dm.hidebar(bar) | 304 dm.hidebar(bar) |
| 210 end | 305 end |
| 211 end | 306 end |
| 212 dm:SetHeight((#ordered + 1) * 24) | 307 dm:SetHeight((#ordered + 1) * 24) |
| 213 dm:SetWidth(meterWidth) | 308 dm:SetWidth(meterWidth) |
| 214 end | 309 end |
| 215 --------------------------------------------------------- | 310 --------------------------------------------------------- |
| 216 -- DAMAGE DONE | 311 -- DAMAGE DONE |
| 217 local dd = prototypes.damageDone | |
| 218 dd.SPELL_DAMAGE = function(subEvent, ...) | |
| 219 local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, spellID, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing = ... | |
| 220 | |
| 221 if not sourceName then | |
| 222 return | |
| 223 end | |
| 224 | |
| 225 view[sourceName] = view[sourceName] or {} | |
| 226 local p = view[sourceName] | |
| 227 | |
| 228 p.actor = dm.actor(sourceGUID, sourceName, sourceFlags) | |
| 229 dm.actor(destGUID, destName, destFlags) | |
| 230 | |
| 231 p.last = amount | |
| 232 p.damage = (view[sourceName].damage or 0) + amount | |
| 233 p.name = (sourceName or 'Unknown') | |
| 234 | |
| 235 p.child = p.child or {} | |
| 236 p.child[spellName] = p.child[spellName] or {} | |
| 237 p.child[spellName].hit = (p.child[spellName].hit or 0) + 1 | |
| 238 end | |
| 239 dd.SPELL_DAMAGE_PERIODIC = dd.SPELL_DAMAGE | |
| 240 dd.RANGE_DAMAGE = dd.SPELL_DAMAGE | |
| 241 | |
| 242 dd.SWING_DAMAGE = function(subEvent, ...) | |
| 243 local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing = ... | |
| 244 local spellID, spellName, spellSchool = -1, 'Attack', 1 | |
| 245 dd.SPELL_DAMAGE(subEvent, sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, spellID, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing) | |
| 246 end | |
| 247 | |
| 248 dd.init = function() | |
| 249 dd.maxDamage = 0 | |
| 250 end | |
| 251 | |
| 252 dd.sort = function(a, b) | |
| 253 return a.damage > b.damage | |
| 254 end | |
| 255 | |
| 256 dd.calculate = function(bar, data, actor) | |
| 257 if dd.maxDamage < data.damage then | |
| 258 dd.maxDamage = data.damage | |
| 259 end | |
| 260 | |
| 261 end | |
| 262 | |
| 263 dd.refresh = function(bar, data, actor) | |
| 264 if actor.class and CLASS_ICON_TCOORDS[actor.classFilename] then | |
| 265 bar.icon:Show() | |
| 266 bar.icon:SetTexture("Interface\\TargetingFrame\\UI-Classes-Circles") | |
| 267 bar.icon:SetTexCoord(unpack(CLASS_ICON_TCOORDS[actor.classFilename])) | |
| 268 else | |
| 269 bar.icon:Hide() | |
| 270 end | |
| 271 bar.header:SetText(data.name) | |
| 272 bar.headerRight:SetText(data.damage .. ' ('..data.last..')') | |
| 273 | |
| 274 local color = dummyColor | |
| 275 if actor.class and RAID_CLASS_COLORS[actor.classFilename] then | |
| 276 color = RAID_CLASS_COLORS[actor.classFilename] | |
| 277 end | |
| 278 | |
| 279 bar:SetColorTexture(color.r, color.g, color.b, 1) | |
| 280 | |
| 281 bar:SetWidth(meterWidth * (data.damage / dd.maxDamage)) | |
| 282 end | |
| 283 | 312 |
| 284 | 313 |
| 285 --------------------------------------------------------- | 314 --------------------------------------------------------- |
| 286 -- HEALING DONE | 315 -- HEALING DONE |
