Repository navigation
Expand file tree
/
Copy pathDcr_12_1_Sounds.lua
More file actions
242 lines (197 loc) · 7.63 KB
/
Copy pathDcr_12_1_Sounds.lua
File metadata and controls
242 lines (197 loc) · 7.63 KB
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
--[[
This file is part of Decursive.
Decursive add-on for World of Warcraft UI
Copyright (C) 2006-2026 John Wellesz
WoW 12.1 current-season dispel spell classifications are based on the
GPLv3 DispelDB from Zhaohu's Decursive, Copyright (C) 2026 Randy Lorfing.
Decursive is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
--]]
local addonName, T = ...
local D = T.Dcr
local DC = T._C
-- big ugly scary fatal error message display function {{{
if not T._FatalError then
-- the beautiful error popup : {{{ -
StaticPopupDialogs["DECURSIVE_ERROR_FRAME"] = {
text = "|cFFFF0000Decursive Error:|r\n%s",
button1 = "OK",
OnAccept = function()
return false;
end,
timeout = 0,
whileDead = 1,
hideOnEscape = 1,
showAlert = 1,
preferredIndex = 3,
}; -- }}}
T._FatalError = function (TheError) T._StaticPopupDialogsWasShown = true; StaticPopup_Show ("DECURSIVE_ERROR_FRAME", TheError); end
end
-- }}}
if not T._LoadedFiles or not T._LoadedFiles["Dcr_DebuffsFrame.xml"] or not T._LoadedFiles["Dcr_DebuffsFrame.lua"] then -- XML are loaded even if LUA syntax errors exixts
if not DecursiveInstallCorrupted then T._FatalError("Decursive installation is corrupted! (Dcr_DebuffsFrame.xml or Dcr_DebuffsFrame.lua not loaded)"); end;
DecursiveInstallCorrupted = true;
return;
end
T._LoadedFiles["Dcr_12_1_Sounds.lua"] = not DC.RESTRICTED_AURAS and "@project-version@";
function D:Schedule_MN_SoundsRegistration(delay)
if DC.RESTRICTED_AURAS then
D:ScheduleDelayedCall("12.1RegisterSounds", D.Refresh12_1AuraSounds, delay or 1, D)
end
end
if not DC.RESTRICTED_AURAS or not C_UnitAuras or type(C_UnitAuras.AddAuraSound) ~= "function" then
return
end
-- AddAuraSound requires an exact public spell ID. These are the friendly,
-- actionable dispels in the current 12.1 dungeon rotation and raid. Blizzard
-- owns detection and playback after registration; addon Lua never reads the
-- protected aura or its AuraButton state.
local SPELLS_BY_TYPE = {
[DC.MAGIC] = {
1294569, 1217633, 1228198, 1201554, 1235549, 1239860, 1259365,
1238084, 1249238, 276031, 1294815, 372682, 373589, 1305234,
381515, 392641, 392924, 268008, 268013, 1296052, 1286922,
270920, 270499,
},
[DC.POISON] = {
1294845, 1305368, 1307571, 474515, 1216590, 1234846, 1250937,
1226031, 1289258, 1263971, 267273, 271564, 1298104, 1306763,
263957, 272699, 273563, 1308100, 1308148, 267027,
1301800, 1306906,
11918 -- poison from an Elwyn forest spider I use for my tests...
},
[DC.DISEASE] = {
1296069, 1302867, 1245456, 267763, 269686,
},
[DC.CURSE] = {
1309980, 1310017, 1238255, 1217973, 1238801, 1252095, 269972,
270492,
},
[DC.BLEED] = {
474740, 1216300, 1295035, 1295427, 1311136, 1238439, 1235865,
1238076, 1241058, 1247746, 1242135, 1237267, 1267894, 1299133,
1311778, 266191, 266231, 1297781, 1297918, 1301851, 1302945,
1303490, 372796, 1291399,
},
}
local allSpells = {}
for k, s in pairs(SPELLS_BY_TYPE) do
for _, id in ipairs(s) do
allSpells[id] = k
end
end
local expectedCount = (
#SPELLS_BY_TYPE[DC.MAGIC]
+ #SPELLS_BY_TYPE[DC.POISON]
+ #SPELLS_BY_TYPE[DC.DISEASE]
+ #SPELLS_BY_TYPE[DC.CURSE]
+ #SPELLS_BY_TYPE[DC.BLEED]
)
local actualCount = D:tCount(allSpells)
assert(
actualCount == expectedCount,
("Bad SPELLS_BY_TYPE table (non unique or duplicated ids): expected: %d, found: %d"):format(expectedCount, actualCount)
)
DC.KNOWN_SIDS_to_TYPES = allSpells
DC.KNOWN_SIDS_by_TYPES = SPELLS_BY_TYPE
function D:AddKnownSpellIDToSoundReg(spellID, spellType)
if spellType == DC.ENEMYMAGIC then
spellType = DC.MAGIC
end
if not SPELLS_BY_TYPE[spellType] then
D:Debug("AddKnownSpellIDToSoundReg bad usage: unknown type:", spellType)
return
end
if allSpells[spellID] then return end
allSpells[spellID] = spellType
SPELLS_BY_TYPE[spellType][#SPELLS_BY_TYPE[spellType] + 1] = spellID
D:Schedule_MN_SoundsRegistration()
end
function D:RemoveKnownSpellIDFromSoundReg(spellID)
if not allSpells[spellID] then return end
local spellType = allSpells[spellID]
allSpells[spellID] = nil
for i = #SPELLS_BY_TYPE[spellType], 1, -1 do
if SPELLS_BY_TYPE[spellType][i] == spellID then
table.remove(SPELLS_BY_TYPE[spellType], i)
break
end
end
D:Schedule_MN_SoundsRegistration()
end
local handles = {}
local soundRegCache = setmetatable({}, {
__mode = "kv",
})
local cacheMissCount = 0
local function buildDesiredRegistrations()
local desired = {}
cacheMissCount = 0
if not D.profile or not D.profile.PlaySound or not D.Status or not D.Status.CuringSpells then
return desired
end
local curingSpells = D.Status.CuringSpells
local cureOrder = D:GetCureOrderTable() -- key are types, values are positive number when type is enabled, false when not
local soundFile = D.profile.SoundFile or DC.AfflictionSound
for _, unit in ipairs(D.Status.Unit_Array) do
for debuffType, spellIDs in pairs(SPELLS_BY_TYPE) do
local typePrioEnabledWithSpell = cureOrder[debuffType] and curingSpells[debuffType]
if typePrioEnabledWithSpell then
for _, spellID in ipairs(spellIDs) do
local key = unit .. ":" .. spellID .. ":" .. soundFile
if not soundRegCache[key] then
soundRegCache[key] = {
unitToken = unit,
spellID = spellID,
soundFileName = soundFile,
outputChannel = "Master",
}
cacheMissCount = cacheMissCount + 1
end
desired[key] = soundRegCache[key]
end
end
end
end
return desired
end
function D:Refresh12_1AuraSounds()
if D:AurasRestricted() then
D:Debug("|cFFFF0000Sound registration not possible while auras are restricted... rescheduling in 5s|r")
D:Schedule_MN_SoundsRegistration(5)
return false
end
local desired = buildDesiredRegistrations()
local trigger = Enum.UnitAuraSoundTrigger and Enum.UnitAuraSoundTrigger.Added or 0
local addedCount = 0
local removedCount = 0
-- Add replacements first so a failed refresh never removes the last
-- working registration.
for key, soundInfo in pairs(desired) do
if not handles[key] then
local ok, handle = pcall(C_UnitAuras.AddAuraSound, trigger, soundInfo)
if ok and handle then
handles[key] = handle
addedCount = addedCount + 1
end
end
end
for key, handle in pairs(handles) do
if not desired[key] then
local ok = pcall(C_UnitAuras.RemoveAuraSound, handle)
if ok then
handles[key] = nil
removedCount = removedCount + 1
end
end
end
local handleCount = 0
for _ in pairs(handles) do
handleCount = handleCount + 1
end
D:Debug("|cFF00FF0012.1 aura sounds registered:|r", handleCount, ", Added:", addedCount, ", Removed:", removedCount, ", CacheMiss:", cacheMissCount)
return true
end
T._LoadedFiles["Dcr_12_1_Sounds.lua"] = "@project-version@";