예제 #1
0
        private void EndlessCantRestartSnarky(On.Celeste.Level.orig_GiveUp orig, Level self, int returnIndex, bool restartArea, bool minimal, bool showHint)
        {
            var settings = this.InRandomizerSettings;

            if (settings == null || settings.Algorithm != LogicType.Endless || !restartArea)
            {
                orig(self, returnIndex, restartArea, minimal, showHint);
                return;
            }

            self.Paused = true;
            var menu = new TextMenu()
            {
                new TextMenu.Header(Dialog.Clean("MENU_CANTRESTART_HEADER")),
            };

            menu.AutoScroll = false;
            menu.OnPause    = menu.OnESC = () => {
                menu.RemoveSelf();
                self.Paused        = false;
                Engine.FreezeTimer = 0.15f;
                Audio.Play("event:/ui/game/unpause");
            };
            menu.OnCancel = () => {
                Audio.Play("event:/ui/main/button_back");
                menu.RemoveSelf();
                self.Pause(returnIndex, minimal);
            };
            self.Add(menu);
        }
예제 #2
0
        private void ModifyLevelMenu(Level level, TextMenu pausemenu, bool minimal)
        {
            if (this.InRandomizer)
            {
                foreach (var item in new System.Collections.Generic.List <TextMenu.Item>(pausemenu.GetItems()))
                {
                    if (item.GetType() == typeof(TextMenu.Button))
                    {
                        var btn = (TextMenu.Button)item;
                        if (btn.Label == Dialog.Clean("MENU_PAUSE_SAVEQUIT") || btn.Label == Dialog.Clean("MENU_PAUSE_RETURN"))
                        {
                            pausemenu.Remove(item);
                        }
                        if (btn.Label == Dialog.Clean("MENU_PAUSE_RESTARTAREA"))
                        {
                            btn.Label = Dialog.Clean("MENU_PAUSE_RESTARTRANDO");
                        }
                    }
                }

                int returnIdx = pausemenu.GetItems().Count;
                pausemenu.Add(new TextMenu.Button(Dialog.Clean("MENU_PAUSE_QUITRANDO")).Pressed(() => {
                    level.PauseMainMenuOpen = false;
                    pausemenu.RemoveSelf();

                    TextMenu menu   = new TextMenu();
                    menu.AutoScroll = false;
                    menu.Position   = new Vector2((float)Engine.Width / 2f, (float)((double)Engine.Height / 2.0 - 100.0));
                    menu.Add(new TextMenu.Header(Dialog.Clean("MENU_QUITRANDO_TITLE")));
                    menu.Add(new TextMenu.Button(Dialog.Clean("MENU_QUITRANDO_CONFIRM")).Pressed((Action)(() => {
                        Engine.TimeRate = 1f;
                        menu.Focused = false;
                        level.Session.InArea = false;
                        Audio.SetMusic((string)null, true, true);
                        Audio.BusStopAll("bus:/gameplay_sfx", true);
                        level.DoScreenWipe(false, (Action)(() => Engine.Scene = (Scene) new LevelExit(LevelExit.Mode.SaveAndQuit, level.Session, level.HiresSnow)), true);
                        foreach (LevelEndingHook component in level.Tracker.GetComponents <LevelEndingHook>())
                        {
                            if (component.OnEnd != null)
                            {
                                component.OnEnd();
                            }
                        }
                    })));
                    menu.Add(new TextMenu.Button(Dialog.Clean("MENU_QUITRANDO_CANCEL")).Pressed((Action)(() => menu.OnCancel())));
                    menu.OnPause = menu.OnESC = (Action)(() => {
                        menu.RemoveSelf();
                        level.Paused = false;
                        Engine.FreezeTimer = 0.15f;
                        Audio.Play("event:/ui/game/unpause");
                    });
                    menu.OnCancel = (Action)(() => {
                        Audio.Play("event:/ui/main/button_back");
                        menu.RemoveSelf();
                        level.Pause(returnIdx, minimal, false);
                    });
                    level.Add((Entity)menu);
                }));
            }
        }
 private void CloseMenu()
 {
     ResumeSfx();
     Audio.Play("event:/ui/game/unpause");
     if (menu != null)
     {
         menu.RemoveSelf();
     }
     menu = null;
 }
예제 #4
0
 private void CloseMenu()
 {
     Audio.Play(SFX.ui_game_unpause);
     Audio.Resume(sfx);
     menu?.RemoveSelf();
     menu = null;
 }
        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);
            }
        }
