/// <summary> /// Radio station buttons in vanilla game have multiple sprites (one for normal state, /// another one for if the button is pressed, ...). Custom stations only have a thumbnail. /// This detour method overwrites the vanilla behavior and makes is possible for /// music pack creators to only provide a thumbnail. /// </summary> /// <param name="button">Button.</param> /// <param name="station">Station.</param> private void CustomAssignStationToButton(UIButton button, RadioChannelInfo station) { UserRadioCollection collection = LoadingExtension.UserRadioContainer; UISprite iconsprite = button.Find <UISprite>("sprite"); // Additional sprite on top of the button if (iconsprite == null) { iconsprite = button.AddUIComponent <UISprite>(); iconsprite.name = "sprite"; } // Different behavior depending on if the button is displayed in the panel or in the list if (button.parent != null && button.parent.name == "StationsList") { if (ModOptions.Instance.EnableImprovedRadioStationList) { AssignStationToButtonInList(button, iconsprite, station, collection); } else { AssignStationToButtonInPanel(button, iconsprite, station, collection); } } else { AssignStationToButtonInPanel(button, iconsprite, station, collection); // if(ModOptions.Instance.EnableImprovedRadioStationList) // AddComboboxVisualClue(button, iconsprite, station); } }
/// <summary> /// Switches to the next station /// </summary> /// <returns><c>true</c>, if it was possible to switch to the next station, <c>false</c> otherwise.</returns> public static bool NextStation() { var radiopanel = Resources.FindObjectsOfTypeAll <RadioPanel>().FirstOrDefault(); if (radiopanel != null) { RadioChannelInfo current = ReflectionHelper.GetPrivateField <RadioChannelInfo>(radiopanel, "m_selectedStation"); RadioChannelInfo[] stations = ReflectionHelper.GetPrivateField <RadioChannelInfo[]>(radiopanel, "m_stations"); if (stations != null && stations.Length != 0) { int index = current != null?Array.IndexOf(stations, current) : 0; if (index == -1) { index = 0; } else { index = (index + 1) % stations.Length; } RadioChannelInfo next = stations[index]; if (next != null) { ReflectionHelper.InvokePrivateVoidMethod(radiopanel, "SelectStation", next); } } } return(false); }
private void AddComboboxVisualClue(UIButton button, UISprite iconsprite, RadioChannelInfo station) { iconsprite.position = new Vector3(23, -23); iconsprite.size = new Vector2(16, 16); iconsprite.atlas = ListAtlas; iconsprite.spriteName = "Arrow"; iconsprite.isVisible = true; }
private void DebugOutput() { for (uint i = 0; i < PrefabCollection <RadioChannelInfo> .PrefabCount(); ++i) { String message = ""; RadioChannelInfo info = PrefabCollection <RadioChannelInfo> .GetPrefab(i); if (info == null) { continue; } message += "[ChannelInfo] " + info + "\n"; message += "Schedule:\n"; if (info.m_stateChain != null) { foreach (RadioChannelInfo.State s in info.m_stateChain) { message += "\t" + s.m_contentType + " " + s.m_minCount + " - " + s.m_maxCount + "\n"; } } message += "Content:\n"; for (uint j = 0; j < PrefabCollection <RadioContentInfo> .PrefabCount(); ++j) { RadioContentInfo content = PrefabCollection <RadioContentInfo> .GetPrefab(j); if (content == null) { continue; } if (content.m_radioChannels != null) { if (content.m_radioChannels.Contains(info)) { message += "\t[ContentInfo] " + content + " " + content.m_fileName + "\n"; } } } CSLMusicMod.Log(message); } for (uint i = 0; i < PrefabCollection <DisasterInfo> .PrefabCount(); ++i) { DisasterInfo info = PrefabCollection <DisasterInfo> .GetPrefab(i); if (info == null) { continue; } CSLMusicMod.Log("[DisasterContext] Disaster name: " + info.name); } }
protected static RadioChannelInfo ClonePrefab(RadioChannelInfo originalPrefab, string newName, Transform parentTransform) { var instance = UnityEngine.Object.Instantiate(originalPrefab.gameObject); instance.name = newName; var newPrefab = instance.GetComponent <RadioChannelInfo>(); newPrefab.m_Atlas = originalPrefab.m_Atlas; newPrefab.m_Thumbnail = originalPrefab.m_Thumbnail; instance.SetActive(false); newPrefab.m_prefabInitialized = false; return(newPrefab); }
/// <summary> /// Returns the custom channel info from a vanilla channel info if available. /// Otherwise returns null. /// </summary> /// <returns>The user channel info.</returns> /// <param name="info">Info.</param> public static UserRadioChannel GetUserChannelInfo(RadioChannelInfo info) { AudioManager mgr = Singleton <AudioManager> .instance; UserRadioChannel userchannel; if (LoadingExtension.UserRadioContainer.m_UserRadioDict.TryGetValue(info, out userchannel)) { return(userchannel); } else { return(null); } }
private void RemoveUnsupportedContent() { // Apply filtering after loading for (uint i = 0; i < PrefabCollection <RadioChannelInfo> .PrefabCount(); ++i) { RadioChannelInfo info = PrefabCollection <RadioChannelInfo> .GetPrefab(i); if (info == null) { continue; } RemoveUnsupportedContent(info); } }
public static void ToggleRadio(bool enabled) { var radioPanel = GameObject.Find("RadioPanel"); if (radioPanel != null) { RadioPanel rp = radioPanel.GetComponent(typeof(RadioPanel)) as RadioPanel; if (rp != null) { var btn = rp.Find <UIButton>("RadioButton"); var pnl = rp.Find <UIPanel>("RadioPlayingPanel"); if (btn != null && pnl != null) { if (pnl.isVisible) { pnl.isVisible = enabled; } else { btn.isVisible = enabled; } bool isDisabled = !btn.isVisible && !pnl.isVisible; AudioManager AM = Singleton <AudioManager> .instance; if (isDisabled) { savedRadioInfo = AM.GetActiveRadioChannelInfo(); AM.SetActiveRadioChannel(0); } else { AM.SetActiveRadioChannelInfo(savedRadioInfo); AM.PlayAudio(AM.CurrentListenerInfo); } AM.MuteRadio = isDisabled; } } } ExtendedInfoManager.RadionVisible = PanelTimer.IsRadioToggle(); }
/// <summary> /// Collects information that is available after loading of the game /// </summary> public void CollectPostLoadingData() { for (uint i = 0; i < PrefabCollection <RadioChannelInfo> .PrefabCount(); ++i) { RadioChannelInfo info = PrefabCollection <RadioChannelInfo> .GetPrefab(i); if (info == null) { continue; } UserRadioChannel user; if (m_Stations.TryGetValue(info.name, out user)) { m_UserRadioDict[info] = user; user.m_VanillaChannelInfo = info; } } for (uint i = 0; i < PrefabCollection <RadioContentInfo> .PrefabCount(); ++i) { RadioContentInfo info = PrefabCollection <RadioContentInfo> .GetPrefab(i); if (info == null) { continue; } UserRadioContent user; if (m_Songs.TryGetValue(info.name, out user)) { m_UserContentDict[info] = user; user.m_VanillaContentInfo = info; } } }
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> /// Allows restriction of content to specific songs /// </summary> /// <returns>The collect radio content info.</returns> /// <param name="type">Type.</param> /// <param name="channel">Channel.</param> public FastList<ushort> CustomCollectRadioContentInfo(RadioContentInfo.ContentType type, RadioChannelInfo channel) { var mgr = Singleton<AudioManager>.instance; //Debug.Log("[CSLMusic][Internal] Rebuilding the radio content of channel " + channel.GetLocalizedTitle()); // CO makes some things public and other things private. This is completely insane. var m_tempRadioContentBuffer = ReflectionHelper.GetPrivateField<FastList<ushort>>(mgr, "m_tempRadioContentBuffer"); // This variable is being worked on var m_radioContentTable = ReflectionHelper.GetPrivateField<FastList<ushort>[]>(mgr, "m_radioContentTable"); m_tempRadioContentBuffer.Clear(); if (m_radioContentTable == null) { // Let's all sing the "Expensive Song!" ♬Expensive, Expensive♬ ♩OMG it's so expensive♩ (Rest of lyrics didn't load, yet) ReflectionHelper.InvokePrivateVoidMethod(mgr, "RefreshRadioContentTable"); m_radioContentTable = ReflectionHelper.GetPrivateField<FastList<ushort>[]>(mgr, "m_radioContentTable"); } // Get the allowed radio content HashSet<RadioContentInfo> disallowed_content = null; if(channel != null) { RadioContentWatcher.DisallowedContent.TryGetValue(channel, out disallowed_content); } //Debug.Log("[update]" + channel.GetLocalizedTitle() + " | " + allowed_content); /*if(allowed_content == null || allowed_content.Count == 0) { Debug.Log(channel.GetLocalizedTitle() + ": All content enabled!"); }*/ int prefabDataIndex = channel.m_prefabDataIndex; if (prefabDataIndex != -1) { int num = (int)(prefabDataIndex * 5 + type); if (num < m_radioContentTable.Length) { FastList<ushort> fastList = m_radioContentTable[num]; if (fastList != null) { for (int i = 0; i < fastList.m_size; i++) { ushort num2 = fastList.m_buffer[i]; RadioContentInfo prefab = PrefabCollection<RadioContentInfo>.GetPrefab((uint)num2); if (prefab != null && Singleton<UnlockManager>.instance.Unlocked(prefab.m_UnlockMilestone)) { // Filter only content info that should be kept if( disallowed_content == null || disallowed_content.Count == 0 || !disallowed_content.Contains(prefab)) { prefab.m_cooldown = 1000000; m_tempRadioContentBuffer.Add(num2); } } } } } } for (int j = 0; j < mgr.m_radioContents.m_size; j++) { RadioContentData.Flags flags = mgr.m_radioContents.m_buffer[j].m_flags; if ((flags & RadioContentData.Flags.Created) != RadioContentData.Flags.None) { RadioContentInfo info = mgr.m_radioContents.m_buffer[j].Info; if (info != null) { info.m_cooldown = Mathf.Min(info.m_cooldown, (int)mgr.m_radioContents.m_buffer[j].m_cooldown); } } } return m_tempRadioContentBuffer; }
private void AssignStationToButtonInList(UIButton button, UISprite iconsprite, RadioChannelInfo station, UserRadioCollection collection) { if (ModOptions.Instance.DisabledRadioStations.Contains(station.name)) { button.isVisible = false; } else { button.isVisible = true; } ((UIPanel)button.parent).autoLayoutPadding = new RectOffset(0, 0, 0, 0); button.atlas = ListAtlas; button.normalFgSprite = "ListEntryNormal"; button.hoveredFgSprite = "ListEntryHover"; button.pressedFgSprite = "ListEntryHover"; button.focusedFgSprite = "ListEntryNormal"; button.disabledFgSprite = "ListEntryNormal"; button.color = new Color32(200, 200, 200, 255); button.hoveredColor = new Color32(255, 255, 255, 255); button.tooltip = station.GetLocalizedTitle(); button.text = station.GetLocalizedTitle(); button.textColor = new Color32(255, 255, 255, 255); button.size = new Vector2(200, 20); button.textHorizontalAlignment = UIHorizontalAlignment.Left; button.textPadding = new RectOffset(25, 2, 2, 2); button.textScale = 0.75f; button.BringToFront(); iconsprite.position = new Vector3(0, 0); iconsprite.size = new Vector2(20, 20); iconsprite.atlas = station.m_Atlas; iconsprite.spriteName = station.m_Thumbnail; iconsprite.isVisible = true; }
private void AssignStationToButtonInPanel(UIButton button, UISprite iconsprite, RadioChannelInfo station, UserRadioCollection collection) { button.atlas = station.m_Atlas; if (collection != null && collection.m_Stations.ContainsKey(station.name)) { button.normalFgSprite = station.m_Thumbnail; button.hoveredFgSprite = station.m_Thumbnail; button.pressedFgSprite = station.m_Thumbnail; button.focusedFgSprite = station.m_Thumbnail; button.disabledFgSprite = station.m_Thumbnail; button.color = new Color32(225, 225, 225, 255); button.hoveredColor = new Color32(255, 255, 255, 255); button.tooltip = station.GetLocalizedTitle(); button.BringToFront(); } else { if (station.m_Thumbnail == null) { Debug.LogError("Station " + station.GetLocalizedTitle() + " has no thumbnail assigned."); } button.normalFgSprite = station.m_Thumbnail; button.hoveredFgSprite = station.m_Thumbnail + "Hovered"; button.pressedFgSprite = station.m_Thumbnail + "Pressed"; button.focusedFgSprite = station.m_Thumbnail; button.disabledFgSprite = station.m_Thumbnail + "Disabled"; button.color = new Color32(255, 255, 255, 255); button.hoveredColor = new Color32(255, 255, 255, 255); button.tooltip = station.GetLocalizedTitle(); button.BringToFront(); } button.text = ""; button.spritePadding = new RectOffset(0, 0, 0, 0); }
/// <summary> /// Adds music files that are placed in the vanilla directories to the vanilla channels /// </summary> private void ExtendVanillaContent() { if (!ModOptions.Instance.EnableAddingContentToVanillaStations) { return; } if (!ModOptions.Instance.AddVanillaSongsToMusicMix) { return; } for (uint i = 0; i < PrefabCollection <RadioChannelInfo> .PrefabCount(); ++i) { RadioChannelInfo info = PrefabCollection <RadioChannelInfo> .GetPrefab(i); if (info == null) { continue; } if (!UserRadioContainer.m_UserRadioDict.ContainsKey(info)) { // Collect existing radio content HashSet <string> existing = new HashSet <string>(); for (uint j = 0; j < PrefabCollection <RadioContentInfo> .PrefabCount(); ++j) { RadioContentInfo content = PrefabCollection <RadioContentInfo> .GetPrefab(j); if (content == null) { continue; } if (content.m_radioChannels == null) { continue; } if (content.m_radioChannels.Contains(info)) { string text = Path.Combine(DataLocation.gameContentPath, "Radio"); text = Path.Combine(text, content.m_contentType.ToString()); text = Path.Combine(text, content.m_folderName); text = Path.Combine(text, content.m_fileName); existing.Add(text); } } HashSet <string> validcollectionnames = new HashSet <string>(); foreach (RadioContentInfo.ContentType type in Enum.GetValues(typeof(RadioContentInfo.ContentType))) { validcollectionnames.Add(type + ": " + info.name); } // Check our collection for non-existing files foreach (UserRadioContent usercontent in UserRadioContainer.m_Songs.Values) { if (!existing.Contains(usercontent.m_FileName) && validcollectionnames.Contains(usercontent.m_Collection)) { CSLMusicMod.Log("[ExtendedVanillaContent] Adding " + usercontent.m_FileName + " to vanilla station " + info.name); List <RadioChannelInfo> v = GenericHelper.CopyOrCreateList <RadioChannelInfo>(usercontent.m_VanillaContentInfo.m_radioChannels); v.Add(info); usercontent.m_VanillaContentInfo.m_radioChannels = v.ToArray(); } } } } }
/// <summary> /// Removes disabled content from this channel. /// </summary> /// <param name="info">Info.</param> private void RemoveUnsupportedContent(RadioChannelInfo info) { if (info == null) { return; } if (info.m_stateChain == null) { return; } CSLMusicMod.Log("Removing unsupported content from " + info); var options = ModOptions.Instance; List <RadioChannelInfo.State> states = new List <RadioChannelInfo.State>(info.m_stateChain); states.RemoveAll((RadioChannelInfo.State obj) => { switch (obj.m_contentType) { case RadioContentInfo.ContentType.Blurb: if (!options.AllowContentBlurb) { return(true); } break; case RadioContentInfo.ContentType.Broadcast: if (!options.AllowContentBroadcast) { return(true); } break; case RadioContentInfo.ContentType.Commercial: if (!options.AllowContentCommercial) { return(true); } break; case RadioContentInfo.ContentType.Music: if (!options.AllowContentMusic) { return(true); } break; case RadioContentInfo.ContentType.Talk: if (!options.AllowContentTalk) { return(true); } break; } return(false); }); info.m_stateChain = states.ToArray(); }