1990a75ae2
Commented ll. 79 & 80 because if you run the game with LUA errors enabled it turns annoying trying to open Dungeon Caches for example, since it's not a valid QuestID for the addon. I feel they should be commented and if someone is working on the addon they can simply remove those lines as comments
524 lines
23 KiB
Lua
524 lines
23 KiB
Lua
setfenv(1, VoiceOver)
|
|
|
|
if not strsplit then
|
|
function strsplit(delimiter, text)
|
|
local result = {}
|
|
local from = 1
|
|
local delim_from, delim_to = string.find(text, delimiter, from)
|
|
while delim_from do
|
|
table.insert(result, string.sub(text, from, delim_from - 1))
|
|
from = delim_to + 1
|
|
delim_from, delim_to = string.find(text, delimiter, from)
|
|
end
|
|
table.insert(result, string.sub(text, from))
|
|
return unpack(result)
|
|
end
|
|
end
|
|
|
|
if not GetAddOnEnableState then
|
|
function GetAddOnEnableState(character, addon)
|
|
addon = addon or character -- GetAddOnEnableState([character], addon)
|
|
local name, _, _, _, loadable, reason = _G.GetAddOnInfo(addon)
|
|
if not name or not loadable and reason == "DISABLED" then
|
|
return 0
|
|
end
|
|
return 2
|
|
end
|
|
|
|
function GetAddOnInfo(indexOrName)
|
|
local name, title, notes, enabled, loadable, reason, security, newVersion = _G.GetAddOnInfo(indexOrName)
|
|
return name, title, notes, loadable, reason, security, newVersion
|
|
end
|
|
end
|
|
|
|
if not GetQuestID then
|
|
local source, text
|
|
local old_QUEST_DETAIL = Addon.QUEST_DETAIL
|
|
local old_QUEST_PROGRESS = Addon.QUEST_PROGRESS
|
|
local old_QUEST_COMPLETE = Addon.QUEST_COMPLETE
|
|
function Addon:QUEST_DETAIL() source = "accept" text = GetQuestText() old_QUEST_DETAIL(self) end
|
|
function Addon:QUEST_PROGRESS() source = "progress" text = GetProgressText() old_QUEST_PROGRESS(self) end
|
|
function Addon:QUEST_COMPLETE() source = "complete" text = GetRewardText() old_QUEST_COMPLETE(self) end
|
|
function GetQuestID()
|
|
local npcName = Utils:GetNPCName()
|
|
if Utils:IsNPCPlayer() then
|
|
-- Can't do anything about quest sharing currently, because we need the original questgiver's name to obtain quest ID, and we need quest ID to obtain the questgiver's name
|
|
return 0
|
|
end
|
|
|
|
return DataModules:GetQuestID(source, GetTitleText(), npcName, text) or 0
|
|
end
|
|
end
|
|
|
|
if not QUESTS_DISPLAYED then
|
|
if QuestLogScrollFrame then
|
|
QUESTS_DISPLAYED = getn(QuestLogScrollFrame.buttons)
|
|
end
|
|
end
|
|
|
|
-- Not sure when exactly were UI-Cursor-Move and UI-Cursor-SizeRight added, but the former was present in 6.0.1
|
|
if Version:IsBelowLegacyVersion(60000) then
|
|
function SetCursor() end
|
|
end
|
|
|
|
Enums.GUID.Player = tonumber("0000", 16)
|
|
Enums.GUID.Item = tonumber("4000", 16)
|
|
Enums.GUID.Creature = tonumber("F130", 16)
|
|
Enums.GUID.Vehicle = tonumber("F150", 16)
|
|
Enums.GUID.GameObject = tonumber("F110", 16)
|
|
|
|
function Utils:GetGUIDType(guid)
|
|
return guid and tonumber(guid:sub(3, 3 + 4 - 1), 16)
|
|
end
|
|
|
|
function Utils:GetIDFromGUID(guid)
|
|
if not guid then
|
|
return
|
|
end
|
|
local type = assert(self:GetGUIDType(guid), format([[Failed to determine the type of GUID "%s"]], guid))
|
|
-- assert(Enums.GUID:GetName(type), format([[Unknown GUID type %d]], type))
|
|
-- assert(Enums.GUID:CanHaveID(type), format([[GUID "%s" does not contain ID]], guid))
|
|
return tonumber(guid:sub(7, 7 + 6 - 1), 16)
|
|
end
|
|
|
|
function Utils:MakeGUID(type, id)
|
|
assert(Enums.GUID:CanHaveID(type), format("GUID of type %d (%s) cannot contain ID", type, Enums.GUID:GetName(type) or "Unknown"))
|
|
return format("0x%04X%06X%06X", type, id, 0)
|
|
end
|
|
|
|
-- Patch 6.0.2 (2014-10-14): Removed returns 'questTag' and 'isDaily'. Added returns 'frequency', 'isOnMap', 'hasLocalPOI', 'isTask', and 'isStory'.
|
|
if Version:IsBelowLegacyVersion(60000) then
|
|
function GetQuestLogTitle(questIndex)
|
|
local title, level, questTag, suggestedGroup, isHeader, isCollapsed, isComplete, isDaily, questID, displayQuestID = _G.GetQuestLogTitle(questIndex)
|
|
local frequency = isDaily and 2 or 1
|
|
return title, level, suggestedGroup, isHeader, isCollapsed, isComplete, frequency, questID
|
|
end
|
|
end
|
|
|
|
local FrameMixins = {}
|
|
local ModelMixins = {}
|
|
local hookFrame
|
|
local hookModel
|
|
function CreateFrame(frameType, name, parent, template)
|
|
if UIParent.SetBackdrop and template == "BackdropTemplate" then
|
|
template = nil
|
|
end
|
|
|
|
local frame = _G.CreateFrame(frameType, name, parent, template)
|
|
for k, v in pairs(FrameMixins) do
|
|
if not frame[k] then
|
|
frame[k] = v
|
|
end
|
|
end
|
|
if hookFrame then
|
|
hookFrame(frame)
|
|
end
|
|
if frameType == "Model" or frameType == "PlayerModel" or frameType == "DressUpModel" then
|
|
for k, v in pairs(ModelMixins) do
|
|
if not frame[k] then
|
|
frame[k] = v
|
|
end
|
|
end
|
|
if hookModel then
|
|
hookModel(frame)
|
|
end
|
|
end
|
|
return frame
|
|
end
|
|
|
|
function FrameMixins:SetResizeBounds(minWidth, minHeight, maxWidth, maxHeight)
|
|
self:SetMinResize(minWidth, minHeight)
|
|
if maxWidth and maxHeight then
|
|
self:SetMaxResize(maxWidth, maxHeight)
|
|
end
|
|
end
|
|
function ModelMixins:SetAnimation(animation)
|
|
self:SetSequence(animation)
|
|
end
|
|
function ModelMixins:SetCustomCamera(camera)
|
|
self:SetCamera(camera)
|
|
end
|
|
-- Patch 7.0.3 (2016-07-19): Added.
|
|
if Version:IsBelowLegacyVersion(70000) then
|
|
local modelToFileID = {
|
|
["Original"] = {
|
|
["interface/buttons/talktomequestion_white"] = 130737,
|
|
|
|
["character/bloodelf/female/bloodelffemale"] = 116921,
|
|
["character/bloodelf/male/bloodelfmale"] = 117170,
|
|
["character/broken/female/brokenfemale"] = 117400,
|
|
["character/broken/male/brokenmale"] = 117412,
|
|
["character/draenei/female/draeneifemale"] = 117437,
|
|
["character/draenei/male/draeneimale"] = 117721,
|
|
["character/dwarf/female/dwarffemale"] = 118135,
|
|
["character/dwarf/female/dwarffemale_hd"] = 950080,
|
|
["character/dwarf/female/dwarffemale_npc"] = 950080,
|
|
["character/dwarf/male/dwarfmale"] = 118355,
|
|
["character/dwarf/male/dwarfmale_hd"] = 878772,
|
|
["character/dwarf/male/dwarfmale_npc"] = 878772,
|
|
["character/felorc/female/felorcfemale"] = 118652,
|
|
["character/felorc/male/felorcmale"] = 118653,
|
|
["character/felorc/male/felorcmaleaxe"] = 118654,
|
|
["character/felorc/male/felorcmalesword"] = 118667,
|
|
["character/foresttroll/male/foresttrollmale"] = 118798,
|
|
["character/gnome/female/gnomefemale"] = 119063,
|
|
["character/gnome/female/gnomefemale_hd"] = 940356,
|
|
["character/gnome/female/gnomefemale_npc"] = 940356,
|
|
["character/gnome/male/gnomemale"] = 119159,
|
|
["character/gnome/male/gnomemale_hd"] = 900914,
|
|
["character/gnome/male/gnomemale_npc"] = 900914,
|
|
["character/goblin/female/goblinfemale"] = 119369,
|
|
["character/goblin/male/goblinmale"] = 119376,
|
|
["character/goblinold/male/goblinoldmale"] = 119376,
|
|
["character/human/female/humanfemale"] = 119563,
|
|
["character/human/female/humanfemale_hd"] = 1000764,
|
|
["character/human/female/humanfemale_npc"] = 1000764,
|
|
["character/human/male/humanmale"] = 119940,
|
|
["character/human/male/humanmale_cata"] = 119940,
|
|
["character/human/male/humanmale_hd"] = 1011653,
|
|
["character/human/male/humanmale_npc"] = 1011653,
|
|
["character/icetroll/male/icetrollmale"] = 232863,
|
|
["character/naga_/female/naga_female"] = 120263,
|
|
["character/naga_/male/naga_male"] = 120294,
|
|
["character/nightelf/female/nightelffemale"] = 120590,
|
|
["character/nightelf/female/nightelffemale_hd"] = 921844,
|
|
["character/nightelf/female/nightelffemale_npc"] = 921844,
|
|
["character/nightelf/male/nightelfmale"] = 120791,
|
|
["character/nightelf/male/nightelfmale_hd"] = 974343,
|
|
["character/nightelf/male/nightelfmale_npc"] = 974343,
|
|
["character/northrendskeleton/male/northrendskeletonmale"] = 233367,
|
|
["character/orc/female/orcfemale"] = 121087,
|
|
["character/orc/female/orcfemale_npc"] = 121087,
|
|
["character/orc/male/orcmale"] = 121287,
|
|
["character/orc/male/orcmale_hd"] = 917116,
|
|
["character/orc/male/orcmale_npc"] = 917116,
|
|
["character/scourge/female/scourgefemale"] = 121608,
|
|
["character/scourge/female/scourgefemale_hd"] = 997378,
|
|
["character/scourge/female/scourgefemale_npc"] = 997378,
|
|
["character/scourge/male/scourgemale"] = 121768,
|
|
["character/scourge/male/scourgemale_hd"] = 959310,
|
|
["character/scourge/male/scourgemale_npc"] = 959310,
|
|
["character/skeleton/male/skeletonmale"] = 121942,
|
|
["character/taunka/male/taunkamale"] = 233878,
|
|
["character/tauren/female/taurenfemale"] = 121961,
|
|
["character/tauren/female/taurenfemale_hd"] = 986648,
|
|
["character/tauren/female/taurenfemale_npc"] = 986648,
|
|
["character/tauren/male/taurenmale"] = 122055,
|
|
["character/tauren/male/taurenmale_hd"] = 968705,
|
|
["character/tauren/male/taurenmale_npc"] = 968705,
|
|
["character/troll/female/trollfemale"] = 122414,
|
|
["character/troll/female/trollfemale_hd"] = 1018060,
|
|
["character/troll/female/trollfemale_npc"] = 1018060,
|
|
["character/troll/male/trollmale"] = 122560,
|
|
["character/troll/male/trollmale_hd"] = 1022938,
|
|
["character/troll/male/trollmale_npc"] = 1022938,
|
|
["character/tuskarr/male/tuskarrmale"] = 122738,
|
|
["character/vrykul/male/vrykulmale"] = 122815,
|
|
},
|
|
["HD"] = {
|
|
["character/scourge/female/scourgefemale"] = 997378,
|
|
},
|
|
}
|
|
local function CleanupModelName(model)
|
|
return model:lower():gsub("\\", "/"):gsub("%.m2", ""):gsub("%.mdx", "")
|
|
end
|
|
function ModelMixins:GetModelFileID()
|
|
local model = self:GetModel()
|
|
if model and type(model) == "string" then
|
|
model = CleanupModelName(model)
|
|
local models = modelToFileID[Utils:GetCurrentModelSet()] or modelToFileID["Original"]
|
|
return models[model] or modelToFileID["Original"][model]
|
|
end
|
|
end
|
|
end
|
|
|
|
if Version.IsLegacyWrath then
|
|
|
|
function Utils:GetQuestLogScrollOffset()
|
|
return HybridScrollFrame_GetOffset(QuestLogScrollFrame)
|
|
end
|
|
|
|
function Utils:GetQuestLogTitleFrame(index)
|
|
return _G["QuestLogScrollFrameButton" .. index]
|
|
end
|
|
|
|
function Utils:GetQuestLogTitleNormalText(index)
|
|
return _G["QuestLogScrollFrameButton" .. index .. "NormalText"]
|
|
end
|
|
|
|
function Utils:GetQuestLogTitleCheck(index)
|
|
return _G["QuestLogScrollFrameButton" .. index .. "Check"]
|
|
end
|
|
|
|
local prefix
|
|
local QuestLogTitleButton_Resize = QuestLogTitleButton_Resize
|
|
function QuestOverlayUI:UpdateQuestTitle(questLogTitleFrame, playButton, normalText, questCheck)
|
|
if not prefix then
|
|
local text = normalText:GetText()
|
|
for i = 1, 20 do
|
|
normalText:SetText(string.rep(" ", i))
|
|
if normalText:GetStringWidth() >= 24 then
|
|
prefix = normalText:GetText()
|
|
break
|
|
end
|
|
end
|
|
prefix = prefix or " "
|
|
normalText:SetText(text)
|
|
end
|
|
|
|
playButton:SetPoint("LEFT", normalText, "LEFT", 4, 0)
|
|
normalText:SetText(prefix .. (normalText:GetText() or ""):trim())
|
|
QuestLogTitleButton_Resize(questLogTitleFrame)
|
|
end
|
|
|
|
hooksecurefunc(Addon, "OnInitialize", function()
|
|
QuestLogScrollFrame.update = QuestLog_Update
|
|
end)
|
|
|
|
function Utils:WillSoundPlay(soundData)
|
|
return soundData.fileName and soundData.fileName ~= "missingSound" and soundData.length ~= nil
|
|
end
|
|
|
|
function hookModel(self)
|
|
local function HasModelLoaded(self)
|
|
local model = self:GetModel()
|
|
return model and type(model) == "string" and self:GetModelFileID() ~= 130737
|
|
end
|
|
self._sequence = 0
|
|
hooksecurefunc(self, "ClearModel", function(self)
|
|
self._awaitingModel = nil
|
|
self._camera = nil
|
|
self._sequence = 0
|
|
self._sequenceStart = nil
|
|
end)
|
|
local oldSetSequence = self.SetSequence
|
|
function self:SetSequence(sequence)
|
|
self._sequence = sequence
|
|
self._sequenceStart = GetTime()
|
|
if not self._awaitingModel then
|
|
oldSetSequence(self, sequence)
|
|
end
|
|
end
|
|
local oldSetCreature = self.SetCreature
|
|
function self:SetCreature(id)
|
|
self:ClearModel()
|
|
self:SetModel([[Interface\Buttons\TalkToMeQuestion_White.mdx]])
|
|
oldSetCreature(self, id)
|
|
self._awaitingModel = not HasModelLoaded(self)
|
|
if self._awaitingModel then
|
|
self:SetPosition(5, 0, 2)
|
|
end
|
|
end
|
|
local oldSetCamera = self.SetCamera
|
|
function self:SetCamera(id)
|
|
self._camera = id
|
|
if not self._awaitingModel then
|
|
oldSetCamera(self, id)
|
|
end
|
|
end
|
|
self:HookScript("OnUpdate", function(self, elapsed)
|
|
if self._awaitingModel and HasModelLoaded(self) then
|
|
self._awaitingModel = nil
|
|
self:SetPosition(0, 0, 0)
|
|
|
|
if self._sequence ~= 0 then
|
|
self:SetSequence(self._sequence)
|
|
end
|
|
end
|
|
if self._sequence ~= 0 and not self._awaitingModel then
|
|
self:SetSequenceTime(self._sequence, (GetTime() - self._sequenceStart) * 1000)
|
|
end
|
|
end)
|
|
end
|
|
|
|
hooksecurefunc(SoundQueueUI, "InitPortrait", function(self)
|
|
self.frame.portrait.pause:HookScript("OnEnter", function()
|
|
if self.frame.portrait.model._awaitingModel then
|
|
GameTooltip:SetOwner(self.frame.portrait.pause, "ANCHOR_NONE")
|
|
GameTooltip:SetPoint("BOTTOMLEFT", self.frame.portrait.pause, "BOTTOMRIGHT", 4, -4)
|
|
GameTooltip:SetText("Uncached NPC", HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b)
|
|
GameTooltip:AddLine("Encounter this NPC in the world again to be able to see their model.", NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
|
|
GameTooltip:Show()
|
|
end
|
|
end)
|
|
self.frame.portrait.pause:HookScript("OnLeave", GameTooltip_Hide)
|
|
end)
|
|
|
|
--[[
|
|
Here begins the code the plays the VO over music channel in order to support the ability to pause/stop the VO.
|
|
3.3.5's PlaySound/PlaySoundFile cannot be stopped by any means short of restarting the whole sound system (freezes the client for a couple of seconds).
|
|
But PlayMusic can be stopped with StopMusic. This, however, causes the currently played script music to fade out instead of cutting,
|
|
which is a problem, because by letting this happen we'll hear the VO looping until it fully fades out. This can be worked around
|
|
by PlayMusic'ing another file (even one that doesn't exist), as that causes the script music to be instantly interrupted.
|
|
Toggling Sound_EnableMusic cvar off-and-on additionally allows us to interrupt the current in-game background music.
|
|
The whole process looks as follows:
|
|
1. Sound queue requests to start playing the VO by calling Utils:PlaySound
|
|
2. Music volume is smoothly lowered to 0 over the config.FadeOutMusic duration
|
|
3. In-game background music is instantly stopped by toggling Sound_EnableMusic cvar off-and-on
|
|
4. Music volume is instantly changed to config.Volume level
|
|
5. VO sound file is played on the music channel
|
|
6. Once the VO's duration has ran out (soundData.stopSoundTimer) - silence.wav is played as music to instantly stop the VO and prevent it from looping
|
|
7. Sound queue requests to stop playing the VO by calling Utils:StopSound (either due to pause or soundData being removed from the queue) - silence.wav is played again to interrupt the VO in case it hasn't finished playing naturally
|
|
8. Music volume is instantly changed to 0
|
|
9. Music volume is smoothly raised to back to the pre-VO level over the config.FadeOutMusic duration
|
|
10. In-game background music is removed by calling StopMusic()
|
|
]]
|
|
local function GetCurrentVolume()
|
|
return tonumber(GetCVar("Sound_MusicVolume")) or 1
|
|
end
|
|
|
|
-- Functions that deal with temporarily changing player's sound settings to utilize the music channel for VO playback
|
|
local prev_Sound_EnableMusic
|
|
local prev_Sound_MusicVolume
|
|
local function ReplaceCVars()
|
|
if prev_Sound_EnableMusic == nil then
|
|
prev_Sound_EnableMusic = GetCVar("Sound_EnableMusic")
|
|
prev_Sound_MusicVolume = GetCVar("Sound_MusicVolume")
|
|
SetCVar("Sound_EnableMusic", 1)
|
|
end
|
|
end
|
|
local function RestoreCVars()
|
|
if prev_Sound_EnableMusic ~= nil then
|
|
SetCVar("Sound_EnableMusic", prev_Sound_EnableMusic)
|
|
SetCVar("Sound_MusicVolume", prev_Sound_MusicVolume)
|
|
prev_Sound_EnableMusic = nil
|
|
prev_Sound_MusicVolume = nil
|
|
end
|
|
end
|
|
|
|
-- Functions that deal with smoothly changing the music channel's volume to avoid abrupt changes
|
|
local slideVolumeTarget
|
|
local slideVolumeRate
|
|
local slideVolumeCallback
|
|
local EPS_VOLUME = 0.01
|
|
local function GetMusicFadeOutDuration()
|
|
if tonumber(prev_Sound_EnableMusic) == 0 or tonumber(prev_Sound_MusicVolume) == 0 then
|
|
return 0
|
|
end
|
|
return Addon.db.profile.LegacyWrath.PlayOnMusicChannel.FadeOutMusic or 0
|
|
end
|
|
local function StopSlideVolume()
|
|
slideVolumeTarget = nil
|
|
slideVolumeRate = nil
|
|
slideVolumeCallback = nil
|
|
end
|
|
local function SlideVolume(target, callback)
|
|
local duration = GetMusicFadeOutDuration()
|
|
if duration <= 0 then
|
|
-- Instantly change the volume if the player had reduced the duration all the way to 0
|
|
return false
|
|
end
|
|
local current = GetCurrentVolume()
|
|
if math.abs(target - current) <= EPS_VOLUME then
|
|
-- Instantly "change" the volume if it's already fuzzy-equal to the target volume, and cancel the ongoing slide volume ("remove currently played sound from queue" case)
|
|
StopSlideVolume()
|
|
return false
|
|
end
|
|
-- Interpolate towards the target volume over the configured duration
|
|
slideVolumeTarget = target
|
|
slideVolumeRate = (target - current) / duration
|
|
slideVolumeCallback = callback
|
|
return true
|
|
end
|
|
local volumeFrame = CreateFrame("Frame", "VoiceOverSlideVolumeFrame", UIParent)
|
|
volumeFrame:RegisterEvent("PLAYER_LOGOUT")
|
|
volumeFrame:HookScript("OnEvent", function(self, event)
|
|
if event == "PLAYER_LOGOUT" then
|
|
StopSlideVolume()
|
|
RestoreCVars()
|
|
end
|
|
end)
|
|
volumeFrame:HookScript("OnUpdate", function(self, elapsed)
|
|
if slideVolumeRate then
|
|
local current = GetCurrentVolume()
|
|
local target = slideVolumeTarget
|
|
local next = current + slideVolumeRate * elapsed
|
|
local finished = false
|
|
if math.abs(target - current) <= EPS_VOLUME or current < target and next >= target or current > target and next <= target then
|
|
next = target
|
|
finished = true
|
|
end
|
|
SetCVar("Sound_MusicVolume", next)
|
|
if finished then
|
|
if slideVolumeCallback then
|
|
slideVolumeCallback()
|
|
end
|
|
StopSlideVolume()
|
|
end
|
|
end
|
|
end)
|
|
|
|
function Utils:PlaySound(soundData)
|
|
soundData.delay = nil
|
|
if not Addon.db.profile.LegacyWrath.PlayOnMusicChannel.Enabled then
|
|
-- Play VO as a sound, but have no ability to stop it
|
|
_G.PlaySoundFile(soundData.filePath)
|
|
return
|
|
end
|
|
|
|
soundData.handle = 1 -- Just put something here to flag the sound as stoppable
|
|
|
|
ReplaceCVars()
|
|
local function Play()
|
|
-- Hack to instantly interrupt the music
|
|
SetCVar("Sound_EnableMusic", 0)
|
|
SetCVar("Sound_EnableMusic", 1)
|
|
|
|
SetCVar("Sound_MusicVolume", Addon.db.profile.LegacyWrath.PlayOnMusicChannel.Volume)
|
|
PlayMusic(soundData.filePath)
|
|
|
|
soundData.stopSoundTimer = Addon:ScheduleTimer(function()
|
|
PlayMusic([[Interface\AddOns\AI_VoiceOver\Sounds\silence.wav]]) -- Instantly interrupt the VO sound
|
|
end, soundData.length)
|
|
end
|
|
if SlideVolume(0, Play) then
|
|
soundData.delay = GetMusicFadeOutDuration()
|
|
else
|
|
Play()
|
|
end
|
|
end
|
|
|
|
function Utils:StopSound(soundData)
|
|
if not soundData.handle then
|
|
-- VO was played as a sound - we cannot stop it
|
|
return
|
|
end
|
|
|
|
Addon:CancelTimer(soundData.stopSoundTimer)
|
|
soundData.stopSoundTimer = nil
|
|
|
|
PlayMusic([[Interface\AddOns\AI_VoiceOver\Sounds\silence.wav]]) -- Instantly interrupt the VO sound
|
|
SetCVar("Sound_MusicVolume", 0)
|
|
|
|
local function ResumeMusic()
|
|
StopMusic()
|
|
RestoreCVars()
|
|
end
|
|
if not SlideVolume(tonumber(prev_Sound_MusicVolume) or 1, ResumeMusic) then
|
|
ResumeMusic()
|
|
end
|
|
end
|
|
|
|
-- Frame fade-in animation to help alleviate the UX damage caused by delaying the VO
|
|
hooksecurefunc(SoundQueueUI, "InitDisplay", function(self)
|
|
local fadeIn = self.frame:CreateAnimationGroup()
|
|
local animation = fadeIn:CreateAnimation("Alpha")
|
|
animation:SetOrder(1)
|
|
animation:SetDuration(0)
|
|
animation:SetChange(-1)
|
|
animation = fadeIn:CreateAnimation("Alpha")
|
|
animation:SetOrder(2)
|
|
animation:SetDuration(0.75)
|
|
animation:SetChange(1)
|
|
animation:SetSmoothing("OUT")
|
|
self.frame:HookScript("OnShow", function(self)
|
|
fadeIn:Stop()
|
|
local duration = Addon.db.profile.LegacyWrath.PlayOnMusicChannel.Enabled and GetMusicFadeOutDuration() or 0
|
|
if duration > 0 then
|
|
animation:SetDuration(duration)
|
|
fadeIn:Play()
|
|
end
|
|
end)
|
|
end)
|
|
end
|