예제 #6
0
        public override IEnumerator Leave(Oui next)
        {
            if (!Everest.Flags.IsDisabled)
            {
                TextInput.OnInput -= OnTextInput;
            }

            menu.Focused = false;

            Audio.Play(SFX.ui_main_whoosh_large_out);

            if (Overworld != null)
            {
                Overworld.Maddy.Show = true;
                Overworld.Mountain.EaseCamera(Overworld.Mountain.Area, cameraStart, 0.4f);
            }

            for (float p = 0f; p < 1f; p += Engine.DeltaTime * 4f)
            {
                menu.X = onScreenX + 1920f * Ease.CubeIn(p);
                alpha  = 1f - Ease.CubeIn(p);
                yield return(null);
            }

            menu.Visible = Visible = false;
            menu.RemoveSelf();
            menu = null;
        }
예제 #7
0
        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);
            }));
        }
예제 #8
0
        private void StartGame()
        {
            textCoroutine = null;
            StopSfx();
            session.Audio.Music.Event = areaMusic;

            if (menu != null)
            {
                menu.RemoveSelf();
                menu = null;
            }

            new FadeWipe(this, false, () => Engine.Scene = new LevelLoader(session))
            .OnUpdate = (f) => textAlpha = Math.Min(textAlpha, 1f - f);

            started = true;
            exiting = true;
        }
        /// <summary>
        ///     Method getting called on the Oui instance when the method just above is called.
        /// </summary>
        ///
        private TextMenuButtonExt buildOpenMenuButton(TextMenu parentMenu, bool inGame)
        {
            if (inGame)
            {
                // this is how it works in-game
                return((TextMenuButtonExt) new TextMenuButtonExt(getButtonName()).Pressed(() => {
                    Level level = Engine.Scene as Level;
                    // close the parent menu
                    parentMenu.RemoveSelf();

                    // create our menu and prepare it
                    TextMenu thisMenu = buildMenu(true);

                    // notify the pause menu that we aren't in the main menu anymore (hides the strawberry tracker)
                    bool comesFromPauseMainMenu = level.PauseMainMenuOpen;
                    level.PauseMainMenuOpen = false;

                    thisMenu.OnESC = thisMenu.OnCancel = () => {
                        // close this menu
                        Audio.Play(SFX.ui_main_button_back);

                        StrawberryToolModule.Instance.SaveSettings();
                        thisMenu.Close();

                        // and open the parent menu back (this should work, right? we only removed it from the scene earlier, but it still exists and is intact)
                        // "what could possibly go wrong?" ~ famous last words
                        level.Add(parentMenu);

                        // restore the pause "main menu" flag to make strawberry tracker appear again if required.
                        level.PauseMainMenuOpen = comesFromPauseMainMenu;
                    };

                    thisMenu.OnPause = () => {
                        // we're unpausing, so close that menu, and save the mod Settings because the Mod Options menu won't do that for us
                        Audio.Play(SFX.ui_main_button_back);

                        StrawberryToolModule.Instance.SaveSettings();
                        thisMenu.Close();

                        level.Paused = false;
                        Engine.FreezeTimer = 0.15f;
                    };

                    // finally, add the menu to the scene
                    level.Add(thisMenu);
                }));
            }

            // this is how it works in the main menu: way more simply than the in-game mess.
            return((TextMenuButtonExt) new TextMenuButtonExt(getButtonName()).Pressed(() => {
                gotoMenu(OuiModOptions.Instance.Overworld);
            }));
        }
예제 #10
0
        public override IEnumerator Leave(Oui next)
        {
            Audio.Play(SFX.ui_main_whoosh_large_out);
            menu.Focused = false;

            for (float p = 0f; p < 1f; p += Engine.DeltaTime * 4f)
            {
                menu.X = onScreenX + 1920f * Ease.CubeIn(p);
                alpha  = 1f - Ease.CubeIn(p);
                yield return(null);
            }

            menu.Visible = Visible = false;
            menu.RemoveSelf();
            menu = null;
        }
