diff 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
line wrap: on
line diff
--- a/SkeletonStats/DamageMeter.lua	Tue Jun 21 08:14:22 2016 -0400
+++ b/SkeletonStats/DamageMeter.lua	Tue Jun 21 11:56:14 2016 -0400
@@ -13,23 +13,27 @@
 local KT = LibKT.register(DamageMeter)
 local dm = DamageMeter
 local db
-local segments = {}
-local actors = {}
-local ordered = {}
-local actorsOrdered = {}
-local prototypes = {}
 
+local addon, core = ...
+core.segments = {}
+core.actors = {}
+core.pets = {}
+core.ordered = {}
+core.actorsOrdered = {}
+core.current = {}
+core.prototypes = {}
+
+local GROUP_SIZE = 4
+local GROUP_TOKEN = 'party'
+local myGUID
+local segments, actors, pets, ordered = core.segments, core.actors, core.pets, core.ordered
+local prototypes = core.prototypes
 local segmentUID
 local viewPos
-local view
 local handler
 local viewType = 'damageDone'
-local sortType
 local meterWidth = 230
 
-local SortByDamage = function(a, b)
-end
-
 dm.init = function()
   dm:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED')
   dm:RegisterEvent('PLAYER_REGEN_DISABLED')
@@ -50,21 +54,20 @@
   db.actors = db.actors or {}
   db.viewType = db.viewType or 'damageDone'
 
