Nenue@0: -------------------------------------------- Nenue@0: -- KrakTool Nenue@0: -- DamageMeter Nenue@0: -- @project-revision@ @project-hash@ Nenue@0: -- @file-revision@ @file-hash@ Nenue@0: -- Created: 6/19/2016 10:43 AM Nenue@0: -------------------------------------------- Nenue@0: -- dm Nenue@0: -- {...} = actor ( name, guid ) -- returns actor table Nenue@0: -- .showbar (bar ) -- toggle row Nenue@0: -- .hidebar ( bar ) -- Nenue@0: -- .ui () -- update chart Nenue@1: local KT = LibKT.register(DamageMeter) Nenue@0: local dm = DamageMeter Nenue@1: local db Nenue@0: local segments = {} Nenue@0: local actors = {} Nenue@0: local ordered = {} Nenue@0: local actorsOrdered = {} Nenue@0: local prototypes = {} Nenue@0: Nenue@0: local segmentUID Nenue@0: local viewPos Nenue@0: local view Nenue@0: local handler Nenue@0: local viewType = 'damageDone' Nenue@0: local sortType Nenue@0: local meterWidth = 230 Nenue@0: Nenue@0: local SortByDamage = function(a, b) Nenue@0: end Nenue@0: Nenue@0: dm.init = function() Nenue@0: dm:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED') Nenue@1: dm:RegisterEvent('PLAYER_REGEN_DISABLED') Nenue@0: dm:RegisterEvent('ENCOUNTER_START') Nenue@0: dm.bars = dm.bars or {} Nenue@0: dm.headings = dm.headings or {} Nenue@0: end Nenue@0: Nenue@0: dm.ENCOUNTER_START = function() Nenue@0: dm.new() Nenue@0: end Nenue@0: Nenue@0: dm.variables = function() Nenue@1: SkeletonStatsDB = SkeletonStatsDB or {} Nenue@1: db = SkeletonStatsDB Nenue@1: db.segments = db.segments or {} Nenue@1: db.currentSegment = db.currentSegment or 0 Nenue@1: db.actors = db.actors or {} Nenue@1: db.viewType = db.viewType or 'damageDone' Nenue@0: Nenue@1: actors = db.actors Nenue@1: segments = db.segments Nenue@1: viewPos = db.currentSegment Nenue@1: viewType = prototypes[viewType] and viewType or 'damageDone' Nenue@0: Nenue@0: dm.handler(viewType) Nenue@0: Nenue@0: -- resolve segment Nenue@0: if not segments[viewPos] then Nenue@0: viewPos = dm.new() Nenue@0: else Nenue@0: view = segments[viewPos] Nenue@0: print('Using segment #', viewPos) Nenue@0: end Nenue@1: db.currentSegment = viewPos Nenue@0: Nenue@0: dm.ui() Nenue@0: end Nenue@0: Nenue@0: dm.handler = function (viewType) Nenue@0: handler = prototypes[viewType] Nenue@0: dm.header:SetText(handler.header) Nenue@0: end Nenue@0: Nenue@0: dm.new = function() Nenue@1: segmentUID = (db.segUID or 0) + 1 Nenue@1: db.segUID = segmentUID Nenue@0: view = {} Nenue@0: viewPos = #segments+1 Nenue@0: segments[viewPos] = view Nenue@1: db.currentSegment = viewPos Nenue@0: print('Starting new segment #', viewPos) Nenue@0: return viewPos Nenue@0: end Nenue@0: local dummyColor = { Nenue@0: r = 0, Nenue@0: g = 0.5, Nenue@0: b = 0 Nenue@0: } Nenue@0: local dummyActor = { Nenue@0: name = 'Unknown', Nenue@0: flags = 0, Nenue@0: class = 'NA', Nenue@0: classFilename = '', Nenue@0: race = 'Unknown', Nenue@0: raceFilename = '', Nenue@0: sex = 1, Nenue@0: realm = '' Nenue@0: } Nenue@0: Nenue@0: dm.actor = function (guid, name, flags) Nenue@0: --if not actors[guid] then Nenue@0: local class, classFilename, race, raceFilename, sex, name, realm = GetPlayerInfoByGUID(guid) Nenue@0: Nenue@0: print('|cFFFFFF00guid|r =', name, flags, 'class', class, classFilename) Nenue@0: actors[guid] = { Nenue@0: name = name, Nenue@0: flags = flags, Nenue@0: class = class, Nenue@0: classFilename = classFilename, Nenue@0: race = race, Nenue@0: raceFilename = raceFilename, Nenue@0: sex = sex, Nenue@0: realm = realm Nenue@0: } Nenue@0: --end Nenue@0: return actors[guid] Nenue@0: end Nenue@0: Nenue@0: Nenue@0: prototypes.damageDone = { Nenue@0: header = 'Damage Done', Nenue@0: } Nenue@0: Nenue@1: dm.PLAYER_REGEN_DISABLED = function() Nenue@1: dm.new() Nenue@1: end Nenue@1: Nenue@0: dm.COMBAT_LOG_EVENT_UNFILTERED = function(self, event, timeStemp, subEvent, u1, ...) Nenue@0: local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags = ... Nenue@0: Nenue@0: Nenue@0: local args = {...} Nenue@0: for key, prototype in pairs(prototypes) do Nenue@0: --print(subEvent) Nenue@0: if prototype[subEvent] then Nenue@0: prototype[subEvent](subEvent, ...) Nenue@0: print('|cFFFFFF00' .. key .. '|r.|cFF00FFFF'..subEvent, '|r', ...) Nenue@0: end Nenue@0: end Nenue@0: Nenue@0: dm.ui() Nenue@0: return true Nenue@0: end Nenue@0: Nenue@0: --- [name] Nenue@0: -- .COMBAT_EVENT = function(event, ...) Nenue@0: -- .init = function() Nenue@0: -- .calculate = function(bar, data, actor) Nenue@0: -- .refresh = function(bar, data, actor Nenue@0: Nenue@0: dm.showbar = function(bar) Nenue@0: bar:Show() Nenue@0: bar.icon:Show() Nenue@0: bar.header:Show() Nenue@0: bar.headerRight:Show() Nenue@0: end Nenue@0: Nenue@0: dm.hidebar = function(bar) Nenue@0: bar:Hide() Nenue@0: bar.icon:Hide() Nenue@0: bar.header:Hide() Nenue@0: bar.headerRight:Hide() Nenue@0: end Nenue@0: Nenue@0: dm.ui = function() Nenue@0: --table.sort(view, sortType) Nenue@0: Nenue@0: Nenue@0: table.wipe(ordered) Nenue@0: for k,v in pairs(view) do Nenue@0: if type(v) ~= 'table' then Nenue@0: view[k] = nil Nenue@0: else Nenue@0: tinsert(ordered, v) Nenue@0: end Nenue@0: end Nenue@0: table.sort(ordered, handler.sort) Nenue@0: Nenue@0: handler.init() Nenue@0: Nenue@0: for i = 1, 12 do Nenue@0: if ordered[i] then Nenue@0: if not dm.bars[i] then Nenue@0: dm.bars[i] = dm:CreateTexture('MeterBar'..i, 'BORDER') Nenue@0: dm.bars[i]:SetHeight(24) Nenue@0: dm.bars[i]:SetPoint('TOPLEFT', dm, 0, i * -24) Nenue@0: dm.bars[i].icon = dm:CreateTexture('MeterIcon' .. i, 'OVERLAY') Nenue@0: dm.bars[i].icon:SetSize(24,24) Nenue@0: dm.bars[i].icon:SetPoint('TOPLEFT', dm.bars[i], 'TOPLEFT', -12, 0) Nenue@0: Nenue@0: dm.bars[i].header = dm:CreateFontString('MeterHeader'..i, 'OVERLAY', 'MeterHeaderLeft') Nenue@0: dm.bars[i].header:SetPoint('LEFT', dm.bars[i], 'LEFT', 22, 0) Nenue@0: Nenue@0: dm.bars[i].headerRight = dm:CreateFontString('MeterHeaderRight'..i, 'OVERLAY', 'MeterHeaderRight') Nenue@0: dm.bars[i].headerRight:SetPoint('TOP', dm.bars[i], 'TOP', 0, -6) Nenue@0: end Nenue@0: handler.calculate(dm.bars[i], ordered[i], ordered[i].actor) Nenue@0: end Nenue@0: end Nenue@0: Nenue@0: for i, bar in ipairs(dm.bars) do Nenue@0: if ordered[i] then Nenue@0: handler.refresh(bar, ordered[i], ordered[i].actor) Nenue@0: dm.showbar(bar) Nenue@0: else Nenue@0: dm.hidebar(bar) Nenue@0: end Nenue@0: end Nenue@0: dm:SetHeight((#ordered + 1) * 24) Nenue@0: dm:SetWidth(meterWidth) Nenue@0: end Nenue@0: --------------------------------------------------------- Nenue@0: -- DAMAGE DONE Nenue@0: local dd = prototypes.damageDone Nenue@0: dd.SPELL_DAMAGE = function(subEvent, ...) Nenue@0: local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, spellID, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing = ... Nenue@0: Nenue@0: view[sourceName] = view[sourceName] or {} Nenue@0: local p = view[sourceName] Nenue@0: Nenue@0: p.actor = dm.actor(sourceGUID, sourceName, sourceFlags) Nenue@0: dm.actor(destGUID, destName, destFlags) Nenue@0: Nenue@0: p.last = amount Nenue@0: p.damage = (view[sourceName].damage or 0) + amount Nenue@0: p.name = (sourceName or 'Unknown') Nenue@0: Nenue@0: p.child = p.child or {} Nenue@0: p.child[spellName] = p.child[spellName] or {} Nenue@0: p.child[spellName].hit = (p.child[spellName].hit or 0) + 1 Nenue@0: end Nenue@0: dd.SPELL_DAMAGE_PERIODIC = dd.SPELL_DAMAGE Nenue@0: dd.RANGE_DAMAGE = dd.SPELL_DAMAGE Nenue@0: Nenue@0: dd.SWING_DAMAGE = function(subEvent, ...) Nenue@0: local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing = ... Nenue@0: local spellID, spellName, spellSchool = -1, 'Attack', 1 Nenue@0: dd.SPELL_DAMAGE(subEvent, sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, spellID, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing) Nenue@0: end Nenue@0: Nenue@0: dd.init = function() Nenue@0: dd.maxDamage = 0 Nenue@0: end Nenue@0: Nenue@0: dd.sort = function(a, b) Nenue@0: return a.damage > b.damage Nenue@0: end Nenue@0: Nenue@0: dd.calculate = function(bar, data, actor) Nenue@0: if dd.maxDamage < data.damage then Nenue@0: dd.maxDamage = data.damage Nenue@0: end Nenue@0: Nenue@0: end Nenue@0: Nenue@0: dd.refresh = function(bar, data, actor) Nenue@0: if actor.class and CLASS_ICON_TCOORDS[actor.classFilename] then Nenue@0: bar.icon:Show() Nenue@0: bar.icon:SetTexture("Interface\\TargetingFrame\\UI-Classes-Circles") Nenue@0: bar.icon:SetTexCoord(unpack(CLASS_ICON_TCOORDS[actor.classFilename])) Nenue@0: else Nenue@0: bar.icon:Hide() Nenue@0: end Nenue@0: bar.header:SetText(data.name) Nenue@0: bar.headerRight:SetText(data.damage .. ' ('..data.last..')') Nenue@0: Nenue@0: local color = dummyColor Nenue@0: if actor.class and RAID_CLASS_COLORS[actor.classFilename] then Nenue@0: color = RAID_CLASS_COLORS[actor.classFilename] Nenue@0: end Nenue@0: Nenue@0: bar:SetColorTexture(color.r, color.g, color.b, 1) Nenue@0: Nenue@0: bar:SetWidth(meterWidth * (data.damage / dd.maxDamage)) Nenue@0: end Nenue@0: Nenue@0: Nenue@0: --------------------------------------------------------- Nenue@0: -- HEALING DONE