Hello, I maintain an addon that uses this, and when this function is enabled, after some time playing, about 10-15 minutes all NPC dialog will stop playing. If I remove this function or prevent it from firing, this breakage does not happen. This is an addon to suppress talking heads and this issue only appeared in 10.0.7. There is no addon/Lua error being thrown. The hook I’m using is:
function f:OnEvent(event, ...) if event == "PLAYER_LOGIN" then hooksecurefunc(TalkingHeadFrame, "PlayCurrent", close_head); end end
function close_head()
--Query current zone and subzone when talking head is triggered
subZoneName = GetSubZoneText();
zoneName = GetZoneText();
--Only run this logic if the functionality is turned on
if ENABLED == 1 then
--Block the talking head unless its in the whitelist
if (has_value(WHITELIST, subZoneName) ~= true and has_value(WHITELIST, zoneName) ~= true) then
--Close the talking head
TalkingHeadFrame:CloseImmediately();
if VERBOSE == 1 then
print("BeQuiet blocked a talking head! /bq verbose to turn this alert off.")
end
end
end
end
By delaying it one frame it has essentially the same effect but does not break dialog. I’m guessing there is some race condition happening now in 10.0.7.
C_TalkingHead.IgnoreCurrentTalkingHead() appears to be the issue. If it’s run to soon after PlayCurrent() it causes the dialog sound to break (which probably makes it appear that StopSound is broken).
You could probably run your addon with something like:
--Create the frame
local f = CreateFrame("Frame")
local PlayCurrent = TalkingHeadFrame.PlayCurrent
TalkingHeadFrame.PlayCurrent = function(self)
--function close_head()
--Query current zone and subzone when talking head is triggered
subZoneName = GetSubZoneText();
zoneName = GetZoneText();
--Only run this logic if the functionality is turned on
if ENABLED == 1 then
--Block the talking head unless its in the whitelist
if (has_value(WHITELIST, subZoneName) == true and has_value(WHITELIST, zoneName) == true) then
PlayCurrent(self)
return
end
--Close the talking head
if VERBOSE == 1 then
print("BeQuiet blocked a talking head! /bq verbose to turn this alert off.")
end
end
end
--Main function
--function f:OnEvent(event, ...)
-- if event == "PLAYER_LOGIN" then
-- hooksecurefunc(TalkingHeadFrame, "PlayCurrent", close_head);
-- end
--end
This is still an issue as of 10.1.5, calling this method breaks npc dialog immediately, the current workaround is to do:
function block_head()
--Close the talking head
--TalkingHeadFrame:CloseImmediately(); pre 10.0.7
TalkingHeadFrame:Hide()
if TalkingHeadFrame.voHandle ~= nil and VO_ENABLED == 0 then
C_Timer.After(0.025, function() StopSound(TalkingHeadFrame.voHandle) end);
end
if VERBOSE == 1 then
print("BeQuiet blocked a talking head! /bq verbose to turn this alert off.")
end
end
which for some users yields a lot of errors such as
42x BeQuiet/BeQuiet.lua:70: Usage: StopSound(soundHandleID, [optional: fadeout time in ms])
[string "=[C]"]: in function `StopSound'
[string "@BeQuiet/BeQuiet.lua"]:70: in function
which i can never reproduce, i expect this is a client performance/race condition issue
Maybe by the time the C_Timer.After runs the sound has finished playing/been cancelled and TalkingHeadFrame.voHandle has been set to nil. Possibly check if voHandle is not nil before actually running StopSound().
In the code you posted, you check for TalkingHeadFrame.voHandle being nil and then call C_Timer.After(…)
That gives control back to the sytem and a whopping 0.025 seconds during which anything can happen before the C_Timer function actually runs.
One of those things that might happen is that talking head code finds out the sound has been cancelled and resetting TalkingHeadFrame.voHandle to nil (any lua code running when C_Timer is due to run your function will have to complete before your function can be called).
C_Timer.After(0.025, function() if TalkingHeadFrame.voHandle then StopSound(TalkingHeadFrame.voHandle) end end);
Makes sure there is still a handle to cancel.
The error:
Usage: StopSound(soundHandleID, [optional: fadeout time in ms])
Is telling you it’s not getting anything in the first parameter as that is the only one that is not optional.
I see, the reason for the delay was that immediately cancelling it was also breaking npc dialog, the change you suggest does seem more elegant since im not really GOOD at lua/wow api