-    actors = db.actors
-    segments = db.segments
-    viewPos = db.currentSegment
-    viewType = prototypes[viewType] and viewType or 'damageDone'
+
+
+  myGUID = UnitGUID('player')
+  core.actor(myGUID)
+  segments = db.segments
+  viewPos = db.currentSegment
+  viewType = prototypes[viewType] and viewType or 'damageDone'
+
+  if not segments[#segments] then
+    dm.new()
+  end
 
   dm.handler(viewType)
-
-  -- resolve segment
-  if not segments[viewPos] then
-    viewPos = dm.new()
-  else
-    view = segments[viewPos]
-    print('Using segment #', viewPos)
-  end
-  db.currentSegment = viewPos
+  dm.view(viewPos)
 
   dm.ui()
 end
@@ -75,15 +78,35 @@
 end
 
 dm.new = function()
+  if core.active then
+    core.active.finish = GetTime()
+  end
+
   segmentUID = (db.segUID or 0) + 1
   db.segUID = segmentUID
-  view = {}
-  viewPos = #segments+1
-  segments[viewPos] = view
-  db.currentSegment = viewPos
-  print('Starting new segment #', viewPos)
+
+  local segPos = #segments+1
+  core.segments[segPos] = {
+    view = {},
+    start = GetTime(),
+    uid = segmentUID
+  }
+  core.active = core.segments[viewPos].view
+  print('Starting new segment #', segPos, 'UID', segmentUID, core.active, core.segments[viewPos])
+
+  dm.view(segPos)
+
   return viewPos
 end
+
+dm.view = function(pos)
+  if not segments[pos] then
+    pos = 1
+  end
+  core.current = segments[pos]
+  core.current.view = core.current.view or {}
+end
+
 local dummyColor = {
   r = 0,
   g = 0.5,
@@ -100,30 +123,63 @@
   realm = ''
 }
 
-dm.actor = function (guid, name, flags)
-  --if not actors[guid] then
-    local class, classFilename, race, raceFilename, sex, name, realm = GetPlayerInfoByGUID(guid)
+local UNKNOWN_ACTOR = {
+  name = 'Unknown',
+  flags = 0,
+  class = 'NADA'
+}
+--- Pull stored actor info if possible
+core.actor = function (guid, name, flags)
+  local class, classFilename, race, raceFilename, sex, name, realm
+  local actor = UNKNOWN_ACTOR
+  if actors[guid] then
+    print('cached GUID', guid)
+    return actors[guid]
+  end
 
-    --print('|cFFFFFF00guid|r =', name, flags, 'class', class, classFilename)
-    actors[guid] = {
+  if guid:match('^Player') then
+    if db.actors[guid] then
+      actor = db.actors[guid]
+      print('using saved player GUID')
+    else
+
+      class, classFilename, race, raceFilename, sex, name, realm = GetPlayerInfoByGUID(guid)
+      actor = {
+        name = name,
+        flags = flags,
+        class = class,
+        classFilename = classFilename,
+        race = race,
+        raceFilename = raceFilename,
+        sex = sex,
+        realm = realm
+      }
+      print('saving player GUID')
+      db.actors[guid] = actor
+
+    end
+
+    actors[guid] = actor
+  elseif guid:match('^Pet') then
+    print('analyzing pet GUID')
+    actor = {
       name = name,
-      flags = flags,
-      class = class,
-      classFilename = classFilename,
-      race = race,
-      raceFilename = raceFilename,
-      sex = sex,
-      realm = realm
+      class = 'PET',
     }
-  --end
-  return actors[guid]
+    if not pets[guid] then
+      if bit.band(flags, COMBATLOG_OBJECT_AFFILIATION_MINE) > 0 then
+        pets[guid] = myGUID
+        actors[myGUID].pets = actors[myGUID].pets or {}
+        actors[myGUID].pets[guid] = actor
+      elseif bit.band(flags, COMBATLOG_OBJECT_AFFILIATION_PARTY+COMBATLOG_OBJECT_AFFILIATION_RAID > 0) then
+        -- todo: handle party/raid pets
+      end
+    end
+    actors[guid] = actor
+  end
+  return actor
 end
 
-
-prototypes.damageDone = {
-  header = 'Damage Done',
-}
-
 dm.PLAYER_REGEN_DISABLED = function()
   dm.new()
 end
@@ -131,16 +187,22 @@
 dm.COMBAT_LOG_EVENT_UNFILTERED = function(self, event, timeStemp, subEvent, u1, ...)
   local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags = ...
 
-
+  local storeActor = false
   local args = {...}
   for key, prototype in pairs(prototypes) do
     --print(subEvent)
     if prototype[subEvent] then
-       prototype[subEvent](subEvent, ...)
+       local result = prototype[subEvent](subEvent, ...)
+       storeActor = (storeActor or result)
        --print('|cFFFFFF00' .. key .. '|r.|cFF00FFFF'..subEvent, '|r', ...)
     end
   end
 
+  if storeActor then
+    core.actor(sourceGUID, sourceName, sourceFlags)
+    core.actor(destGUID, destName, destFlags)
+  end
+
   dm.ui()
   return true
 end
@@ -167,7 +229,7 @@
 
 dm.ui = function()
   --table.sort(view, sortType)
-
+  local view = core.current.view
 
   table.wipe(ordered)
   for k,v in pairs(view) do
@@ -197,14 +259,47 @@
         dm.bars[i].headerRight = dm:CreateFontString('MeterHeaderRight'..i, 'OVERLAY', 'MeterHeaderRight')
         dm.bars[i].headerRight:SetPoint('TOP', dm.bars[i], 'TOP', 0, -6)
       end
-      handler.calculate(dm.bars[i], ordered[i], ordered[i].actor)
+
+      local actor = actors[ordered[i].guid] or UNKNOWN_ACTOR
+      handler.calculate(dm.bars[i], ordered[i], ordered[i], actor)
     end
   end
 
   for i, bar in ipairs(dm.bars) do
     if ordered[i] then
-      handler.refresh(bar, ordered[i], ordered[i].actor)
-      dm.showbar(bar)
+
+      local actor = actors[ordered[i].guid] or UNKNOWN_ACTOR
+      local icon, textLeft, textRight, r, g, b, a, percent = handler.refresh(bar, ordered[i], actor)
+
+      bar:SetColorTexture(r, g, b, a)
+
+      if icon then
+        bar.icon:Show()
+        bar.icon:SetTexture(icon[1])
+        if icon[2] then
+          bar.icon:SetTexCoord(unpack(icon[2]))
+        else
+          bar.icon:SetTexCoord(1,0,1,0)
+        end
+      else
+        bar.icon:Hide()
+      end
+
+      if textLeft then
+        bar.header:Show()
+        bar.header:SetText(textLeft)
+      else
+        bar.header:Hide()
+      end
+      if textRight then
+        bar.headerRight:Show()
+        bar.headerRight:SetText(textRight)
+      else
+        bar.headerRight:Hide()
+      end
+
+      bar:SetWidth(meterWidth*percent)
+      bar:Show()
     else
       dm.hidebar(bar)
     end
@@ -214,72 +309,6 @@
 end
 ---------------------------------------------------------
 -- DAMAGE DONE
-local dd = prototypes.damageDone
-dd.SPELL_DAMAGE = function(subEvent, ...)
-  local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, spellID, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing = ...
-
-  if not sourceName then
-    return
-  end
-
-  view[sourceName] = view[sourceName] or {}
-  local p = view[sourceName]
-
-  p.actor = dm.actor(sourceGUID, sourceName, sourceFlags)
-  dm.actor(destGUID, destName, destFlags)
-
-  p.last = amount
-  p.damage = (view[sourceName].damage or 0) + amount
-  p.name = (sourceName or 'Unknown')
-
-  p.child = p.child or {}
-  p.child[spellName] = p.child[spellName] or {}
-  p.child[spellName].hit = (p.child[spellName].hit or 0) + 1
-end
-dd.SPELL_DAMAGE_PERIODIC = dd.SPELL_DAMAGE
-dd.RANGE_DAMAGE = dd.SPELL_DAMAGE
-
-dd.SWING_DAMAGE = function(subEvent, ...)
-  local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing = ...
-  local spellID, spellName, spellSchool = -1, 'Attack', 1
-  dd.SPELL_DAMAGE(subEvent, sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, spellID, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing)
-end
-
-dd.init = function()
-  dd.maxDamage = 0
-end
-
-dd.sort =  function(a, b)
-  return a.damage > b.damage
-end
-
-dd.calculate = function(bar, data, actor)
-  if dd.maxDamage < data.damage then
-    dd.maxDamage = data.damage
-  end
-
-end
-
-dd.refresh = function(bar, data, actor)
-  if actor.class and CLASS_ICON_TCOORDS[actor.classFilename] then
-    bar.icon:Show()
-    bar.icon:SetTexture("Interface\\TargetingFrame\\UI-Classes-Circles")
-    bar.icon:SetTexCoord(unpack(CLASS_ICON_TCOORDS[actor.classFilename]))
-  else
-    bar.icon:Hide()
-  end
-  bar.header:SetText(data.name)
-  bar.headerRight:SetText(data.damage .. ' ('..data.last..')')
-
-  local color = dummyColor
-  if actor.class and  RAID_CLASS_COLORS[actor.classFilename] then
-    color = RAID_CLASS_COLORS[actor.classFilename]
-  end
-
-  bar:SetColorTexture(color.r, color.g, color.b, 1)
-
-  bar:SetWidth(meterWidth * (data.damage / dd.maxDamage))
-end
 
 
 ---------------------------------------------------------