/// <summary> /// Switches to the next track, but smooth /// This does NOT work as intended without RadioContentWatcher's ApplySmoothTransition! /// </summary> /// <returns><c>true</c>, if track smooth was nexted, <c>false</c> otherwise.</returns> public static bool NextTrack_Smooth() { AudioManager mgr = Singleton <AudioManager> .instance; // musicFileIsRadio is false if no radio channel is active. We cannot // do anything in this case. if (ReflectionHelper.GetPrivateField <bool>(mgr, "m_musicFileIsRadio")) { ushort activechannel = ReflectionHelper.GetPrivateField <ushort>(mgr, "m_activeRadioChannel"); if (activechannel >= 0) { RadioChannelData data = mgr.m_radioChannels[activechannel]; data.m_currentContent = 0; mgr.m_radioChannels[activechannel] = data; return(true); } else { return(false); } } else { return(true); } }
/// <summary> /// Returns the currently active channel data /// </summary> /// <returns>The active channel.</returns> public static RadioChannelData?GetActiveChannelData() { AudioManager mgr = Singleton <AudioManager> .instance; ushort activechannel = ReflectionHelper.GetPrivateField <ushort>(mgr, "m_activeRadioChannel"); if (activechannel >= 0) { RadioChannelData data = mgr.m_radioChannels[activechannel]; return(data); } else { return(null); } }
/// <summary> /// Tells the vanilla radio system to issue a rebuild of the internal song list of the active channel /// </summary> /// <returns><c>true</c>, if track with rebuild was nexted, <c>false</c> otherwise.</returns> public static bool TriggerRebuildInternalSongList() { // Note: there is GetActiveChannelData. But radio channels are structs, so we need to access directly. AudioManager mgr = Singleton <AudioManager> .instance; ushort activechannel = ReflectionHelper.GetPrivateField <ushort>(mgr, "m_activeRadioChannel"); if (activechannel >= 0) { RadioChannelData data = mgr.m_radioChannels[activechannel]; data.m_nextContent = 0; mgr.m_radioChannels[activechannel] = data; // Did you know that you don't need this in C++? return(true); } else { return(false); } }
private void RebuildList() { AudioManager mgr = Singleton <AudioManager> .instance; ushort activechannel = ReflectionHelper.GetPrivateField <ushort>(mgr, "m_activeRadioChannel"); //Debug.Log("Selected active channel " + activechannel + " of " + mgr.m_radioChannelCount); //Dictionary<RadioContentInfo, String> entrytexts = new Dictionary<RadioContentInfo, string>(); if (activechannel >= 0) { RadioChannelData channeldata = mgr.m_radioChannels[activechannel]; RadioChannelInfo info = channeldata.Info; m_CurrentContent.Clear(); if (info != null) { // Only show supported content entries HashSet <RadioContentInfo.ContentType> supported_content = new HashSet <RadioContentInfo.ContentType>(); foreach (var state in info.m_stateChain) { supported_content.Add(state.m_contentType); } for (uint i = 0; i < PrefabCollection <RadioContentInfo> .PrefabCount(); ++i) { var c = PrefabCollection <RadioContentInfo> .GetPrefab(i); if (c == null) { continue; } if (c.m_radioChannels == null) { continue; } if (supported_content.Contains(c.m_contentType) && c.m_radioChannels.Contains(info)) { //entrytexts[c] = GetEntryTextFor(c); //if(!IsFiltered(entrytexts[c])) if (!IsFiltered(AudioManagerHelper.GetContentName(c))) { m_CurrentContent.Add(c); } } } } m_RadioChannelInfo.isVisible = m_CurrentContent.Count == 0; //Debug.Log(m_CurrentContent.Count + " entries "); } m_CurrentContent.Sort((RadioContentInfo x, RadioContentInfo y) => { if (m_SortAscending) { //return string.Compare(entrytexts[x], entrytexts[y], StringComparison.CurrentCulture); return(string.Compare(AudioManagerHelper.GetContentName(x), AudioManagerHelper.GetContentName(y), StringComparison.CurrentCulture)); } else { //return string.Compare(entrytexts[y], entrytexts[x], StringComparison.CurrentCulture); return(string.Compare(AudioManagerHelper.GetContentName(y), AudioManagerHelper.GetContentName(x), StringComparison.CurrentCulture)); } }); RefreshListWidget(); }
/// <summary> /// Switches to a specific radio content (music) /// </summary> /// <returns><c>true</c>, if the switch was successful, <c>false</c> otherwise.</returns> /// <param name="info">Info.</param> public static bool SwitchToContent(RadioContentInfo info) { AudioManager mgr = Singleton <AudioManager> .instance; // musicFileIsRadio is false if no radio channel is active. We cannot // do anything in this case. if (ReflectionHelper.GetPrivateField <bool>(mgr, "m_musicFileIsRadio")) { ushort contentindex = 0; bool found = false; for (int i = 0; i < mgr.m_radioContentCount; ++i) { RadioContentData data = mgr.m_radioContents[i]; //Debug.Log("CC: " + data + " + " + data.Info + " == " + info); if (data.Info == info) { contentindex = (ushort)i; //Debug.Log("Found content index for " + info); found = true; break; } } if (!found) { CSLMusicMod.Log("Switching to unloaded music " + info); if (!mgr.CreateRadioContent(out contentindex, info)) { CSLMusicMod.Log("... failed to create content " + info); return(false); } } CSLMusicMod.Log("Radio switches to track " + info); //Debug.Log("Content index: " + contentindex); // Next content ushort activechannel = ReflectionHelper.GetPrivateField <ushort>(mgr, "m_activeRadioChannel"); if (activechannel >= 0) { RadioChannelData data = mgr.m_radioChannels[activechannel]; data.m_currentContent = contentindex; //data.m_nextContent = contentindex; mgr.m_radioChannels[activechannel] = data; //mgr.m_radioChannels[activechannel].ChangeContent(activechannel); return(true); } //var player = ReflectionHelper.GetPrivateField<AudioManager.AudioPlayer>(mgr, "m_currentRadioPlayer"); //player.m_source.Stop(); return(false); } else { return(false); } }
/// <summary> /// Rebuilds the allowed content for a channel. /// </summary> /// <param name="channel">Channel.</param> private void RebuildDisallowedContentForChannel(RadioChannelData channel) { if (channel.Info == null) { return; } HashSet <RadioContentInfo> disallowed; if (!DisallowedContent.TryGetValue(channel.Info, out disallowed)) { disallowed = new HashSet <RadioContentInfo>(); DisallowedContent[channel.Info] = disallowed; } else { disallowed.Clear(); } UserRadioChannel userchannel = AudioManagerHelper.GetUserChannelInfo(channel.Info); if (userchannel != null) { // If the channel is a custom channel, we can check for context and for content disabling // The method returns NULL if all songs apply! var allowedsongs = userchannel.GetApplyingSongs(); if (allowedsongs == null) { if (ModOptions.Instance.EnableDisabledContent && ModOptions.Instance.DisabledContent.Count != 0) { foreach (UserRadioContent usercontent in userchannel.m_Content) { if (usercontent.m_VanillaContentInfo != null) { bool isenabled = (!ModOptions.Instance.EnableDisabledContent || AudioManagerHelper.ContentIsEnabled(usercontent.m_VanillaContentInfo)); if (!isenabled) { disallowed.Add(usercontent.m_VanillaContentInfo); } } } } } else { foreach (UserRadioContent usercontent in userchannel.m_Content) { if (usercontent.m_VanillaContentInfo != null) { bool isincontext = (!ModOptions.Instance.EnableContextSensitivity || allowedsongs.Contains(usercontent)); bool isenabled = (!ModOptions.Instance.EnableDisabledContent || AudioManagerHelper.ContentIsEnabled(usercontent.m_VanillaContentInfo)); if (!isincontext || !isenabled) { disallowed.Add(usercontent.m_VanillaContentInfo); } } } } } else { // If the channel is a vanilla channel, we can still disable content AudioManager mgr = Singleton <AudioManager> .instance; if (mgr.m_radioContents.m_size > 0) { for (int i = 0; i < mgr.m_radioContents.m_size; ++i) { var content = mgr.m_radioContents[i]; if (content.Info != null && content.Info.m_radioChannels != null && content.Info.m_radioChannels.Contains(channel.Info)) { if (!AudioManagerHelper.ContentIsEnabled(content.Info)) { disallowed.Add(content.Info); } } } } } }