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
|
Nenue@4
|
17 local addon, core = ...
|
Nenue@4
|
18 core.segments = {}
|
Nenue@4
|
19 core.actors = {}
|
Nenue@4
|
20 core.pets = {}
|
Nenue@4
|
21 core.ordered = {}
|
Nenue@4
|
22 core.actorsOrdered = {}
|
Nenue@4
|
23 core.current = {}
|
Nenue@4
|
24 core.prototypes = {}
|
Nenue@4
|
25
|
Nenue@4
|
26 local GROUP_SIZE = 4
|
Nenue@4
|
27 local GROUP_TOKEN = 'party'
|
Nenue@4
|
28 local myGUID
|
Nenue@4
|
29 local segments, actors, pets, ordered = core.segments, core.actors, core.pets, core.ordered
|
Nenue@4
|
30 local prototypes = core.prototypes
|
Nenue@0
|
31 local segmentUID
|
Nenue@0
|
32 local viewPos
|
Nenue@0
|
33 local handler
|
Nenue@0
|
34 local viewType = 'damageDone'
|
Nenue@0
|
35 local meterWidth = 230
|
Nenue@0
|
36
|
Nenue@0
|
37 dm.init = function()
|
Nenue@0
|
38 dm:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED')
|
Nenue@1
|
39 dm:RegisterEvent('PLAYER_REGEN_DISABLED')
|
Nenue@0
|
40 dm:RegisterEvent('ENCOUNTER_START')
|
Nenue@0
|
41 dm.bars = dm.bars or {}
|
Nenue@0
|
42 dm.headings = dm.headings or {}
|
Nenue@0
|
43 end
|
Nenue@0
|
44
|
Nenue@0
|
45 dm.ENCOUNTER_START = function()
|
Nenue@0
|
46 dm.new()
|
Nenue@0
|
47 end
|
Nenue@0
|
48
|
Nenue@0
|
49 dm.variables = function()
|
Nenue@1
|
50 SkeletonStatsDB = SkeletonStatsDB or {}
|
Nenue@1
|
51 db = SkeletonStatsDB
|
Nenue@1
|
52 db.segments = db.segments or {}
|
Nenue@1
|
53 db.currentSegment = db.currentSegment or 0
|
Nenue@1
|
54 db.actors = db.actors or {}
|
Nenue@1
|
55 db.viewType = db.viewType or 'damageDone'
|
Nenue@0
|
56
|
Nenue@4
|
57
|
Nenue@4
|
58
|
Nenue@4
|
59 myGUID = UnitGUID('player')
|
Nenue@4
|
60 core.actor(myGUID)
|
Nenue@4
|
61 segments = db.segments
|
Nenue@4
|
62 viewPos = db.currentSegment
|
Nenue@4
|
63 viewType = prototypes[viewType] and viewType or 'damageDone'
|
Nenue@4
|
64
|
Nenue@4
|
65 if not segments[#segments] then
|
Nenue@4
|
66 dm.new()
|
Nenue@4
|
67 end
|
Nenue@0
|
68
|
Nenue@0
|
69 dm.handler(viewType)
|
Nenue@4
|
70 dm.view(viewPos)
|
Nenue@0
|
71
|
Nenue@0
|
72 dm.ui()
|
Nenue@0
|
73 end
|
Nenue@0
|
74
|
Nenue@0
|
75 dm.handler = function (viewType)
|
Nenue@0
|
76 handler = prototypes[viewType]
|
Nenue@0
|
77 dm.header:SetText(handler.header)
|
Nenue@0
|
78 end
|
Nenue@0
|
79
|
Nenue@0
|
80 dm.new = function()
|
Nenue@4
|
81 if core.active then
|
Nenue@4
|
82 core.active.finish = GetTime()
|
Nenue@4
|
83 end
|
Nenue@4
|
84
|
Nenue@1
|
85 segmentUID = (db.segUID or 0) + 1
|
Nenue@1
|
86 db.segUID = segmentUID
|
Nenue@4
|
87
|
Nenue@4
|
88 local segPos = #segments+1
|
Nenue@4
|
89 core.segments[segPos] = {
|
Nenue@4
|
90 view = {},
|
Nenue@4
|
91 start = GetTime(),
|
Nenue@4
|
92 uid = segmentUID
|
Nenue@4
|
93 }
|
Nenue@4
|
94 core.active = core.segments[viewPos].view
|
Nenue@4
|
95 print('Starting new segment #', segPos, 'UID', segmentUID, core.active, core.segments[viewPos])
|
Nenue@4
|
96
|
Nenue@4
|
97 dm.view(segPos)
|
Nenue@4
|
98
|
Nenue@0
|
99 return viewPos
|
Nenue@0
|
100 end
|
Nenue@4
|
101
|
Nenue@4
|
102 dm.view = function(pos)
|
Nenue@4
|
103 if not segments[pos] then
|
Nenue@4
|
104 pos = 1
|
Nenue@4
|
105 end
|
Nenue@4
|
106 core.current = segments[pos]
|
Nenue@4
|
107 core.current.view = core.current.view or {}
|
Nenue@4
|
108 end
|
Nenue@4
|
109
|
Nenue@0
|
110 local dummyColor = {
|
Nenue@0
|
111 r = 0,
|
Nenue@0
|
112 g = 0.5,
|
Nenue@0
|
113 b = 0
|
Nenue@0
|
114 }
|
Nenue@0
|
115 local dummyActor = {
|
Nenue@0
|
116 name = 'Unknown',
|
Nenue@0
|
117 flags = 0,
|
Nenue@0
|
118 class = 'NA',
|
Nenue@0
|
119 classFilename = '',
|
Nenue@0
|
120 race = 'Unknown',
|
Nenue@0
|
121 raceFilename = '',
|
Nenue@0
|
122 sex = 1,
|
Nenue@0
|
123 realm = ''
|
Nenue@0
|
124 }
|
Nenue@0
|
125
|
Nenue@4
|
126 local UNKNOWN_ACTOR = {
|
Nenue@4
|
127 name = 'Unknown',
|
Nenue@4
|
128 flags = 0,
|
Nenue@4
|
129 class = 'NADA'
|
Nenue@4
|
130 }
|
Nenue@4
|
131 --- Pull stored actor info if possible
|
Nenue@4
|
132 core.actor = function (guid, name, flags)
|
Nenue@4
|
133 local class, classFilename, race, raceFilename, sex, name, realm
|
Nenue@4
|
134 local actor = UNKNOWN_ACTOR
|
Nenue@4
|
135 if actors[guid] then
|
Nenue@4
|
136 print('cached GUID', guid)
|
Nenue@4
|
137 return actors[guid]
|
Nenue@4
|
138 end
|
Nenue@0
|
139
|
Nenue@4
|
140 if guid:match('^Player') then
|
Nenue@4
|
141 if db.actors[guid] then
|
Nenue@4
|
142 actor = db.actors[guid]
|
Nenue@4
|
143 print('using saved player GUID')
|
Nenue@4
|
144 else
|
Nenue@4
|
145
|
Nenue@4
|
146 class, classFilename, race, raceFilename, sex, name, realm = GetPlayerInfoByGUID(guid)
|
Nenue@4
|
147 actor = {
|
Nenue@4
|
148 name = name,
|
Nenue@4
|
149 flags = flags,
|
Nenue@4
|
150 class = class,
|
Nenue@4
|
151 classFilename = classFilename,
|
Nenue@4
|
152 race = race,
|
Nenue@4
|
153 raceFilename = raceFilename,
|
Nenue@4
|
154 sex = sex,
|
Nenue@4
|
155 realm = realm
|
Nenue@4
|
156 }
|
Nenue@4
|
157 print('saving player GUID')
|
Nenue@4
|
158 db.actors[guid] = actor
|
Nenue@4
|
159
|
Nenue@4
|
160 end
|
Nenue@4
|
161
|
Nenue@4
|
162 actors[guid] = actor
|
Nenue@4
|
163 elseif guid:match('^Pet') then
|
Nenue@4
|
164 print('analyzing pet GUID')
|
Nenue@4
|
165 actor = {
|
Nenue@0
|
166 name = name,
|
Nenue@4
|
167 class = 'PET',
|
Nenue@0
|
168 }
|
Nenue@4
|
169 if not pets[guid] then
|
Nenue@4
|
170 if bit.band(flags, COMBATLOG_OBJECT_AFFILIATION_MINE) > 0 then
|
Nenue@4
|
171 pets[guid] = myGUID
|
Nenue@4
|
172 actors[myGUID].pets = actors[myGUID].pets or {}
|
Nenue@4
|
173 actors[myGUID].pets[guid] = actor
|
Nenue@4
|
174 elseif bit.band(flags, COMBATLOG_OBJECT_AFFILIATION_PARTY+COMBATLOG_OBJECT_AFFILIATION_RAID > 0) then
|
Nenue@4
|
175 -- todo: handle party/raid pets
|
Nenue@4
|
176 end
|
Nenue@4
|
177 end
|
Nenue@4
|
178 actors[guid] = actor
|
Nenue@4
|
179 end
|
Nenue@4
|
180 return actor
|
Nenue@0
|
181 end
|
Nenue@0
|
182
|
Nenue@1
|
183 dm.PLAYER_REGEN_DISABLED = function()
|
Nenue@1
|
184 dm.new()
|
Nenue@1
|
185 end
|
Nenue@1
|
186
|
Nenue@0
|
187 dm.COMBAT_LOG_EVENT_UNFILTERED = function(self, event, timeStemp, subEvent, u1, ...)
|
Nenue@0
|
188 local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags = ...
|
Nenue@0
|
189
|
Nenue@4
|
190 local storeActor = false
|
Nenue@0
|
191 local args = {...}
|
Nenue@0
|
192 for key, prototype in pairs(prototypes) do
|
Nenue@0
|
193 --print(subEvent)
|
Nenue@0
|
194 if prototype[subEvent] then
|
Nenue@4
|
195 local result = prototype[subEvent](subEvent, ...)
|
Nenue@4
|
196 storeActor = (storeActor or result)
|
Nenue@3
|
197 --print('|cFFFFFF00' .. key .. '|r.|cFF00FFFF'..subEvent, '|r', ...)
|
Nenue@0
|
198 end
|
Nenue@0
|
199 end
|
Nenue@0
|
200
|
Nenue@4
|
201 if storeActor then
|
Nenue@4
|
202 core.actor(sourceGUID, sourceName, sourceFlags)
|
Nenue@4
|
203 core.actor(destGUID, destName, destFlags)
|
Nenue@4
|
204 end
|
Nenue@4
|
205
|
Nenue@0
|
206 dm.ui()
|
Nenue@0
|
207 return true
|
Nenue@0
|
208 end
|
Nenue@0
|
209
|
Nenue@0
|
210 --- [name]
|
Nenue@0
|
211 -- .COMBAT_EVENT = function(event, ...)
|
Nenue@0
|
212 -- .init = function()
|
Nenue@0
|
213 -- .calculate = function(bar, data, actor)
|
Nenue@0
|
214 -- .refresh = function(bar, data, actor
|
Nenue@0
|
215
|
Nenue@0
|
216 dm.showbar = function(bar)
|
Nenue@0
|
217 bar:Show()
|
Nenue@0
|
218 bar.icon:Show()
|
Nenue@0
|
219 bar.header:Show()
|
Nenue@0
|
220 bar.headerRight:Show()
|
Nenue@0
|
221 end
|
Nenue@0
|
222
|
Nenue@0
|
223 dm.hidebar = function(bar)
|
Nenue@0
|
224 bar:Hide()
|
Nenue@0
|
225 bar.icon:Hide()
|
Nenue@0
|
226 bar.header:Hide()
|
Nenue@0
|
227 bar.headerRight:Hide()
|
Nenue@0
|
228 end
|
Nenue@0
|
229
|
Nenue@0
|
230 dm.ui = function()
|
Nenue@0
|
231 --table.sort(view, sortType)
|
Nenue@4
|
232 local view = core.current.view
|
Nenue@0
|
233
|
Nenue@0
|
234 table.wipe(ordered)
|
Nenue@0
|
235 for k,v in pairs(view) do
|
Nenue@0
|
236 if type(v) ~= 'table' then
|
Nenue@0
|
237 view[k] = nil
|
Nenue@0
|
238 else
|
Nenue@0
|
239 tinsert(ordered, v)
|
Nenue@0
|
240 end
|
Nenue@0
|
241 end
|
Nenue@0
|
242 table.sort(ordered, handler.sort)
|
Nenue@0
|
243
|
Nenue@0
|
244 handler.init()
|
Nenue@0
|
245
|
Nenue@0
|
246 for i = 1, 12 do
|
Nenue@0
|
247 if ordered[i] then
|
Nenue@0
|
248 if not dm.bars[i] then
|
Nenue@0
|
249 dm.bars[i] = dm:CreateTexture('MeterBar'..i, 'BORDER')
|
Nenue@0
|
250 dm.bars[i]:SetHeight(24)
|
Nenue@0
|
251 dm.bars[i]:SetPoint('TOPLEFT', dm, 0, i * -24)
|
Nenue@0
|
252 dm.bars[i].icon = dm:CreateTexture('MeterIcon' .. i, 'OVERLAY')
|
Nenue@0
|
253 dm.bars[i].icon:SetSize(24,24)
|
Nenue@0
|
254 dm.bars[i].icon:SetPoint('TOPLEFT', dm.bars[i], 'TOPLEFT', -12, 0)
|
Nenue@0
|
255
|
Nenue@0
|
256 dm.bars[i].header = dm:CreateFontString('MeterHeader'..i, 'OVERLAY', 'MeterHeaderLeft')
|
Nenue@0
|
257 dm.bars[i].header:SetPoint('LEFT', dm.bars[i], 'LEFT', 22, 0)
|
Nenue@0
|
258
|
Nenue@0
|
259 dm.bars[i].headerRight = dm:CreateFontString('MeterHeaderRight'..i, 'OVERLAY', 'MeterHeaderRight')
|
Nenue@0
|
260 dm.bars[i].headerRight:SetPoint('TOP', dm.bars[i], 'TOP', 0, -6)
|
Nenue@0
|
261 end
|
Nenue@4
|
262
|
Nenue@4
|
263 local actor = actors[ordered[i].guid] or UNKNOWN_ACTOR
|
Nenue@4
|
264 handler.calculate(dm.bars[i], ordered[i], ordered[i], actor)
|
Nenue@0
|
265 end
|
Nenue@0
|
266 end
|
Nenue@0
|
267
|
Nenue@0
|
268 for i, bar in ipairs(dm.bars) do
|
Nenue@0
|
269 if ordered[i] then
|
Nenue@4
|
270
|
Nenue@4
|
271 local actor = actors[ordered[i].guid] or UNKNOWN_ACTOR
|
Nenue@4
|
272 local icon, textLeft, textRight, r, g, b, a, percent = handler.refresh(bar, ordered[i], actor)
|
Nenue@4
|
273
|
Nenue@4
|
274 bar:SetColorTexture(r, g, b, a)
|
Nenue@4
|
275
|
Nenue@4
|
276 if icon then
|
Nenue@4
|
277 bar.icon:Show()
|
Nenue@4
|
278 bar.icon:SetTexture(icon[1])
|
Nenue@4
|
279 if icon[2] then
|
Nenue@4
|
280 bar.icon:SetTexCoord(unpack(icon[2]))
|
Nenue@4
|
281 else
|
Nenue@4
|
282 bar.icon:SetTexCoord(1,0,1,0)
|
Nenue@4
|
283 end
|
Nenue@4
|
284 else
|
Nenue@4
|
285 bar.icon:Hide()
|
Nenue@4
|
286 end
|
Nenue@4
|
287
|
Nenue@4
|
288 if textLeft then
|
Nenue@4
|
289 bar.header:Show()
|
Nenue@4
|
290 bar.header:SetText(textLeft)
|
Nenue@4
|
291 else
|
Nenue@4
|
292 bar.header:Hide()
|
Nenue@4
|
293 end
|
Nenue@4
|
294 if textRight then
|
Nenue@4
|
295 bar.headerRight:Show()
|
Nenue@4
|
296 bar.headerRight:SetText(textRight)
|
Nenue@4
|
297 else
|
Nenue@4
|
298 bar.headerRight:Hide()
|
Nenue@4
|
299 end
|
Nenue@4
|
300
|
Nenue@4
|
301 bar:SetWidth(meterWidth*percent)
|
Nenue@4
|
302 bar:Show()
|
Nenue@0
|
303 else
|
Nenue@0
|
304 dm.hidebar(bar)
|
Nenue@0
|
305 end
|
Nenue@0
|
306 end
|
Nenue@0
|
307 dm:SetHeight((#ordered + 1) * 24)
|
Nenue@0
|
308 dm:SetWidth(meterWidth)
|
Nenue@0
|
309 end
|
Nenue@0
|
310 ---------------------------------------------------------
|
Nenue@0
|
311 -- DAMAGE DONE
|
Nenue@0
|
312
|
Nenue@0
|
313
|
Nenue@0
|
314 ---------------------------------------------------------
|
Nenue@0
|
315 -- HEALING DONE |