-
Notifications
You must be signed in to change notification settings - Fork 11
/
Transcriptor.lua
2448 lines (2315 loc) · 104 KB
/
Transcriptor.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
local Transcriptor = {}
local PLAYER_SPELL_BLOCKLIST
local TIMERS_SPECIAL_EVENTS
local TIMERS_SPECIAL_EVENTS_DATA
local TIMERS_BLOCKLIST
local RETAIL
do
local _, addonTbl = ...
PLAYER_SPELL_BLOCKLIST = addonTbl.PLAYER_SPELL_BLOCKLIST or {} -- PlayerSpellBlocklist.lua
TIMERS_SPECIAL_EVENTS = addonTbl.TIMERS_SPECIAL_EVENTS or {} -- TimersSpecialEvents.lua
TIMERS_SPECIAL_EVENTS_DATA = addonTbl.TIMERS_SPECIAL_EVENTS_DATA or {} -- TimersSpecialEvents.lua
TIMERS_BLOCKLIST = addonTbl.TIMERS_BLOCKLIST or {} -- TimersBlocklist.lua
RETAIL = addonTbl.retail or false
end
local logName = nil
local currentLog = nil
local logStartTime = nil
local logging = nil
local compareSuccess = nil
local compareUnitSuccess = nil
local compareEmotes = nil
local compareStart = nil
local compareAuraApplied = nil
local compareStartTime = nil
local collectNameplates = nil
local collectPlayerAuras = nil
local hiddenUnitAuraCollector = nil
local playerSpellCollector = nil
local hiddenAuraPermList = {
[5384] = true, -- Feign Death
[209997] = true, -- Play Dead (Hunter Pet)
}
local playerSpecList = {}
local previousSpecialEvent = nil
local hiddenAuraEngageList = nil
local prevEncounterStart = nil
local shouldLogFlags = false
local inEncounter, blockingRelease, limitingRes = false, false, false
local mineOrPartyOrRaid = 7 -- COMBATLOG_OBJECT_AFFILIATION_MINE + COMBATLOG_OBJECT_AFFILIATION_PARTY + COMBATLOG_OBJECT_AFFILIATION_RAID
local band = bit.band
local tinsert, tsort, twipe, tconcat = table.insert, table.sort, table.wipe, table.concat
local format, find, strjoin, strsplit, gsub, strmatch = string.format, string.find, string.join, string.split, string.gsub, string.match
local tostring, tostringall, date = tostring, tostringall, date
local type, next, print = type, next, print
local debugprofilestop = debugprofilestop
local C_Scenario, C_DeathInfo_GetSelfResurrectOptions, Enum = C_Scenario, C_DeathInfo.GetSelfResurrectOptions, Enum
local IsEncounterInProgress, IsEncounterLimitingResurrections, IsEncounterSuppressingRelease = IsEncounterInProgress, IsEncounterLimitingResurrections, IsEncounterSuppressingRelease
local UnitInRaid, UnitInParty, UnitIsFriend, UnitCastingInfo, UnitChannelInfo = UnitInRaid, UnitInParty, UnitIsFriend, UnitCastingInfo, UnitChannelInfo
local UnitCanAttack, UnitExists, UnitIsVisible, UnitGUID, UnitClassification = UnitCanAttack, UnitExists, UnitIsVisible, UnitGUID, UnitClassification
local UnitName, UnitPower, UnitPowerMax, UnitPowerType, UnitHealth = UnitName, UnitPower, UnitPowerMax, UnitPowerType, UnitHealth
local UnitLevel, UnitCreatureType, UnitPercentHealthFromGUID, UnitTokenFromGUID = UnitLevel, UnitCreatureType, UnitPercentHealthFromGUID, UnitTokenFromGUID
local GetInstanceInfo = GetInstanceInfo
local GetZoneText, GetRealZoneText, GetSubZoneText = GetZoneText, GetRealZoneText, GetSubZoneText
local GetSpellName = C_Spell and C_Spell.GetSpellName or GetSpellInfo
local GetBestMapForUnit = C_Map.GetBestMapForUnit
local C_GossipInfo_GetOptions = C_GossipInfo.GetOptions
if not UnitTokenFromGUID then -- XXX not on classic yet
UnitTokenFromGUID = function() return end
end
do
local origPrint = print
function print(msg, ...)
return origPrint(format("|cFF33FF99Transcriptor|r: %s", tostring(msg)), tostringall(...))
end
local origUnitName = UnitName
function UnitName(unit)
local name, server = origUnitName(unit)
if not name then
return "??"
elseif server and server ~= "" then
name = name .."-".. server
end
return name
end
end
local function MobId(guid, extra)
if not guid then return 1 end
local _, _, _, _, _, strId, unq = strsplit("-", guid)
if extra then
local id = tonumber(strId)
if id then
return strId.."-"..unq
else
return 1
end
else
return tonumber(strId) or 1
end
end
local function InsertSpecialEvent(name)
if type(name) == "function" then
name = name()
end
if not name then return end
local t = debugprofilestop()
previousSpecialEvent = {t, name}
if compareSuccess then
for _,tbl in next, compareSuccess do
for _, list in next, tbl do
list[#list+1] = {t, name}
end
end
end
if compareStart then
for _,tbl in next, compareStart do
for _, list in next, tbl do
list[#list+1] = {t, name}
end
end
end
if compareAuraApplied then
for _,tbl in next, compareAuraApplied do
for _, list in next, tbl do
list[#list+1] = {t, name}
end
end
end
if compareUnitSuccess then
for _,tbl in next, compareUnitSuccess do
for _, list in next, tbl do
list[#list+1] = {t, name}
end
end
end
if compareEmotes then
for _,tbl in next, compareEmotes do
for _, list in next, tbl do
list[#list+1] = {t, name}
end
end
end
end
--------------------------------------------------------------------------------
-- Utility
--
function GetMapArtID(name)
name = name:lower()
for i=1,100000 do
local fetchedTbl = C_Map.GetMapInfo(i)
if fetchedTbl and fetchedTbl.name then
local lowerFetchedName = fetchedTbl.name:lower()
if find(lowerFetchedName, name, nil, true) then
print(fetchedTbl.name..": "..i)
end
end
end
end
function GetInstanceID(name)
name = name:lower()
for i=1,100000 do
local fetchedName = GetRealZoneText(i)
local lowerFetchedName = fetchedName:lower()
if find(lowerFetchedName, name, nil, true) then
print(fetchedName..": "..i)
end
end
end
function GetBossID(name)
if EJ_GetEncounterInfo then
name = name:lower()
for i=1,100000 do
local fetchedName = EJ_GetEncounterInfo(i)
if fetchedName then
local lowerFetchedName = fetchedName:lower()
if find(lowerFetchedName, name, nil, true) then
print(fetchedName..": "..i)
end
end
end
else
print("Cannot use GetBossID(name) when the EJ_GetEncounterInfo namespace doesn't exist.")
end
end
function GetSectionID(name)
if C_EncounterJournal then
name = name:lower()
for i=1,100000 do
local tbl = C_EncounterJournal.GetSectionInfo(i)
if tbl then
local fetchedName = tbl.title
local lowerFetchedName = fetchedName:lower()
if find(lowerFetchedName, name, nil, true) then
print(fetchedName..": "..i)
end
end
end
else
print("Cannot use GetSectionID(name) when the C_EncounterJournal namespace doesn't exist.")
end
end
--------------------------------------------------------------------------------
-- Spell blocklist parser: /getspells
--
do
-- Create UI spell display, copied from BasicChatMods
local frame, editBox = {}, {}
for i = 1, 2 do
frame[i] = CreateFrame("Frame", nil, UIParent, "SettingsFrameTemplate")
frame[i]:SetWidth(650)
frame[i]:SetHeight(650)
frame[i]:Hide()
frame[i]:SetFrameStrata("DIALOG")
frame[i].NineSlice.Text:SetText(
i==1 and "Transcriptor Spells" or
i==2 and "Transcriptor Spells Full DB"
)
local scrollArea = CreateFrame("ScrollFrame", nil, frame[i], "ScrollFrameTemplate")
scrollArea:SetPoint("TOPLEFT", frame[i], "TOPLEFT", 8, -30)
scrollArea:SetPoint("BOTTOMRIGHT", frame[i], "BOTTOMRIGHT", -25, 5)
editBox[i] = CreateFrame("EditBox", nil, frame[i])
editBox[i]:SetMultiLine(true)
editBox[i]:SetMaxLetters(0)
editBox[i]:EnableMouse(true)
editBox[i]:SetAutoFocus(false)
editBox[i]:SetFontObject(ChatFontNormal)
editBox[i]:SetWidth(620)
editBox[i]:SetHeight(450)
editBox[i]:SetScript("OnEscapePressed", function(f) f:GetParent():GetParent():Hide() f:SetText("") end)
if i == 1 then
editBox[i]:SetScript("OnHyperlinkLeave", GameTooltip_Hide)
editBox[i]:SetScript("OnHyperlinkEnter", function(_, link)
if link and find(link, "spell", nil, true) then
local spellId = strmatch(link, "(%d+)")
if spellId then
GameTooltip:SetOwner(frame[i], "ANCHOR_LEFT", 0, -500)
GameTooltip:SetSpellByID(spellId)
end
end
end)
editBox[i]:SetHyperlinksEnabled(true)
end
scrollArea:SetScrollChild(editBox[i])
end
local function GetLogSpells(slashCommandText)
if InCombatLockdown() or UnitAffectingCombat("player") or IsFalling() then print("You cannot do that in combat.") return end
if slashCommandText == "logflags" then TranscriptIgnore.logFlags = true print("Player flags will be added to all future logs.") return end
local total, totalSorted = {}, {}
local auraTbl, castTbl, summonTbl, extraAttacksTbl, empowerTbl, healTbl, energizeTbl, spellDmgTbl = {}, {}, {}, {}, {}, {}, {}, {}
local aurasSorted, castsSorted, summonSorted, extraAttacksSorted, empowerSorted, healSorted, energizeSorted, spellDmgSorted = {}, {}, {}, {}, {}, {}, {}, {}
local playerCastList = {}
local ignoreList = {
[43681] = true, -- Inactive (PvP)
[94028] = true, -- Inactive (PvP)
[66186] = true, -- Napalm (IoC PvP)
[66195] = true, -- Napalm (IoC PvP)
[66268] = true, -- Place Seaforium Bomb (IoC PvP)
[66271] = true, -- Carrying Seaforium (IoC PvP)
[66456] = true, -- Glaive Throw (IoC PvP)
[66518] = true, -- Airship Cannon (IoC PvP)
[66541] = true, -- Incendiary Rocket (IoC PvP)
[66542] = true, -- Incendiary Rocket (IoC PvP)
[66657] = true, -- Parachute (IoC PvP)
[66674] = true, -- Place Huge Seaforium Bomb (IoC PvP)
[67195] = true, -- Blade Salvo (IoC PvP)
[67200] = true, -- Blade Salvo (IoC PvP)
[67440] = true, -- Hurl Boulder (IoC PvP)
[67441] = true, -- Ram (IoC PvP)
[67452] = true, -- Rocket Blast (IoC PvP)
[67461] = true, -- Fire Cannon (IoC PvP)
[67796] = true, -- Ram (IoC PvP)
[67797] = true, -- Steam Rush (IoC PvP)
[68077] = true, -- Repair Cannon (IoC PvP)
[68298] = true, -- Parachute (IoC PvP)
[68377] = true, -- Carrying Huge Seaforium (IoC PvP)
}
local npcIgnoreList = {
[154297] = true, -- Ankoan Bladesman
[154304] = true, -- Waveblade Shaman
[150202] = true, -- Waveblade Hunter
[201647] = true, -- Ebon Lieutenant
[201383] = true, -- Ebon Lieutenant
[201382] = true, -- Highmountain Seer
[201268] = true, -- Highmountain Seer
[201646] = true, -- Highmountain Seer
[201578] = true, -- Highmountain Seer
}
local events = { --event#sourceOrDestFlags#sourceGUID#sourceName#destGUID or empty#destName or 'nil'#spellId#spellName
"SPELL_AURA_[AR][^#]+#(%d+)#([^#]+%-[^#]+)#([^#]+)#([^#]*)#([^#]+)#(%d+)#[^#]+", -- SPELL_AURA_[AR] to filter _BROKEN
"SPELL_CAST_[^#]+#(%d+)#([^#]+%-[^#]+)#([^#]+)#([^#]*)#([^#]+)#(%d+)#[^#]+",
"SPELL_SUMMON#(%d+)#([^#]+%-[^#]+)#([^#]+)#([^#]*)#([^#]+)#(%d+)#[^#]+",
"SPELL_EXTRA_ATTACKS#(%d+)#([^#]+%-[^#]+)#([^#]+)#([^#]*)#([^#]+)#(%d+)#[^#]+",
"SPELL_EMPOWER_[SEI][^#]+#(%d+)#([^#]+%-[^#]+)#([^#]+)#([^#]*)#([^#]+)#(%d+)#[^#]+",
"_HEAL#(%d+)#([^#]+%-[^#]+)#([^#]+)#([^#]*)#([^#]+)#(%d+)#[^#]+", -- SPELL_HEAL/SPELL_PERIODIC_HEAL
"_ENERGIZE#(%d+)#([^#]+%-[^#]+)#([^#]+)#([^#]*)#([^#]+)#(%d+)#[^#]+", -- SPELL_ENERGIZE/SPELL_PERIODIC_ENERGIZE
"_[DM][AI][MS][AS][GE][ED]#(%d+)#([^#]+%-[^#]+)#([^#]+)#([^#]*)#([^#]+)#(%d+)#[^#]+", -- SPELL_DAMAGE/SPELL_MISSED/SPELL_PERIODIC_DAMAGE/SPELL_PERIODIC_MISSED
}
local tables = {
auraTbl,
castTbl,
summonTbl,
extraAttacksTbl,
empowerTbl,
healTbl,
energizeTbl,
spellDmgTbl,
}
local sortedTables = {
aurasSorted,
castsSorted,
summonSorted,
extraAttacksSorted,
empowerSorted,
healSorted,
energizeSorted,
spellDmgSorted,
}
for _, logTbl in next, TranscriptDB do
if type(logTbl) == "table" then
if logTbl.total then
for i=1, #logTbl.total do
local text = logTbl.total[i]
for j = 1, #events do
local flagsText, srcGUID, srcName, destGUID, destName, idText = strmatch(text, events[j])
local spellId = tonumber(idText)
local flags = tonumber(flagsText)
local tbl = tables[j]
local sortedTbl = sortedTables[j]
if spellId and flags and band(flags, mineOrPartyOrRaid) ~= 0 and not ignoreList[spellId] and not PLAYER_SPELL_BLOCKLIST[spellId] then -- Check total to avoid duplicates
if not total[spellId] or destGUID ~= "" then -- Attempt to replace START (no dest) with SUCCESS (sometimes has a dest)
local srcGUIDType, _, _, _, _, npcIdStr = strsplit("-", srcGUID)
local npcId = tonumber(npcIdStr)
if not npcIgnoreList[npcId] then
local destGUIDType, _, _, _, _, destNpcIdStr = strsplit("-", destGUID)
if find(destGUID, "^P[le][at]") then -- Only players/pets, don't remove "-" from NPC names
destName = gsub(destName, "%-.+", "*") -- Replace server name with *
end
if find(srcGUID, "^P[le][at]") then-- Only players/pets, don't remove "-" from NPCs names
srcName = gsub(srcName, "%-.+", "*") -- Replace server name with *
end
srcName = gsub(srcName, "%(.+", "") -- Remove health/mana
if find(srcGUID, "^P[le][at]") and find(destGUID, "^P[le][at]") then
tbl[spellId] = "|cFF81BEF7".. srcName .."(".. srcGUIDType ..") >> ".. destName .."(".. destGUIDType ..")|r"
else
if srcGUIDType == "Creature" then srcGUIDType = srcGUIDType .."[".. npcIdStr .."]" end
if destGUIDType == "Creature" then destGUIDType = destGUIDType .."[".. destNpcIdStr .."]" end
if find(srcGUID, "^P[le][at]") and find(destGUIDType, "Creature", nil, true) then
tbl[spellId] = "|cFF3ADF00".. srcName .."(".. srcGUIDType ..") >> ".. destName .."(".. destGUIDType ..")|r"
else
tbl[spellId] = "|cFF964B00".. srcName .."(".. srcGUIDType ..") >> ".. destName .."(".. destGUIDType ..")|r"
end
end
if not total[spellId] then
total[spellId] = true
sortedTbl[#sortedTbl+1] = spellId
end
end
end
end
end
end
end
if logTbl.TIMERS and logTbl.TIMERS.PLAYER_SPELLS then
for i=1, #logTbl.TIMERS.PLAYER_SPELLS do
local text = logTbl.TIMERS.PLAYER_SPELLS[i]
local spellId, _, _, player = strsplit("#", text)
local id = tonumber(spellId)
if id and not PLAYER_SPELL_BLOCKLIST[id] and not playerCastList[id] and not total[id] then
playerCastList[id] = player
total[id] = true
end
end
end
end
end
tsort(aurasSorted)
local text = "-- SPELL_AURA_[APPLIED/REMOVED/REFRESH]\n"
for i = 1, #aurasSorted do
local id = aurasSorted[i]
local name = GetSpellName(id)
text = format("%s%d || |cFFFFFF00|Hspell:%d|h%s|h|r || %s\n", text, id, id, name, auraTbl[id])
end
tsort(castsSorted)
text = text.. "\n-- SPELL_CAST_[START/SUCCESS]\n"
for i = 1, #castsSorted do
local id = castsSorted[i]
local name = GetSpellName(id)
text = format("%s%d || |cFFFFFF00|Hspell:%d|h%s|h|r || %s\n", text, id, id, name, castTbl[id])
end
tsort(summonSorted)
text = text.. "\n-- SPELL_SUMMON\n"
for i = 1, #summonSorted do
local id = summonSorted[i]
local name = GetSpellName(id)
text = format("%s%d || |cFFFFFF00|Hspell:%d|h%s|h|r || %s\n", text, id, id, name, summonTbl[id])
end
tsort(extraAttacksSorted)
text = text.. "\n-- SPELL_EXTRA_ATTACKS\n"
for i = 1, #extraAttacksSorted do
local id = extraAttacksSorted[i]
local name = GetSpellName(id)
text = format("%s%d || |cFFFFFF00|Hspell:%d|h%s|h|r || %s\n", text, id, id, name, extraAttacksTbl[id])
end
tsort(empowerSorted)
text = text.. "\n-- SPELL_EMPOWER_[START/END/INTERRUPT]\n"
for i = 1, #empowerSorted do
local id = empowerSorted[i]
local name = GetSpellName(id)
text = format("%s%d || |cFFFFFF00|Hspell:%d|h%s|h|r || %s\n", text, id, id, name, empowerTbl[id])
end
tsort(healSorted)
text = text.. "\n-- SPELL_[HEAL/PERIODIC_HEAL]\n"
for i = 1, #healSorted do
local id = healSorted[i]
local name = GetSpellName(id)
text = format("%s%d || |cFFFFFF00|Hspell:%d|h%s|h|r || %s\n", text, id, id, name, healTbl[id])
end
tsort(energizeSorted)
text = text.. "\n-- SPELL_[ENERGIZE/PERIODIC_ENERGIZE]\n"
for i = 1, #energizeSorted do
local id = energizeSorted[i]
local name = GetSpellName(id)
text = format("%s%d || |cFFFFFF00|Hspell:%d|h%s|h|r || %s\n", text, id, id, name, energizeTbl[id])
end
tsort(spellDmgSorted)
text = text.. "\n-- SPELL_[DAMAGE/PERIODIC_DAMAGE/MISSED]\n"
for i = 1, #spellDmgSorted do
local id = spellDmgSorted[i]
local name = GetSpellName(id)
text = format("%s%d || |cFFFFFF00|Hspell:%d|h%s|h|r || %s\n", text, id, id, name, spellDmgTbl[id])
end
text = text.. "\n-- PLAYER_CASTS\n"
for k, v in next, playerCastList do
local name = GetSpellName(k)
text = format("%s%d || |cFFFFFF00|Hspell:%d|h%s|h|r || %s\n", text, k, k, name, v)
end
-- Display newly found spells for analysis
if not TranscriptIgnore.logFlags then
editBox[1]:SetText("For this feature to work, player flags must be added to the logs.\nYou can enable additional logging by typing:\n/getspells logflags")
else
if not text:find("%d%d%d") then
editBox[1]:SetText("Nothing was found.\nYou might be looking at logs that didn't have player flags recorded.")
else
editBox[1]:SetText(text)
end
end
frame[1]:ClearAllPoints()
frame[1]:SetPoint("RIGHT", UIParent, "CENTER")
frame[1]:Show()
for k in next, PLAYER_SPELL_BLOCKLIST do
if GetSpellName(k) then -- Filter out removed spells when a new patch hits
total[k] = true
end
end
for k in next, total do
totalSorted[#totalSorted+1] = k
end
tsort(totalSorted)
local exportText = "local addonTbl\ndo\n\tlocal _\n\t_, addonTbl = ...\nend\n\n"
exportText = exportText .."-- Block specific player spells from appearing in the logs.\n"
exportText = exportText .."-- This list is generated in game and there is not much point filling it in manually.\naddonTbl.PLAYER_SPELL_BLOCKLIST = {\n"
for i = 1, #totalSorted do
local id = totalSorted[i]
local name = GetSpellName(id)
exportText = format("%s\t[%d] = true, -- %s\n", exportText, id, name)
end
exportText = exportText .."}\n"
-- Display full blacklist for copying into Transcriptor
editBox[2]:SetText(exportText)
frame[2]:ClearAllPoints()
frame[2]:SetPoint("LEFT", UIParent, "CENTER")
frame[2]:Show()
end
SlashCmdList.GETSPELLS = GetLogSpells
SLASH_GETSPELLS1 = "/getspells"
end
--------------------------------------------------------------------------------
-- Localization
--
local L = {}
L["Remember to stop and start Transcriptor between each wipe or boss kill to get the best logs."] = "Remember to stop and start Transcriptor between each wipe or boss kill to get the best logs."
L["You are already logging an encounter."] = "You are already logging an encounter."
L["Beginning Transcript: "] = "Beginning Transcript: "
L["You are not logging an encounter."] = "You are not logging an encounter."
L["Ending Transcript: "] = "Ending Transcript: "
L["Logs will probably be saved to WoW\\WTF\\Account\\<name>\\SavedVariables\\Transcriptor.lua once you relog or reload the user interface."] = "Logs will probably be saved to WoW\\WTF\\Account\\<name>\\SavedVariables\\Transcriptor.lua once you relog or reload the user interface."
L["All transcripts cleared."] = "All transcripts cleared."
L["You can't clear your transcripts while logging an encounter."] = "You can't clear your transcripts while logging an encounter."
L["|cff696969Idle|r"] = "|cff696969Idle|r"
L["|cffeda55fClick|r to start or stop transcribing. |cffeda55fRight-Click|r to configure events. |cffeda55fAlt-Middle Click|r to clear all stored transcripts."] = "|cffeda55fClick|r to start or stop transcribing. |cffeda55fRight-Click|r to configure events. |cffeda55fAlt-Middle Click|r to clear all stored transcripts."
L["|cffFF0000Recording|r"] = "|cffFF0000Recording|r"
L["|cFFFFD200Transcriptor|r - Disabled Events"] = "|cFFFFD200Transcriptor|r - Disabled Events"
do
local locale = GetLocale()
if locale == "deDE" then
L["Remember to stop and start Transcriptor between each wipe or boss kill to get the best logs."] = "Um die besten Logs zu bekommen, solltest du Transcriptor zwischen Wipes oder Bosskills stoppen bzw. starten."
L["You are already logging an encounter."] = "Du zeichnest bereits einen Begegnung auf."
L["Beginning Transcript: "] = "Beginne Aufzeichnung: "
L["You are not logging an encounter."] = "Du zeichnest keine Begegnung auf."
L["Ending Transcript: "] = "Beende Aufzeichnung: "
L["Logs will probably be saved to WoW\\WTF\\Account\\<name>\\SavedVariables\\Transcriptor.lua once you relog or reload the user interface."] = "Aufzeichnungen werden gespeichert nach WoW\\WTF\\Account\\<name>\\SavedVariables\\Transcriptor.lua sobald du reloggst oder das Interface neu lädst."
L["All transcripts cleared."] = "Alle Aufzeichnungen gelöscht."
L["You can't clear your transcripts while logging an encounter."] = "Du kannst deine Aufzeichnungen nicht löschen, während du eine Begegnung aufnimmst."
L["|cff696969Idle|r"] = "|cff696969Leerlauf|r"
L["|cffeda55fClick|r to start or stop transcribing. |cffeda55fRight-Click|r to configure events. |cffeda55fAlt-Middle Click|r to clear all stored transcripts."] = "|cffeda55fKlicken|r, um eine Aufzeichnung zu starten oder zu stoppen. |cffeda55fRechts-Klicken|r, um Events zu konfigurieren. |cffeda55fAlt-Mittel-Klicken|r, um alle Aufzeichnungen zu löschen."
L["|cffFF0000Recording|r"] = "|cffFF0000Aufzeichnung|r"
--L["|cFFFFD200Transcriptor|r - Disabled Events"] = "|cFFFFD200Transcriptor|r - Disabled Events"
elseif locale == "zhTW" then
L["You are already logging an encounter."] = "你已經準備記錄戰鬥"
L["Beginning Transcript: "] = "開始記錄於: "
L["You are not logging an encounter."] = "你不處於記錄狀態"
L["Ending Transcript: "] = "結束記錄於: "
L["Logs will probably be saved to WoW\\WTF\\Account\\<name>\\SavedVariables\\Transcriptor.lua once you relog or reload the user interface."] = "記錄儲存於 WoW\\WTF\\Account\\<名字>\\SavedVariables\\Transcriptor.lua"
L["You are not logging an encounter."] = "你沒有記錄此次戰鬥"
L["All transcripts cleared."] = "所有記錄已清除"
L["You can't clear your transcripts while logging an encounter."] = "正在記錄中,你不能清除。"
L["|cffFF0000Recording|r: "] = "|cffFF0000記錄中|r: "
L["|cff696969Idle|r"] = "|cff696969閒置|r"
L["|cffeda55fClick|r to start or stop transcribing. |cffeda55fRight-Click|r to configure events. |cffeda55fAlt-Middle Click|r to clear all stored transcripts."] = "|cffeda55f點擊|r開始/停止記錄戰鬥"
L["|cffFF0000Recording|r"] = "|cffFF0000記錄中|r"
--L["|cFFFFD200Transcriptor|r - Disabled Events"] = "|cFFFFD200Transcriptor|r - Disabled Events"
elseif locale == "zhCN" then
L["Remember to stop and start Transcriptor between each wipe or boss kill to get the best logs."] = "提醒,最好在每次清理小怪时暂停Transcriptor,在准备击杀首领前启用Transcriptor,以获得最佳记录。"
L["You are already logging an encounter."] = "你已经准备记录战斗"
L["Beginning Transcript: "] = "开始记录于: "
L["You are not logging an encounter."] = "你不处于记录状态"
L["Ending Transcript: "] = "结束记录于:"
L["Logs will probably be saved to WoW\\WTF\\Account\\<name>\\SavedVariables\\Transcriptor.lua once you relog or reload the user interface."] = "记录保存于WoW\\WTF\\Account\\<名字>\\SavedVariables\\Transcriptor.lua中,你可以上传到github.com/BigWigsMods和Discord的地址,提供最新的BOSS数据。"
L["You are not logging an encounter."] = "你没有记录此次战斗"
L["Added Note: "] = "添加书签于: "
L["All transcripts cleared."] = "所有记录已清除"
L["You can't clear your transcripts while logging an encounter."] = "正在记录中,你不能清除."
L["|cffFF0000Recording|r: "] = "|cffFF0000记录中|r: "
L["|cff696969Idle|r"] = "|cff696969空闲|r"
L["|cffeda55fClick|r to start or stop transcribing. |cffeda55fRight-Click|r to configure events. |cffeda55fAlt-Middle Click|r to clear all stored transcripts."] = "|cffeda55f点击|r开始/停止记录战斗."
L["|cffFF0000Recording|r"] = "|cffFF0000记录中|r"
--L["|cFFFFD200Transcriptor|r - Disabled Events"] = "|cFFFFD200Transcriptor|r - Disabled Events"
elseif locale == "koKR" then
L["Remember to stop and start Transcriptor between each wipe or boss kill to get the best logs."] = "최상의 기록을 얻으려면 전멸이나 우두머리 처치 후에 Transcriptor를 중지하고 시작하는 걸 기억하세요."
L["You are already logging an encounter."] = "이미 우두머리 전투를 기록 중입니다."
L["Beginning Transcript: "] = "기록 시작: "
L["You are not logging an encounter."] = "우두머리 전투를 기록하고 있지 않습니다."
L["Ending Transcript: "] = "기록 종료: "
L["Logs will probably be saved to WoW\\WTF\\Account\\<name>\\SavedVariables\\Transcriptor.lua once you relog or reload the user interface."] = "재기록하거나 사용자 인터페이스를 다시 불러오면 WoW\\WTF\\Account\\<name>\\SavedVariables\\Transcriptor.lua에 기록이 저장됩니다."
L["All transcripts cleared."] = "모든 기록이 초기화되었습니다."
L["You can't clear your transcripts while logging an encounter."] = "우두머리 전투를 기록 중일 때는 기록을 초기화 할 수 없습니다."
L["|cff696969Idle|r"] = "|cff696969대기|r"
L["|cffeda55fClick|r to start or stop transcribing. |cffeda55fRight-Click|r to configure events. |cffeda55fAlt-Middle Click|r to clear all stored transcripts."] = "|cffeda55f클릭|r - 기록을 시작하거나 중지합니다.\n|cffeda55f오른쪽-클릭|r - 이벤트를 구성합니다.\n|cffeda55fAlt-가운데 클릭|r - 저장된 모든 기록을 초기화합니다."
L["|cffFF0000Recording|r"] = "|cffFF0000기록 중|r"
L["|cFFFFD200Transcriptor|r - Disabled Events"] = "|cFFFFD200Transcriptor|r - 비활성된 이벤트"
elseif locale == "ruRU" then
L["Remember to stop and start Transcriptor between each wipe or boss kill to get the best logs."] = "Чтобы получить лучшие записи боя, не забудьте остановить и запустить Transcriptor между вайпом или убийством босса."
L["You are already logging an encounter."] = "Вы уже записываете бой."
L["Beginning Transcript: "] = "Начало записи: "
L["You are not logging an encounter."] = "Вы не записываете бой."
L["Ending Transcript: "] = "Окончание записи: "
L["Logs will probably be saved to WoW\\WTF\\Account\\<name>\\SavedVariables\\Transcriptor.lua once you relog or reload the user interface."] = "Записи боя будут записаны в WoW\\WTF\\Account\\<название>\\SavedVariables\\Transcriptor.lua после того как вы перезайдете или перезагрузите пользовательский интерфейс."
L["All transcripts cleared."] = "Все записи очищены."
L["You can't clear your transcripts while logging an encounter."] = "Вы не можете очистить ваши записи пока идет запись боя."
L["|cff696969Idle|r"] = "|cff696969Ожидание|r"
L["|cffeda55fClick|r to start or stop transcribing. |cffeda55fRight-Click|r to configure events. |cffeda55fAlt-Middle Click|r to clear all stored transcripts."] = "|cffeda55fЛКМ|r - запустить или остановить запись.\n|cffeda55fПКМ|r - настройка событий.\n|cffeda55fAlt-СКМ|r - очистить все сохраненные записи."
L["|cffFF0000Recording|r"] = "|cffFF0000Запись|r"
--L["|cFFFFD200Transcriptor|r - Disabled Events"] = "|cFFFFD200Transcriptor|r - Disabled Events"
end
end
--------------------------------------------------------------------------------
-- Events
--
local eventFrame = CreateFrame("Frame")
eventFrame:Hide()
local sh = {}
--[[
UIWidget
see https://wowpedia.fandom.com/wiki/UPDATE_UI_WIDGET
widgetID =
The Black Morass: 507 (health), 527 (waves)
The Violet Hold (WotLK): 565 (health), 566 (waves)
]]
do
local blackList = {
[1309] = true, -- C_UIWidgetManager.GetStatusBarWidgetVisualizationInfo(1309)
[1311] = true, -- C_UIWidgetManager.GetStatusBarWidgetVisualizationInfo(1311)
[1313] = true, -- C_UIWidgetManager.GetStatusBarWidgetVisualizationInfo(1313)
[1315] = true, -- C_UIWidgetManager.GetStatusBarWidgetVisualizationInfo(1315)
[1317] = true, -- C_UIWidgetManager.GetStatusBarWidgetVisualizationInfo(1317)
[1319] = true, -- C_UIWidgetManager.GetStatusBarWidgetVisualizationInfo(1319)
--[[ Shadowlands - Castle Nathria ]]--
[2436] = true, -- Lady Inerva Darkvein, static icon (widgetType:13)
[2437] = true, -- Lady Inerva Darkvein, static icon (widgetType:13)
[2438] = true, -- Lady Inerva Darkvein, static icon (widgetType:13)
[2439] = true, -- Lady Inerva Darkvein, static icon (widgetType:13)
[3457] = true, -- Stone Soup
[4236] = true, -- Accumulated Hoard of Draconic Delicacies
[4460] = true, -- Dragonriding - Vigor
[5140] = true, -- Dragonriding - Vigor
[5143] = true, -- Dragonriding - Vigor
[5144] = true, -- Dragonriding - Vigor
[5145] = true, -- Dragonriding - Vigor
}
-- Each widgetType has a different function to get all data for the widget.
-- Those function names are consistent with the enum.
local widgetFuncs = {}
for name,n in pairs(Enum.UIWidgetVisualizationType) do
widgetFuncs[n] = C_UIWidgetManager["Get"..name.. "WidgetVisualizationInfo"] or C_UIWidgetManager["Get"..name.."VisualizationInfo"]
end
function sh.UPDATE_UI_WIDGET(tbl)
if blackList[tbl.widgetID] then return end
-- Store widget data, so we're able to only add changes to the log
if not currentLog.WIDGET then currentLog.WIDGET = {} end
local txt
if not currentLog.WIDGET[tbl.widgetID] then -- New widget in this log
currentLog.WIDGET[tbl.widgetID] = {}
for k, v in next, tbl do
if not txt then
txt = format("%s:%s", k, v)
else
txt = format("%s, %s:%s", txt, k, v)
end
end
else -- Shorter output with just the id
txt = format("%s:%s", "widgetID", tbl.widgetID)
end
if tbl.widgetType and widgetFuncs[tbl.widgetType] then
local t = widgetFuncs[tbl.widgetType](tbl.widgetID)
if t then
for k, v in next, t do
if type(v) == "table" then -- We don't care about data in tables
v = "table"
elseif type(v) == "boolean" then -- Needs to be done manually in Lua 5.1
v = tostring(v)
end
-- Only add data to log if it's new or it changed to reduce spam
if not currentLog.WIDGET[tbl.widgetID][k] or currentLog.WIDGET[tbl.widgetID][k] ~= v then
currentLog.WIDGET[tbl.widgetID][k] = v
txt = format("%s, %s:%s", txt, k, v)
end
end
end
end
return txt
end
end
do
local auraEvents = {
["SPELL_AURA_APPLIED"] = true,
["SPELL_AURA_APPLIED_DOSE"] = true,
["SPELL_AURA_REFRESH"] = true,
["SPELL_AURA_REMOVED"] = true,
["SPELL_AURA_REMOVED_DOSE"] = true,
}
local badPlayerFilteredEvents = {
["SPELL_CAST_SUCCESS"] = true,
["SPELL_AURA_APPLIED"] = true,
["SPELL_AURA_APPLIED_DOSE"] = true,
["SPELL_AURA_REFRESH"] = true,
["SPELL_AURA_REMOVED"] = true,
["SPELL_AURA_REMOVED_DOSE"] = true,
["SPELL_CAST_START"] = true,
["SPELL_SUMMON"] = true,
["SPELL_EMPOWER_START"] = true,
["SPELL_EMPOWER_END"] = true,
["SPELL_EMPOWER_INTERRUPT"] = true,
["SPELL_EXTRA_ATTACKS"] = true,
--"<87.10 17:55:03> [CLEU] SPELL_AURA_BROKEN_SPELL#Creature-0-3771-1676-28425-118022-000004A6B5#Infernal Chaosbringer#Player-XYZ#XYZ#115191#Stealth#242906#Immolation Aura", -- [148]
--"<498.56 22:02:38> [CLEU] SPELL_AURA_BROKEN_SPELL#Creature-0-3895-1676-10786-106551-00008631CC-TSGuardian#Hati#Creature-0-3895-1676-10786-120697-000086306F#Worshiper of Elune#206961#Tremble Before Me#118459#Beast Cleave", -- [8039]
--["SPELL_AURA_BROKEN_SPELL"] = true,
["SPELL_HEAL"] = true,
["SPELL_PERIODIC_HEAL"] = true,
["SPELL_ENERGIZE"] = true,
["SPELL_PERIODIC_ENERGIZE"] = true,
["SPELL_DAMAGE"] = true,
["SPELL_MISSED"] = true,
["SPELL_PERIODIC_DAMAGE"] = true,
["SPELL_PERIODIC_MISSED"] = true,
}
local badPlayerEvents = {
["SWING_DAMAGE"] = true,
["SWING_MISSED"] = true,
["RANGE_DAMAGE"] = true,
["RANGE_MISSED"] = true,
["DAMAGE_SPLIT"] = true,
}
local badEvents = {
["SPELL_ABSORBED"] = true,
["SPELL_CAST_FAILED"] = true,
}
local badNPCs = { -- These are NPCs summoned by your group but are incorrectly not marked as mineOrPartyOrRaid, so we manually filter
[3527] = true, -- Healing Stream Totem, casts Healing Stream Totem (52042) on friendlies
[5334] = true, -- Windfury Totem, casts Windfury Totem (327942) on friendlies
[27829] = true, -- Ebon Gargoyle, casts Gargoyle Strike (51963) on hostiles
[27893] = true, -- Rune Weapon, casts Blood Plague (55078) on hostiles
[29264] = true, -- Spirit Wolf, casts Earthen Weapon (392375) on friendlies
[61245] = true, -- Capacitor Totem, casts Static Charge (118905) on hostiles
[198236] = true, -- Divine Image, casts Blessed Light (196813) on friendlies
}
local guardian = 8192 -- COMBATLOG_OBJECT_TYPE_GUARDIAN
local dmgCache, dmgPrdcCache = {}, {}
local CombatLogGetCurrentEventInfo = CombatLogGetCurrentEventInfo
-- Note some things we are trying to avoid filtering:
-- BRF/Kagraz - Player damage with no source "SPELL_DAMAGE##nil#Player-GUID#PLAYER#154938#Molten Torrent#"
-- HFC/Socrethar - Player cast on friendly vehicle "SPELL_CAST_SUCCESS#Player-GUID#PLAYER#Vehicle-0-3151-1448-8853-90296-00001D943C#Soulbound Construct#190466#Incomplete Binding"
-- HFC/Zakuun - Player boss debuff cast on self "SPELL_AURA_APPLIED#Player-GUID#PLAYER#Player-GUID#PLAYER#189030#Befouled#DEBUFF#"
-- ToS/Sisters - Boss pet marked as guardian "SPELL_CAST_SUCCESS#Creature-0-3895-1676-10786-119205-0000063360#Moontalon##nil#236697#Deathly Screech"
-- Neltharus/Sargha - Player picks up an item from gold pile that makes you cast a debuff on yourself, SPELL_PERIODIC_DAMAGE#Player-GUID#PLAYER#Player-GUID#PLAYER#391762#Curse of the Dragon Hoard
function sh.COMBAT_LOG_EVENT_UNFILTERED()
local timeStamp, event, _, sourceGUID, sourceName, sourceFlags, _, destGUID, destName, destFlags, _, spellId, spellName, _, extraSpellId, amount, _, _, absorbSpellId, absorbSpellName, _, absorbAmount, totalAmount = CombatLogGetCurrentEventInfo()
if auraEvents[event] and not hiddenAuraPermList[spellId] then
hiddenAuraPermList[spellId] = true
end
local npcId = MobId(sourceGUID)
if badEvents[event] or
badNPCs[npcId] or -- Filter NPCs that are friendly summons but aren't flagged as guardians or as being in the group (COMBATLOG_OBJECT_AFFILIATION_OUTSIDER)
(event == "UNIT_DIED" and band(destFlags, mineOrPartyOrRaid) ~= 0 and band(destFlags, guardian) == guardian) or -- Filter guardian deaths only, player deaths can explain debuff removal
(sourceName and badPlayerEvents[event] and band(sourceFlags, mineOrPartyOrRaid) ~= 0) or
(sourceName and badPlayerFilteredEvents[event] and PLAYER_SPELL_BLOCKLIST[spellId] and band(sourceFlags, mineOrPartyOrRaid) ~= 0) or
(spellId == 22568 and event == "SPELL_DRAIN" and band(sourceFlags, mineOrPartyOrRaid) ~= 0) or -- Feral Druid casting Ferocious Bite
(spellId == 81782 and not sourceName and band(destFlags, mineOrPartyOrRaid) ~= 0) or -- Power Word: Barrier on players has a nil source
(spellId == 145629 and not sourceName and band(destFlags, mineOrPartyOrRaid) ~= 0) -- Anti-Magic Zone on players has a nil source
then
return
else
--if (sourceName and badPlayerFilteredEvents[event] and PLAYER_SPELL_BLOCKLIST[spellId] and band(sourceFlags, mineOrPartyOrRaid) == 0) then
-- print("Transcriptor:", sourceName..":"..npcId, "used spell", spellName..":"..spellId, "in event", event, "but isn't in our group.")
--end
if event == "SPELL_CAST_SUCCESS" and (not sourceName or (band(sourceFlags, mineOrPartyOrRaid) == 0 and not find(sourceGUID, "Player", nil, true))) then
if not compareSuccess then compareSuccess = {} end
if not compareSuccess[spellId] then compareSuccess[spellId] = {} end
local npcIdString = MobId(sourceGUID, true)
if not compareSuccess[spellId][npcIdString] then
if previousSpecialEvent then
compareSuccess[spellId][npcIdString] = {{compareStartTime, previousSpecialEvent[1], previousSpecialEvent[2]}}
else
compareSuccess[spellId][npcIdString] = {compareStartTime}
end
end
compareSuccess[spellId][npcIdString][#compareSuccess[spellId][npcIdString]+1] = debugprofilestop()
end
if event == "SPELL_CAST_START" and (not sourceName or (band(sourceFlags, mineOrPartyOrRaid) == 0 and not find(sourceGUID, "Player", nil, true))) then
if not compareStart then compareStart = {} end
if not compareStart[spellId] then compareStart[spellId] = {} end
local npcIdString = MobId(sourceGUID, true)
if not compareStart[spellId][npcIdString] then
if previousSpecialEvent then
compareStart[spellId][npcIdString] = {{compareStartTime, previousSpecialEvent[1], previousSpecialEvent[2]}}
else
compareStart[spellId][npcIdString] = {compareStartTime}
end
end
compareStart[spellId][npcIdString][#compareStart[spellId][npcIdString]+1] = debugprofilestop()
end
if event == "SPELL_AURA_APPLIED" and (not sourceName or (band(sourceFlags, mineOrPartyOrRaid) == 0 and not find(sourceGUID, "Player", nil, true))) then
if not compareAuraApplied then compareAuraApplied = {} end
if not compareAuraApplied[spellId] then compareAuraApplied[spellId] = {} end
local npcIdString = MobId(sourceGUID, true)
if not compareAuraApplied[spellId][npcIdString] then
if previousSpecialEvent then
compareAuraApplied[spellId][npcIdString] = {{compareStartTime, previousSpecialEvent[1], previousSpecialEvent[2]}}
else
compareAuraApplied[spellId][npcIdString] = {compareStartTime}
end
end
compareAuraApplied[spellId][npcIdString][#compareAuraApplied[spellId][npcIdString]+1] = debugprofilestop()
end
if sourceName and badPlayerFilteredEvents[event] and band(sourceFlags, mineOrPartyOrRaid) ~= 0 then
if not collectPlayerAuras then collectPlayerAuras = {} end
if not collectPlayerAuras[spellId] then collectPlayerAuras[spellId] = {} end
if not collectPlayerAuras[spellId][event] then collectPlayerAuras[spellId][event] = true end
end
if event == "UNIT_DIED" then
local name = TIMERS_SPECIAL_EVENTS.UNIT_DIED[npcId]
if name then
InsertSpecialEvent(name)
end
elseif TIMERS_SPECIAL_EVENTS[event] and TIMERS_SPECIAL_EVENTS[event][spellId] then
local name = TIMERS_SPECIAL_EVENTS[event][spellId][npcId]
if name then
InsertSpecialEvent(name)
end
end
if event == "SPELL_DAMAGE" or event == "SPELL_MISSED" then
if dmgPrdcCache.spellId then
if dmgPrdcCache.count == 1 then
if shouldLogFlags and dmgCache.sourceName ~= "nil" then
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%s#%d#%s", dmgPrdcCache.timeStop, dmgPrdcCache.time, dmgPrdcCache.event, dmgPrdcCache.sourceFlags, dmgPrdcCache.sourceGUID, dmgPrdcCache.sourceName, dmgPrdcCache.destGUID, dmgPrdcCache.destName, dmgPrdcCache.spellId, dmgPrdcCache.spellName)
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%d#%s", dmgPrdcCache.timeStop, dmgPrdcCache.time, dmgPrdcCache.event, dmgPrdcCache.sourceGUID, dmgPrdcCache.sourceName, dmgPrdcCache.destGUID, dmgPrdcCache.destName, dmgPrdcCache.spellId, dmgPrdcCache.spellName)
end
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] SPELL_PERIODIC_DAMAGE[CONDENSED]#%s#%s#%d Targets#%d#%s", dmgPrdcCache.timeStop, dmgPrdcCache.time, dmgPrdcCache.sourceGUID, dmgPrdcCache.sourceName, dmgPrdcCache.count, dmgPrdcCache.spellId, dmgPrdcCache.spellName)
end
dmgPrdcCache.spellId = nil
end
if spellId == dmgCache.spellId then
if timeStamp - dmgCache.timeStamp > 0.2 then
if dmgCache.count == 1 then
if shouldLogFlags and dmgCache.sourceName ~= "nil" then
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%s#%d#%s", dmgCache.timeStop, dmgCache.time, dmgCache.event, dmgCache.sourceFlags, dmgCache.sourceGUID, dmgCache.sourceName, dmgCache.destGUID, dmgCache.destName, dmgCache.spellId, dmgCache.spellName)
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%d#%s", dmgCache.timeStop, dmgCache.time, dmgCache.event, dmgCache.sourceGUID, dmgCache.sourceName, dmgCache.destGUID, dmgCache.destName, dmgCache.spellId, dmgCache.spellName)
end
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] SPELL_DAMAGE[CONDENSED]#%s#%s#%d Targets#%d#%s", dmgCache.timeStop, dmgCache.time, dmgCache.sourceGUID, dmgCache.sourceName, dmgCache.count, dmgCache.spellId, dmgCache.spellName)
end
dmgCache.spellId = spellId
dmgCache.sourceGUID = sourceGUID
dmgCache.sourceName = sourceName or "nil"
dmgCache.sourceFlags = sourceFlags
dmgCache.spellName = spellName
dmgCache.timeStop = (debugprofilestop() / 1000) - logStartTime
dmgCache.time = date("%H:%M:%S")
dmgCache.timeStamp = timeStamp
dmgCache.count = 1
dmgCache.event = event
dmgCache.destGUID = destGUID
dmgCache.destName = destName
else
dmgCache.count = dmgCache.count + 1
end
else
if dmgCache.spellId then
if dmgCache.count == 1 then
if shouldLogFlags and dmgCache.sourceName ~= "nil" then
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%s#%d#%s", dmgCache.timeStop, dmgCache.time, dmgCache.event, dmgCache.sourceFlags, dmgCache.sourceGUID, dmgCache.sourceName, dmgCache.destGUID, dmgCache.destName, dmgCache.spellId, dmgCache.spellName)
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%d#%s", dmgCache.timeStop, dmgCache.time, dmgCache.event, dmgCache.sourceGUID, dmgCache.sourceName, dmgCache.destGUID, dmgCache.destName, dmgCache.spellId, dmgCache.spellName)
end
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] SPELL_DAMAGE[CONDENSED]#%s#%s#%d Targets#%d#%s", dmgCache.timeStop, dmgCache.time, dmgCache.sourceGUID, dmgCache.sourceName, dmgCache.count, dmgCache.spellId, dmgCache.spellName)
end
end
dmgCache.spellId = spellId
dmgCache.sourceGUID = sourceGUID
dmgCache.sourceName = sourceName or "nil"
dmgCache.sourceFlags = sourceFlags
dmgCache.spellName = spellName
dmgCache.timeStop = (debugprofilestop() / 1000) - logStartTime
dmgCache.time = date("%H:%M:%S")
dmgCache.timeStamp = timeStamp
dmgCache.count = 1
dmgCache.event = event
dmgCache.destGUID = destGUID
dmgCache.destName = destName
end
elseif event == "SPELL_PERIODIC_DAMAGE" or event == "SPELL_PERIODIC_MISSED" then
if dmgCache.spellId then
if dmgCache.count == 1 then
if shouldLogFlags and dmgCache.sourceName ~= "nil" then
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%s#%d#%s", dmgCache.timeStop, dmgCache.time, dmgCache.event, dmgCache.sourceFlags, dmgCache.sourceGUID, dmgCache.sourceName, dmgCache.destGUID, dmgCache.destName, dmgCache.spellId, dmgCache.spellName)
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%d#%s", dmgCache.timeStop, dmgCache.time, dmgCache.event, dmgCache.sourceGUID, dmgCache.sourceName, dmgCache.destGUID, dmgCache.destName, dmgCache.spellId, dmgCache.spellName)
end
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] SPELL_DAMAGE[CONDENSED]#%s#%s#%d Targets#%d#%s", dmgCache.timeStop, dmgCache.time, dmgCache.sourceGUID, dmgCache.sourceName, dmgCache.count, dmgCache.spellId, dmgCache.spellName)
end
dmgCache.spellId = nil
end
if spellId == dmgPrdcCache.spellId then
if timeStamp - dmgPrdcCache.timeStamp > 0.2 then
if dmgPrdcCache.count == 1 then
if shouldLogFlags and dmgPrdcCache.sourceName ~= "nil" then
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%s#%d#%s", dmgPrdcCache.timeStop, dmgPrdcCache.time, dmgPrdcCache.event, dmgPrdcCache.sourceFlags, dmgPrdcCache.sourceGUID, dmgPrdcCache.sourceName, dmgPrdcCache.destGUID, dmgPrdcCache.destName, dmgPrdcCache.spellId, dmgPrdcCache.spellName)
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%d#%s", dmgPrdcCache.timeStop, dmgPrdcCache.time, dmgPrdcCache.event, dmgPrdcCache.sourceGUID, dmgPrdcCache.sourceName, dmgPrdcCache.destGUID, dmgPrdcCache.destName, dmgPrdcCache.spellId, dmgPrdcCache.spellName)
end
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] SPELL_PERIODIC_DAMAGE[CONDENSED]#%s#%s#%d Targets#%d#%s", dmgPrdcCache.timeStop, dmgPrdcCache.time, dmgPrdcCache.sourceGUID, dmgPrdcCache.sourceName, dmgPrdcCache.count, dmgPrdcCache.spellId, dmgPrdcCache.spellName)
end
dmgPrdcCache.spellId = spellId
dmgPrdcCache.sourceGUID = sourceGUID
dmgPrdcCache.sourceName = sourceName or "nil"
dmgPrdcCache.sourceFlags = sourceFlags
dmgPrdcCache.spellName = spellName
dmgPrdcCache.timeStop = (debugprofilestop() / 1000) - logStartTime
dmgPrdcCache.time = date("%H:%M:%S")
dmgPrdcCache.timeStamp = timeStamp
dmgPrdcCache.count = 1
dmgPrdcCache.event = event
dmgPrdcCache.destGUID = destGUID
dmgPrdcCache.destName = destName
else
dmgPrdcCache.count = dmgPrdcCache.count + 1
end
else
if dmgPrdcCache.spellId then
if dmgPrdcCache.count == 1 then
if shouldLogFlags and dmgPrdcCache.sourceName ~= "nil" then
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%s#%d#%s", dmgPrdcCache.timeStop, dmgPrdcCache.time, dmgPrdcCache.event, dmgPrdcCache.sourceFlags, dmgPrdcCache.sourceGUID, dmgPrdcCache.sourceName, dmgPrdcCache.destGUID, dmgPrdcCache.destName, dmgPrdcCache.spellId, dmgPrdcCache.spellName)
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%d#%s", dmgPrdcCache.timeStop, dmgPrdcCache.time, dmgPrdcCache.event, dmgPrdcCache.sourceGUID, dmgPrdcCache.sourceName, dmgPrdcCache.destGUID, dmgPrdcCache.destName, dmgPrdcCache.spellId, dmgPrdcCache.spellName)
end
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] SPELL_PERIODIC_DAMAGE[CONDENSED]#%s#%s#%d Targets#%d#%s", dmgPrdcCache.timeStop, dmgPrdcCache.time, dmgPrdcCache.sourceGUID, dmgPrdcCache.sourceName, dmgPrdcCache.count, dmgPrdcCache.spellId, dmgPrdcCache.spellName)
end
end
dmgPrdcCache.spellId = spellId
dmgPrdcCache.sourceGUID = sourceGUID
dmgPrdcCache.sourceName = sourceName or "nil"
dmgPrdcCache.sourceFlags = sourceFlags
dmgPrdcCache.spellName = spellName
dmgPrdcCache.timeStop = (debugprofilestop() / 1000) - logStartTime
dmgPrdcCache.time = date("%H:%M:%S")
dmgPrdcCache.timeStamp = timeStamp
dmgPrdcCache.count = 1
dmgPrdcCache.event = event
dmgPrdcCache.destGUID = destGUID
dmgPrdcCache.destName = destName
end
else
if dmgCache.spellId then
if dmgCache.count == 1 then
if shouldLogFlags and dmgCache.sourceName ~= "nil" then
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%s#%d#%s", dmgCache.timeStop, dmgCache.time, dmgCache.event, dmgCache.sourceFlags, dmgCache.sourceGUID, dmgCache.sourceName, dmgCache.destGUID, dmgCache.destName, dmgCache.spellId, dmgCache.spellName)
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%d#%s", dmgCache.timeStop, dmgCache.time, dmgCache.event, dmgCache.sourceGUID, dmgCache.sourceName, dmgCache.destGUID, dmgCache.destName, dmgCache.spellId, dmgCache.spellName)
end
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] SPELL_DAMAGE[CONDENSED]#%s#%s#%d Targets#%d#%s", dmgCache.timeStop, dmgCache.time, dmgCache.sourceGUID, dmgCache.sourceName, dmgCache.count, dmgCache.spellId, dmgCache.spellName)
end
dmgCache.spellId = nil
elseif dmgPrdcCache.spellId then
if dmgPrdcCache.count == 1 then
if shouldLogFlags and dmgPrdcCache.sourceName ~= "nil" then
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%s#%d#%s", dmgPrdcCache.timeStop, dmgPrdcCache.time, dmgPrdcCache.event, dmgPrdcCache.sourceFlags, dmgPrdcCache.sourceGUID, dmgPrdcCache.sourceName, dmgPrdcCache.destGUID, dmgPrdcCache.destName, dmgPrdcCache.spellId, dmgPrdcCache.spellName)
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] %s#%s#%s#%s#%s#%d#%s", dmgPrdcCache.timeStop, dmgPrdcCache.time, dmgPrdcCache.event, dmgPrdcCache.sourceGUID, dmgPrdcCache.sourceName, dmgPrdcCache.destGUID, dmgPrdcCache.destName, dmgPrdcCache.spellId, dmgPrdcCache.spellName)
end
else
currentLog.total[#currentLog.total+1] = format("<%.2f %s> [CLEU] SPELL_PERIODIC_DAMAGE[CONDENSED]#%s#%s#%d Targets#%d#%s", dmgPrdcCache.timeStop, dmgPrdcCache.time, dmgPrdcCache.sourceGUID, dmgPrdcCache.sourceName, dmgPrdcCache.count, dmgPrdcCache.spellId, dmgPrdcCache.spellName)
end
dmgPrdcCache.spellId = nil
end
if (event == "SPELL_CAST_START" or event == "SPELL_CAST_SUCCESS") and sourceName and sourceGUID then
local unit = UnitTokenFromGUID(sourceGUID)
if unit then
local hp = UnitPercentHealthFromGUID(sourceGUID)
local maxPower = UnitPowerMax(unit)
local power = maxPower == 0 and maxPower or (UnitPower(unit) / maxPower * 100)
sourceName = format("%s(%.1f%%-%.1f%%)", sourceName, hp*100, power)
end
end
if shouldLogFlags and sourceName and badPlayerFilteredEvents[event] then
return strjoin("#", tostringall(event, sourceFlags, sourceGUID, sourceName, destGUID, destName, spellId, spellName, extraSpellId, amount, absorbSpellId, absorbSpellName, absorbAmount, totalAmount))
else
return strjoin("#", tostringall(event, sourceGUID, sourceName, destGUID, destName, spellId, spellName, extraSpellId, amount, absorbSpellId, absorbSpellName, absorbAmount, totalAmount))
end
end
end
end