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 |