예제 #11
0
        public override IEnumerator Leave(Oui next)
        {
            Audio.Play("event:/ui/main/whoosh_large_out");
            Overworld.Maddy.Show = true;
            menu.Focused         = false;

            for (float p = 0f; p < 1f; p += Engine.DeltaTime * 4f)
            {
                menu.X = onScreenX + 1920f * Ease.CubeIn(p);
                alpha  = 1f - Ease.CubeIn(p);
                yield return(null);
            }

            menu.Visible = Visible = false;
            menu.RemoveSelf();
            menu = null;
        }
        public override IEnumerator Leave(Oui next)
        {
            Audio.Play(SFX.ui_main_whoosh_large_out);
            menu.Focused = false;

            // save the menu position in case we want to restore it.
            savedMenuIndex = menu.Selection;

            for (float p = 0f; p < 1f; p += Engine.DeltaTime * 4f)
            {
                menu.X = onScreenX + 1920f * Ease.CubeIn(p);
                alpha  = 1f - Ease.CubeIn(p);
                yield return(null);
            }

            menu.Visible = Visible = false;
            menu.RemoveSelf();
            menu = null;
        }
예제 #13
0
        // Set up any hooks, event handlers and your mod in general here.
        // Load runs before Celeste itself has initialized properly.
        public override void Load()
        {
            // Stuff that runs orig(self) always
            /* ************************************************ */
            Everest.Events.Level.OnLoadEntity += Level_OnLoadEntity;
            Everest.Events.Level.OnLoadLevel  += (level, playerIntro, isFromLoader) => this.level = level;
            DreamBlockRNGSyncer.Load();
            MinigameInfinityTrigger.Load();
            On.Celeste.LevelEnter.Go += (orig, session, fromSaveData) => {
                if (IsSIDMadelineParty(session.Area.GetSID()) && !session.Level.Equals(START_ROOM))
                {
                    session.Level        = START_ROOM;
                    session.RespawnPoint = session.GetSpawnPoint(Vector2.Zero);
                    //Player player = level.Tracker.GetEntity<Player>();
                    //sendToStart(player);
                }
                orig(session, fromSaveData);
            };
            On.Celeste.Player.Update     += Player_Update;
            On.Celeste.Level.UnloadLevel += (orig, self) => {
                if (IsSIDMadelineParty(self.Session.Area.GetSID()))
                {
                    TextMenu menu = self.Entities.FindFirst <TextMenu>();
                    if (menu != null)
                    {
                        self.PauseMainMenuOpen = false;
                        menu.RemoveSelf();
                        self.Paused = false;
                    }
                }
                orig(self);
            };
            MinigameSwitchGatherer.Load();
            BoardController.Load();
            TiebreakerController.Load();
            PersistentMiniTextbox.Load();
            TextMenuPlus.Load();

            MultiplayerSingleton.Instance.RegisterHandler <Party>(HandleParty);
            MultiplayerSingleton.Instance.RegisterHandler <MinigameEnd>(HandleMinigameEnd);
            MultiplayerSingleton.Instance.RegisterHandler <MinigameStatus>(HandleMinigameStatus);
            MultiplayerSingleton.Instance.RegisterHandler <RandomSeed>(HandleRandomSeed);
        }
예제 #14
0
        private static void onCreatePauseMenuButtons(Level level, TextMenu menu, bool minimal)
        {
            // create the Restart Speed Berry option at the bottom of the menu
            SpeedBerry berry;

            if ((berry = level.Tracker.GetEntity <SpeedBerry>()) != null && berry.Follower.HasLeader && !minimal)
            {
                TextMenu.Button item = new TextMenu.Button(Dialog.Clean("collabutils2_restartspeedberry"))
                {
                    OnPressed = () => {
                        level.Paused            = false;
                        level.PauseMainMenuOpen = false;
                        menu.RemoveSelf();
                        berry.TimeRanOut = true;
                    }
                };
                menu.Add(item);
            }
        }
예제 #15
0
        public override IEnumerator Leave(Oui next)
        {
            Audio.Play(SFX.ui_main_whoosh_large_out);
            menu.Focused = false;

            for (float p = 0f; p < 1f; p += Engine.DeltaTime * 4f)
            {
                menu.X = onScreenX + 1920f * Ease.CubeIn(p);
                alpha  = 1f - Ease.CubeIn(p);
                yield return(null);
            }

            menu.Visible = Visible = false;
            menu.RemoveSelf();
            menu = null;

            updateCatalog           = null;
            availableUpdatesCatalog = new SortedDictionary <ModUpdateInfo, EverestModuleMetadata>();
            task = null;
        }
