annotate SkeletonStats/DamageMeter.lua @ 1:cd7d06bcd98d

KeyBinds: set hotkey text for blizzard action buttons UnitFrame: prototype templates for the majority of units
author Nenue
date Tue, 21 Jun 2016 04:47:52 -0400
parents 69e828f4238a
children 07293831dd7b
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 local segments = {}
Nenue@0 17 local actors = {}
Nenue@0 18 local ordered = {}
Nenue@0 19 local actorsOrdered = {}
Nenue@0 20 local prototypes = {}
Nenue@0 21
Nenue@0 22 local segmentUID
Nenue@0 23 local viewPos
Nenue@0 24 local view
Nenue@0 25 local handler
Nenue@0 26 local viewType = 'damageDone'
Nenue@0 27 local sortType
Nenue@0 28 local meterWidth = 230
Nenue@0 29
Nenue@0 30 local SortByDamage = function(a, b)
Nenue@0 31 end
Nenue@0 32
Nenue@0 33 dm.init = function()
Nenue@0 34 dm:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED')
Nenue@1 35 dm:RegisterEvent('PLAYER_REGEN_DISABLED')
Nenue@0 36 dm:RegisterEvent('ENCOUNTER_START')
Nenue@0 37 dm.bars = dm.bars or {}
Nenue@0 38 dm.headings = dm.headings or {}
Nenue@0 39 end
Nenue@0 40
Nenue@0 41 dm.ENCOUNTER_START = function()
Nenue@0 42 dm.new()
Nenue@0 43 end
Nenue@0 44
Nenue@0 45 dm.variables = function()
Nenue@1 46 SkeletonStatsDB = SkeletonStatsDB or {}
Nenue@1 47 db = SkeletonStatsDB
Nenue@1 48 db.segments = db.segments or {}
Nenue@1 49 db.currentSegment = db.currentSegment or 0
Nenue@1 50 db.actors = db.actors or {}
Nenue@1 51 db.viewType = db.viewType or 'damageDone'
Nenue@0 52
Nenue@1 53 actors = db.actors
Nenue@1 54 segments = db.segments
Nenue@1 55 viewPos = db.currentSegment
Nenue@1 56 viewType = prototypes[viewType] and viewType or 'damageDone'
Nenue@0 57
Nenue@0 58 dm.handler(viewType)
Nenue@0 59
Nenue@0 60 -- resolve segment
Nenue@0 61 if not segments[viewPos] then
Nenue@0 62 viewPos = dm.new()
Nenue@0 63 else
Nenue@0 64 view = segments[viewPos]
Nenue@0 65 print('Using segment #', viewPos)
Nenue@0 66 end
Nenue@1 67 db.currentSegment = viewPos
Nenue@0 68
Nenue@0 69 dm.ui()
Nenue@0 70 end
Nenue@0 71
Nenue@0 72 dm.handler = function (viewType)
Nenue@0 73 handler = prototypes[viewType]
Nenue@0 74 dm.header:SetText(handler.header)
Nenue@0 75 end
Nenue@0 76
Nenue@0 77 dm.new = function()
Nenue@1 78 segmentUID = (db.segUID or 0) + 1
Nenue@1 79 db.segUID = segmentUID
Nenue@0 80 view = {}
Nenue@0 81 viewPos = #segments+1
Nenue@0 82 segments[viewPos] = view
Nenue@1 83 db.currentSegment = viewPos
Nenue@0 84 print('Starting new segment #', viewPos)
Nenue@0 85 return viewPos
Nenue@0 86 end
Nenue@0 87 local dummyColor = {
Nenue@0 88 r = 0,
Nenue@0 89 g = 0.5,
Nenue@0 90 b = 0
Nenue@0 91 }
Nenue@0 92 local dummyActor = {
Nenue@0 93 name = 'Unknown',
Nenue@0 94 flags = 0,
Nenue@0 95 class = 'NA',
Nenue@0 96 classFilename = '',
Nenue@0 97 race = 'Unknown',
Nenue@0 98 raceFilename = '',
Nenue@0 99 sex = 1,
Nenue@0 100 realm = ''
Nenue@0 101 }
Nenue@0 102
Nenue@0 103 dm.actor = function (guid, name, flags)
Nenue@0 104 --if not actors[guid] then
Nenue@0 105 local class, classFilename, race, raceFilename, sex, name, realm = GetPlayerInfoByGUID(guid)
Nenue@0 106
Nenue@0 107 print('|cFFFFFF00guid|r =', name, flags, 'class', class, classFilename)
Nenue@0 108 actors[guid] = {
Nenue@0 109 name = name,
Nenue@0 110 flags = flags,
Nenue@0 111 class = class,
Nenue@0 112 classFilename = classFilename,
Nenue@0 113 race = race,
Nenue@0 114 raceFilename = raceFilename,
Nenue@0 115 sex = sex,
Nenue@0 116 realm = realm
Nenue@0 117 }
Nenue@0 118 --end
Nenue@0 119 return actors[guid]
Nenue@0 120 end
Nenue@0 121
Nenue@0 122
Nenue@0 123 prototypes.damageDone = {
Nenue@0 124 header = 'Damage Done',
Nenue@0 125 }
Nenue@0 126
Nenue@1 127 dm.PLAYER_REGEN_DISABLED = function()
Nenue@1 128 dm.new()
Nenue@1 129 end
Nenue@1 130
Nenue@0 131 dm.COMBAT_LOG_EVENT_UNFILTERED = function(self, event, timeStemp, subEvent, u1, ...)
Nenue@0 132 local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags = ...
Nenue@0 133
Nenue@0 134
Nenue@0 135 local args = {...}
Nenue@0 136 for key, prototype in pairs(prototypes) do
Nenue@0 137 --print(subEvent)
Nenue@0 138 if prototype[subEvent] then
Nenue@0 139 prototype[subEvent](subEvent, ...)
Nenue@0 140 print('|cFFFFFF00' .. key .. '|r.|cFF00FFFF'..subEvent, '|r', ...)
Nenue@0 141 end
Nenue@0 142 end
Nenue@0 143
Nenue@0 144 dm.ui()
Nenue@0 145 return true
Nenue@0 146 end
Nenue@0 147
Nenue@0 148 --- [name]
Nenue@0 149 -- .COMBAT_EVENT = function(event, ...)
Nenue@0 150 -- .init = function()
Nenue@0 151 -- .calculate = function(bar, data, actor)
Nenue@0 152 -- .refresh = function(bar, data, actor
Nenue@0 153
Nenue@0 154 dm.showbar = function(bar)
Nenue@0 155 bar:Show()
Nenue@0 156 bar.icon:Show()
Nenue@0 157 bar.header:Show()
Nenue@0 158 bar.headerRight:Show()
Nenue@0 159 end
Nenue@0 160
Nenue@0 161 dm.hidebar = function(bar)
Nenue@0 162 bar:Hide()
Nenue@0 163 bar.icon:Hide()
Nenue@0 164 bar.header:Hide()
Nenue@0 165 bar.headerRight:Hide()
Nenue@0 166 end
Nenue@0 167
Nenue@0 168 dm.ui = function()
Nenue@0 169 --table.sort(view, sortType)
Nenue@0 170
Nenue@0 171
Nenue@0 172 table.wipe(ordered)
Nenue@0 173 for k,v in pairs(view) do
Nenue@0 174 if type(v) ~= 'table' then
Nenue@0 175 view[k] = nil
Nenue@0 176 else
Nenue@0 177 tinsert(ordered, v)
Nenue@0 178 end
Nenue@0 179 end
Nenue@0 180 table.sort(ordered, handler.sort)
Nenue@0 181
Nenue@0 182 handler.init()
Nenue@0 183
Nenue@0 184 for i = 1, 12 do
Nenue@0 185 if ordered[i] then
Nenue@0 186 if not dm.bars[i] then
Nenue@0 187 dm.bars[i] = dm:CreateTexture('MeterBar'..i, 'BORDER')
Nenue@0 188 dm.bars[i]:SetHeight(24)
Nenue@0 189 dm.bars[i]:SetPoint('TOPLEFT', dm, 0, i * -24)
Nenue@0 190 dm.bars[i].icon = dm:CreateTexture('MeterIcon' .. i, 'OVERLAY')
Nenue@0 191 dm.bars[i].icon:SetSize(24,24)
Nenue@0 192 dm.bars[i].icon:SetPoint('TOPLEFT', dm.bars[i], 'TOPLEFT', -12, 0)
Nenue@0 193
Nenue@0 194 dm.bars[i].header = dm:CreateFontString('MeterHeader'..i, 'OVERLAY', 'MeterHeaderLeft')
Nenue@0 195 dm.bars[i].header:SetPoint('LEFT', dm.bars[i], 'LEFT', 22, 0)
Nenue@0 196
Nenue@0 197 dm.bars[i].headerRight = dm:CreateFontString('MeterHeaderRight'..i, 'OVERLAY', 'MeterHeaderRight')
Nenue@0 198 dm.bars[i].headerRight:SetPoint('TOP', dm.bars[i], 'TOP', 0, -6)
Nenue@0 199 end
Nenue@0 200 handler.calculate(dm.bars[i], ordered[i], ordered[i].actor)
Nenue@0 201 end
Nenue@0 202 end
Nenue@0 203
Nenue@0 204 for i, bar in ipairs(dm.bars) do
Nenue@0 205 if ordered[i] then
Nenue@0 206 handler.refresh(bar, ordered[i], ordered[i].actor)
Nenue@0 207 dm.showbar(bar)
Nenue@0 208 else
Nenue@0 209 dm.hidebar(bar)
Nenue@0 210 end
Nenue@0 211 end
Nenue@0 212 dm:SetHeight((#ordered + 1) * 24)
Nenue@0 213 dm:SetWidth(meterWidth)
Nenue@0 214 end
Nenue@0 215 ---------------------------------------------------------
Nenue@0 216 -- DAMAGE DONE
Nenue@0 217 local dd = prototypes.damageDone
Nenue@0 218 dd.SPELL_DAMAGE = function(subEvent, ...)
Nenue@0 219 local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, spellID, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing = ...
Nenue@0 220
Nenue@0 221 view[sourceName] = view[sourceName] or {}
Nenue@0 222 local p = view[sourceName]
Nenue@0 223
Nenue@0 224 p.actor = dm.actor(sourceGUID, sourceName, sourceFlags)
Nenue@0 225 dm.actor(destGUID, destName, destFlags)
Nenue@0 226
Nenue@0 227 p.last = amount
Nenue@0 228 p.damage = (view[sourceName].damage or 0) + amount
Nenue@0 229 p.name = (sourceName or 'Unknown')
Nenue@0 230
Nenue@0 231 p.child = p.child or {}
Nenue@0 232 p.child[spellName] = p.child[spellName] or {}
Nenue@0 233 p.child[spellName].hit = (p.child[spellName].hit or 0) + 1
Nenue@0 234 end
Nenue@0 235 dd.SPELL_DAMAGE_PERIODIC = dd.SPELL_DAMAGE
Nenue@0 236 dd.RANGE_DAMAGE = dd.SPELL_DAMAGE
Nenue@0 237
Nenue@0 238 dd.SWING_DAMAGE = function(subEvent, ...)
Nenue@0 239 local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing = ...
Nenue@0 240 local spellID, spellName, spellSchool = -1, 'Attack', 1
Nenue@0 241 dd.SPELL_DAMAGE(subEvent, sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, spellID, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing)
Nenue@0 242 end
Nenue@0 243
Nenue@0 244 dd.init = function()
Nenue@0 245 dd.maxDamage = 0
Nenue@0 246 end
Nenue@0 247
Nenue@0 248 dd.sort = function(a, b)
Nenue@0 249 return a.damage > b.damage
Nenue@0 250 end
Nenue@0 251
Nenue@0 252 dd.calculate = function(bar, data, actor)
Nenue@0 253 if dd.maxDamage < data.damage then
Nenue@0 254 dd.maxDamage = data.damage
Nenue@0 255 end
Nenue@0 256
Nenue@0 257 end
Nenue@0 258
Nenue@0 259 dd.refresh = function(bar, data, actor)
Nenue@0 260 if actor.class and CLASS_ICON_TCOORDS[actor.classFilename] then
Nenue@0 261 bar.icon:Show()
Nenue@0 262 bar.icon:SetTexture("Interface\\TargetingFrame\\UI-Classes-Circles")
Nenue@0 263 bar.icon:SetTexCoord(unpack(CLASS_ICON_TCOORDS[actor.classFilename]))
Nenue@0 264 else
Nenue@0 265 bar.icon:Hide()
Nenue@0 266 end
Nenue@0 267 bar.header:SetText(data.name)
Nenue@0 268 bar.headerRight:SetText(data.damage .. ' ('..data.last..')')
Nenue@0 269
Nenue@0 270 local color = dummyColor
Nenue@0 271 if actor.class and RAID_CLASS_COLORS[actor.classFilename] then
Nenue@0 272 color = RAID_CLASS_COLORS[actor.classFilename]
Nenue@0 273 end
Nenue@0 274
Nenue@0 275 bar:SetColorTexture(color.r, color.g, color.b, 1)
Nenue@0 276
Nenue@0 277 bar:SetWidth(meterWidth * (data.damage / dd.maxDamage))
Nenue@0 278 end
Nenue@0 279
Nenue@0 280
Nenue@0 281 ---------------------------------------------------------
Nenue@0 282 -- HEALING DONE