private void OnReturnedToTitle(object sender, ReturnedToTitleEventArgs e) { Helper.Events.GameLoop.UpdateTicked -= OnUpdateTicked; Helper.Events.Input.ButtonPressed -= OnButtonPressed; SpeechHandlerPolly.stop(); }
private void setUpNPCConfig() { var npcs = Helper.Content.Load <Dictionary <string, string> >("Data//NPCDispositions", ContentSource.GameContent); if (!config.Voices.ContainsKey("Default")) { config.Voices.Add("Default", new VoiceSetup() { Voice = SpeechHandlerPolly.getVoice("default", true) }); } foreach (string npc in npcs.Keys) { if (!config.Voices.ContainsKey(npc)) { config.Voices.Add(npc, new VoiceSetup() { Voice = SpeechHandlerPolly.getVoice(npc, npcs[npc].Contains("female")) }); } } config.Rate = Math.Max(50, Math.Min(config.Rate, 200)); Helper.WriteConfig <ModConfig>(config); }
private void OnSaveLoaded(object sender, SaveLoadedEventArgs e) { Helper.Events.GameLoop.DayStarted += OnDayStarted; SpeechHandlerPolly.Monitor = Monitor; SpeechHandlerPolly.start(Helper); Helper.Events.GameLoop.UpdateTicked += OnUpdateTicked; Helper.Events.Input.ButtonPressed += OnButtonPressed; }
private void SaveEvents_AfterReturnToTitle(object sender, EventArgs e) { GameEvents.OneSecondTick -= GameEvents_OneSecondTick; ControlEvents.KeyPressed -= ControlEvents_KeyPressed; ModConfig config = Helper.ReadConfig <ModConfig>(); if (config.polly == "on" && pollySetup) { SpeechHandlerPolly.stop(); } else { SpeechHandler.stop(); } }
private void GameLoop_GameLaunched(object sender, GameLaunchedEventArgs e) { var npcs = Helper.Content.Load <Dictionary <string, string> >("Data//NPCDispositions", ContentSource.GameContent); foreach (string npc in npcs.Keys) { if (!config.Voices.ContainsKey(npc)) { config.Voices.Add(npc, new VoiceSetup() { Voice = SpeechHandlerPolly.getVoice(npc, npcs[npc].Contains("female")) }); } } Helper.WriteConfig <ModConfig>(config); setUpConfig(); }
private void SaveEvents_AfterLoad(object sender, EventArgs e) { TimeEvents.DayOfMonthChanged += TimeEvents_DayOfMonthChanged; ModConfig config = Helper.ReadConfig <ModConfig>(); if (config.polly == "on" && pollySetup) { SpeechHandlerPolly.Monitor = Monitor; SpeechHandlerPolly.start(Helper); } else { SpeechHandler.start(Helper, Monitor); } GameEvents.OneSecondTick += GameEvents_OneSecondTick; // VoiceControl.start(Monitor); ControlEvents.KeyPressed += ControlEvents_KeyPressed; }
private void SaveEvents_AfterLoad(object sender, EventArgs e) { pollySetup = false; checkPollySetup(); TimeEvents.AfterDayStarted += TimeEvents_AfterDayStarted; ModConfig config = Helper.ReadConfig <ModConfig>(); if (config.polly == "on" && pollySetup) { SpeechHandlerPolly.Monitor = Monitor; SpeechHandlerPolly.start(Helper); } else { SpeechHandler.start(Helper, Monitor); } GameEvents.OneSecondTick += GameEvents_OneSecondTick; ControlEvents.KeyPressed += ControlEvents_KeyPressed; }
private void Display_Rendered(object sender, StardewModdingAPI.Events.RenderedEventArgs e) { PelicanTTSMod._helper.Events.Display.Rendered -= Display_Rendered; shouldRead = false; if (capture == null || capture.Length == 0) { if (capturedTitle.Length > 0) { capture = capturedTitle + ": " + capturedContent; } else { capture = capturedContent; } } if (capture != null && capture != "") { SpeechHandlerPolly.configSay("Default", PelicanTTSMod.config.Voices["Default"]?.Voice ?? "Salli", capture); } }
public static bool UpdateGMCM(object __instance, ref bool __state) { if (!IsThisPage) { return(true); } List <string> choices = new List <string>((string[])__instance.GetType().GetProperty("Choices").GetValue(__instance)); if (!choices[0].Contains(":default")) { return(true); } if (!currentIndex.ContainsKey(__instance)) { currentIndex.Add(__instance, 0); } bool dropped = (bool)__instance.GetType().GetField("dropped").GetValue(__instance); Vector2 pos = (Vector2)__instance.GetType().GetProperty("Position").GetValue(__instance); int aChoice = (int)__instance.GetType().GetProperty("ActiveChoice").GetValue(__instance); object callback = __instance.GetType().GetField("Callback").GetValue(__instance); object parent = __instance.GetType().GetProperty("Parent").GetValue(__instance); MouseState state; int num; if (new Rectangle((int)pos.X, (int)pos.Y, 300, 44).Contains(Game1.getOldMouseX(), Game1.getOldMouseY()) && Game1.oldMouseState.LeftButton == ButtonState.Released) { state = Mouse.GetState(); num = state.LeftButton == ButtonState.Pressed ? 1 : 0; } else { num = 0; } if (num != 0) { __instance.GetType().GetField("dropped").SetValue(__instance, true); parent.GetType().GetProperty("RenderLast").SetValue(parent, __instance); } if (!dropped) { currentIndex[__instance] = Math.Min(aChoice, choices.Count - maxValues); } if (!dropped) { return(false); } state = Mouse.GetState(); if (state.LeftButton == ButtonState.Released) { __instance.GetType().GetField("dropped").SetValue(__instance, false); if (parent.GetType().GetProperty("RenderLast").GetValue(parent) == __instance) { parent.GetType().GetProperty("RenderLast").SetValue(parent, null); } string value = (string)__instance.GetType().GetProperty("Value").GetValue(__instance); string cname = choices[0].Split(':')[0]; if (value == choices[0]) { value = SpeechHandlerPolly.getVoice(cname); } var mvs = activeVoiceSetup.Values.First(avs => avs.Name == choices[0].Split(':')[0]); var intro = choices[0].Split(':')[0]; if (intro == "Default") { intro = i18n.Get("FestivalGreeting"); } else { var dialogues = _helper.Content.Load <Dictionary <string, string> >(@"Characters/Dialogue/" + intro, ContentSource.GameContent); if (dialogues != null && dialogues.ContainsKey("Introduction")) { intro = dialogues["Introduction"].Split('^')[0].Split('#')[0].Replace("@", ""); } } SpeechHandlerPolly.configSay(choices[0].Split(':')[0], value, intro, activeRate, mvs is MenuVoiceSetup ? mvs.Pitch : -1, activeVolume); } if (new Rectangle((int)pos.X, (int)pos.Y, 300, 44 * maxValues).Contains(Game1.getOldMouseX(), Game1.getOldMouseY())) { int idx = ((Game1.getOldMouseY() - (int)pos.Y) / 44) + currentIndex[__instance]; idx = Math.Min(idx, choices.Count - 1); __instance.GetType().GetProperty("ActiveChoice").SetValue(__instance, idx); if (callback != null) { try { callback.GetType().GetMethod("Invoke").Invoke(callback, new[] { __instance }); } catch { } } } return(false); }
public void setUpConfig() { Harmony instance = new Harmony("PelicanTTS.GMCM"); // instance.Patch(typeof(ChatBox).GetMethod("receiveChatMessage"), prefix: new HarmonyMethod(typeof(PelicanTTSMod).GetMethod("receiveChatMessage"))); if (!Helper.ModRegistry.IsLoaded("spacechase0.GenericModConfigMenu")) { return; } var cVoices = voices[LocalizedContentManager.CurrentLanguageCode]; var eVoices = new List <string>(); foreach (var lang in voices.Where(v => v.Key != LocalizedContentManager.CurrentLanguageCode)) { foreach (var voice in lang.Value.Where(v => !cVoices.Contains(v))) { eVoices.Add(voice + "*"); } } foreach (var voice in others.Where(v => !cVoices.Contains(v) && !eVoices.Contains(v + "*"))) { eVoices.Add(voice + "*"); } cVoices.AddRange(eVoices.OrderBy(v => v).Where(v => !cVoices.Contains(v))); maxValues = Math.Min(cVoices.Count + 1, 7); activeVoiceSetup = new Dictionary <string, MenuVoiceSetup>(); var api = Helper.ModRegistry.GetApi <IGMCMAPI>("spacechase0.GenericModConfigMenu"); api.RegisterModConfig(ModManifest, () => { config.Greeting = true; config.MumbleDialogues = false; config.Pitch = 0; config.Volume = 1; config.Rate = 100; config.ReadDialogues = true; config.ReadHudMessages = true; config.ReadLetters = true; config.ReadNonCharacterMessages = true; config.ReadScreenKey = SButton.N; config.LanguageCode = SpeechHandlerPolly.getLanguageCode(true); //config.ReadChatMessages = true; var npcs = Helper.Content.Load <Dictionary <string, string> >("Data//NPCDispositions", ContentSource.GameContent); foreach (var voice in config.Voices.Keys) { config.Voices[voice].Pitch = 0; if (npcs.ContainsKey(voice)) { config.Voices[voice].Voice = SpeechHandlerPolly.getVoice(voice, npcs[voice].Contains("female")); } } }, () => Helper.WriteConfig <ModConfig>(config)); api.RegisterLabel(ModManifest, MainLabelText, ""); api.RegisterSimpleOption(ModManifest, "Mumbling", "Should all NPCs mumble", () => config.MumbleDialogues, (s) => config.MumbleDialogues = s); api.RegisterSimpleOption(ModManifest, "Greeting", "Enables the morning greeting", () => config.Greeting, (s) => config.Greeting = s); api.RegisterSimpleOption(ModManifest, "Read Character Dialogues", "", () => config.ReadDialogues, (s) => config.ReadDialogues = s); api.RegisterSimpleOption(ModManifest, "Read Non-Character Messages", "", () => config.ReadNonCharacterMessages, (s) => config.ReadNonCharacterMessages = s); api.RegisterSimpleOption(ModManifest, "Read Letters", "", () => config.ReadLetters, (s) => config.ReadLetters = s); api.RegisterSimpleOption(ModManifest, "Read Hud Messages", "", () => config.ReadHudMessages, (s) => config.ReadHudMessages = s); api.RegisterSimpleOption(ModManifest, "Read Screen Key", "", () => config.ReadScreenKey, (s) => config.ReadScreenKey = s); api.RegisterSimpleOption(ModManifest, "Language Code", "", () => config.LanguageCode, (s) => config.LanguageCode = s); // api.RegisterSimpleOption(ModManifest, "Read Chat Messages", "", () => config.ReadChatMessages, (s) => config.ReadChatMessages = s); api.RegisterSimpleOption(ModManifest, "Neural Voices", "", () => config.UseNeuralVoices, (s) => config.UseNeuralVoices = s); api.RegisterChoiceOption(ModManifest, "Server", "", () => config.Server, (s) => { config.Server = s; activeEndpoint = endPoints[s]; SpeechHandlerPolly.pc = null; }, endPoints.Keys.ToArray()); api.RegisterClampedOption(ModManifest, "Volume", "Set Volume", () => { activeVolume = config.Volume; return(config.Volume); }, (s) => { config.Volume = (float)Math.Ceiling((double)(s * 100)) / 100f; }, 0, 1); api.RegisterClampedOption(ModManifest, "Rate", "Set Rate (20-200%)", () => { activeRate = config.Rate; return(config.Rate); }, (s) => { config.Rate = (int)s; }, 50, 200); /* instance.Patch(Type.GetType("GenericModConfigMenu.UI.Dropdown, GenericModConfigMenu").GetMethod("Update"), new HarmonyMethod(typeof(PelicanTTSMod).GetMethod("UpdateGMCM"))); * instance.Patch(Type.GetType("GenericModConfigMenu.UI.Dropdown, GenericModConfigMenu").GetMethod("Draw"), new HarmonyMethod(typeof(PelicanTTSMod).GetMethod("DrawGMCM"))); * instance.Patch(Type.GetType("GenericModConfigMenu.UI.Table, GenericModConfigMenu").GetMethod("Update"), new HarmonyMethod(typeof(PelicanTTSMod).GetMethod("UpdateTableGMCM"))); * instance.Patch(Type.GetType("GenericModConfigMenu.UI.Scrollbar, GenericModConfigMenu").GetMethod("Scroll"), new HarmonyMethod(typeof(PelicanTTSMod).GetMethod("ScrollGMCM"))); */ Helper.Events.Input.MouseWheelScrolled += (s, e) => { List <object> obj = new List <object>(); foreach (var dropDown in currentIndex.Keys.Where(k => ((bool)k.GetType().GetField("dropped").GetValue(k)))) { obj.Add(dropDown); currentIndex[dropDown] -= e.Delta / 120; currentIndex[dropDown] = Math.Max(currentIndex[dropDown], 0); break; } }; api.RegisterLabel(ModManifest, "Voices", "Set the voices for each NPC"); int index = 2; foreach (var npc in config.Voices.Keys.OrderBy(k => k)) { if (!activeVoiceSetup.ContainsKey(npc)) { activeVoiceSetup.Add(npc, new MenuVoiceSetup()); } activeVoiceSetup[npc].Index = index; activeVoiceSetup[npc].Name = npc; List <string> npcVoices = new List <string>() { npc + ":default" }; npcVoices.AddRange(cVoices); api.RegisterChoiceOption(ModManifest, npc + " Voice", "Choose a voice", () => { Game1.stopMusicTrack(Game1.MusicContext.Default); if (config.Voices[npc].Voice.Contains("default")) { return(npc + ":default"); } activeVoiceSetup[npc].Voice = config.Voices[npc].Voice; string voice = config.Voices[npc].Voice; if (!voices[LocalizedContentManager.CurrentLanguageCode].Contains(voice)) { return(voice + "*"); } return(voice); }, (s) => { config.Voices[npc].Voice = s.Replace(npc + ":", "").Replace("*", ""); activeVoiceSetup[npc].Voice = config.Voices[npc].Voice; currentName = npc; }, npcVoices.ToArray()); api.RegisterClampedOption(ModManifest, npc + " Pitch", "Choose a Pitch", () => config.Voices[npc].Pitch, (s) => { config.Voices[npc].Pitch = (float)Math.Ceiling((double)(s * 100)) / 100f; activeVoiceSetup[npc].Pitch = config.Voices[npc].Pitch; }, -1, 1); index++; } for (int i = 0; i < 12; i++) { api.RegisterLabel(ModManifest, " ", " "); } api.SubscribeToChange(ModManifest, new Action <string, string>((key, value) => { if (key.EndsWith("Voice")) { string character = key.Split(' ')[0]; if (value == "Default") { value = SpeechHandlerPolly.getVoice(character); } var mvs = activeVoiceSetup.Values.FirstOrDefault(avs => avs.Name == character); value = value.Replace("*", ""); var intro = character; if (intro == "Default") { intro = i18n.Get("FestivalGreeting"); } else { var dialogues = _helper.Content.Load <Dictionary <string, string> >(@"Characters/Dialogue/" + character, ContentSource.GameContent); if (dialogues != null && dialogues.ContainsKey("Introduction")) { intro = dialogues["Introduction"].Split('^')[0].Split('#')[0].Replace("@", ""); if (intro.Length < 7) { intro = dialogues["Mon"].Split('^')[0].Split('#')[0].Replace("@", ""); } } } SpeechHandlerPolly.configSay(character, value, intro, activeRate, mvs is MenuVoiceSetup ? mvs.Pitch : -1, activeVolume); } })); api.SubscribeToChange(ModManifest, new Action <string, int>((key, value) => { if (key.Contains("Rate")) { activeRate = value; } })); api.SubscribeToChange(ModManifest, new Action <string, float>((key, value) => { if (key.EndsWith("Pitch")) { string character = key.Split(' ')[0]; var mvs = activeVoiceSetup.Values.First(avs => avs.Name == character); mvs.Pitch = (float)Math.Ceiling((double)(value * 100)) / 100f; } else if (key.Contains("Volume")) { activeVolume = (float)Math.Ceiling((double)(value * 100)) / 100f; } })); }
public void setUpConfig() { if (!Helper.ModRegistry.IsLoaded("spacechase0.GenericModConfigMenu")) { return; } HarmonyInstance instance = HarmonyInstance.Create("PelicanTTS.GMCM"); var api = Helper.ModRegistry.GetApi <IGMCMAPI>("spacechase0.GenericModConfigMenu"); api.RegisterModConfig(ModManifest, () => { config.Greeting = true; config.MumbleDialogues = false; config.Pitch = 0; config.Volume = 1; var npcs = Helper.Content.Load <Dictionary <string, string> >("Data//NPCDispositions", ContentSource.GameContent); foreach (var voice in config.Voices.Keys) { config.Voices[voice].Pitch = 0; if (npcs.ContainsKey(voice)) { config.Voices[voice].Voice = SpeechHandlerPolly.getVoice(voice, npcs[voice].Contains("female")); } } }, () => Helper.WriteConfig <ModConfig>(config)); api.RegisterSimpleOption(ModManifest, "Mumbling", "Should all NPCs mumble", () => config.MumbleDialogues, (s) => config.MumbleDialogues = s); api.RegisterSimpleOption(ModManifest, "Greeting", "Enables the morning greeting", () => config.Greeting, (s) => config.Greeting = s); api.RegisterClampedOption(ModManifest, "Volume", "Set Volume", () => config.Volume, (s) => { config.Volume = (float)Math.Ceiling((double)(s * 100)) / 100f; }, 0, 1); if (PelicanTTSMod.i18n.LocaleEnum == LocalizedContentManager.LanguageCode.en) { instance.Patch(Type.GetType("GenericModConfigMenu.UI.Dropdown, GenericModConfigMenu").GetMethod("Update"), new HarmonyMethod(typeof(PelicanTTSMod).GetMethod("UpdateGMCM"))); instance.Patch(Type.GetType("GenericModConfigMenu.UI.Dropdown, GenericModConfigMenu").GetMethod("Draw"), new HarmonyMethod(typeof(PelicanTTSMod).GetMethod("DrawGMCM"))); Helper.Events.Input.MouseWheelScrolled += (s, e) => { List <object> obj = new List <object>(); foreach (var dropDown in currentIndex.Keys.Where(k => ((bool)k.GetType().GetField("dropped").GetValue(k)))) { obj.Add(dropDown); currentIndex[dropDown] -= e.Delta / 120; currentIndex[dropDown] = Math.Max(currentIndex[dropDown], 0); break; } }; foreach (var npc in config.Voices.Keys.OrderBy(k => k)) { List <string> npcVoices = new List <string>() { npc + ":default" }; npcVoices.AddRange(voices); api.RegisterChoiceOption(ModManifest, npc + " Voice", "Choose a voice", () => { Game1.stopMusicTrack(Game1.MusicContext.Default); if (config.Voices[npc].Voice.Contains("default")) { return(npc + ":default"); } return(config.Voices[npc].Voice); }, (s) => { config.Voices[npc].Voice = s.Replace(npc + ":", ""); currentName = npc; }, npcVoices.ToArray()); api.RegisterClampedOption(ModManifest, npc + " Pitch", "Choose a Pitch", () => config.Voices[npc].Pitch, (s) => { config.Voices[npc].Pitch = (float)Math.Ceiling((double)(s * 100)) / 100f; }, -1, 1); } for (int i = 0; i < 12; i++) { api.RegisterClampedOption(ModManifest, " ", " ", () => 0, (s) => { }, 0, 0); } } }
public static bool UpdateGMCM(object __instance, ref bool __state) { List <string> choices = new List <string>((string[])__instance.GetType().GetProperty("Choices").GetValue(__instance)); if (!choices[0].Contains(":default")) { return(true); } if (!currentIndex.ContainsKey(__instance)) { currentIndex.Add(__instance, 0); } bool dropped = (bool)__instance.GetType().GetField("dropped").GetValue(__instance); Vector2 pos = (Vector2)__instance.GetType().GetProperty("Position").GetValue(__instance); int aChoice = (int)__instance.GetType().GetProperty("ActiveChoice").GetValue(__instance); object callback = __instance.GetType().GetField("Callback").GetValue(__instance); object parent = __instance.GetType().GetProperty("Parent").GetValue(__instance); MouseState state; int num; if (new Rectangle((int)pos.X, (int)pos.Y, 300, 44).Contains(Game1.getOldMouseX(), Game1.getOldMouseY()) && Game1.oldMouseState.LeftButton == ButtonState.Released) { state = Mouse.GetState(); num = state.LeftButton == ButtonState.Pressed ? 1 : 0; } else { num = 0; } if (num != 0) { __instance.GetType().GetField("dropped").SetValue(__instance, true); parent.GetType().GetProperty("RenderLast").SetValue(parent, __instance); } if (!dropped) { currentIndex[__instance] = Math.Min(aChoice, choices.Count - maxValues); } if (!dropped) { return(false); } state = Mouse.GetState(); if (state.LeftButton == ButtonState.Released) { __instance.GetType().GetField("dropped").SetValue(__instance, false); if (parent.GetType().GetProperty("RenderLast").GetValue(parent) == __instance) { parent.GetType().GetProperty("RenderLast").SetValue(parent, null); } string value = (string)__instance.GetType().GetProperty("Value").GetValue(__instance); string cname = choices[0].Split(':')[0]; if (value == choices[0]) { value = SpeechHandlerPolly.getVoice(cname); } SpeechHandlerPolly.configSay(choices[0].Split(':')[0], value, "Hi, my name is " + choices[0].Split(':')[0] + "."); } if (new Rectangle((int)pos.X, (int)pos.Y, 300, 44 * maxValues).Contains(Game1.getOldMouseX(), Game1.getOldMouseY())) { int idx = ((Game1.getOldMouseY() - (int)pos.Y) / 44) + currentIndex[__instance]; idx = Math.Min(idx, choices.Count - 1); __instance.GetType().GetProperty("ActiveChoice").SetValue(__instance, idx); if (callback != null) { try { callback.GetType().GetMethod("Invoke").Invoke(callback, new[] { __instance }); } catch { } } } return(false); }
public void setUpConfig() { HarmonyInstance instance = HarmonyInstance.Create("PelicanTTS.GMCM"); // instance.Patch(typeof(ChatBox).GetMethod("receiveChatMessage"), prefix: new HarmonyMethod(typeof(PelicanTTSMod).GetMethod("receiveChatMessage"))); if (!Helper.ModRegistry.IsLoaded("spacechase0.GenericModConfigMenu")) { return; } var cVoices = voices[LocalizedContentManager.LanguageCode.en]; if (voices.ContainsKey(Helper.Translation.LocaleEnum)) { cVoices = voices[Helper.Translation.LocaleEnum]; } maxValues = Math.Min(cVoices.Count + 1, 7); activeVoiceSetup = new Dictionary <string, MenuVoiceSetup>(); var api = Helper.ModRegistry.GetApi <IGMCMAPI>("spacechase0.GenericModConfigMenu"); api.RegisterModConfig(ModManifest, () => { config.Greeting = true; config.MumbleDialogues = false; config.Pitch = 0; config.Volume = 1; config.Rate = 100; config.ReadDialogues = true; config.ReadHudMessages = true; config.ReadLetters = true; config.ReadNonCharacterMessages = true; //config.ReadChatMessages = true; var npcs = Helper.Content.Load <Dictionary <string, string> >("Data//NPCDispositions", ContentSource.GameContent); foreach (var voice in config.Voices.Keys) { config.Voices[voice].Pitch = 0; if (npcs.ContainsKey(voice)) { config.Voices[voice].Voice = SpeechHandlerPolly.getVoice(voice, npcs[voice].Contains("female")); } } }, () => Helper.WriteConfig <ModConfig>(config)); api.RegisterLabel(ModManifest, MainLabelText, ""); api.RegisterSimpleOption(ModManifest, "Mumbling", "Should all NPCs mumble", () => config.MumbleDialogues, (s) => config.MumbleDialogues = s); api.RegisterSimpleOption(ModManifest, "Greeting", "Enables the morning greeting", () => config.Greeting, (s) => config.Greeting = s); api.RegisterSimpleOption(ModManifest, "Read Character Dialogues", "", () => config.ReadDialogues, (s) => config.ReadDialogues = s); api.RegisterSimpleOption(ModManifest, "Read Non-Character Messages", "", () => config.ReadNonCharacterMessages, (s) => config.ReadNonCharacterMessages = s); api.RegisterSimpleOption(ModManifest, "Read Letters", "", () => config.ReadLetters, (s) => config.ReadLetters = s); api.RegisterSimpleOption(ModManifest, "Read Hud Messages", "", () => config.ReadHudMessages, (s) => config.ReadHudMessages = s); // api.RegisterSimpleOption(ModManifest, "Read Chat Messages", "", () => config.ReadChatMessages, (s) => config.ReadChatMessages = s); api.RegisterClampedOption(ModManifest, "Volume", "Set Volume", () => { activeVolume = config.Volume; return(config.Volume); }, (s) => { config.Volume = (float)Math.Ceiling((double)(s * 100)) / 100f; }, 0, 1); api.RegisterClampedOption(ModManifest, "Rate", "Set Rate (20-200%)", () => { activeRate = config.Rate; return(config.Rate); }, (s) => { config.Rate = (int)s; }, 50, 200); instance.Patch(Type.GetType("GenericModConfigMenu.UI.Dropdown, GenericModConfigMenu").GetMethod("Update"), new HarmonyMethod(typeof(PelicanTTSMod).GetMethod("UpdateGMCM"))); instance.Patch(Type.GetType("GenericModConfigMenu.UI.Dropdown, GenericModConfigMenu").GetMethod("Draw"), new HarmonyMethod(typeof(PelicanTTSMod).GetMethod("DrawGMCM"))); instance.Patch(Type.GetType("GenericModConfigMenu.UI.Table, GenericModConfigMenu").GetMethod("Update"), new HarmonyMethod(typeof(PelicanTTSMod).GetMethod("UpdateTableGMCM"))); instance.Patch(Type.GetType("GenericModConfigMenu.UI.Scrollbar, GenericModConfigMenu").GetMethod("Scroll"), new HarmonyMethod(typeof(PelicanTTSMod).GetMethod("ScrollGMCM"))); Helper.Events.Input.MouseWheelScrolled += (s, e) => { List <object> obj = new List <object>(); foreach (var dropDown in currentIndex.Keys.Where(k => ((bool)k.GetType().GetField("dropped").GetValue(k)))) { obj.Add(dropDown); currentIndex[dropDown] -= e.Delta / 120; currentIndex[dropDown] = Math.Max(currentIndex[dropDown], 0); break; } }; api.RegisterLabel(ModManifest, "Voices", "Set the voices for each NPC"); int index = 2; foreach (var npc in config.Voices.Keys.OrderBy(k => k)) { if (!activeVoiceSetup.ContainsKey(npc)) { activeVoiceSetup.Add(npc, new MenuVoiceSetup()); } activeVoiceSetup[npc].Index = index; activeVoiceSetup[npc].Name = npc; List <string> npcVoices = new List <string>() { npc + ":default" }; npcVoices.AddRange(cVoices); api.RegisterChoiceOption(ModManifest, npc + " Voice", "Choose a voice", () => { Game1.stopMusicTrack(Game1.MusicContext.Default); if (config.Voices[npc].Voice.Contains("default")) { return(npc + ":default"); } activeVoiceSetup[npc].Voice = config.Voices[npc].Voice; return(config.Voices[npc].Voice); }, (s) => { config.Voices[npc].Voice = s.Replace(npc + ":", ""); activeVoiceSetup[npc].Voice = config.Voices[npc].Voice; currentName = npc; }, npcVoices.ToArray()); api.RegisterClampedOption(ModManifest, npc + " Pitch", "Choose a Pitch", () => config.Voices[npc].Pitch, (s) => { config.Voices[npc].Pitch = (float)Math.Ceiling((double)(s * 100)) / 100f; activeVoiceSetup[npc].Pitch = config.Voices[npc].Pitch; }, -1, 1); index++; } for (int i = 0; i < 12; i++) { api.RegisterLabel(ModManifest, " ", " "); } }