Nenue@6
|
1 --- Combat
|
Nenue@6
|
2 -- @file-author@
|
Nenue@6
|
3 -- @project-revision@ @project-hash@
|
Nenue@6
|
4 -- @file-revision@ @file-hash@
|
Nenue@6
|
5 -- Created: 1/11/2016 4:27 PM
|
Nenue@6
|
6 --- Data collector for API Combat Log Event
|
Nenue@6
|
7 local T, _G = Turok, _G
|
Nenue@6
|
8 local mod = T:NewModule("Combat")
|
Nenue@6
|
9 local pairs, ipairs, select, concat, format, tinsert, wipe = pairs, ipairs, select, table.concat, string.format, tinsert, table.wipe
|
Nenue@6
|
10 local GetSpellTexture, CreateFrame, GetTime, unpack, floor = GetSpellTexture, CreateFrame, GetTime, unpack, floor
|
Nenue@6
|
11 local db
|
Nenue@6
|
12 local cText, cNum, cKey, cWord, cPink, cType, cBool = cText, cNum, cKey, cWord, cPink, cType, cBool
|
Nenue@6
|
13 local print = function(...)
|
Nenue@6
|
14 if _G.Devian and _G.DevianDB.workspace ~= 1 then
|
Nenue@6
|
15 _G.print('CombatText', ...)
|
Nenue@6
|
16 end
|
Nenue@6
|
17 end
|
Nenue@6
|
18
|
Nenue@6
|
19
|
Nenue@6
|
20 --- performance constants
|
Nenue@6
|
21 local SCT_NAME = 'TurokSCT%s'
|
Nenue@6
|
22 local SCT_TEMPLATE = 'TurokSCTAnchorTemplate'
|
Nenue@6
|
23 local SCT_PREGAME = 5
|
Nenue@6
|
24 local SCT_MESSAGE_TEMPLATE = 'TurokCombatMessageTemplate'
|
Nenue@6
|
25 local SCT_MESSAGE_NAME = 'CombatString%d'
|
Nenue@6
|
26 local LOG_TEMPLATE = 'TurokCombatLogAnchorTemplate'
|
Nenue@6
|
27
|
Nenue@6
|
28 --- UX structures
|
Nenue@6
|
29 T.defaults.CombatText = {
|
Nenue@6
|
30 width = 400, height = 800,
|
Nenue@6
|
31 parent = 'UIParent',
|
Nenue@6
|
32 Outgoing = {
|
Nenue@6
|
33 anchor = 'RIGHT', anchorTo = 'RIGHT',
|
Nenue@6
|
34 x = -400, y = -200,
|
Nenue@6
|
35 },
|
Nenue@6
|
36 Incoming = {
|
Nenue@6
|
37 anchor = 'LEFT', anchorTo = 'LEFT',parent = 'UIParent',
|
Nenue@6
|
38 x = 400, y = -200,
|
Nenue@6
|
39 },
|
Nenue@6
|
40 DoTTracker = {
|
Nenue@6
|
41 anchor = 'BOTTOMLEFT', anchorTo = 'BOTTOM', parent = 'UIParent',
|
Nenue@6
|
42 x = 80, y = 400,
|
Nenue@6
|
43 },
|
Nenue@6
|
44 defaultFont = {"Interface\\Addons\\Turok\\Media\\font\\ArchivoNarrow-Regular.ttf", 18, 'OUTLINE'},
|
Nenue@6
|
45 defaultAnimation = 'slide',
|
Nenue@6
|
46
|
Nenue@6
|
47 textFonts = {
|
Nenue@6
|
48 font1 = {"Interface\\Addons\\Turok\\Media\\font\\ArchivoNarrow-Regular.ttf" , 30, 'OUTLINE'},
|
Nenue@6
|
49 font2 = {"Interface\\Addons\\Turok\\Media\\font\\ArchivoNarrow-Regular.ttf" , 24, 'OUTLINE'},
|
Nenue@6
|
50 font3 = {"Interface\\Addons\\Turok\\Media\\font\\ArchivoNarrow-Bold.ttf" , 20, 'OUTLINE'},
|
Nenue@6
|
51 },
|
Nenue@6
|
52
|
Nenue@6
|
53 --- [(string) combatEvent] = {[1] = (string) format [, [2] = fontKey]}
|
Nenue@6
|
54 --- Substitution values
|
Nenue@6
|
55 -- %d [1] amount [2] overkill [3] absorbed [4] blocked
|
Nenue@6
|
56 -- %s [5] spell [6] caster [7] school
|
Nenue@6
|
57 textFormat = {
|
Nenue@6
|
58 ['SWING_DAMAGE'] = {'%d'},
|
Nenue@6
|
59 ['SPELL_DAMAGE'] = {'%d'},
|
Nenue@6
|
60 ['RANGE_DAMAGE'] = {'%d'},
|
Nenue@6
|
61 Incoming = {
|
Nenue@6
|
62 ['SWING_DAMAGE'] = {'-%d'},
|
Nenue@6
|
63 ['SPELL_DAMAGE'] = {'-%d (%s)'},
|
Nenue@6
|
64 ['RANGE_DAMAGE'] = {'-%d'},
|
Nenue@6
|
65 },
|
Nenue@6
|
66 },
|
Nenue@6
|
67 textModifiers ={
|
Nenue@6
|
68 critical = {'%s!', 'pop'},
|
Nenue@6
|
69 overKill = {'%s |cFF0088FFKilling Blow!|r', 'slide'},
|
Nenue@6
|
70 multistrike = {'<%s>', 'lateralSlide', 'font3'},
|
Nenue@6
|
71 absorbed = {'%s (%d)', 'slide'},
|
Nenue@6
|
72 blocked = {'%s {%d}', 'slide'},
|
Nenue@6
|
73 pet = {'(%s)', 'lateralSlide'},
|
Nenue@6
|
74 grouped = {'%s (%d hit)', 'slide'},
|
Nenue@6
|
75 },
|
Nenue@6
|
76 --- [AnimationGroup key] = {[XML attrib] = [value], d[x/y] = (number) 0-1 }
|
Nenue@6
|
77 -- d[x/y] indicates the proportional relevance of each FontString dimension when frames are displaced by a new event
|
Nenue@6
|
78 -- x/y indicates the ranges of movement made by an animation, and are also considered when calculating displacement
|
Nenue@6
|
79 animation = {
|
Nenue@6
|
80 slide = {
|
Nenue@6
|
81 x = 0, dx = 0,
|
Nenue@6
|
82 y = 300, dy = 1,
|
Nenue@6
|
83 duration = 2
|
Nenue@6
|
84 },
|
Nenue@6
|
85 lateralSlide = {
|
Nenue@6
|
86 x = 300, dx = 1,
|
Nenue@6
|
87 y = 0, dy = 0,
|
Nenue@6
|
88 duration = 2
|
Nenue@6
|
89 },
|
Nenue@6
|
90 pop = {
|
Nenue@6
|
91 toScale = 1.4,
|
Nenue@6
|
92 fromScale = 0.1,
|
Nenue@6
|
93 duration = 0.14,
|
Nenue@6
|
94 dx = 0, dy = 1,
|
Nenue@6
|
95 },
|
Nenue@6
|
96 fadeOut = {change = -1, duration = 0.5},
|
Nenue@6
|
97 },
|
Nenue@6
|
98 }
|
Nenue@6
|
99 --- [1] text wrapper [2] animation type
|
Nenue@6
|
100 local dotEvents = {
|
Nenue@6
|
101 SPELL_AURA_APPLIED = true,
|
Nenue@6
|
102 SPELL_PERIODIC_DAMAGE = true,
|
Nenue@6
|
103 SPELL_AURA_REMOVED = true,
|
Nenue@6
|
104 SPELL_AURA_REFRESHED = true,
|
Nenue@6
|
105 }
|
Nenue@6
|
106 local petGUID = {}
|
Nenue@6
|
107
|
Nenue@6
|
108 ------------- data structures
|
Nenue@6
|
109 local defaultAnimation, defaultFont
|
Nenue@6
|
110 local criticalModifier, absorbedModifier, blockedModifier, overKillModifier, multistrikeModifier, groupedModifier
|
Nenue@6
|
111 local criticalAnimation, absorbedAnimation, blockedAnimation, overKillAnimation, multistrikeAnimation, groupedAnimation
|
Nenue@6
|
112 local criticalFont, absorbedFont, blockedFont, overKillFont,multistrikeFont, groupedFont
|
Nenue@6
|
113 local textFonts = {}
|
Nenue@6
|
114 local textFormat = {}
|
Nenue@6
|
115 local animation = {}
|
Nenue@6
|
116 local spellCache = {}
|
Nenue@6
|
117 local DoTFrames = {}
|
Nenue@6
|
118
|
Nenue@6
|
119 local dotTrackingEvents = {
|
Nenue@6
|
120 ['SPELL_AURA_APPLIED'] = true,
|
Nenue@6
|
121 ['SPELL_AURA_REMOVED'] = true,
|
Nenue@6
|
122 ['SPELL_AURA_REFRESHED'] = true,
|
Nenue@6
|
123 }
|
Nenue@6
|
124
|
Nenue@6
|
125 --- multi-hit events data
|
Nenue@6
|
126 -- [(string) localized name] = {
|
Nenue@6
|
127 -- [1] = (bool) controlled channel
|
Nenue@6
|
128 -- [2] = (number) minimum time to wait for next damage tick
|
Nenue@6
|
129 -- [3] = (number) maximum time to log grouped spell hits
|
Nenue@6
|
130 -- [4] = (string) combatEvent full string
|
Nenue@6
|
131 -- [5] = (string) combatEvent short prefix (as opposed to SPELL_PERIODIC)
|
Nenue@6
|
132 -- [6] = (string) combatEvent short suffix (as opposed to AURA_APPLIED)
|
Nenue@6
|
133 -- }
|
Nenue@6
|
134 -- tailing fields are set to reduce the number of arguments passed around
|
Nenue@6
|
135 local groupedSpells = {
|
Nenue@6
|
136 global = {false, 1, 'SPELL_PERIODIC_DAMAGE', 'SPELL', 'DAMAGE'},
|
Nenue@6
|
137 ['Crimson Tempest'] = {false, 0.3, 'SPELL_DAMAGE', 'SPELL', 'DAMAGE'}, -- shockwave dot
|
Nenue@6
|
138 ['Mind Sear'] = {false, 1, 'SPELL_DAMAGE', 'SPELL', 'DAMAGE'}, -- scanning aoe
|
Nenue@6
|
139 ['Searing Insanity'] = {false, 1, 'SPELL_DAMAGE', 'SPELL', 'DAMAGE'}, -- scanning aoe
|
Nenue@6
|
140 ['Ice Nova'] = {false, 0.4, 'SPELL_DAMAGE', 'SPELL', 'DAMAGE'}, -- shockwave aoe
|
Nenue@6
|
141 ['Blizzard'] = {false, 1, 'SPELL_DAMAGE', 'SPELL', 'DAMAGE'}, -- scanning aoe
|
Nenue@6
|
142 ['Frozen Orb'] = {false, 1, 'SPELL_DAMAGE', 'SPELL', 'DAMAGE'},
|
Nenue@6
|
143 ['Ice Bomb'] = {false, 0.4, 'SPELL_DAMAGE', 'SPELL', 'DAMAGE'}, -- shockwave aoe
|
Nenue@6
|
144 ['Comet Storm'] = {false, 2.5, 'SPELL_DAMAGE', 'SPELL', 'DAMAGE'}, -- staggered multi-hit
|
Nenue@6
|
145 ['Barrage'] = {false, 1.1, 'SPELL_DAMAGE', 'SPELL', 'DAMAGE'}, -- projectile vommit
|
Nenue@6
|
146 ['Glaive Toss'] = {false, 3, 'SPELL_DAMAGE', 'SPELL', 'DAMAGE'}, -- path projectile,
|
Nenue@6
|
147 ['Doom Nova'] = {false, 0.4, 'SPELL_DAMAGE', 'SPELL', 'DAMAGE'}
|
Nenue@6
|
148 }
|
Nenue@6
|
149
|
Nenue@6
|
150 local dotSpellIndex = {
|
Nenue@6
|
151 ['Shadow Word: Pain'] = {'HARMFUL|PLAYER'},
|
Nenue@6
|
152 ['Vampiric Touch'] = {'HARMFUL|PLAYER'}
|
Nenue@6
|
153 }
|
Nenue@6
|
154
|
Nenue@6
|
155 local offhandSpellIndex = {
|
Nenue@6
|
156 ['Execute'] = {'Execute Off-Hand'},
|
Nenue@6
|
157 ['Mutilate'] = {'Mutilate Off-Hand'},
|
Nenue@6
|
158 ['Stormstrike'] = {'Stormstrike Off-Hand'},
|
Nenue@6
|
159 }
|
Nenue@6
|
160
|
Nenue@6
|
161 --- stored as a list of field representations to be concatenated together within a loadstring def
|
Nenue@6
|
162
|
Nenue@6
|
163
|
Nenue@6
|
164
|
Nenue@6
|
165 --- Tracking tables
|
Nenue@6
|
166 local groupedQueue = {}
|
Nenue@6
|
167 local groupedEvents = {}
|
Nenue@6
|
168 local offhandQueue = {}
|
Nenue@6
|
169 local sct_format = {}
|
Nenue@6
|
170
|
Nenue@6
|
171
|
Nenue@6
|
172 local function GetGUIDInfo(guid)
|
Nenue@6
|
173 local unitType, flags1, flags2 = guid:match('(%a+)\-(%x+)\-(%x+)')
|
Nenue@6
|
174 return concat({unitType, flags1, flags2},'|r::|cFF0088FF')..'|r'
|
Nenue@6
|
175 end
|
Nenue@6
|
176
|
Nenue@6
|
177 local SpellSchoolColors = {
|
Nenue@6
|
178 [1] = {255, 255,0}, -- physical
|
Nenue@6
|
179 [2] = {255, 230, 128}, -- holy
|
Nenue@6
|
180 [3] = {255, 255, 128}, -- holy+phys
|
Nenue@6
|
181 [4] = {255, 128, 0}, -- fire
|
Nenue@6
|
182 [8] = {77, 255, 77}, -- nature
|
Nenue@6
|
183 [16] = {128, 255, 255}, -- frost
|
Nenue@6
|
184 [20] = {255, 192, 128}, -- frostfire
|
Nenue@6
|
185 [32] = {128, 128, 255}, -- shadow
|
Nenue@6
|
186 [48] = {128, 192, 255}, -- shadow+frost
|
Nenue@6
|
187 [64] = {255, 128, 255}, -- arcane,
|
Nenue@6
|
188 [72] = {255, 128, 128}, -- spellstorm,
|
Nenue@6
|
189 }
|
Nenue@6
|
190
|
Nenue@6
|
191 local h = '|cFF%02X%02X%02X'
|
Nenue@6
|
192 local SpellSchoolColor = function (flags, spellName)
|
Nenue@6
|
193 local i = 64
|
Nenue@6
|
194 local rA, gA, bA
|
Nenue@6
|
195 if SpellSchoolColors[flags] then
|
Nenue@6
|
196 print(flags, 'match')
|
Nenue@6
|
197 print(format('%02X%02X%02X', unpack(SpellSchoolColors[flags])))
|
Nenue@6
|
198 return format(h, unpack(SpellSchoolColors[flags]))
|
Nenue@6
|
199 end
|
Nenue@6
|
200
|
Nenue@6
|
201 repeat
|
Nenue@6
|
202 local rB, gB, bB = unpack(SpellSchoolColors[i])
|
Nenue@6
|
203 if i <= flags then
|
Nenue@6
|
204 if not rA then
|
Nenue@6
|
205 rA = rB
|
Nenue@6
|
206 gA = gB
|
Nenue@6
|
207 bA = bB
|
Nenue@6
|
208 else
|
Nenue@6
|
209 rA = (rA+rB)/2
|
Nenue@6
|
210 gA = (gA+gB)/2
|
Nenue@6
|
211 bA = (bA+bB)/2
|
Nenue@6
|
212 end
|
Nenue@6
|
213 print('test:', cWord(i), '<=', cKey(flags), '=', (i <= flags), cPink(rA), cNum(gA), cText(bA))
|
Nenue@6
|
214 flags = flags - i
|
Nenue@6
|
215 else
|
Nenue@6
|
216 print(i, 'skip')
|
Nenue@6
|
217 end
|
Nenue@6
|
218 i = i/2
|
Nenue@6
|
219 until (i == 1)
|
Nenue@6
|
220 SpellSchoolColors[flags] = {rA, gA, bA }
|
Nenue@6
|
221 --print(string.format('%02X%02X%02X', unpack(SpellSchoolColors[flags])))
|
Nenue@6
|
222 return format(h, unpack(SpellSchoolColors[flags]))
|
Nenue@6
|
223 end
|
Nenue@6
|
224 local myGUID
|
Nenue@6
|
225
|
Nenue@6
|
226 mod.NewCombatMessage = function(frame, index)
|
Nenue@6
|
227 local ct = CreateFrame('Frame', SCT_MESSAGE_NAME:format(frame.lineID), frame, SCT_MESSAGE_TEMPLATE)
|
Nenue@6
|
228 index = index and 'active' or 'expired'
|
Nenue@6
|
229 frame.lineID = frame.lineID + 1
|
Nenue@6
|
230 frame.active[#frame.active+1] = ct
|
Nenue@6
|
231 ct.index = #frame.active
|
Nenue@6
|
232 ct.x = 0
|
Nenue@6
|
233 ct.y = 0
|
Nenue@6
|
234 ct.point = 'BOTTOMLEFT'
|
Nenue@6
|
235 return ct
|
Nenue@6
|
236 end
|
Nenue@6
|
237
|
Nenue@6
|
238 --- frame interaction logic
|
Nenue@6
|
239 mod.AddCombatMessage = function(frame, text, icon, animationType, fontKey)
|
Nenue@6
|
240 local line
|
Nenue@6
|
241 print(fontKey)
|
Nenue@6
|
242
|
Nenue@6
|
243 local expired = frame.expired
|
Nenue@6
|
244 local active = frame.active
|
Nenue@6
|
245 local a = 1
|
Nenue@6
|
246 local shiftY, shiftX
|
Nenue@6
|
247 local lastFrame
|
Nenue@6
|
248 --- If animation has overlap delta values, find the last active frame of that animation type and check for overlaps.
|
Nenue@6
|
249 --- Frames are considered overlapping when the last member's ((height - distance traveled) * delta) is over 0.
|
Nenue@6
|
250 --- This assumes the same string height for the upcoming frame since wordwrap isn't enabled.
|
Nenue@6
|
251 print(animationType)
|
Nenue@6
|
252 if animation[animationType].dx or animation[animationType].dy then
|
Nenue@6
|
253 print('animation has displacement')
|
Nenue@6
|
254 if frame.last then
|
Nenue@6
|
255 lastFrame = frame.last
|
Nenue@6
|
256 local dp = lastFrame[animationType]:GetProgress()
|
Nenue@6
|
257 if animation[animationType].dx then
|
Nenue@6
|
258 local dx = dp * animation[animationType].x
|
Nenue@6
|
259 shiftX = (lastFrame.string:GetStringWidth() - dx) * animation[animationType].dx
|
Nenue@6
|
260 end
|
Nenue@6
|
261 if animation[animationType].dy then
|
Nenue@6
|
262 local dy = dp * animation[animationType].y
|
Nenue@6
|
263 shiftY = (lastFrame.string:GetStringHeight() - dy) * animation[animationType].dy
|
Nenue@6
|
264 print(' ', 'h=', floor(lastFrame.string:GetStringHeight()), 'dY=', dy, 'offsetY=', shiftY)
|
Nenue@6
|
265 end
|
Nenue@6
|
266 print(cWord('lastFrame hit:'), lastFrame and lastFrame:GetName(), cNum(shiftX), cNum(shiftY))
|
Nenue@6
|
267 end
|
Nenue@6
|
268 end
|
Nenue@6
|
269
|
Nenue@6
|
270 -- find a usable frame
|
Nenue@6
|
271 local currentFrame
|
Nenue@6
|
272 for i, ct in ipairs(frame.active) do
|
Nenue@6
|
273 if not currentFrame then
|
Nenue@6
|
274 if ct.discard then
|
Nenue@6
|
275 ct.discard= nil
|
Nenue@6
|
276 currentFrame = ct
|
Nenue@6
|
277 end
|
Nenue@6
|
278 end
|
Nenue@6
|
279
|
Nenue@6
|
280 if lastFrame and ct.animationType == animationType and not ct.discard then
|
Nenue@6
|
281 --print('lastFrame defined, check for overlap')
|
Nenue@6
|
282 if shiftY > 0 then
|
Nenue@6
|
283 print(cWord(' * vertical shift'), cNum('+'..floor(shiftY)))
|
Nenue@6
|
284 ct.y = ct.y + shiftY
|
Nenue@6
|
285 end
|
Nenue@6
|
286 if shiftX > 0 then
|
Nenue@6
|
287 print(cWord(' * horizontal shift'), cNum('+'..floor(shiftX)))
|
Nenue@6
|
288 ct.x = ct.x + shiftX
|
Nenue@6
|
289 end
|
Nenue@6
|
290 ct:SetPoint(ct.point, frame, ct.point, ct.x, ct.y)
|
Nenue@6
|
291 end
|
Nenue@6
|
292 end
|
Nenue@6
|
293 -- if no expired frames became available, make a new one (should max at 20 or so if groupings are right)
|
Nenue@6
|
294 if not currentFrame then
|
Nenue@6
|
295 currentFrame = mod.NewCombatMessage(frame)
|
Nenue@6
|
296 print(cNum(' creating new string object for the heap'))
|
Nenue@6
|
297 end
|
Nenue@6
|
298
|
Nenue@6
|
299 print(cText(' * Starting'), cPink(animationType), 'on', cKey(currentFrame:GetName()), ' ['..cNum(currentFrame.index)..']')
|
Nenue@6
|
300
|
Nenue@6
|
301 if icon then
|
Nenue@6
|
302 currentFrame.icon:Show()
|
Nenue@6
|
303 currentFrame.icon:SetTexture(icon)
|
Nenue@6
|
304 else
|
Nenue@6
|
305 currentFrame.icon:Hide()
|
Nenue@6
|
306 end
|
Nenue@6
|
307 if fontKey then
|
Nenue@6
|
308 local newFont = fontKey and textFonts[fontKey] or defaultFont
|
Nenue@6
|
309
|
Nenue@6
|
310 local path, size, flags = currentFrame.string:GetFont()
|
Nenue@6
|
311 path = newFont[1] or path
|
Nenue@6
|
312 size = newFont[2] or size
|
Nenue@6
|
313 flags = newFont[3] or flags
|
Nenue@6
|
314 print(cText('font ('..cWord(fontKey)..'):'), path, size, flags)
|
Nenue@6
|
315 local result = currentFrame.string:SetFont(path, size, flags)
|
Nenue@6
|
316 print(cNum(' result:'), cNum(result), currentFrame.string:GetFont())
|
Nenue@6
|
317 --currentFrame.fontKey = fontKey
|
Nenue@6
|
318 end
|
Nenue@6
|
319
|
Nenue@6
|
320 currentFrame.animationType = animationType
|
Nenue@6
|
321 currentFrame.string:SetText(text)
|
Nenue@6
|
322 local cHeight = currentFrame.string:GetStringHeight()
|
Nenue@6
|
323 currentFrame:SetSize(currentFrame.string:GetStringWidth(), cHeight)
|
Nenue@6
|
324 currentFrame.icon:SetSize(cHeight, cHeight)
|
Nenue@6
|
325 currentFrame.y = 0
|
Nenue@6
|
326 currentFrame.x = 0
|
Nenue@6
|
327 currentFrame:SetPoint(currentFrame.point, frame, currentFrame.point, currentFrame.x, currentFrame.y)
|
Nenue@6
|
328 currentFrame[animationType]:Play()
|
Nenue@6
|
329 frame.last = currentFrame
|
Nenue@6
|
330 end
|
Nenue@6
|
331
|
Nenue@6
|
332 local GetTextFormatFunc = function(amount, overKill, absorbed, blocked, multistrike, spellName, sourceName, destName)
|
Nenue@6
|
333 local sub_text = {
|
Nenue@6
|
334 ['%d'] = amount,
|
Nenue@6
|
335 ['%o'] = overKill,
|
Nenue@6
|
336 ['%a'] = absorbed,
|
Nenue@6
|
337 ['%b'] = blocked,
|
Nenue@6
|
338 ['%m'] = multistrike,
|
Nenue@6
|
339 ['%s'] = spellName,
|
Nenue@6
|
340 ['%n'] = sourceName,
|
Nenue@6
|
341 ['%t'] = destName,
|
Nenue@6
|
342 }
|
Nenue@6
|
343 local func = function(token)
|
Nenue@6
|
344 print(cPink('gsub run:'), token)
|
Nenue@6
|
345 return sub_text[token]
|
Nenue@6
|
346 end
|
Nenue@6
|
347 return func
|
Nenue@6
|
348 end
|
Nenue@6
|
349
|
Nenue@6
|
350 --- builds CT messages from combat log event data
|
Nenue@6
|
351 -- separated from frame interaction for auxiliary events such as combat/loot/etc
|
Nenue@6
|
352 local CreateDamageText = function(frame, timestamp, combatEvent, sourceName, destName, spellID, spellName, effectSchool, amount, overKill, resisted, blocked, absorbed, critical, glancing, crushing, isOffHand, multistrike, ticks)
|
Nenue@6
|
353 if combatEvent:match('^SWING') then
|
Nenue@6
|
354 spellID = 1
|
Nenue@6
|
355 spellName = 'Attack'
|
Nenue@6
|
356 elseif combatEvent:match('^RANGE') then
|
Nenue@6
|
357 spellID = 2
|
Nenue@6
|
358 spellName = 'Auto Shot'
|
Nenue@6
|
359 end
|
Nenue@6
|
360 if not combatEvent:match('DAMAGE') then
|
Nenue@6
|
361 return
|
Nenue@6
|
362 end
|
Nenue@6
|
363
|
Nenue@6
|
364
|
Nenue@6
|
365 local fontKey = 'font1'
|
Nenue@6
|
366 local icon = GetSpellTexture(spellID)
|
Nenue@6
|
367 local animationType = defaultAnimation
|
Nenue@6
|
368 local text = amount
|
Nenue@6
|
369 if textFormat[combatEvent] then
|
Nenue@6
|
370 local tString, fontKey = unpack(textFormat[combatEvent])
|
Nenue@6
|
371 if amount > 1000000 then
|
Nenue@6
|
372 amount = (floor(amount/100000)/10) ..'M'
|
Nenue@6
|
373 elseif amount > 1000 then
|
Nenue@6
|
374 amount = (floor(amount/100)/10) ..'k'
|
Nenue@6
|
375 end
|
Nenue@6
|
376
|
Nenue@6
|
377 text = tString:gsub('%%[doabsnt]', GetTextFormatFunc(amount, overKill, absorbed, blocked, multistrike, spellName, sourceName, destName))
|
Nenue@6
|
378 print("** font override:", '"'..cText(tString)..'",', cPink(font), cNum(size), cWord(outline))
|
Nenue@6
|
379 end
|
Nenue@6
|
380
|
Nenue@6
|
381 print('** getting color data', cText(spellName))
|
Nenue@6
|
382 if type(effectSchool) == 'number' then
|
Nenue@6
|
383 text = SpellSchoolColor(effectSchool) ..text..'|r'
|
Nenue@6
|
384 end
|
Nenue@6
|
385
|
Nenue@6
|
386 if overKill > 0 then
|
Nenue@6
|
387 text = overKillModifier:format(text, overKill)
|
Nenue@6
|
388 animationType = overKillAnimation
|
Nenue@6
|
389 fontKey = overKillFont or fontKey
|
Nenue@6
|
390 end
|
Nenue@6
|
391 if critical then
|
Nenue@6
|
392 text = criticalModifier:format(text)
|
Nenue@6
|
393 animationType = criticalAnimation
|
Nenue@6
|
394 fontKey = criticalFont or fontKey
|
Nenue@6
|
395 end
|
Nenue@6
|
396 if absorbed then
|
Nenue@6
|
397 text = absorbedModifier:format(text, absorbed)
|
Nenue@6
|
398 animationType = absorbedAnimation
|
Nenue@6
|
399 fontKey = absorbedFont or fontKey
|
Nenue@6
|
400 end
|
Nenue@6
|
401 if blocked then
|
Nenue@6
|
402 text = blockedModifier:format(text, blocked)
|
Nenue@6
|
403 animationType = blockedAnimation
|
Nenue@6
|
404 fontKey = blockedFont or fontKey
|
Nenue@6
|
405 end
|
Nenue@6
|
406 if multistrike then
|
Nenue@6
|
407 text = multistrikeModifier:format(text, multistrike)
|
Nenue@6
|
408 animationType = multistrikeAnimation
|
Nenue@6
|
409 fontKey = multistrikeFont or fontKey
|
Nenue@6
|
410 end
|
Nenue@6
|
411
|
Nenue@6
|
412 print(ticks)
|
Nenue@6
|
413 if ticks then
|
Nenue@6
|
414 text = groupedModifier:format(text, ticks)
|
Nenue@6
|
415 animationType = groupedAnimation
|
Nenue@6
|
416 fontKey = groupedFont or fontKey
|
Nenue@6
|
417 end
|
Nenue@6
|
418
|
Nenue@6
|
419
|
Nenue@6
|
420 print('** sending format to SCT:', text, icon, animationType, fontKey)
|
Nenue@6
|
421
|
Nenue@6
|
422
|
Nenue@6
|
423 mod.AddCombatMessage(frame, text .. '|r', icon, animationType, fontKey)
|
Nenue@6
|
424 end
|
Nenue@6
|
425
|
Nenue@6
|
426 local CT_ShowConsolidated = function()
|
Nenue@6
|
427 for spellName, queuedSpell in pairs(groupedQueue) do
|
Nenue@6
|
428 local isChannel, minDelay, combatEvent, sourceName, destName, spellID, school, SCT, timestamp = unpack(queuedSpell)
|
Nenue@6
|
429 for i, v in ipairs(queuedSpell) do
|
Nenue@6
|
430 print(' ', i, '=', v)
|
Nenue@6
|
431 end
|
Nenue@6
|
432
|
Nenue@6
|
433 print(spellName, 'vars:', spellID, spellName, school, SCT, timestamp)
|
Nenue@6
|
434 if groupedEvents[spellName] and #groupedEvents[spellName] ~= 0 then
|
Nenue@6
|
435 local amount, overKill, resisted, blocked, absorbed, critical, glancing, crushing, multistrike, hit = 0, -1, 0, 0, 0, 0, 0, 0, 0, 0
|
Nenue@6
|
436 for i, line in ipairs(groupedEvents[spellName]) do
|
Nenue@6
|
437 -- extra strike?
|
Nenue@6
|
438 --{amount, overKill, resisted, blocked, absorbed, critical, glancing, crushing, multistrike}
|
Nenue@6
|
439 local amount_n, overKill_n, resisted_n, blocked_n, absorbed_n, critical_n, glancing_n, crushing_n, multi_n, sourceGUID, destGUID, sourceName, destName = unpack (line)
|
Nenue@6
|
440
|
Nenue@6
|
441 amount = amount + amount_n
|
Nenue@6
|
442 if overKill_n > 0 then overKill = overKill + overKill_n end
|
Nenue@6
|
443 if blocked_n then blocked = blocked + line[4] end
|
Nenue@6
|
444 if absorbed_n then absorbed = absorbed + line[5] end
|
Nenue@6
|
445 if critical_n then critical = critical + 1 end
|
Nenue@6
|
446 if multi_n then multistrike = multistrike + 1 end
|
Nenue@6
|
447
|
Nenue@6
|
448 hit = hit + 1
|
Nenue@6
|
449 end
|
Nenue@6
|
450 if overKill == -1 then
|
Nenue@6
|
451 overKill = overKill + 1
|
Nenue@6
|
452 end
|
Nenue@6
|
453 wipe(groupedEvents[spellName])
|
Nenue@6
|
454 groupedQueue[spellName] = nil
|
Nenue@6
|
455 print(' expelling', spellName, cText('A:'), cNum(amount), cText('O:'), cNum(overKill), cText('Ticks:'), cNum(hit), cText('Crits:'), cNum(critical), cText(school))
|
Nenue@6
|
456 print(SCT, timestamp, combatEvent, sourceName, destName, spellID, spellName, school, amount, overKill, resisted, blocked, absorbed, critical, glancing, crushing, multistrike, hit)
|
Nenue@6
|
457 CreateDamageText(SCT, timestamp, combatEvent, sourceName, destName, spellID, spellName, school, amount, -1, nil, nil, nil, false, glancing, crushing, false, multistrike, hit)
|
Nenue@6
|
458 end
|
Nenue@6
|
459 end
|
Nenue@6
|
460 end
|
Nenue@6
|
461
|
Nenue@6
|
462 local CT_ConsolidateText = function (self, timestamp, sourceGUID, destGUID, sourceName, destName, spellID, spellName, school, amount, overKill, resisted, blocked, absorbed, critical, glancing, crushing, isOffHand, multistrike)
|
Nenue@6
|
463 local archive = groupedSpells[spellName] and groupedSpells[spellName] or groupedSpells.global
|
Nenue@6
|
464 local isChannel, minDelay, combatEvent = unpack(archive)
|
Nenue@6
|
465 if not groupedEvents[spellName] then
|
Nenue@6
|
466 groupedEvents[spellName] = {}
|
Nenue@6
|
467 end
|
Nenue@6
|
468
|
Nenue@6
|
469 if #groupedEvents[spellName] == 0 then
|
Nenue@6
|
470 groupedQueue[spellName] = {isChannel, minDelay, combatEvent, sourceName, destName, spellID, school, self, timestamp}
|
Nenue@6
|
471 T:ScheduleTimer(CT_ShowConsolidated, minDelay)
|
Nenue@6
|
472 print(' starting archive for', select(7, unpack(archive)))
|
Nenue@6
|
473 else
|
Nenue@6
|
474 print(' recording into archive', cText(spellName))
|
Nenue@6
|
475 end
|
Nenue@6
|
476 tinsert(groupedEvents[spellName], {amount, overKill, resisted, blocked, absorbed, critical, glancing, crushing, multistrike, sourceGUID, destGUID, sourceName, destName, sourceName, destName,})
|
Nenue@6
|
477 end
|
Nenue@6
|
478
|
Nenue@6
|
479 local CT_OnCast = function(self, event, unit, spellName, lineID, spellID)
|
Nenue@6
|
480 if unit ~= 'player' and unit ~= 'pet' then
|
Nenue@6
|
481 return
|
Nenue@6
|
482 end
|
Nenue@6
|
483
|
Nenue@6
|
484 if groupedSpells[spellName] then
|
Nenue@6
|
485 print(cText('** Spell casting info received'))
|
Nenue@6
|
486 local isChannel, delay = unpack(groupedSpells[spellName])
|
Nenue@6
|
487 if isChannel and event == 'CHANNEL_STOP' and groupedEvents[spellName] then
|
Nenue@6
|
488 T:ScheduleTimer(CT_ShowConsolidated, delay)
|
Nenue@6
|
489 else
|
Nenue@6
|
490 if not groupedEvents[spellName] then
|
Nenue@6
|
491 groupedEvents[spellName] = {}
|
Nenue@6
|
492 end
|
Nenue@6
|
493 end
|
Nenue@6
|
494 end
|
Nenue@6
|
495 end
|
Nenue@6
|
496
|
Nenue@6
|
497 local CT_Unlock = function(str)
|
Nenue@6
|
498 for i, CT in pairs(mod.CombatTextFrames) do
|
Nenue@6
|
499 local frame = CT.frame
|
Nenue@6
|
500 frame.configMode = (frame.configMode == nil) and true or nil
|
Nenue@6
|
501 frame:RegisterForDrag(frame.configMode and 'LeftButton' or nil)
|
Nenue@6
|
502 frame:EnableMouse(frame.configMode and true or false)
|
Nenue@6
|
503 print(i, frame.configMode and 'ON' or 'OFF')
|
Nenue@6
|
504 for _, reg in ipairs(frame.configRegions) do
|
Nenue@6
|
505 if frame.configMode then
|
Nenue@6
|
506 reg:Show()
|
Nenue@6
|
507 else
|
Nenue@6
|
508 reg:Hide()
|
Nenue@6
|
509 end
|
Nenue@6
|
510 end
|
Nenue@6
|
511
|
Nenue@6
|
512 if frame.configMode then
|
Nenue@6
|
513 CT.configTimer = T:ScheduleRepeatingTimer(function()
|
Nenue@6
|
514 print(i, 'config tick')
|
Nenue@6
|
515 for i, s in ipairs(CT.sample) do
|
Nenue@6
|
516 CT.OnEvent(frame, unpack(s))
|
Nenue@6
|
517 end
|
Nenue@6
|
518 end, 2)
|
Nenue@6
|
519 else
|
Nenue@6
|
520 print(CT.configTimer)
|
Nenue@6
|
521 T:CancelTimer(CT.configTimer)
|
Nenue@6
|
522 end
|
Nenue@6
|
523
|
Nenue@6
|
524 end
|
Nenue@6
|
525 end
|
Nenue@6
|
526
|
Nenue@6
|
527 --- check for sectors
|
Nenue@6
|
528 local queue = {}
|
Nenue@6
|
529 mod.OnDamage = function(self, event, ...)
|
Nenue@6
|
530 local isVisible
|
Nenue@6
|
531
|
Nenue@6
|
532 local timestamp, combatEvent = ...
|
Nenue@6
|
533 print(cText('* CT'), cKey(combatEvent))
|
Nenue@6
|
534 if combatEvent == 'UNIT_DIED' then
|
Nenue@6
|
535 return
|
Nenue@6
|
536 end
|
Nenue@6
|
537 local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, spellID, spellName, spellSchool = select(4, ...)
|
Nenue@6
|
538 print(' from', cPink(sourceGUID), 'spell', cNum(spellID), cText(spellName), '->', cKey(destGUID))
|
Nenue@6
|
539
|
Nenue@6
|
540 -- SWING starts at arg 10, SPELL/RANGE start at arg 13, ENVIRONMENTAL starts at arg 8
|
Nenue@6
|
541 local offset = 15
|
Nenue@6
|
542 print(combatEvent:sub(0,3))
|
Nenue@6
|
543 if combatEvent:sub(0,3) == 'SWI' then
|
Nenue@6
|
544 offset = 10
|
Nenue@6
|
545 elseif combatEvent:sub(0,3) == 'ENV' then
|
Nenue@6
|
546 offset = 8
|
Nenue@6
|
547 end
|
Nenue@6
|
548 local amount, overKill, effectSchool, resisted, blocked, absorbed, critical, glancing, crushing, isOffHand, multistrike = select(offset, ...)
|
Nenue@6
|
549
|
Nenue@6
|
550 print(' dmg', amount, overKill)
|
Nenue@6
|
551
|
Nenue@6
|
552 local sc = SpellSchoolColors[effectSchool]
|
Nenue@6
|
553 if groupedSpells[spellName] then
|
Nenue@6
|
554 print('* ', cText(spellName), 'to consolidator')
|
Nenue@6
|
555 CT_ConsolidateText(self, timestamp, sourceGUID, destGUID, sourceName, destName, spellID, spellName, effectSchool, amount, overKill, resisted, blocked, absorbed, critical, glancing, crushing, isOffHand, multistrike)
|
Nenue@6
|
556 return
|
Nenue@6
|
557 end
|
Nenue@6
|
558
|
Nenue@6
|
559 print('displaying on', cWord(self:GetName()))
|
Nenue@6
|
560 CreateDamageText(self, timestamp, combatEvent, sourceName, destName, spellID, spellName, effectSchool, amount, overKill, resisted, blocked, absorbed, critical, glancing, crushing, isOffHand, multistrike)
|
Nenue@6
|
561 end
|
Nenue@6
|
562
|
Nenue@6
|
563 mod.maxDotFrame = 1
|
Nenue@6
|
564 mod.OnDotEvent = function (self, event, timestamp, combatEvent, ...)
|
Nenue@6
|
565 print(cWord('DOT'), combatEvent)
|
Nenue@6
|
566 local sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, destExtraFlags, spellID, spellName, castSchool, amount, overKill, resisted, blocked, absorbed, critical, glancing, crushing, isOffHand, multistrike = select(2, ...)
|
Nenue@6
|
567 print(cText('dot from'), cWord(sourceGUID), 'to', cKey(destGUID))
|
Nenue@6
|
568 if sourceGUID == T.GUID then
|
Nenue@6
|
569 local p = mod.PeriodicTable
|
Nenue@6
|
570 p[destGUID] = p[destGUID] or {}
|
Nenue@6
|
571 local unit = p[destGUID]
|
Nenue@6
|
572 if not p[spellID] then
|
Nenue@6
|
573 if not p.frames[#p.frames] then
|
Nenue@6
|
574 unit[spellID] = CreateFrame('Frame', 'DotBar'..mod.maxDotFrame, p, 'TkDotBarTemplate')
|
Nenue@6
|
575 mod.maxDotFrame = mod.maxDotFrame + 1
|
Nenue@6
|
576 unit[spellID].dotID = mod.maxDotFrame
|
Nenue@6
|
577
|
Nenue@6
|
578 print(' create new frame ['..cKey(unit[spellID]:GetID(), '] for'), cWord(spellName), cKey(destGUID))
|
Nenue@6
|
579 else
|
Nenue@6
|
580 unit[spellID] = p.frames[#p.frames]
|
Nenue@6
|
581 p.frames[#p.frames] = nil -- remove that entry
|
Nenue@6
|
582 print(' recycling frame ['..cKey(unit[spellID].dotID, '] for'), cWord(spellName), cKey(destGUID))
|
Nenue@6
|
583 end
|
Nenue@6
|
584
|
Nenue@6
|
585 unit[spellID]:Show()
|
Nenue@6
|
586 end
|
Nenue@6
|
587 local dot = unit[spellID]
|
Nenue@6
|
588 local time = GetTime()
|
Nenue@6
|
589 end
|
Nenue@6
|
590 end
|
Nenue@6
|
591
|
Nenue@6
|
592
|
Nenue@6
|
593
|
Nenue@6
|
594
|
Nenue@6
|
595 function mod:OnInitialize()
|
Nenue@6
|
596 print('This is a thing.')
|
Nenue@6
|
597 self.UNIT_SPELLCAST_SUCCEEDED = CT_OnCast
|
Nenue@6
|
598 self.UNIT_SPELLCAST_CHANNEL_START = CT_OnCast
|
Nenue@6
|
599 self.UNIT_SPELLCAST_CHANNEL_STOP = CT_OnCast
|
Nenue@6
|
600 end
|
Nenue@6
|
601
|
Nenue@6
|
602 function mod:OnInitialize()
|
Nenue@6
|
603 mod.db = TurokData.CombatText
|
Nenue@6
|
604 db = TurokData.CombatText
|
Nenue@6
|
605 myGUID = T.GUID
|
Nenue@6
|
606 mod.PeriodicTable = mod.PeriodicTable or CreateFrame('Frame', 'TurokPeriodicFrame', UIParent)
|
Nenue@6
|
607 mod.PeriodicTable.frames = {}
|
Nenue@6
|
608
|
Nenue@6
|
609 local m = mod.db.textModifiers
|
Nenue@6
|
610 --- These values are going to be looked up a lot, so cache as close as possible
|
Nenue@6
|
611 criticalModifier = m.critical[1] or '%s CRIT'
|
Nenue@6
|
612 criticalAnimation = m.critical[2] or 'slide'
|
Nenue@6
|
613 criticalFont = m.critical[3]
|
Nenue@6
|
614
|
Nenue@6
|
615 absorbedModifier = m.absorbed[1] or '%s ABS'
|
Nenue@6
|
616 absorbedAnimation = m.absorbed[2] or 'slide'
|
Nenue@6
|
617 absorbedFont = m.absorbed[3]
|
Nenue@6
|
618
|
Nenue@6
|
619 blockedModifier = m.blocked[1] or '%s BLK'
|
Nenue@6
|
620 blockedAnimation = m.blocked[2] or 'slide'
|
Nenue@6
|
621 blockedFont = m.blocked[3]
|
Nenue@6
|
622
|
Nenue@6
|
623 overKillModifier = m.overKill[1] or '%s KILL'
|
Nenue@6
|
624 overKillAnimation = m.overKill[2] or 'slide'
|
Nenue@6
|
625 overKillFont = m.overKill[3]
|
Nenue@6
|
626
|
Nenue@6
|
627 multistrikeModifier = m.multistrike[1] or '%s MS'
|
Nenue@6
|
628 multistrikeAnimation = m.multistrike[2] or 'slide'
|
Nenue@6
|
629 multistrikeFont = m.multistrike[3]
|
Nenue@6
|
630
|
Nenue@6
|
631 groupedModifier = m.grouped[1] or '%s'
|
Nenue@6
|
632 groupedAnimation = m.grouped[2] or 'slide'
|
Nenue@6
|
633 groupedFont = m.grouped[3]
|
Nenue@6
|
634
|
Nenue@6
|
635 --- Same as above, but for specific table values, key is determined by the combat event
|
Nenue@6
|
636 defaultAnimation = mod.db.defaultAnimation
|
Nenue@6
|
637 defaultFont = mod.db.defaultFont
|
Nenue@6
|
638 for k,v in pairs(mod.db.textFormat) do
|
Nenue@6
|
639 textFormat[k] = {v[1], v[2]}
|
Nenue@6
|
640 print('imported textFormat.'..k, cText(textFormat[k][1]), cNum(textFormat[k][2]))
|
Nenue@6
|
641 end
|
Nenue@6
|
642 for k,v in pairs(mod.db.textFonts) do
|
Nenue@6
|
643 textFonts[k] = {v[1] or defaultFont[1], v[2] or defaultFont[2], v[3] or defaultFont[3]}
|
Nenue@6
|
644 print('imported font.'..k, cText(textFonts[k][1]), cNum(textFonts[k][2]), cWord(textFonts[k][3]))
|
Nenue@6
|
645 end
|
Nenue@6
|
646
|
Nenue@6
|
647 for k,v in pairs(mod.db.animation) do
|
Nenue@6
|
648 animation[k] = {}
|
Nenue@6
|
649 animation[k].x = v.x
|
Nenue@6
|
650 animation[k].y = v.y
|
Nenue@6
|
651 animation[k].dx = v.dx
|
Nenue@6
|
652 animation[k].dy = v.dy
|
Nenue@6
|
653 animation[k].fromScale = v.fromScale
|
Nenue@6
|
654 animation[k].toScale = v.toScale
|
Nenue@6
|
655 animation[k].deviation = v.deviation
|
Nenue@6
|
656 animation[k].change = v.change
|
Nenue@6
|
657 animation[k].fromAlpha = v.fromAlpha
|
Nenue@6
|
658 animation[k].toAlpha = v.toAlpha
|
Nenue@6
|
659 animation[k].duration = v.duration
|
Nenue@6
|
660 end
|
Nenue@6
|
661 end
|
Nenue@6
|
662
|
Nenue@6
|
663 function mod:OnEnable()
|
Nenue@6
|
664 T:RegisterChatCommand('tkc', CT_Unlock)
|
Nenue@6
|
665
|
Nenue@6
|
666 --- Populate CT frames
|
Nenue@6
|
667 for name, CT in pairs(mod.CombatTextFrames) do
|
Nenue@6
|
668 print('create CT', name)
|
Nenue@6
|
669 -- make frame
|
Nenue@6
|
670 CT.frame = CT.frame or CreateFrame('Frame', SCT_NAME:format(name), UIParent, SCT_TEMPLATE)
|
Nenue@6
|
671
|
Nenue@6
|
672 -- local vars
|
Nenue@6
|
673 local db = db[name] or db
|
Nenue@6
|
674 local frame = CT.frame
|
Nenue@6
|
675
|
Nenue@6
|
676 -- script defs
|
Nenue@6
|
677 frame.IsFrameEvent = CT.trigger
|
Nenue@6
|
678 frame.name = name
|
Nenue@6
|
679 frame.lineID = 0
|
Nenue@6
|
680 frame.expired = {}
|
Nenue@6
|
681 frame.active = {}
|
Nenue@6
|
682
|
Nenue@6
|
683 -- frame defs
|
Nenue@6
|
684 frame:SetPoint(db.anchor, db.parent, db.anchorTo, db.x, db.y)
|
Nenue@6
|
685 frame:RegisterEvent('COMBAT_LOG_EVENT_UNFILTERED')
|
Nenue@6
|
686 print('bound ', name, 'with', CT.OnEvent)
|
Nenue@6
|
687 db.sample = {}
|
Nenue@6
|
688 local logged = {}
|
Nenue@6
|
689 frame:SetScript('OnEvent', function(self, e,...)
|
Nenue@6
|
690 if CT.trigger(e, ...) then
|
Nenue@6
|
691 print('event trigger fired', name)
|
Nenue@6
|
692 if #db.sample < 5 and not logged[select(2,...)] then
|
Nenue@6
|
693 logged[select(2,...)] = true
|
Nenue@6
|
694 tinsert(db.sample, {e, ...})
|
Nenue@6
|
695 end
|
Nenue@6
|
696
|
Nenue@6
|
697 CT.OnEvent(frame, e, ...)
|
Nenue@6
|
698 end
|
Nenue@6
|
699 end)
|
Nenue@6
|
700
|
Nenue@6
|
701 -- configurators
|
Nenue@6
|
702 frame.configHeader:SetText(name)
|
Nenue@6
|
703 frame:EnableMouse(false)
|
Nenue@6
|
704
|
Nenue@6
|
705 -- pre-pop some text frames
|
Nenue@6
|
706 for i = (CT.lineID or 1), SCT_PREGAME do
|
Nenue@6
|
707 print(frame:GetName(), 'pre-pop #'..i)
|
Nenue@6
|
708 mod.NewCombatMessage(frame)
|
Nenue@6
|
709 end
|
Nenue@6
|
710 end
|
Nenue@6
|
711 end
|
Nenue@6
|
712
|
Nenue@6
|
713
|
Nenue@6
|
714 local damageEvents = {
|
Nenue@6
|
715 ['SPELL_DAMAGE'] = true,
|
Nenue@6
|
716 ['SPELL_PERIODIC_DAMAGE'] = true,
|
Nenue@6
|
717 ['SWING_DAMAGE'] = true,
|
Nenue@6
|
718 ['RANGE_DAMAGE'] = true,
|
Nenue@6
|
719 ['SPELL_HEAL'] = true,
|
Nenue@6
|
720 }
|
Nenue@6
|
721 mod.CombatTextFrames = {
|
Nenue@6
|
722 Incoming = {
|
Nenue@6
|
723 trigger = function(e, _, c, _, _, _, _, _, d) return (d == T.GUID and damageEvents[c]) end,
|
Nenue@6
|
724 OnEvent = mod.OnDamage,
|
Nenue@6
|
725 sample = {
|
Nenue@6
|
726 {"COMBAT_LOG_EVENT_UNFILTERED", 1455887795.271, "SPELL_HEAL", false, "Player-3684-07235A4E", "Klakyn", 1297, 0, "Player-3684-07235A4E", "Klakyn", 1297, 0, 143924, "Leech", 1, 93, 93, 0, false, false, },
|
Nenue@6
|
727 }
|
Nenue@6
|
728 },
|
Nenue@6
|
729 Outgoing = {
|
Nenue@6
|
730 trigger = function(e, _,c,_, s) return (s == T.GUID and damageEvents[c]) end,
|
Nenue@6
|
731 OnEvent = mod.OnDamage,
|
Nenue@6
|
732 sample = {
|
Nenue@6
|
733 {
|
Nenue@6
|
734 "COMBAT_LOG_EVENT_UNFILTERED", 1455887795.006, "SPELL_DAMAGE", false, "Player-3684-07235A4E", "Klakyn", 1297, 0, "Creature-0-3684-1116-7-87761-0000C32119", "Dungeoneer's Training Dummy", 68136, 0, 589, "Shadow Word: Pain", 32, 3944, -1, 32, nil, nil, nil, false, false, false, false, false, }, {
|
Nenue@6
|
735 "COMBAT_LOG_EVENT_UNFILTERED", 1455887795.271, "SPELL_HEAL", false, "Player-3684-07235A4E", "Klakyn", 1297, 0, "Player-3684-07235A4E", "Klakyn", 1297, 0, 143924, "Leech", 1, 93, 93, 0, false, false, }, {
|
Nenue@6
|
736 "COMBAT_LOG_EVENT_UNFILTERED", 1455887797.377, "SPELL_PERIODIC_DAMAGE", false, "Player-3684-07235A4E", "Klakyn", 1297, 0, "Creature-0-3684-1116-7-87761-0000C32119", "Dungeoneer's Training Dummy", 68136, 0, 589, "Shadow Word: Pain", 32, 3944, -1, 32, nil, nil, nil, false, false, false, false, false, }, {
|
Nenue@6
|
737 "COMBAT_LOG_EVENT_UNFILTERED", 1455887812.702, "SWING_DAMAGE", false, "Player-3684-07235A4E", "Klakyn", 1297, 0, "Creature-0-3684-1116-7-87761-0000C32119", "Dungeoneer's Training Dummy", 68136, 0, 279, -1, 1, nil, 120, nil, false, false, false, false, false, }, -- [4]
|
Nenue@6
|
738 }
|
Nenue@6
|
739 },
|
Nenue@6
|
740 DoTTracker = {
|
Nenue@6
|
741 trigger = function(e, _, c, _, s) return (s == T.GUID and dotEvents[c]) end,
|
Nenue@6
|
742 OnEvent = mod.OnDotEvent,
|
Nenue@6
|
743 sample = {
|
Nenue@6
|
744 {"COMBAT_LOG_EVENT_UNFILTERED", 1455887795.006, "SPELL_AURA_APPLIED", false,
|
Nenue@6
|
745 "Player-3684-07235A4E", "Klakyn", 1297, 0,
|
Nenue@6
|
746 "Creature-0-3684-1116-7-87761-0000C32119", "Dungeoneer's Training Dummy", 68136, 0,
|
Nenue@6
|
747 589, "Shadow Word: Pain", 32, "DEBUFF", },
|
Nenue@6
|
748 {"COMBAT_LOG_EVENT_UNFILTERED", 1455887797.377, "SPELL_PERIODIC_DAMAGE", false,
|
Nenue@6
|
749 "Player-3684-07235A4E", "Klakyn", 1297, 0,
|
Nenue@6
|
750 "Creature-0-3684-1116-7-87761-0000C32119", "Dungeoneer's Training Dummy", 68136, 0,
|
Nenue@6
|
751 589, "Shadow Word: Pain", 32, 3944, -1, 32, nil, nil, nil, false, false, false, false, false, },
|
Nenue@6
|
752 {"COMBAT_LOG_EVENT_UNFILTERED", 1455887807.199, "SPELL_AURA_REMOVED", false,
|
Nenue@6
|
753 "Player-3684-07235A4E", "Klakyn", 1297, 0,
|
Nenue@6
|
754 "Player-3684-07235A4E", "Klakyn", 1297, 0,
|
Nenue@6
|
755 15473, "Shadowform", 32, "BUFF", },
|
Nenue@6
|
756 }
|
Nenue@6
|
757 }
|
Nenue@6
|
758 } |