vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | ----------------------- |
2 | -- TeamSpeak monitor -- |
||
3 | ----------------------- |
||
4 | |||
5 | local meSpeaking = false |
||
6 | local meSpeakChannel |
||
7 | local endSpeaking |
||
8 | speakerIcons = {} |
||
9 | Speaking = {} |
||
10 | local functions = {} |
||
11 | local tsFrame |
||
12 | local updatingName |
||
13 | |||
14 | if (not XPerlColourTable) then |
||
15 | local function MashXX(class) |
||
16 | local c = RAID_CLASS_COLORS[class] |
||
17 | XPerlColourTable[class] = string.format("|c00%02X%02X%02X", 255 * c.r, 255 * c.g, 255 * c.b) |
||
18 | end |
||
19 | XPerlColourTable = {} |
||
20 | MashXX("HUNTER") |
||
21 | MashXX("WARLOCK") |
||
22 | MashXX("PRIEST") |
||
23 | MashXX("PALADIN") |
||
24 | MashXX("MAGE") |
||
25 | MashXX("ROGUE") |
||
26 | MashXX("DRUID") |
||
27 | MashXX("SHAMAN") |
||
28 | MashXX("WARRIOR") |
||
29 | end |
||
30 | |||
31 | XPerlTeamSpeak = {} |
||
32 | |||
33 | -- CheckOnUpdate |
||
34 | local function CheckOnUpdate() |
||
35 | local any |
||
36 | if (endSpeaking) then |
||
37 | any = true |
||
38 | else |
||
39 | for k,v in pairs(Speaking) do |
||
40 | any = true |
||
41 | break |
||
42 | end |
||
43 | end |
||
44 | |||
45 | if (any) then |
||
46 | XPerl_TeamSpeak_Events:SetScript("OnUpdate", XPerl_TeamSpeak_OnUpdate) |
||
47 | else |
||
48 | XPerl_TeamSpeak_Events:SetScript("OnUpdate", nil) |
||
49 | XPerl_TeamSpeakIcon:SetTexCoord(0.75, 1, 0, 1) |
||
50 | end |
||
51 | end |
||
52 | |||
53 | -- StartSpeaking(name) |
||
54 | local function StartSpeaking(name) |
||
55 | |||
56 | if (not Speaking[name]) then |
||
57 | Speaking[name] = {start = GetTime(), icons = {}} |
||
58 | |||
59 | updatingName = name |
||
60 | if (name == UnitName("player")) then |
||
61 | if (functions.player) then |
||
62 | functions.player() |
||
63 | end |
||
64 | else |
||
65 | if (functions.party) then |
||
66 | functions.party(name) |
||
67 | end |
||
68 | end |
||
69 | if (functions.raid) then |
||
70 | functions.raid(name) |
||
71 | end |
||
72 | updatingName = nil |
||
73 | |||
74 | if (XPerl_TeamSpeak_Frame:IsShown()) then |
||
75 | XPerl_SetInfoText() |
||
76 | end |
||
77 | |||
78 | CheckOnUpdate() |
||
79 | end |
||
80 | end |
||
81 | |||
82 | -- StopSpeaking |
||
83 | local function StopSpeaking(name) |
||
84 | |||
85 | local stopSpeaking = Speaking[name] |
||
86 | if (stopSpeaking) then |
||
87 | for k,v in pairs(stopSpeaking.icons) do |
||
88 | v.SpeakerIcon.SpeakingName = nil |
||
89 | v.SpeakerIcon.SpeakStart = nil |
||
90 | v.SpeakerIcon:Hide() |
||
91 | speakerIcons[v] = nil |
||
92 | end |
||
93 | |||
94 | Speaking[name] = nil |
||
95 | |||
96 | if (XPerl_TeamSpeak_Frame:IsShown()) then |
||
97 | XPerl_SetInfoText() |
||
98 | end |
||
99 | |||
100 | CheckOnUpdate() |
||
101 | end |
||
102 | end |
||
103 | |||
104 | -- SetInfoText |
||
105 | local depth = 0 |
||
106 | function XPerl_SetInfoText() |
||
107 | depth = depth + 1 |
||
108 | local sorter = {} |
||
109 | for k,v in pairs(Speaking) do |
||
110 | tinsert(sorter, {name = k, time = GetTime()}) |
||
111 | end |
||
112 | sort(sorter, function(a,b) return a.time < b.time end) |
||
113 | |||
114 | local text = "" |
||
115 | local removeName |
||
116 | for k,v in pairs(sorter) do |
||
117 | if (text ~= "") then |
||
118 | text = text.."|r, " |
||
119 | end |
||
120 | |||
121 | if (UnitName("player") == v.name) then |
||
122 | local _, class = UnitClass("player") |
||
123 | text = text..XPerlColourTable[class] |
||
124 | elseif (UnitInRaid("player")) then |
||
125 | local name, rank, subgroup, level, _, class, zone, online |
||
126 | for i = 1,GetNumRaidMembers() do |
||
127 | name, rank, subgroup, level, _, class, zone, online = GetRaidRosterInfo(i) |
||
128 | if (online) then |
||
129 | if (name == v.name) then |
||
130 | text = text..XPerlColourTable[class] |
||
131 | break |
||
132 | end |
||
133 | elseif (not removeName) then |
||
134 | removeName = name |
||
135 | break -- Since we'll be redoing the list anyway. |
||
136 | end |
||
137 | end |
||
138 | elseif (UnitInParty("player")) then |
||
139 | for i = 1,GetNumPartyMembers() do |
||
140 | if (UnitName("party"..i) == v.name) then |
||
141 | local _, class = UnitClass("party"..i) |
||
142 | text = text..XPerlColourTable[class] |
||
143 | break |
||
144 | end |
||
145 | end |
||
146 | end |
||
147 | |||
148 | text = text..v.name |
||
149 | end |
||
150 | XPerl_TeamSpeakText:SetText(text) |
||
151 | |||
152 | if (removeName and depth < 10) then |
||
153 | StopSpeaking(removeName) |
||
154 | end |
||
155 | depth = depth - 1 |
||
156 | end |
||
157 | |||
158 | |||
159 | -- XPerl_BarUpdate |
||
160 | local speakerTimer = 0 |
||
161 | local speakerCycle = 0 |
||
162 | function XPerl_TeamSpeak_OnUpdate() |
||
163 | |||
164 | if (endSpeaking) then |
||
165 | if (GetTime() >= endSpeaking) then |
||
166 | endSpeaking = nil |
||
167 | if (meSpeakChannel) then |
||
168 | SendAddonMessage(XPERL_COMMS_PREFIX, "NOSPEAK", meSpeakChannel) |
||
169 | end |
||
170 | CheckOnUpdate() |
||
171 | end |
||
172 | end |
||
173 | |||
174 | speakerTimer = speakerTimer + arg1 |
||
175 | if (speakerTimer >= 0.1) then |
||
176 | speakerTimer = 0 |
||
177 | speakerCycle = speakerCycle + 1 |
||
178 | if (speakerCycle > 6) then |
||
179 | speakerCycle = 0 |
||
180 | end |
||
181 | |||
182 | local left |
||
183 | if (speakerCycle > 3) then |
||
184 | left = (6 - speakerCycle) / 4 |
||
185 | else |
||
186 | left = speakerCycle / 4 |
||
187 | end |
||
188 | local right = left + 0.25 |
||
189 | |||
190 | local any |
||
191 | local now = GetTime() |
||
192 | local remove |
||
193 | for k,v in pairs(speakerIcons) do |
||
194 | if (not remove and v.SpeakStart and v.SpeakStart < now - 60) then |
||
195 | remove = k |
||
196 | end |
||
197 | |||
198 | v:SetTexCoord(left, right, 0, 1) |
||
199 | any = true |
||
200 | end |
||
201 | |||
202 | if (any) then |
||
203 | XPerl_TeamSpeakIcon:SetTexCoord(left, right, 0, 1) |
||
204 | else |
||
205 | XPerl_TeamSpeakIcon:SetTexCoord(0.75, 1, 0, 1) |
||
206 | end |
||
207 | |||
208 | if (remove) then |
||
209 | StopSpeaking(speakerIcons[remove].SpeakingName) |
||
210 | end |
||
211 | end |
||
212 | end |
||
213 | |||
214 | -- It won't send repetative SPEAK, NOSPEAK messages if you spam the button. |
||
215 | -- Will instead join them together until speak button released for at least 1 second |
||
216 | |||
217 | -- XPerl_TeamSpeakToggle |
||
218 | function XPerl_TeamSpeakToggle(keystate) |
||
219 | local myName = UnitName("player") |
||
220 | |||
221 | if (keystate == "down") then |
||
222 | meSpeaking = true |
||
223 | if (not endSpeaking) then |
||
224 | if (UnitInRaid("player")) then |
||
225 | meSpeakChannel = "RAID" |
||
226 | elseif (UnitInParty("player")) then |
||
227 | meSpeakChannel = "PARTY" |
||
228 | end |
||
229 | if (meSpeakChannel) then |
||
230 | SendAddonMessage(XPERL_COMMS_PREFIX, "SPEAK", meSpeakChannel) |
||
231 | end |
||
232 | else |
||
233 | endSpeaking = nil |
||
234 | end |
||
235 | |||
236 | StartSpeaking(myName) |
||
237 | else |
||
238 | StopSpeaking(myName) |
||
239 | |||
240 | if (meSpeaking) then |
||
241 | meSpeaking = false |
||
242 | -- We speak for at least 1 second. This way spamming the speak button won't send a lot of traffic out |
||
243 | endSpeaking = GetTime() + 1 |
||
244 | end |
||
245 | end |
||
246 | end |
||
247 | |||
248 | -- XPerl_TeamspeakMessage |
||
249 | local function XPerl_TeamspeakMessage(name, msg, channel) |
||
250 | if (name ~= UnitName("player")) then |
||
251 | if (msg == "SPEAK") then |
||
252 | StartSpeaking(name) |
||
253 | elseif (msg == "NOSPEAK") then |
||
254 | StopSpeaking(name) |
||
255 | end |
||
256 | end |
||
257 | end |
||
258 | |||
259 | -- XPerl_ActivateSpeaker |
||
260 | function XPerl_ActivateSpeaker(frame, anchor) |
||
261 | if (frame) then |
||
262 | if (not frame.SpeakerIcon) then |
||
263 | if (not anchor) then |
||
264 | anchor = "LEFT" |
||
265 | end |
||
266 | |||
267 | frame.SpeakerIcon = frame:CreateTexture(nil, "OVERLAY") |
||
268 | frame.SpeakerIcon:SetWidth(20) |
||
269 | frame.SpeakerIcon:SetHeight(20) |
||
270 | frame.SpeakerIcon:SetPoint(anchor, frame, anchor, 5, -1) |
||
271 | frame.SpeakerIcon:SetTexture("Interface\\Addons\\XPerl_TeamSpeak\\XPerl_Speakers") |
||
272 | frame.SpeakerIcon:SetTexCoord(0, 0.25, 0, 1) |
||
273 | end |
||
274 | |||
275 | tinsert(Speaking[updatingName].icons, frame) |
||
276 | |||
277 | speakerIcons[frame] = frame.SpeakerIcon |
||
278 | frame.SpeakerIcon.SpeakingName = updatingName |
||
279 | frame.SpeakerIcon.SpeakStart = GetTime() |
||
280 | frame.SpeakerIcon:Show() |
||
281 | end |
||
282 | end |
||
283 | |||
284 | -- XPerl_TeamSpeak_Register |
||
285 | -- Parameters: |
||
286 | -- group = "player" func = function(speaking) |
||
287 | -- group = "party" func = function(name, speaking) |
||
288 | -- group = "raid" func = function(name, speaking) |
||
289 | function XPerl_TeamSpeak_Register(group, func) |
||
290 | functions[group] = func |
||
291 | end |
||
292 | |||
293 | -- SetupAnchor() |
||
294 | local function SetupAnchor() |
||
295 | |||
296 | XPerl_TeamSpeakText:ClearAllPoints() |
||
297 | |||
298 | local r, jH, jV |
||
299 | if (XPerlTeamSpeak.Anchor == "TOPLEFT") then |
||
300 | r = "BOTTOMLEFT" |
||
301 | jH = "LEFT" |
||
302 | jV = "TOP" |
||
303 | elseif (XPerlTeamSpeak.Anchor == "TOPRIGHT") then |
||
304 | r = "BOTTOMRIGHT" |
||
305 | jH = "RIGHT" |
||
306 | jV = "TOP" |
||
307 | elseif (XPerlTeamSpeak.Anchor == "BOTTOMLEFT") then |
||
308 | r = "TOPLEFT" |
||
309 | jH = "LEFT" |
||
310 | jV = "BOTTOM" |
||
311 | else |
||
312 | r = "TOPRIGHT" |
||
313 | jH = "RIGHT" |
||
314 | jV = "BOTTOM" |
||
315 | end |
||
316 | |||
317 | XPerl_TeamSpeakText:SetPoint(XPerlTeamSpeak.Anchor, XPerl_TeamSpeakIcon, r, 0, 0) |
||
318 | XPerl_TeamSpeakText:SetJustifyH(jH) |
||
319 | XPerl_TeamSpeakText:SetJustifyV(jV) |
||
320 | end |
||
321 | |||
322 | -- XPerlTeamspeakSlashCmd() |
||
323 | local function XPerlTeamspeakSlashCmd() |
||
324 | XPerl_TeamSpeak_Frame:Show() |
||
325 | SetupAnchor() |
||
326 | end |
||
327 | |||
328 | -- XPerl_GetRaidPosition |
||
329 | if (not XPerl_GetRaidPosition) then |
||
330 | function XPerl_GetRaidPosition(findName) |
||
331 | for i = 1,GetNumRaidMembers() do |
||
332 | if (UnitName("raid"..i) == findName) then |
||
333 | return i |
||
334 | end |
||
335 | end |
||
336 | end |
||
337 | end |
||
338 | |||
339 | if (not XPerl_GetPartyPosition) then |
||
340 | function XPerl_GetPartyPosition(findName) |
||
341 | for i = 1,GetNumPartyMembers() do |
||
342 | if (UnitName("party"..i) == findName) then |
||
343 | return i |
||
344 | end |
||
345 | end |
||
346 | end |
||
347 | end |
||
348 | |||
349 | -- SetDefaultHandlers() |
||
350 | local function SetDefaultHandlers() |
||
351 | |||
352 | if (not functions.player) then |
||
353 | if (XPerl_Player) then |
||
354 | functions.player = function() |
||
355 | XPerl_ActivateSpeaker(XPerl_Player_NameFrame) |
||
356 | end |
||
357 | elseif (Perl_Player_Frame) then |
||
358 | functions.player = function() |
||
359 | XPerl_ActivateSpeaker(Perl_Player_NameFrame) |
||
360 | end |
||
361 | elseif (Nurfed_player) then |
||
362 | functions.player = function() |
||
363 | XPerl_ActivateSpeaker(Nurfed_player) |
||
364 | end |
||
365 | elseif (NUFPlayerFrame) then |
||
366 | functions.player = function() |
||
367 | XPerl_ActivateSpeaker(NUI_Player_ClickNDragFrame, "CENTER") |
||
368 | end |
||
369 | elseif (PlayerFrame) then |
||
370 | functions.player = function() |
||
371 | XPerl_ActivateSpeaker(PlayerFrame, "TOP") |
||
372 | end |
||
373 | end |
||
374 | |||
375 | if (XPerl_party1) then |
||
376 | functions.party = function(name) |
||
377 | local id = XPerl_GetPartyPosition(name) |
||
378 | if (id) then |
||
379 | local nameFrame = getglobal("XPerl_party"..id.."_NameFrame") |
||
380 | XPerl_ActivateSpeaker(nameFrame) |
||
381 | end |
||
382 | end |
||
383 | elseif (Perl_party1) then |
||
384 | functions.party = function(name) |
||
385 | local id = XPerl_GetPartyPosition(name) |
||
386 | if (id) then |
||
387 | local nameFrame = getglobal("Perl_party"..id.."_NameFrame") |
||
388 | XPerl_ActivateSpeaker(nameFrame) |
||
389 | end |
||
390 | end |
||
391 | elseif (Nurfed_party1) then |
||
392 | functions.party = function(name) |
||
393 | local id = XPerl_GetPartyPosition(name) |
||
394 | if (id) then |
||
395 | local frame = getglobal("Nurfed_party"..id) |
||
396 | XPerl_ActivateSpeaker(frame) |
||
397 | end |
||
398 | end |
||
399 | elseif (NUFPartyMemberFrame1) then |
||
400 | functions.party = function(name) |
||
401 | local id = XPerl_GetPartyPosition(name) |
||
402 | if (id) then |
||
403 | local frame = getglobal("NUIPartyClickNDragFrame"..id) |
||
404 | XPerl_ActivateSpeaker(frame, "CENTER") |
||
405 | end |
||
406 | end |
||
407 | elseif (PartyMemberFrame1) then |
||
408 | functions.party = function(name) |
||
409 | local id = XPerl_GetPartyPosition(name) |
||
410 | if (id) then |
||
411 | local frame = getglobal("PartyMemberFrame"..id.."Disconnect"):GetParent():GetParent() |
||
412 | XPerl_ActivateSpeaker(frame, "LEFT") |
||
413 | end |
||
414 | end |
||
415 | end |
||
416 | |||
417 | if (XPerl_Raid_Frame) then |
||
418 | functions.raid = function(name) |
||
419 | local id = XPerl_GetRaidPosition(name) |
||
420 | if (id) then |
||
421 | local frame = getglobal("XPerl_raid"..id.."_NameFrame") |
||
422 | if (frame) then |
||
423 | XPerl_ActivateSpeaker(frame) |
||
424 | end |
||
425 | end |
||
426 | end |
||
427 | return |
||
428 | elseif (Perl_Raid1) then |
||
429 | functions.raid = function(name) |
||
430 | local id = XPerl_GetRaidPosition(name) |
||
431 | if (id) then |
||
432 | local frame = getglobal("Perl_Raid"..id.."_NameFrame") |
||
433 | if (frame) then |
||
434 | XPerl_ActivateSpeaker(frame) |
||
435 | end |
||
436 | end |
||
437 | end |
||
438 | elseif (CT_RAMember1) then |
||
439 | functions.raid = function(name) |
||
440 | local id = XPerl_GetRaidPosition(name) |
||
441 | if (id) then |
||
442 | local frame = getglobal("CT_RAMember"..id) |
||
443 | if (frame) then |
||
444 | XPerl_ActivateSpeaker(frame, "TOP") |
||
445 | end |
||
446 | end |
||
447 | end |
||
448 | elseif (Nurfed_RaidUnit1) then |
||
449 | functions.raid = function(name) |
||
450 | local id = XPerl_GetRaidPosition(name) |
||
451 | if (id) then |
||
452 | for i = 1,400 do |
||
453 | local button = getglobal("Nurfed_RaidUnit"..i) |
||
454 | if (not button) then |
||
455 | break |
||
456 | end |
||
457 | if (button.id == id) then |
||
458 | XPerl_ActivateSpeaker(button, "CENTER") |
||
459 | end |
||
460 | end |
||
461 | end |
||
462 | end |
||
463 | end |
||
464 | end |
||
465 | end |
||
466 | |||
467 | -- XPerl_TeamSpeak_OnEvent |
||
468 | function XPerl_TeamSpeak_OnEvent(event) |
||
469 | if (event == "CHAT_MSG_ADDON") then |
||
470 | if (arg1 == "X-Perl") then |
||
471 | XPerl_TeamspeakMessage(arg4, arg2, arg3) |
||
472 | end |
||
473 | elseif (event == "PLAYER_ENTERING_WORLD") then |
||
474 | this:UnregisterEvent("PLAYER_ENTERING_WORLD") |
||
475 | if (not XPerlTeamSpeak) then |
||
476 | XPerlTeamSpeak = {} |
||
477 | |||
478 | if (XPerl_Player == nil) then |
||
479 | XPerlTeamSpeak.tsFrame = true |
||
480 | end |
||
481 | end |
||
482 | |||
483 | if (not XPerlTeamSpeak.Anchor) then |
||
484 | XPerlTeamSpeak.Anchor = "TOPLEFT" |
||
485 | end |
||
486 | |||
487 | SetDefaultHandlers() |
||
488 | |||
489 | SlashCmdList["XPERL_TEAMSPEAK"] = XPerlTeamspeakSlashCmd |
||
490 | SLASH_XPERL_TEAMSPEAK1 = "/ts" |
||
491 | SLASH_XPERL_TEAMSPEAK2 = "/teamspeak" |
||
492 | SLASH_XPERL_TEAMSPEAK3 = "/ventrilo" |
||
493 | SLASH_XPERL_TEAMSPEAK4 = "/vent" |
||
494 | |||
495 | if (XPerlTeamSpeak.tsFrame) then |
||
496 | XPerl_TeamSpeak_Frame:Show() |
||
497 | SetupAnchor() |
||
498 | end |
||
499 | end |
||
500 | end |
||
501 | |||
502 | -- XPerl_TeamSpeakMenu() |
||
503 | function XPerl_TeamSpeakMenu() |
||
504 | ToggleDropDownMenu(1, nil, XPerl_TeamSpeak_DropDown, "XPerl_TeamSpeak_Frame", 0, 0) |
||
505 | end |
||
506 | |||
507 | -- XPerl_Teamspeak_Dropdown_OnLoad |
||
508 | function XPerl_Teamspeak_Dropdown_OnLoad() |
||
509 | UIDropDownMenu_Initialize(this, XPerl_Teamspeak_Dropdown_Initialize, "MENU") |
||
510 | end |
||
511 | |||
512 | -- SetAnchor |
||
513 | local function SetAnchor(a) |
||
514 | XPerlTeamSpeak.Anchor = a |
||
515 | HideDropDownMenu(1) |
||
516 | SetupAnchor() |
||
517 | end |
||
518 | |||
519 | function XPerl_Teamspeak_Dropdown_Initialize() |
||
520 | |||
521 | local info = {} |
||
522 | |||
523 | if (UIDROPDOWNMENU_MENU_LEVEL == 2) then |
||
524 | if (UIDROPDOWNMENU_MENU_VALUE == XPERL_TSMENU_ANCHOR) then |
||
525 | info = {} |
||
526 | info.text = XPERL_TSMENU_ANCHOR_TL |
||
527 | if (XPerlTeamSpeak.Anchor == "TOPLEFT") then |
||
528 | info.checked = 1 |
||
529 | end |
||
530 | info.func = function() SetAnchor("TOPLEFT") end |
||
531 | UIDropDownMenu_AddButton(info, 2) |
||
532 | |||
533 | info = {} |
||
534 | info.text = XPERL_TSMENU_ANCHOR_TR |
||
535 | if (XPerlTeamSpeak.Anchor == "TOPRIGHT") then |
||
536 | info.checked = 1 |
||
537 | end |
||
538 | info.func = function() SetAnchor("TOPRIGHT") end |
||
539 | UIDropDownMenu_AddButton(info, 2) |
||
540 | |||
541 | info = {} |
||
542 | info.text = XPERL_TSMENU_ANCHOR_BL |
||
543 | if (XPerlTeamSpeak.Anchor == "BOTTOMLEFT") then |
||
544 | info.checked = 1 |
||
545 | end |
||
546 | info.func = function() SetAnchor("BOTTOMLEFT") end |
||
547 | UIDropDownMenu_AddButton(info, 2) |
||
548 | |||
549 | info = {} |
||
550 | info.text = XPERL_TSMENU_ANCHOR_BR |
||
551 | if (XPerlTeamSpeak.Anchor == "BOTTOMRIGHT") then |
||
552 | info.checked = 1 |
||
553 | end |
||
554 | info.func = function() SetAnchor("BOTTOMRIGHT") end |
||
555 | UIDropDownMenu_AddButton(info, 2) |
||
556 | end |
||
557 | return |
||
558 | end |
||
559 | |||
560 | info = {} |
||
561 | info.text = XPERL_TSMENU_ANCHOR |
||
562 | info.hasArrow = 1 |
||
563 | info.notCheckable = 1 |
||
564 | UIDropDownMenu_AddButton(info) |
||
565 | |||
566 | info = {} |
||
567 | info.text = RESET |
||
568 | info.notCheckable = 1 |
||
569 | info.func = XPerl_TeamSpeakReset |
||
570 | UIDropDownMenu_AddButton(info) |
||
571 | |||
572 | info = {} |
||
573 | info.text = CLOSE |
||
574 | info.notCheckable = 1 |
||
575 | info.func = function() XPerl_TeamSpeak_Frame:Hide() end |
||
576 | UIDropDownMenu_AddButton(info) |
||
577 | end |
||
578 | |||
579 | -- XPerl_TeamSpeakReset |
||
580 | function XPerl_TeamSpeakReset() |
||
581 | for k,v in pairs(Speakers) do |
||
582 | StopSpeaking(k) |
||
583 | end |
||
584 | end |