예제 #16
0
파일: OuiOOBE.cs 프로젝트: max4805/Everest
        private IEnumerator GotoTransition(TextMenu target, bool back = false)
        {
            Audio.Play(SFX.ui_main_whoosh_list_in);

            TextMenu menuOld = menu;

            menuOld.Visible = true;
            menuOld.Focused = false;

            step         = new DynData <TextMenu>(target).Get <int>("oobeStep");
            menu         = target;
            menu.Visible = true;
            menu.Focused = false;
            Scene.Add(menu);

            if (back)
            {
                for (float p = 0f; p < 1f; p += Engine.DeltaTime * 4f)
                {
                    menuOld.X = onScreenX + 1920f * Ease.CubeInOut(p);
                    menu.X    = offScreenLeftX + 1920f * Ease.CubeInOut(p);
                    yield return(null);
                }
            }
            else
            {
                for (float p = 0f; p < 1f; p += Engine.DeltaTime * 4f)
                {
                    menuOld.X = onScreenX - 1920f * Ease.CubeInOut(p);
                    menu.X    = offScreenRightX - 1920f * Ease.CubeInOut(p);
                    yield return(null);
                }
            }

            menuOld.Visible = false;
            menuOld.RemoveSelf();

            menu.Focused = true;
        }
예제 #17
0
파일: OuiOOBE.cs 프로젝트: max4805/Everest
        public override IEnumerator Leave(Oui next)
        {
            Audio.Play(SFX.ui_main_whoosh_large_out);
            menu.Focused = false;

            if (fromModOptions)
            {
                Add(new Coroutine(FadeBgTo(0f)));
            }

            yield return(Everest.SaveSettings());

            for (float p = 0f; p < 1f; p += Engine.DeltaTime * 4f)
            {
                menu.X = onScreenX - 1920f * Ease.CubeIn(p);
                yield return(null);
            }

            menu.Visible = Visible = false;
            menu.RemoveSelf();
            menu = null;

            Overworld.Maddy.Hide();
        }
예제 #18
0
        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 static void openReturnToLobbyConfirmMenu(Level level, int returnIndex)
        {
            level.Paused = true;
            TextMenu menu = new TextMenu();

            menu.AutoScroll = false;
            menu.Position   = new Vector2((float)Engine.Width / 2f, (float)Engine.Height / 2f - 100f);

            // RETURN TO LOBBY?
            menu.Add(new TextMenu.Header(Dialog.Clean("collabutils2_returntolobby_confirm_title")));

            // Save
            if (CollabModule.Instance.Session.SaveAndReturnToLobbyAllowed)
            {
                // add some explanatory text on the "Save" and "Do Not Save" options
                menu.Add(new TextMenu.SubHeader(Dialog.Clean("collabutils2_returntolobby_confirm_note1")));
                menu.Add(new TextMenuExt.SubHeaderExt(Dialog.Clean("collabutils2_returntolobby_confirm_note2"))
                {
                    HeightExtra = 0f
                });
                menu.Add(new TextMenu.SubHeader(""));

                menu.Add(new TextMenu.Button(Dialog.Clean("collabutils2_returntolobby_confirm_save")).Pressed(() => {
                    Engine.TimeRate = 1f;
                    menu.Focused    = false;
                    Audio.SetMusic(null);
                    Audio.BusStopAll("bus:/gameplay_sfx", immediate: true);

                    // add a death, like vanilla Save & Quit
                    level.Session.InArea = true;
                    level.Session.Deaths++;
                    level.Session.DeathsInCurrentLevel++;
                    SaveData.Instance.AddDeath(level.Session.Area);

                    level.DoScreenWipe(wipeIn: false, () => {
                        CollabModule.Instance.SaveData.SessionsPerLevel.Add(level.Session.Area.GetSID(), Encoding.UTF8.GetString(UserIO.Serialize(level.Session)));

                        // save all mod sessions of mods that have mod sessions.
                        Dictionary <string, string> modSessions = new Dictionary <string, string>();
                        foreach (EverestModule mod in Everest.Modules)
                        {
                            if (mod._Session != null && !(mod._Session is EverestModuleBinarySession))
                            {
                                try {
                                    modSessions[mod.Metadata.Name] = YamlHelper.Serializer.Serialize(mod._Session);
                                } catch (Exception e) {
                                    // this is the same fallback message as the base EverestModule class if something goes wrong.
                                    Logger.Log(LogLevel.Warn, "CollabUtils2/ReturnToLobbyHelper", "Failed to save the session of " + mod.Metadata.Name + "!");
                                    Logger.LogDetailed(e);
                                }
                            }
                        }
                        CollabModule.Instance.SaveData.ModSessionsPerLevel.Add(level.Session.Area.GetSID(), modSessions);

                        Engine.Scene = new LevelExitToLobby(LevelExit.Mode.SaveAndQuit, level.Session);
                    });

                    foreach (LevelEndingHook component in level.Tracker.GetComponents <LevelEndingHook>())
                    {
                        component.OnEnd?.Invoke();
                    }
                }));
            }

            // Do Not Save
            menu.Add(new TextMenu.Button(Dialog.Clean(CollabModule.Instance.Session.SaveAndReturnToLobbyAllowed ? "collabutils2_returntolobby_confirm_donotsave" : "menu_return_continue")).Pressed(() => {
                Engine.TimeRate = 1f;
                menu.Focused    = false;
                Audio.SetMusic(null);
                Audio.BusStopAll("bus:/gameplay_sfx", immediate: true);

                level.DoScreenWipe(wipeIn: false, () => {
                    Engine.Scene = new LevelExitToLobby(LevelExit.Mode.GiveUp, level.Session);
                });

                foreach (LevelEndingHook component in level.Tracker.GetComponents <LevelEndingHook>())
                {
                    component.OnEnd?.Invoke();
                }
            }));

            // Cancel
            menu.Add(new TextMenu.Button(Dialog.Clean(CollabModule.Instance.Session.SaveAndReturnToLobbyAllowed ? "collabutils2_returntolobby_confirm_cancel" : "menu_return_cancel")).Pressed(() => {
                menu.OnCancel();
            }));

            // handle Pause button
            menu.OnPause = (menu.OnESC = () => {
                menu.RemoveSelf();
                level.Paused = false;
                Engine.FreezeTimer = 0.15f;
                Audio.Play("event:/ui/game/unpause");
            });

            // handle Cancel button
            menu.OnCancel = () => {
                Audio.Play("event:/ui/main/button_back");
                menu.RemoveSelf();
                level.Pause(returnIndex, minimal: false);
            };

            level.Add(menu);
        }
