# HG changeset patch
# User Nenue
# Date 1466524574 14400
# Node ID a30285f8191edae5c03281aafb9b0384fab287d6
# Parent 07293831dd7bb4745fdc03a252f9ebc162472a7d
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
diff -r 07293831dd7b -r a30285f8191e SkeletonStats/DamageMeter.lua
--- 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
---------------------------------------------------------
diff -r 07293831dd7b -r a30285f8191e SkeletonStats/SkeletonStats.toc
--- a/SkeletonStats/SkeletonStats.toc Tue Jun 21 08:14:22 2016 -0400
+++ b/SkeletonStats/SkeletonStats.toc Tue Jun 21 11:56:14 2016 -0400
@@ -12,4 +12,5 @@
libKT-1.0\libKT-1.0.xml
DamageMeter.xml
-DamageMeter.lua
\ No newline at end of file
+DamageMeter.lua
+Views\DamageDone.lua
\ No newline at end of file
diff -r 07293831dd7b -r a30285f8191e SkeletonStats/Views/DamageDone.lua
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SkeletonStats/Views/DamageDone.lua Tue Jun 21 11:56:14 2016 -0400
@@ -0,0 +1,83 @@
+
+local core = select(2, ...)
+local prototypes = core.prototypes
+local SOURCE_MASK = COMBATLOG_OBJECT_AFFILIATION_RAID+COMBATLOG_OBJECT_AFFILIATION_PARTY+COMBATLOG_OBJECT_AFFILIATION_MINE
+
+local dd = {
+ header = 'Damage Done',
+}
+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 false
+ end
+
+ if bit.band(sourceFlags, SOURCE_MASK) == 0 then
+ --print('discarded non-raid damage event', sourceFlags, sourceName)
+ return false
+ end
+
+ local view = core.current.view
+ view[sourceName] = view[sourceName] or {}
+ local p = view[sourceName]
+
+
+ p.guid = sourceGUID
+ p.last = amount
+ p.damage = (p.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
+
+ -- true = store this event's actor
+ return true
+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)
+ local icon, textLeft, textRight
+ local r, g, b, a, percent = 1,1,1,1,1
+ if actor.class and CLASS_ICON_TCOORDS[actor.classFilename] then
+ icon = { "Interface\\TargetingFrame\\UI-Classes-Circles" , CLASS_ICON_TCOORDS[actor.classFilename] }
+ end
+ textLeft = data.name
+ textRight = data.damage .. ' ('..data.last..')'
+
+
+ if actor.class and RAID_CLASS_COLORS[actor.classFilename] then
+ r = RAID_CLASS_COLORS[actor.classFilename].r
+ g = RAID_CLASS_COLORS[actor.classFilename].g
+ b = RAID_CLASS_COLORS[actor.classFilename].b
+ end
+ percent = (data.damage / dd.maxDamage)
+
+ return icon, textLeft, textRight, r, g, b, a, percent
+end
+
+prototypes.damageDone = dd
\ No newline at end of file
diff -r 07293831dd7b -r a30285f8191e SkeletonUnit/UnitFrame.lua
--- a/SkeletonUnit/UnitFrame.lua Tue Jun 21 08:14:22 2016 -0400
+++ b/SkeletonUnit/UnitFrame.lua Tue Jun 21 11:56:14 2016 -0400
@@ -19,10 +19,11 @@
local params = setmetatable({}, {
__index = function(t, k)
print('get', k)
- return rawget(t.player, k)
+ return t.player
end,
__newindex = function(t, k, v)
if type(v) == 'table' then
+ print('branch', k)
v = setmetatable(v, {
__index = function(tt, kk)
print('get', k, kk)
@@ -30,6 +31,7 @@
end,
__newindex = function(tt, kk, vv)
if type(vv) == 'table' then
+ print('_branch', k, kk)
vv = setmetatable(vv, {
__index = function(_tt, _kk)
print('_get', k, kk, _kk)
@@ -50,12 +52,23 @@
height = 30,
health = { height = 24 },
power = { height = 6},
- }
+ position = {'CENTER', nil, 'CENTER',0,-120 }
+}
params.pet = {
width = 180,
- height = 25
+ height = 25,
+
+ position = {'TOPLEFT', 'player', 'BOTTOMLEFT',0,-4}
}
-params.focus = params.pet
+params.target = {
+
+ position = {'TOPLEFT', 'player', 'TOPRIGHT',4,0}
+}
+params.focus = {
+ width = 180,
+ height = 25,
+ position = {'BOTTOMRIGHT', 'target', 'TOPRIGHT',0,4}
+}
uf.handler = uf -- so uf.event can work
@@ -77,7 +90,6 @@
buttons[unit][index] = CreateFrame('Frame', 'KT'..unit..'Buff'..index, self, 'KTAuraButton')
buttons[unit][index]:SetSize(BUFF_SIZE, BUFF_SIZE)
buttons[unit][index].cooldown:SetHideCountdownNumbers(true)
-
end
return buttons[unit][index]
end
@@ -88,34 +100,36 @@
end
print('|cFFFFFF00unit|r:', unit)
+ local c = params[unit]
+
if not _G['KT'..unit..'Frame'] then
- CreateFrame('Frame', 'KT'.. unit .. 'Frame', uf)
+ local new = CreateFrame('Button', 'KT'.. unit .. 'Frame', uf, 'KTUnitFrameTemplate')
+ new.unit = unit
+ new.anchorPoint = {new:GetPoint(1)}
+ new.handler = prototypes[unit]
+ new.params = c
+
+ --if not db.position[unit] then
+ db.position[unit] = c.position
+ --end
+ new.position = db.position[unit]
+
+
+ buttons[unit] = {}
+ new.buttons = buttons[unit]
+ new.refresh = prototypes[unit].refresh
+ new.init = prototypes[unit].init
+
+ new:EnableMouse(true)
+ new:SetScript('OnMouseUp', prototypes[unit].OnMouseUp)
+
+ new:SetAttribute("type", "target")
+ new:SetAttribute("unit", unit)
+ RegisterUnitWatch(new)
+ units[unit] = new
end
- local frame = _G['KT'..unit..'Frame']
- frame.unit = unit
- frame.anchorPoint = {frame:GetPoint(1)}
- frame.handler = prototypes[unit]
-
- buttons[unit] = {}
- units[unit] = frame
-
- local width = params.player.width
- local height = params.player.height
-
- if params[unit] then
- if params[unit].width then
- width = params[unit].width
- end
- if params[unit].height then
- height = params[unit].height
- end
- end
-
- frame:SetWidth(width)
- frame:SetHeight(height)
-
- return frame
+ return _G['KT'..unit..'Frame']
end
uf.ui = function ()
@@ -126,6 +140,7 @@
uf.init = function()
uf:RegisterEvent('PLAYER_TARGET_CHANGED')
+ uf:RegisterEvent('PLAYER_FOCUS_CHANGED')
uf:RegisterUnitEvent("UNIT_AURA")
end
@@ -156,7 +171,12 @@
end
uf.PLAYER_TARGET_CHANGED = function()
- prototypes.player.refresh(units.target)
+ print('caught target change')
+ units.target:refresh()
+end
+
+uf.PLAYER_FOCUS_CHANGED = function()
+ units.focus:refresh()
end
prototypes.player = {}
@@ -168,16 +188,30 @@
self:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
self:RegisterEvent("UNIT_TARGET")
self:SetScript('OnEvent', uf.event)
+
+ local anchor, parent, relative, x, y = unpack(self.position)
+ if parent and units[parent] then
+ parent = units[parent]
+ else
+ parent = UIParent
+ end
+
+ self:SetPoint(anchor, parent, relative, x, y)
+ self:SetSize(self.params.width, self.params.height)
+
end
--- Runs when event handler decides so
player.refresh = function(self)
+ print(self.unit, UnitExists(self.unit))
if not UnitExists(self.unit) then
+ print('hiding unit')
self:Hide()
return
end
+ self:Show()
if UnitIsPlayer(self.unit) then
local class, classFile = UnitClass(self.unit)
if classFile then
@@ -198,12 +232,12 @@
else
self.healthbar:SetHeight(params[self.unit].health.height + params[self.unit].power.height)
end
-
-
+ uf.UNIT_AURA(self, 'UNIT_AURA', self.unit)
self.handler.UNIT_HEALTH_FREQUENT(self)
end
+
uf.UNIT_AURA = function(self, event, unit)
if not units[unit] then return true end
@@ -240,7 +274,7 @@
player.UNIT_HEALTH_FREQUENT = function(self, ...)
if UnitHealthMax(self.unit) > 0 then
- self.healthbar:SetWidth(PLAYER_WIDTH * UnitHealth(self.unit) / UnitHealthMax(self.unit))
+ self.healthbar:SetWidth(self.params.width * UnitHealth(self.unit) / UnitHealthMax(self.unit))
self.healthtext:SetText(UnitHealth(self.unit))
else
self.healthbar:SetWidth(PLAYER_WIDTH)
@@ -251,7 +285,7 @@
player.UNIT_POWER_FREQUENT = function(self)
if UnitPowerMax(self.unit) > 0 then
- self.powerbar:SetWidth(PLAYER_WIDTH * UnitPower(self.unit) / UnitPowerMax(self.unit))
+ self.powerbar:SetWidth(self.params.width * UnitPower(self.unit) / UnitPowerMax(self.unit))
self.powertext:SetText(UnitPower(self.unit))
else
self.powerbar:Hide()
@@ -271,4 +305,5 @@
end
prototypes.pet = player
-prototypes.target = player
\ No newline at end of file
+prototypes.target = player
+prototypes.focus = player
\ No newline at end of file
diff -r 07293831dd7b -r a30285f8191e SkeletonUnit/UnitFrame.xml
--- a/SkeletonUnit/UnitFrame.xml Tue Jun 21 08:14:22 2016 -0400
+++ b/SkeletonUnit/UnitFrame.xml Tue Jun 21 11:56:14 2016 -0400
@@ -4,7 +4,7 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file