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@0
|
13 local KT = select(2,...)
|
Nenue@0
|
14 local dm = DamageMeter
|
Nenue@0
|
15 KT.register(dm)
|
Nenue@0
|
16
|
Nenue@0
|
17 local segments = {}
|
Nenue@0
|
18 local actors = {}
|
Nenue@0
|
19 local ordered = {}
|
Nenue@0
|
20 local actorsOrdered = {}
|
Nenue@0
|
21 local prototypes = {}
|
Nenue@0
|
22
|
Nenue@0
|
23 local segmentUID
|
Nenue@0
|
24 local viewPos
|
Nenue@0
|
25 local view
|
Nenue@0
|
26 local handler
|
Nenue@0
|
27 local viewType = 'damageDone'
|
Nenue@0
|
28 local sortType
|
Nenue@0
|
29 local meterWidth = 230
|
Nenue@0
|
30
|
Nenue@0
|
31 local SortByDamage = function(a, b)
|
Nenue@0
|
32 end
|
Nenue@0
|
33
|
Nenue@0
|
34 dm.init = function()
|
Nenue@0
|
35 dm:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED')
|
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
|
Nenue@0
|
40 sortType = SortByDamage
|
Nenue@0
|
41 end
|
Nenue@0
|
42
|
Nenue@0
|
43 dm.ENCOUNTER_START = function()
|
Nenue@0
|
44 dm.new()
|
Nenue@0
|
45 end
|
Nenue@0
|
46
|
Nenue@0
|
47 dm.variables = function()
|
Nenue@0
|
48 KT.db.segments = KT.db.segments or {}
|
Nenue@0
|
49 KT.db.currentSegment = KT.db.currentSegment or 0
|
Nenue@0
|
50 KT.db.actors = KT.db.actors or {}
|
Nenue@0
|
51 actors = KT.db.actors
|
Nenue@0
|
52 segments = KT.db.segments
|
Nenue@0
|
53 viewPos = KT.db.currentSegment
|
Nenue@0
|
54
|
Nenue@0
|
55
|
Nenue@0
|
56 dm.handler(viewType)
|
Nenue@0
|
57
|
Nenue@0
|
58 -- resolve segment
|
Nenue@0
|
59 if not segments[viewPos] then
|
Nenue@0
|
60 viewPos = dm.new()
|
Nenue@0
|
61 else
|
Nenue@0
|
62 view = segments[viewPos]
|
Nenue@0
|
63 print('Using segment #', viewPos)
|
Nenue@0
|
64 end
|
Nenue@0
|
65 KT.db.currentSegment = viewPos
|
Nenue@0
|
66
|
Nenue@0
|
67 dm.ui()
|
Nenue@0
|
68 end
|
Nenue@0
|
69
|
Nenue@0
|
70 dm.handler = function (viewType)
|
Nenue@0
|
71 handler = prototypes[viewType]
|
Nenue@0
|
72 dm.header:SetText(handler.header)
|
Nenue@0
|
73 end
|
Nenue@0
|
74
|
Nenue@0
|
75 dm.new = function()
|
Nenue@0
|
76 segmentUID = (KT.db.segUID or 0) + 1
|
Nenue@0
|
77 KT.db.segUID = segmentUID
|
Nenue@0
|
78 view = {}
|
Nenue@0
|
79 viewPos = #segments+1
|
Nenue@0
|
80 segments[viewPos] = view
|
Nenue@0
|
81 KT.db.currentSegment = viewPos
|
Nenue@0
|
82 print('Starting new segment #', viewPos)
|
Nenue@0
|
83 return viewPos
|
Nenue@0
|
84 end
|
Nenue@0
|
85 local dummyColor = {
|
Nenue@0
|
86 r = 0,
|
Nenue@0
|
87 g = 0.5,
|
Nenue@0
|
88 b = 0
|
Nenue@0
|
89 }
|
Nenue@0
|
90 local dummyActor = {
|
Nenue@0
|
91 name = 'Unknown',
|
Nenue@0
|
92 flags = 0,
|
Nenue@0
|
93 class = 'NA',
|
Nenue@0
|
94 classFilename = '',
|
Nenue@0
|
95 race = 'Unknown',
|
Nenue@0
|
96 raceFilename = '',
|
Nenue@0
|
97 sex = 1,
|
Nenue@0
|
98 realm = ''
|
Nenue@0
|
99 }
|
Nenue@0
|
100
|
Nenue@0
|
101 dm.actor = function (guid, name, flags)
|
Nenue@0
|
102 --if not actors[guid] then
|
Nenue@0
|
103 local class, classFilename, race, raceFilename, sex, name, realm = GetPlayerInfoByGUID(guid)
|
Nenue@0
|
104
|
Nenue@0
|
105 print('|cFFFFFF00guid|r =', name, flags, 'class', class, classFilename)
|
Nenue@0
|
106 actors[guid] = {
|
Nenue@0
|
107 name = name,
|
Nenue@0
|
108 flags = flags,
|
Nenue@0
|
109 class = class,
|
Nenue@0
|
110 classFilename = classFilename,
|
Nenue@0
|
111 race = race,
|
Nenue@0
|
112 raceFilename = raceFilename,
|
Nenue@0
|
113 sex = sex,
|
Nenue@0
|
114 realm = realm
|
Nenue@0
|
115 }
|
Nenue@0
|
116 --end
|
Nenue@0
|
117 return actors[guid]
|
Nenue@0
|
118 end
|
Nenue@0
|
119
|
Nenue@0
|
120
|
Nenue@0
|
121 prototypes.damageDone = {
|
Nenue@0
|
122 header = 'Damage Done',
|
Nenue@0
|
123 }
|
Nenue@0
|
124
|
Nenue@0
|
125 dm.COMBAT_LOG_EVENT_UNFILTERED = function(self, event, timeStemp, subEvent, u1, ...)
|
Nenue@0
|
126 local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags = ...
|
Nenue@0
|
127
|
Nenue@0
|
128
|
Nenue@0
|
129 local args = {...}
|
Nenue@0
|
130 for key, prototype in pairs(prototypes) do
|
Nenue@0
|
131 --print(subEvent)
|
Nenue@0
|
132 if prototype[subEvent] then
|
Nenue@0
|
133 prototype[subEvent](subEvent, ...)
|
Nenue@0
|
134 print('|cFFFFFF00' .. key .. '|r.|cFF00FFFF'..subEvent, '|r', ...)
|
Nenue@0
|
135 end
|
Nenue@0
|
136 end
|
Nenue@0
|
137
|
Nenue@0
|
138 dm.ui()
|
Nenue@0
|
139 return true
|
Nenue@0
|
140 end
|
Nenue@0
|
141
|
Nenue@0
|
142 --- [name]
|
Nenue@0
|
143 -- .COMBAT_EVENT = function(event, ...)
|
Nenue@0
|
144 -- .init = function()
|
Nenue@0
|
145 -- .calculate = function(bar, data, actor)
|
Nenue@0
|
146 -- .refresh = function(bar, data, actor
|
Nenue@0
|
147
|
Nenue@0
|
148 dm.showbar = function(bar)
|
Nenue@0
|
149 bar:Show()
|
Nenue@0
|
150 bar.icon:Show()
|
Nenue@0
|
151 bar.header:Show()
|
Nenue@0
|
152 bar.headerRight:Show()
|
Nenue@0
|
153 end
|
Nenue@0
|
154
|
Nenue@0
|
155 dm.hidebar = function(bar)
|
Nenue@0
|
156 bar:Hide()
|
Nenue@0
|
157 bar.icon:Hide()
|
Nenue@0
|
158 bar.header:Hide()
|
Nenue@0
|
159 bar.headerRight:Hide()
|
Nenue@0
|
160 end
|
Nenue@0
|
161
|
Nenue@0
|
162 dm.ui = function()
|
Nenue@0
|
163 --table.sort(view, sortType)
|
Nenue@0
|
164
|
Nenue@0
|
165
|
Nenue@0
|
166 table.wipe(ordered)
|
Nenue@0
|
167 for k,v in pairs(view) do
|
Nenue@0
|
168 if type(v) ~= 'table' then
|
Nenue@0
|
169 view[k] = nil
|
Nenue@0
|
170 else
|
Nenue@0
|
171 tinsert(ordered, v)
|
Nenue@0
|
172 end
|
Nenue@0
|
173 end
|
Nenue@0
|
174 table.sort(ordered, handler.sort)
|
Nenue@0
|
175
|
Nenue@0
|
176 handler.init()
|
Nenue@0
|
177
|
Nenue@0
|
178 for i = 1, 12 do
|
Nenue@0
|
179 if ordered[i] then
|
Nenue@0
|
180 if not dm.bars[i] then
|
Nenue@0
|
181 dm.bars[i] = dm:CreateTexture('MeterBar'..i, 'BORDER')
|
Nenue@0
|
182 dm.bars[i]:SetHeight(24)
|
Nenue@0
|
183 dm.bars[i]:SetPoint('TOPLEFT', dm, 0, i * -24)
|
Nenue@0
|
184 dm.bars[i].icon = dm:CreateTexture('MeterIcon' .. i, 'OVERLAY')
|
Nenue@0
|
185 dm.bars[i].icon:SetSize(24,24)
|
Nenue@0
|
186 dm.bars[i].icon:SetPoint('TOPLEFT', dm.bars[i], 'TOPLEFT', -12, 0)
|
Nenue@0
|
187
|
Nenue@0
|
188 dm.bars[i].header = dm:CreateFontString('MeterHeader'..i, 'OVERLAY', 'MeterHeaderLeft')
|
Nenue@0
|
189 dm.bars[i].header:SetPoint('LEFT', dm.bars[i], 'LEFT', 22, 0)
|
Nenue@0
|
190
|
Nenue@0
|
191 dm.bars[i].headerRight = dm:CreateFontString('MeterHeaderRight'..i, 'OVERLAY', 'MeterHeaderRight')
|
Nenue@0
|
192 dm.bars[i].headerRight:SetPoint('TOP', dm.bars[i], 'TOP', 0, -6)
|
Nenue@0
|
193 end
|
Nenue@0
|
194 handler.calculate(dm.bars[i], ordered[i], ordered[i].actor)
|
Nenue@0
|
195 end
|
Nenue@0
|
196 end
|
Nenue@0
|
197
|
Nenue@0
|
198 for i, bar in ipairs(dm.bars) do
|
Nenue@0
|
199 if ordered[i] then
|
Nenue@0
|
200 handler.refresh(bar, ordered[i], ordered[i].actor)
|
Nenue@0
|
201 dm.showbar(bar)
|
Nenue@0
|
202 else
|
Nenue@0
|
203 dm.hidebar(bar)
|
Nenue@0
|
204 end
|
Nenue@0
|
205 end
|
Nenue@0
|
206 dm:SetHeight((#ordered + 1) * 24)
|
Nenue@0
|
207 dm:SetWidth(meterWidth)
|
Nenue@0
|
208 end
|
Nenue@0
|
209 ---------------------------------------------------------
|
Nenue@0
|
210 -- DAMAGE DONE
|
Nenue@0
|
211 local dd = prototypes.damageDone
|
Nenue@0
|
212 dd.SPELL_DAMAGE = function(subEvent, ...)
|
Nenue@0
|
213 local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, spellID, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing = ...
|
Nenue@0
|
214
|
Nenue@0
|
215 view[sourceName] = view[sourceName] or {}
|
Nenue@0
|
216 local p = view[sourceName]
|
Nenue@0
|
217
|
Nenue@0
|
218 p.actor = dm.actor(sourceGUID, sourceName, sourceFlags)
|
Nenue@0
|
219 dm.actor(destGUID, destName, destFlags)
|
Nenue@0
|
220
|
Nenue@0
|
221 p.last = amount
|
Nenue@0
|
222 p.damage = (view[sourceName].damage or 0) + amount
|
Nenue@0
|
223 p.name = (sourceName or 'Unknown')
|
Nenue@0
|
224
|
Nenue@0
|
225 p.child = p.child or {}
|
Nenue@0
|
226 p.child[spellName] = p.child[spellName] or {}
|
Nenue@0
|
227 p.child[spellName].hit = (p.child[spellName].hit or 0) + 1
|
Nenue@0
|
228 end
|
Nenue@0
|
229 dd.SPELL_DAMAGE_PERIODIC = dd.SPELL_DAMAGE
|
Nenue@0
|
230 dd.RANGE_DAMAGE = dd.SPELL_DAMAGE
|
Nenue@0
|
231
|
Nenue@0
|
232 dd.SWING_DAMAGE = function(subEvent, ...)
|
Nenue@0
|
233 local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing = ...
|
Nenue@0
|
234 local spellID, spellName, spellSchool = -1, 'Attack', 1
|
Nenue@0
|
235 dd.SPELL_DAMAGE(subEvent, sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, spellID, spellName, spellSchool, amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing)
|
Nenue@0
|
236 end
|
Nenue@0
|
237
|
Nenue@0
|
238 dd.init = function()
|
Nenue@0
|
239 dd.maxDamage = 0
|
Nenue@0
|
240 end
|
Nenue@0
|
241
|
Nenue@0
|
242 dd.sort = function(a, b)
|
Nenue@0
|
243 return a.damage > b.damage
|
Nenue@0
|
244 end
|
Nenue@0
|
245
|
Nenue@0
|
246 dd.calculate = function(bar, data, actor)
|
Nenue@0
|
247 if dd.maxDamage < data.damage then
|
Nenue@0
|
248 dd.maxDamage = data.damage
|
Nenue@0
|
249 end
|
Nenue@0
|
250
|
Nenue@0
|
251 end
|
Nenue@0
|
252
|
Nenue@0
|
253 dd.refresh = function(bar, data, actor)
|
Nenue@0
|
254 if actor.class and CLASS_ICON_TCOORDS[actor.classFilename] then
|
Nenue@0
|
255 bar.icon:Show()
|
Nenue@0
|
256 bar.icon:SetTexture("Interface\\TargetingFrame\\UI-Classes-Circles")
|
Nenue@0
|
257 bar.icon:SetTexCoord(unpack(CLASS_ICON_TCOORDS[actor.classFilename]))
|
Nenue@0
|
258 else
|
Nenue@0
|
259 bar.icon:Hide()
|
Nenue@0
|
260 end
|
Nenue@0
|
261 bar.header:SetText(data.name)
|
Nenue@0
|
262 bar.headerRight:SetText(data.damage .. ' ('..data.last..')')
|
Nenue@0
|
263
|
Nenue@0
|
264 local color = dummyColor
|
Nenue@0
|
265 if actor.class and RAID_CLASS_COLORS[actor.classFilename] then
|
Nenue@0
|
266 color = RAID_CLASS_COLORS[actor.classFilename]
|
Nenue@0
|
267 end
|
Nenue@0
|
268
|
Nenue@0
|
269 bar:SetColorTexture(color.r, color.g, color.b, 1)
|
Nenue@0
|
270
|
Nenue@0
|
271 bar:SetWidth(meterWidth * (data.damage / dd.maxDamage))
|
Nenue@0
|
272 end
|
Nenue@0
|
273
|
Nenue@0
|
274
|
Nenue@0
|
275 ---------------------------------------------------------
|
Nenue@0
|
276 -- HEALING DONE |