예제 #20
0
        //创建暂停界面逻辑
        public void CreatePauseMenu()
        {
            Audio.Play(Sfxs.ui_game_pause);
            Audio.PauseGameplaySfx = true;
            snapshot = Audio.CreateSnapshot(Snapshots.PAUSE_MENU);

            var menu = new TextMenu();

            // Resume Button
            menu.Add(new TextMenu.Button(Dialog.Clean("pico8_pause_continue")).Pressed(() => menu.OnCancel()));

            // Restart Button
            menu.Add(new TextMenu.Button(Dialog.Clean("pico8_pause_restart")).Pressed(() =>
            {
                pauseMenu = null;
                music(-1, 0, 0);

                new FadeWipe(this, false, () =>
                {
                    Audio.BusStopAll(Buses.GAMEPLAY, false);
                    Audio.PauseGameplaySfx = false;
                    Audio.EndSnapshot(snapshot);
                    snapshot = null;

                    ResetScreen();
                    game       = null;
                    gameFrame  = 0;
                    gameActive = true;
                    new FadeWipe(this, true);
                });
            }));

            // Quit Button
            menu.Add(new TextMenu.Button(Dialog.Clean("pico8_pause_quit")).Pressed(() =>
            {
                leaving    = true;
                gameActive = false;
                pauseMenu  = null;
                music(-1, 0, 0);

                new FadeWipe(this, false, () =>
                {
                    Audio.BusStopAll(Buses.GAMEPLAY, false);
                    Audio.PauseGameplaySfx = false;
                    Audio.EndSnapshot(snapshot);
                    Audio.Stop(bgSfx);
                    snapshot = null;
                    //返回关卡场景
                    if (ReturnTo != null)
                    {
                        if (ReturnTo is Level)
                        {
                            (ReturnTo as Level).Session.Audio.Apply();
                            new FadeWipe(ReturnTo, true);
                        }

                        Engine.Scene = ReturnTo;
                    }
                    //返回主菜单场景
                    else
                    {
                        Engine.Scene = new OverworldLoader(Overworld.StartMode.Titlescreen);
                    }
                });
            }));

            menu.OnCancel = menu.OnESC = menu.OnPause = () =>
            {
                Audio.PauseGameplaySfx = false;
                Audio.EndSnapshot(snapshot);
                snapshot = null;

                gameDelay  = 0.1f;
                pauseMenu  = null;
                gameActive = true;
                menu.RemoveSelf();
            };

            gameActive = false;
            pauseMenu  = menu;
        }