public override void CreateModMenuSection(TextMenu menu, bool inGame, EventInstance snapshot) { base.CreateModMenuSection(menu, inGame, snapshot); // this could maybe be refactored into a helper function with some generics magic foreach (var item in menu.Items) { if (!(item is TextMenu.Button btn) || !btn.Label.StartsWith(Dialog.Clean("modoptions_bingoclient_playername"))) { continue; } var messageHeader = new TextMenuExt.EaseInSubHeaderExt(Dialog.Clean("modoptions_bingoclient_playername_about"), false, menu) { HeightExtra = 17f, Offset = new Vector2(30, -5), }; menu.Insert(menu.Items.IndexOf(item) + 1, messageHeader); btn.OnEnter = () => messageHeader.FadeVisible = true; btn.OnLeave = () => messageHeader.FadeVisible = false; break; } foreach (var item in menu.Items) { if (!(item is TextMenu.OnOff btn) || !btn.Label.StartsWith(Dialog.Clean("modoptions_bingoclient_claimassist"))) { continue; } var messageHeader = new TextMenuExt.EaseInSubHeaderExt(Dialog.Clean("modoptions_bingoclient_claimassist_about"), false, menu) { HeightExtra = 17f, Offset = new Vector2(30, -5), }; menu.Insert(menu.Items.IndexOf(item) + 1, messageHeader); btn.OnEnter = () => messageHeader.FadeVisible = true; btn.OnLeave = () => messageHeader.FadeVisible = false; break; } if (this.Password != null && !this.Connected) { var retryBtn = new TextMenu.Button(Dialog.Clean("modoptions_bingoclient_reconnect")); retryBtn.OnPressed = () => { this.Connect(); }; menu.Add(retryBtn); } if (this.Connected) { var disconnectBtn = new TextMenu.Button(Dialog.Clean("modoptions_bingoclient_disconnect")); disconnectBtn.OnPressed = () => { this.Disconnect(); }; menu.Add(disconnectBtn); } }
/// <summary> /// Add an Enter and Leave handler, displaying a description if selected. /// </summary> /// <param name="option">The input TextMenu.Item option.</param> /// <param name="containingMenu">The menu containing the TextMenu.Item option.</param> /// <param name="description"></param> /// <returns>The passed option.</returns> public static TextMenu.Item AddDescription(this TextMenu.Item option, TextMenu containingMenu, string description) { // build the description menu entry TextMenuExt.EaseInSubHeaderExt descriptionText = new TextMenuExt.EaseInSubHeaderExt(description, false, containingMenu) { TextColor = Color.Gray, HeightExtra = 0f }; List <TextMenu.Item> items = containingMenu.GetItems(); if (items.Contains(option)) { // insert the description after the option. containingMenu.Insert(items.IndexOf(option) + 1, descriptionText); } option.OnEnter += delegate { // make the description appear. descriptionText.FadeVisible = true; }; option.OnLeave += delegate { // make the description disappear. descriptionText.FadeVisible = false; }; return(option); }
/// <summary> /// Add an Enter and Leave handler, notifying the user that a relaunch is required to apply the changes. /// </summary> /// <param name="option">The input TextMenu.Item option.</param> /// <param name="containingMenu">The menu containing the TextMenu.Item option.</param> /// <param name="needsRelaunch">This method does nothing if this is set to false.</param> /// <returns>The passed option.</returns> public static TextMenu.Item NeedsRelaunch(this TextMenu.Item option, TextMenu containingMenu, bool needsRelaunch = true) { if (!needsRelaunch) { return(option); } // build the "Restart is required" text menu entry TextMenuExt.EaseInSubHeaderExt needsRelaunchText = new TextMenuExt.EaseInSubHeaderExt(Dialog.Clean("MODOPTIONS_NEEDSRELAUNCH"), false, containingMenu) { TextColor = Color.OrangeRed, HeightExtra = 0f }; List <TextMenu.Item> items = containingMenu.GetItems(); if (items.Contains(option)) { // insert the text after the option that needs relaunch. containingMenu.Insert(items.IndexOf(option) + 1, needsRelaunchText); } option.OnEnter += delegate { // make the description appear. needsRelaunchText.FadeVisible = true; }; option.OnLeave += delegate { // make the description disappear. needsRelaunchText.FadeVisible = false; }; return(option); }
private static void onCreatePauseMenuButtons(Level level, TextMenu menu, bool minimal) { if (CollabModule.Instance.Session.LobbySID != null) { // find the position just under "Return to Map". int returnToMapIndex = menu.GetItems().FindIndex(item => item.GetType() == typeof(TextMenu.Button) && ((TextMenu.Button)item).Label == Dialog.Clean("MENU_PAUSE_RETURN")); if (returnToMapIndex == -1) { // fall back to the bottom of the menu. returnToMapIndex = menu.GetItems().Count - 1; } // add the "Return to Lobby" button TextMenu.Button returnToLobbyButton = new TextMenu.Button(Dialog.Clean("collabutils2_returntolobby")); returnToLobbyButton.Pressed(() => { level.PauseMainMenuOpen = false; menu.RemoveSelf(); openReturnToLobbyConfirmMenu(level, menu.Selection); }); returnToLobbyButton.ConfirmSfx = "event:/ui/main/message_confirm"; menu.Insert(returnToMapIndex + 1, returnToLobbyButton); } }
public void CreatePauseMenuButtons(Level level, TextMenu menu, bool minimal) { if (Everest.Flags.IsDisabled || !Settings.ShowModOptionsInGame) { return; } List <TextMenu.Item> items = menu.GetItems(); int index; // Find the options button and place our button below it. string cleanedOptions = Dialog.Clean("menu_pause_options"); index = items.FindIndex(_ => { TextMenu.Button other = (_ as TextMenu.Button); if (other == null) { return(false); } return(other.Label == cleanedOptions); }); if (index != -1) { index++; } // Otherwise, place it below the last button. else { index = items.Count; } TextMenu.Item itemModOptions = null; menu.Insert(index, itemModOptions = new TextMenu.Button(Dialog.Clean("menu_pause_modoptions")).Pressed(() => { int returnIndex = menu.IndexOf(itemModOptions); menu.RemoveSelf(); level.PauseMainMenuOpen = false; level.Paused = true; TextMenu options = OuiModOptions.CreateMenu(true, LevelExt.PauseSnapshot); options.OnESC = options.OnCancel = () => { Audio.Play(Sfxs.ui_main_button_back); options.CloseAndRun(Everest.SaveSettings(), () => level.Pause(returnIndex, minimal, false)); }; options.OnPause = () => { Audio.Play(Sfxs.ui_main_button_back); options.CloseAndRun(Everest.SaveSettings(), () => { level.Paused = false; Engine.FreezeTimer = 0.15f; }); }; level.Add(options); })); }
public void CreateOpenBackupFolderEntry(TextMenu textMenu, bool inGame) { TextMenu.Item item = new TextMenu.Button(DialogId.Options.OpenBackupFolder.DialogClean()) .Pressed(() => { try { string backupPath = Modules.InfiniteBackups.BackupPath; if (!Directory.Exists(backupPath)) { Directory.CreateDirectory(backupPath); } Process.Start(backupPath); } catch (Exception err) { LogUtil.Log("Open backup folder failed!", LogLevel.Warn); err.LogDetailed(); TextMenu.Item openBackupFolder = menuItems[DialogId.Options.OpenBackupFolder]; TextMenu.Item openFailed = menuItems[DialogId.Subtext.OpenBackupFolderFailed]; if (!textMenu.Items.Contains(openFailed)) { textMenu.Insert(textMenu.IndexOf(openBackupFolder) + 1, openFailed); } } }); textMenu.Add(item); menuItems.Add(DialogId.Options.OpenBackupFolder, item); // split the string into multiple lines to prevent off-screen menus caused by long path string[] descriptionLines = string.Format(DialogId.Subtext.BackupLocation.DialogGet(), Path.GetFullPath(Modules.InfiniteBackups.BackupPath)).SplitIntoFixedLength(50); TextMenuExt.EaseInSubHeaderExt backupLocationSubtext = new TextMenuExt.EaseInSubHeaderExt(string.Join("\n", descriptionLines), false, textMenu) { TextColor = Color.Gray }; // increase the height and make it vertical align backupLocationSubtext.HeightExtra = (backupLocationSubtext.Title.Split('\n').Length - 1) * ActiveFont.LineHeight * 0.6f; backupLocationSubtext.Offset = new Vector2(0f, -Math.Max(0f, -16f + backupLocationSubtext.HeightExtra) + textMenu.ItemSpacing); textMenu.Add(backupLocationSubtext); TextMenuExt.EaseInSubHeaderExt openFailedSubtext = new TextMenuExt.EaseInSubHeaderExt(DialogId.Subtext.OpenBackupFolderFailed.DialogClean(), false, textMenu) { TextColor = Color.OrangeRed, HeightExtra = 0f }; item.OnEnter += delegate { openFailedSubtext.FadeVisible = true; backupLocationSubtext.FadeVisible = true; }; item.OnLeave += delegate { openFailedSubtext.FadeVisible = false; backupLocationSubtext.FadeVisible = false; }; menuItems.Add(DialogId.Subtext.BackupLocation, backupLocationSubtext); menuItems.Add(DialogId.Subtext.OpenBackupFolderFailed, openFailedSubtext); }
private void onCreatePauseMenuButtons(Level level, TextMenu menu, bool minimal) { int optionsIndex = menu.GetItems().FindIndex(item => item.GetType() == typeof(TextMenu.Button) && ((TextMenu.Button)item).Label == Dialog.Clean("menu_pause_options")); // insert ourselves just before Options if required (this is below Variants if variant mode is enabled) if (Settings.OptionsOutOfModOptionsMenuEnabled) { menu.Insert(optionsIndex, AbstractSubmenu.BuildOpenMenuButton <OuiExtendedVariantsSubmenu>(menu, true, null /* this is not used when in-game anyway */, new object[] { true })); } }
public override void CreateModMenuSection(TextMenu menu, bool inGame, EventInstance snapshot) { // Optional - reload mod settings when entering the mod options. // LoadSettings(); base.CreateModMenuSection(menu, inGame, snapshot); if (!inGame) { List <TextMenu.Item> items = menu.GetItems(); // change the "key config" labels (items[items.Count - 2] as TextMenu.Button).Label = Dialog.Clean("MODOPTIONS_COREMODULE_KEYCONFIG") + " " + (items[items.Count - 2] as TextMenu.Button).Label; (items[items.Count - 1] as TextMenu.Button).Label = Dialog.Clean("MODOPTIONS_COREMODULE_KEYCONFIG") + " " + (items[items.Count - 1] as TextMenu.Button).Label; // insert extra options before the "key config" options menu.Insert(items.Count - 2, new TextMenu.Button(Dialog.Clean("modoptions_coremodule_oobe")).Pressed(() => { OuiModOptions.Instance.Overworld.Goto <OuiOOBE>(); })); menu.Insert(items.Count - 2, new TextMenu.Button(Dialog.Clean("modoptions_coremodule_soundtest")).Pressed(() => { OuiModOptions.Instance.Overworld.Goto <OuiSoundTest>(); })); menu.Insert(items.Count - 2, new TextMenu.Button(Dialog.Clean("modoptions_coremodule_versionlist")).Pressed(() => { OuiModOptions.Instance.Overworld.Goto <OuiVersionList>(); })); menu.Insert(items.Count - 2, new TextMenu.Button(Dialog.Clean("modoptions_coremodule_modupdates")).Pressed(() => { OuiModOptions.Instance.Overworld.Goto <OuiModUpdateList>(); })); menu.Insert(items.Count - 2, new TextMenu.Button(Dialog.Clean("modoptions_coremodule_togglemods")).Pressed(() => { OuiModOptions.Instance.Overworld.Goto <OuiModToggler>(); })); } }
private void OnPause(Level level, TextMenu menu, bool minimal) { void tweakVariantsMenu(TextMenu.Button btn, int idx) { var messageHeader = new TextMenuExt.EaseInSubHeaderExt(Dialog.Clean("bingoclient_variants_warning"), false, menu) { HeightExtra = 17f, Offset = new Vector2(30, -5), }; var oldAction = btn.OnPressed; btn.OnPressed = () => { this.ModSession.CheckpointStartedVariant = null; oldAction?.Invoke(); }; btn.OnEnter = () => messageHeader.FadeVisible = true; btn.OnLeave = () => messageHeader.FadeVisible = false; menu.Insert(idx + 1, messageHeader); } for (int i = 0; i < menu.Items.Count; i++) { var item = menu.Items[i]; if (!(item is TextMenu.Button btn)) { continue; } if (btn.Label == Dialog.Clean("menu_pause_variant") || btn.Label == Dialog.Clean("modoptions_extendedvariants_pausemenu_button")) { tweakVariantsMenu(btn, i); } } }
public void CreatePauseMenuButtons(Level level, TextMenu menu, bool minimal) { if (Everest.Flags.IsDisabled || !Settings.ShowModOptionsInGame) { return; } List <TextMenu.Item> items = menu.GetItems(); int index; // Find the options button and place our button below it. string cleanedOptions = Dialog.Clean("menu_pause_options"); index = items.FindIndex(_ => { TextMenu.Button other = (_ as TextMenu.Button); if (other == null) { return(false); } return(other.Label == cleanedOptions); }); if (index != -1) { index++; } // Otherwise, place it below the last button. else { index = items.Count; } TextMenu.Item itemModOptions = null; menu.Insert(index, itemModOptions = new TextMenu.Button(Dialog.Clean("menu_pause_modoptions")).Pressed(() => { int returnIndex = menu.IndexOf(itemModOptions); menu.RemoveSelf(); level.PauseMainMenuOpen = false; level.Paused = true; TextMenu options = OuiModOptions.CreateMenu(true, LevelExt.PauseSnapshot); options.OnESC = options.OnCancel = () => { Audio.Play(SFX.ui_main_button_back); options.CloseAndRun(Everest.SaveSettings(), () => { level.Pause(returnIndex, minimal, false); // adjust the Mod Options menu position, in case it moved (pause menu entries added/removed after changing mod options). TextMenu textMenu = level.Entities.GetToAdd().FirstOrDefault((Entity e) => e is TextMenu) as TextMenu; TextMenu.Button modOptionsButton = textMenu?.GetItems().OfType <TextMenu.Button>() .FirstOrDefault(button => button.Label == Dialog.Clean("menu_pause_modoptions")); if (modOptionsButton != null) { textMenu.Selection = textMenu.IndexOf(modOptionsButton); } }); }; options.OnPause = () => { Audio.Play(SFX.ui_main_button_back); options.CloseAndRun(Everest.SaveSettings(), () => { level.Paused = false; Engine.FreezeTimer = 0.15f; }); }; level.Add(options); })); }
private void ReloadMenu() { menu = new TextMenu { new TextMenu.Header(Dialog.Clean("MODOPTIONS_RANDOMIZER_MAPPICKER_HEADER")), new TextMenu.Button(Dialog.Clean("MODOPTIONS_RANDOMIZER_MAPPICKER_TOGGLEALL")).Pressed(() => { var items = menu.GetItems(); TextMenu.OnOff firstToggle = null; foreach (var item in items) { if (item is TextMenu.OnOff) { firstToggle = item as TextMenu.OnOff; break; } } if (firstToggle == null) { // ??? return; } var newValue = 1 - firstToggle.Index; for (int i = 0; i < items.Count; i++) { if (items[i] is TextMenu.OnOff toggle) { toggle.Index = newValue; toggle.OnValueChange(toggle.Values[newValue].Item2); } } }), }; var lvlCount = new Dictionary <RandoSettings.AreaKeyNotStupid, int>(); foreach (var room in RandoLogic.AllRooms) { var notstupid = new RandoSettings.AreaKeyNotStupid(room.Area); if (lvlCount.TryGetValue(notstupid, out int c)) { lvlCount[notstupid] = c + 1; } else { lvlCount[notstupid] = 1; } } string currentSet = null; foreach (var key in RandoLogic.AvailableAreas) { var area = AreaData.Get(key); var mode = AreaData.GetMode(key); if (currentSet != area.GetLevelSet()) { currentSet = area.GetLevelSet(); menu.Add(new TextMenu.SubHeader(DialogExt.CleanLevelSet(currentSet))); } var on = Settings.MapIncluded(key); var name = area.Name; name = name.DialogCleanOrNull() ?? name.SpacedPascalCase(); if (key.Mode != AreaMode.Normal || (area.Mode.Length != 1 && area.Mode[1] != null)) { name += " " + Char.ToString((char)('A' + (int)key.Mode)); } menu.Add(new TextMenu.OnOff(name, on).Change(this.MakeChangeFunc(key))); menu.Add(new TextMenuExt.SubHeaderExt(lvlCount[new RandoSettings.AreaKeyNotStupid(key)].ToString() + " " + Dialog.Clean("MODOPTIONS_RANDOMIZER_MAPPICKER_LEVELS")) { HeightExtra = -10f, Offset = new Vector2(30, -5), }); } if (currentSet != "Celeste") { menu.Insert(2, new TextMenu.Button(Dialog.Clean("MODOPTIONS_RANDOMIZER_MAPPICKER_RESET")).Pressed(() => { Settings.SetNormalMaps(); // this is a stupid way to do this int levelsetIdx = -1; foreach (var item in menu.GetItems()) { if (item is TextMenu.SubHeader && !(item is TextMenuExt.SubHeaderExt)) { levelsetIdx++; } else if (item is TextMenu.OnOff toggle) { toggle.Index = levelsetIdx == 0 ? 1 : 0; } } })); } Scene.Add(menu); }
private void ReloadMenu() { menu = new TextMenu { new TextMenu.Header(Dialog.Clean("MODOPTIONS_RANDOMIZER_MAPPICKER_HEADER")), new TextMenu.Button(Dialog.Clean("MODOPTIONS_RANDOMIZER_MAPPICKER_TOGGLEALL")).Pressed(() => { var items = menu.GetItems(); TextMenu.OnOff firstToggle = null; foreach (var item in items) { if (item is TextMenu.OnOff) { firstToggle = item as TextMenu.OnOff; break; } } if (firstToggle == null) { // ??? return; } var newValue = 1 - firstToggle.Index; for (int i = 0; i < items.Count; i++) { if (items[i] is TextMenu.OnOff toggle) { toggle.Index = newValue; toggle.OnValueChange(toggle.Values[newValue].Item2); } } }), }; // Create submenu for Celeste, campaigns, then other levelsets AddLevelSetMenu("Celeste"); List <string> completedLevelSets = new List <string> { "Celeste" }; var campaigns = RandoModule.Instance.MetaConfig.Campaigns; foreach (RandoMetadataCampaign campaign in campaigns) { menu.Add(new TextMenu.SubHeader(DialogExt.CleanLevelSet(campaign.Name))); foreach (RandoMetadataLevelSet levelSet in campaign.LevelSets) { var name = levelSet.Name; if (RandoLogic.LevelSets.TryGetValue(levelSet.ID, out var keys)) { AddLevelSetToggle(name, keys); completedLevelSets.Add(levelSet.ID); } } } foreach (string levelSet in RandoLogic.LevelSets.Keys) { if (!completedLevelSets.Contains(levelSet)) { AddLevelSetMenu(levelSet); } } // If Celeste is not the only levelset, Reset should turn all other levelsets off if (RandoLogic.LevelSets.Count > 1) { menu.Insert(2, new TextMenu.Button(Dialog.Clean("MODOPTIONS_RANDOMIZER_MAPPICKER_RESET")).Pressed(() => { Settings.SetNormalMaps(); // this is a stupid way to do this int levelsetIdx = -1; foreach (var item in menu.GetItems()) { if (item is TextMenu.SubHeader && !(item is TextMenuExt.SubHeaderExt)) { levelsetIdx++; } else if (item is TextMenu.OnOff toggle) { toggle.Index = levelsetIdx == 0 ? 1 : 0; } } })); } Scene.Add(menu); }