private void HijackExitBegin(On.Celeste.LevelExit.orig_Begin orig, LevelExit self)
        {
            orig(self);
            var settings = this.InRandomizerSettings;

            this.endingSettings = settings;
            if (settings == null || settings.Algorithm != LogicType.Endless)
            {
                return;
            }

            LevelExit.Mode mode = (LevelExit.Mode) typeof(LevelExit).GetField("mode", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(self);
            if (mode != LevelExit.Mode.Completed)
            {
                return;
            }

            var newSettings = settings.Copy();

            newSettings.EndlessLevel++;
            Audio.SetMusic(SFX.music_complete_bside);
            Audio.SetAmbience(null);

            this.genTask = Task.Run(() => {
                try {
                    return(RandoLogic.GenerateMap(newSettings));
                } catch (GenerationError e) {
                    LevelEnterExt.ErrorMessage = e.Message ?? "Failed to generate area";
                    LevelEnter.Go(new Session(new AreaKey(1).SetSID("")), false);
                    return(AreaKey.None);
                }
            });
        }
Ejemplo n.º 2
0
        private IEnumerator StartRoutine(string checkpoint = null)
        {
            int checkpointAreaSplit = checkpoint?.IndexOf('|') ?? -1;

            if (checkpointAreaSplit >= 0)
            {
                Area       = AreaDataExt.Get(checkpoint.Substring(0, checkpointAreaSplit))?.ToKey(Area.Mode) ?? Area;
                checkpoint = checkpoint.Substring(checkpointAreaSplit + 1);
            }

            EnteringChapter = true;
            Overworld.Maddy.Hide(false);
            Overworld.Mountain.EaseCamera(Area.ID, Data.MountainZoom, 1f);
            Add(new Coroutine(EaseOut(false)));
            yield return(0.2f);

            ScreenWipe.WipeColor = Color.Black;
            AreaData.Get(Area).Wipe(Overworld, false, null);
            Audio.SetMusic(null);
            Audio.SetAmbience(null);
            // TODO: Determine if the area should keep the overworld snow.
            if ((Area.ID == 0 || Area.ID == 9) && checkpoint == null && Area.Mode == AreaMode.Normal)
            {
                Overworld.RendererList.UpdateLists();
                Overworld.RendererList.MoveToFront(Overworld.Snow);
            }
            yield return(0.5f);

            LevelEnter.Go(new Session(Area, checkpoint), false);
        }
Ejemplo n.º 3
0
        private IEnumerator EnterFirstAreaRoutine()
        {
            // Replace ID 0 with SaveData.Instance.LastArea.ID

            Overworld overworld = fileSelect.Overworld;
            AreaData  area      = AreaData.Areas[SaveData.Instance.LastArea.ID];

            if (area.GetLevelSet() != "Celeste")
            {
                // Pretend that we've beaten Prologue.
                LevelSetStats stats = SaveData.Instance.GetLevelSetStatsFor("Celeste");
                stats.UnlockedAreas = 1;
                stats.AreasIncludingCeleste[0].Modes[0].Completed = true;
            }

            yield return(fileSelect.Leave(null));

            yield return(overworld.Mountain.EaseCamera(0, area.MountainIdle));

            yield return(0.3f);

            overworld.Mountain.EaseCamera(0, area.MountainZoom, 1f);
            yield return(0.4f);

            area.Wipe(overworld, false, null);
            overworld.RendererList.UpdateLists();
            overworld.RendererList.MoveToFront(overworld.Snow);

            yield return(0.5f);

            LevelEnter.Go(new Session(SaveData.Instance.LastArea), false);
        }
Ejemplo n.º 4
0
        private IEnumerator StartRoutine(string checkpoint = null)
        {
            Overworld.Maddy.Hide(false);
            Overworld.Mountain.EaseCamera(Area.ID, Data.MountainZoom, 1f);
            Add(new Coroutine(EaseOut(false)));
            yield return(0.2f);

            AreaData.Get(Area).Wipe(Overworld, false, null);
            Audio.SetMusic(null);
            Audio.SetAmbience(null);
            // TODO: Determine if the area should keep the overworld snow.
            if ((Area.ID == 0 || Area.ID == 9) && checkpoint == null && Area.Mode == AreaMode.Normal)
            {
                Overworld.RendererList.UpdateLists();
                Overworld.RendererList.MoveToFront(Overworld.Snow);
            }
            yield return(0.5f);

            try {
                LevelEnter.Go(new Session(Area, checkpoint), false);
            } catch (Exception e) {
                Mod.Logger.Log(LogLevel.Warn, "misc", $"Failed entering area {Area}");
                e.LogDetailed();

                string message = Dialog.Get("postcard_levelloadfailed");
                message = message.Replace("((player))", SaveData.Instance.Name);
                message = message.Replace("((sid))", Area.GetSID());

                LevelEnterExt.ErrorMessage = message;
                LevelEnter.Go(new Session(new AreaKey(1).SetSID("")), false);
            }
        }
Ejemplo n.º 5
0
        public static void Go(Session session, bool fromSaveData)
        {
            if (ErrorMessage != null)
            {
                // We are entering the error screen. Invoke the original method which will display it.
                orig_Go(session, fromSaveData);
            }
            else
            {
                try {
                    if (!PlayCustomVignette(session, fromSaveData))
                    {
                        orig_Go(session, fromSaveData);
                    }

                    Everest.Events.Level.Enter(session, fromSaveData);
                } catch (Exception e) {
                    Logger.Log(LogLevel.Warn, "misc", $"Failed entering area {session.Area}");
                    Logger.LogDetailed(e);

                    string message = Dialog.Get("postcard_levelloadfailed")
                                     .Replace("((player))", SaveData.Instance.Name)
                                     .Replace("((sid))", session.Area.GetSID())
                    ;

                    LevelEnterExt.ErrorMessage = message;
                    LevelEnter.Go(new Session(session.Area), false);
                }
            }
        }
Ejemplo n.º 6
0
        private IEnumerator Routine()
        {
            if (targetSID != null && AreaData.Get(targetSID) == null)
            {
                // we are returning to a map that does not exist!
                Logger.Log(LogLevel.Warn, "CollabUtils2/LevelExitToLobby", $"We are trying to return to a nonexistent lobby: {targetSID}!");
                targetSID  = null;
                targetRoom = null;

                // try detecting the lobby. if we don't succeed, targetSID will stay null and we will return to map.
                string lobbySID = LobbyHelper.GetLobbyForLevelSet(SaveData.Instance.CurrentSession_Safe.Area.GetLevelSet());
                if (lobbySID == null)
                {
                    lobbySID = LobbyHelper.GetLobbyForGym(SaveData.Instance.CurrentSession_Safe.Area.GetSID());
                }
                if (lobbySID != null)
                {
                    Logger.Log(LogLevel.Warn, "CollabUtils2/LevelExitToLobby", $"We will be returning to the detected lobby for the current map instead: {lobbySID}.");
                    targetSID = lobbySID;
                }
            }

            Session oldSession = SaveData.Instance.CurrentSession_Safe;
            Session newSession = null;

            if (targetSID != null)
            {
                newSession                      = new Session(AreaData.Get(targetSID).ToKey());
                newSession.FirstLevel           = false;
                newSession.StartedFromBeginning = false;
                newSession.Level                = targetRoom ?? newSession.MapData.StartLevel().Name;
                newSession.RespawnPoint         = targetRoom == null ? (Vector2?)null : targetSpawnPoint;
                SaveData.Instance.StartSession(newSession);
            }

            UserIO.SaveHandler(file: true, settings: true);
            while (UserIO.Saving)
            {
                yield return(null);
            }
            while (SaveLoadIcon.OnScreen)
            {
                yield return(null);
            }

            SaveData.Instance.CurrentSession_Safe = oldSession;

            if (targetSID == null)
            {
                // failsafe: if there is no lobby to return to, return to map instead.
                Engine.Scene = new OverworldLoader(
                    exitMode == LevelExit.Mode.Completed ? Overworld.StartMode.AreaComplete : Overworld.StartMode.AreaQuit);
            }
            else
            {
                new DynData <Session>(newSession)["pauseTimerUntilAction"] = true;
                LevelEnter.Go(newSession, false);
            }
        }
Ejemplo n.º 7
0
        private IEnumerator ErrorRoutine(string message)
        {
            yield return(null);

            Audio.SetMusic(null);

            LevelEnterExt.ErrorMessage = message;
            LevelEnter.Go(new Session(Session?.Area ?? new AreaKey(1).SetSID("")), false);
        }
Ejemplo n.º 8
0
        private IEnumerator StartRoutine(AreaData area, AreaMode mode = AreaMode.Normal, string checkpoint = null)
        {
            Overworld.Maddy.Hide(false);
            area.Wipe(Overworld, false, null);
            Audio.SetMusic(null, true, true);
            Audio.SetAmbience(null, true);
            if ((area.ID == 0 || area.ID == 9) && checkpoint == null && mode == AreaMode.Normal)
            {
                Overworld.RendererList.UpdateLists();
                Overworld.RendererList.MoveToFront(Overworld.Snow);
            }
            yield return(0.5f);

            LevelEnter.Go(new Session(area.ToKey(mode), checkpoint), false);
        }
Ejemplo n.º 9
0
        private void MainThreadHook(On.Celeste.AutoSplitterInfo.orig_Update orig, AutoSplitterInfo self)
        {
            orig(self);

            if (AreaHandoff != null)
            {
                AreaData.Areas.Add(AreaHandoff);
                var key = new AreaKey(AreaData.Areas.Count - 1); // does this trigger some extra behavior
                AreaHandoff = null;
            }
            if (StartMe != null && !Entering)
            {
                var newArea = StartMe.Value;
                Audio.SetMusic((string)null, true, true);
                Audio.SetAmbience((string)null, true);
                Audio.Play("event:/ui/main/savefile_begin");

                // use the debug file
                SaveData.InitializeDebugMode();
                // turn on/off variants mode
                SaveData.Instance.VariantMode = Settings.Variants;
                SaveData.Instance.AssistMode  = false;
                // mark as completed to spawn golden berry
                SaveData.Instance.Areas[newArea.ID].Modes[0].Completed = true;
                // mark heart as not collected
                SaveData.Instance.Areas[newArea.ID].Modes[0].HeartGem = false;
                Entering = true;

                var fade = new FadeWipe(Engine.Scene, false, () => {   // assign to variable to suppress compiler warning
                    var session = new Session(newArea, null, null)
                    {
                        FirstLevel           = true,
                        StartedFromBeginning = true,
                    };
                    session.SeedCleanRandom(Settings.SeedType == SeedType.Random);
                    SaveData.Instance.StartSession(session);    // need to set this earlier than we would get otherwise
                    LevelEnter.Go(session, true);
                    StartMe  = null;
                    Entering = false;
                });

                /*foreach (AreaData area in AreaData.Areas) {
                 *  Logger.Log("randomizer", $"Skeleton for {area.GetSID()}");
                 *  RandoConfigFile.YamlSkeleton(area);
                 *
                 * }*/
            }
        }
Ejemplo n.º 10
0
        private void OnDebug()
        {
            Audio.Play("event:/ui/main/whoosh_list_out");
            Audio.Play("event:/ui/main/button_select");

            SaveData.InitializeDebugMode(true);

            if (SaveData.Instance.CurrentSession != null && SaveData.Instance.CurrentSession.InArea)
            {
                Audio.SetMusic(null);
                Audio.SetAmbience(null);
                Overworld.ShowInputUI = false;
                new FadeWipe(Scene, false, () => LevelEnter.Go(SaveData.Instance.CurrentSession, true));
                return;
            }

            Overworld.Goto <OuiChapterSelect>();
        }
Ejemplo n.º 11
0
        private IEnumerator StartRoutine(string checkpoint = null)
        {
            Overworld.Maddy.Hide(false);
            Overworld.Mountain.EaseCamera(Area.ID, Data.MountainZoom, 1f);
            Add(new Coroutine(EaseOut(false)));
            yield return(0.2f);

            AreaData.Get(Area).Wipe(Overworld, false, null);
            Audio.SetMusic(null);
            Audio.SetAmbience(null);
            // TODO: Determine if the area should keep the overworld snow.
            if ((Area.ID == 0 || Area.ID == 9) && checkpoint == null && Area.Mode == AreaMode.Normal)
            {
                Overworld.RendererList.UpdateLists();
                Overworld.RendererList.MoveToFront(Overworld.Snow);
            }
            yield return(0.5f);

            LevelEnter.Go(new Session(Area, checkpoint), false);
        }
Ejemplo n.º 12
0
        public override void OnEnter(Player player)
        {
            base.OnEnter(player);

            if (swapping)
            {
                return;
            }
            swapping = true;

            Level level = SceneAs <Level>();

            level.DoScreenWipe(false, () => {
                if (string.IsNullOrEmpty(room) || room == "-")
                {
                    room = null;
                }

                if (!Enum.TryParse(side, out AreaMode mode))
                {
                    mode = AreaMode.Normal;
                }

                // TODO: Keep track of where the session actually began. Don't overwrite StartCheckpoint.

                Session session = level.Session;
                session.Area    = AreaData.Get(map)?.ToKey(mode) ?? new AreaKey(-1);
                if (session.Area.ID == -1)
                {
                    LevelEnter.Go(new Session(new AreaKey(-1)), false);
                    return;
                }

                session.StartCheckpoint      = room;
                session.Level                = room;
                session.StartedFromBeginning = false;
                session.RespawnPoint         = null;
                LevelEnter.Go(session, false);
            });
        }
Ejemplo n.º 13
0
        private IEnumerator Routine()
        {
            Session oldSession = SaveData.Instance.CurrentSession_Safe;
            Session newSession = null;

            if (targetSID != null)
            {
                newSession                            = new Session(AreaData.Get(targetSID).ToKey());
                newSession.FirstLevel                 = false;
                newSession.StartedFromBeginning       = false;
                newSession.Level                      = targetRoom ?? newSession.MapData.StartLevel().Name;
                newSession.RespawnPoint               = targetRoom == null ? (Vector2?)null : targetSpawnPoint;
                SaveData.Instance.CurrentSession_Safe = newSession;
            }

            UserIO.SaveHandler(file: true, settings: true);
            while (UserIO.Saving)
            {
                yield return(null);
            }
            while (SaveLoadIcon.OnScreen)
            {
                yield return(null);
            }

            SaveData.Instance.CurrentSession_Safe = oldSession;

            if (targetSID == null)
            {
                // failsafe: if there is no lobby to return to, return to map instead.
                Engine.Scene = new OverworldLoader(
                    exitMode == LevelExit.Mode.Completed ? Overworld.StartMode.AreaComplete : Overworld.StartMode.AreaQuit);
            }
            else
            {
                new DynData <Session>(newSession)["pauseTimerUntilAction"] = true;
                LevelEnter.Go(newSession, false);
            }
        }
Ejemplo n.º 14
0
        private IEnumerator addForceEnabledVariantsPostcard(On.Celeste.LevelEnter.orig_Routine orig, LevelEnter self)
        {
            if (showForcedVariantsPostcard)
            {
                showForcedVariantsPostcard = false;

                // let's show a postcard to let the player know Extended Variants have been enabled.
                self.Add(forceEnabledVariantsPostcard = new Postcard(Dialog.Get("POSTCARD_EXTENDEDVARIANTS_FORCEENABLED"), "event:/ui/main/postcard_csides_in", "event:/ui/main/postcard_csides_out"));
                yield return(forceEnabledVariantsPostcard.DisplayRoutine());

                forceEnabledVariantsPostcard = null;
            }

            // just go on with vanilla behavior (other postcards, B-side intro, etc)
            yield return(new SwapImmediately(orig(self)));
        }
Ejemplo n.º 15
0
        // this is heavily inspired by Vortex Helper by catapillie, and also requires Vortex Helper to fully work.
        private IEnumerator shatterSequence()
        {
            if (!Everest.Loader.DependencyLoaded(new EverestModuleMetadata {
                Name = "VortexHelper", Version = new Version(1, 1, 0)
            }))
            {
                // error postcards are nicer than crashes!
                LevelEnter.ErrorMessage = "{big}Oops!{/big}{n}To use {# F94A4A}Shatter Flag Switch Gates{#}, you need to have {# d678db}Vortex Helper{#} installed!";
                LevelEnter.Go(new Session(SceneAs <Level>().Session.Area), fromSaveData: false);
                yield break;
            }

            Level level = SceneAs <Level>();

            while ((!Triggered || allowReturn) && !SceneAs <Level>().Session.GetFlag(Flag))
            {
                yield return(null);
            }

            openSfx.Play("event:/game/general/fallblock_shake");
            yield return(0.1f);

            if (shakeTime > 0f)
            {
                StartShaking(shakeTime);
                while (icon.Rate < 1f)
                {
                    icon.Color = Color.Lerp(inactiveColor, finishColor, icon.Rate);
                    icon.Rate += Engine.DeltaTime / shakeTime;
                    yield return(null);
                }
            }
            else
            {
                icon.Rate = 1f;
            }

            yield return(0.1f);

            for (int k = 0; k < 32; k++)
            {
                float num = Calc.Random.NextFloat((float)Math.PI * 2f);
                SceneAs <Level>().ParticlesFG.Emit(TouchSwitch.P_Fire, Position + iconOffset + Calc.AngleToVector(num, 4f), num);
            }
            openSfx.Stop();
            Audio.Play("event:/game/general/wall_break_stone", Center);
            Audio.Play(finishedSound, Center);
            level.Shake();

            string debrisPath;

            switch (blockSpriteName)
            {
            default:
                debrisPath = "debris/VortexHelper/disintegate/1";
                break;

            case "mirror":
                debrisPath = "debris/VortexHelper/disintegate/2";
                break;

            case "temple":
                debrisPath = "debris/VortexHelper/disintegate/3";
                break;

            case "stars":
                debrisPath = "debris/VortexHelper/disintegate/4";
                break;
            }

            for (int i = 0; i < Width / 8f; i++)
            {
                for (int j = 0; j < Height / 8f; j++)
                {
                    Debris           debris     = new Debris().orig_Init(Position + new Vector2(4 + i * 8, 4 + j * 8), '1').BlastFrom(Center);
                    DynData <Debris> debrisData = new DynData <Debris>(debris);
                    debrisData.Get <Image>("image").Texture = GFX.Game[debrisPath];
                    Scene.Add(debris);
                }
            }
            DestroyStaticMovers();
            RemoveSelf();
        }
        private void MainThreadHook(On.Celeste.AutoSplitterInfo.orig_Update orig, AutoSplitterInfo self)
        {
            orig(self);

            if (AreaHandoff != null)
            {
                if (AreaHandoff.ID < AreaData.Areas.Count)
                {
                    AreaData.Areas[AreaHandoff.ID] = AreaHandoff;
                }
                else if (AreaHandoff.ID == AreaData.Areas.Count)
                {
                    AreaData.Areas.Add(AreaHandoff);
                }
                else
                {
                    throw new Exception("Strange edge case in the randomizer, please report this bug");
                }
                var unused = new AreaKey(AreaData.Areas.Count - 1); // does this trigger some extra behavior
                AreaHandoff = null;
            }
            if (StartMe != null && !Entering)
            {
                var newArea = StartMe.Value;

                var area         = AreaData.Get(newArea);
                var dyn          = new DynData <AreaData>(area);
                var areaSettings = dyn.Get <RandoSettings>("RandoSettings");
                Audio.SetMusic(null);
                Audio.SetAmbience(null);
                Audio.Play("event:/ui/main/savefile_begin");

                // use the debug file
                SaveData.InitializeDebugMode();
                // turn on/off variants mode
                SaveData.Instance.VariantMode = areaSettings.Variants;
                SaveData.Instance.AssistMode  = false;
                // mark as completed to spawn golden berry
                SaveData.Instance.Areas[newArea.ID].Modes[0].Completed = true;
                // mark heart as not collected
                SaveData.Instance.Areas[newArea.ID].Modes[0].HeartGem = false;
                Entering = true;

                var unused = new FadeWipe(Engine.Scene, false, () => {   // assign to variable to suppress compiler warning
                    Session session;
                    if (UseSession != null)
                    {
                        session    = UseSession;
                        UseSession = null;
                    }
                    else
                    {
                        session = new Session(newArea)
                        {
                            FirstLevel           = true,
                            StartedFromBeginning = true,
                        };
                        session.SeedCleanRandom(Settings.SeedType == SeedType.Random);
                    }
                    SaveData.Instance.StartSession(session);    // need to set this earlier than we would get otherwise
                    StartMe  = null;
                    Entering = false;
                    LevelEnter.Go(session, true);
                });

                /*foreach (AreaData area in AreaData.Areas) {
                 *  Logger.Log("randomizer", $"Skeleton for {area.GetSID()}");
                 *  RandoConfigFile.YamlSkeleton(area);
                 *
                 * }*/
            }

            // update endless mode score
            var settings = (Engine.Scene is AreaComplete) ? this.endingSettings : this.InRandomizerSettings;

            if (settings != null && settings.Algorithm == LogicType.Endless)
            {
                this.CurrentScore = ComputeScore(settings);
            }
            else
            {
                this.CurrentScore = -1;
            }
        }
Ejemplo n.º 17
0
        private void addForceEnabledVariantsPostcardRendering(On.Celeste.LevelEnter.orig_BeforeRender orig, LevelEnter self)
        {
            orig(self);

            if (forceEnabledVariantsPostcard != null)
            {
                forceEnabledVariantsPostcard.BeforeRender();
            }
        }
Ejemplo n.º 18
0
        private void ReloadMenu()
        {
            menu = new DisablableTextMenu {
                new TextMenu.Header(Dialog.Clean("MODOPTIONS_RANDOMIZER_HEADER"))
            };

            var hashtext = new TextMenuExt.EaseInSubHeaderExt("{hash}", true, menu)
            {
                HeightExtra = -10f,
                Offset      = new Vector2(30, -5),
            };

            void updateHashText()
            {
                hashtext.Title = "v" + RandoModule.Instance.Metadata.VersionString;
                if (Settings.SeedType == SeedType.Custom)
                {
                    hashtext.Title += " #" + Settings.Hash.ToString();
                }
            }

            updateHashText();

            var errortext = new TextMenuExt.EaseInSubHeaderExt("{error}", false, menu)
            {
                HeightExtra = -10f,
                Offset      = new Vector2(30, -5),
            };

            var seedbutton = new TextMenu.Button(Dialog.Clean("MODOPTIONS_RANDOMIZER_SEED") + ": " + Settings.Seed);

            seedbutton.Pressed(() => {
                Audio.Play(SFX.ui_main_savefile_rename_start);
                menu.SceneAs <Overworld>().Goto <UI.OuiTextEntry>().Init <OuiRandoSettings>(
                    Settings.Seed,
                    (v) => Settings.Seed = v,
                    RandoModule.MAX_SEED_CHARS
                    );
            });
            seedbutton.Visible = Settings.SeedType == SeedType.Custom;

            var seedtypetoggle = new TextMenu.Slider(Dialog.Clean("MODOPTIONS_RANDOMIZER_SEEDTYPE"), (i) => {
                return(Dialog.Clean("MODOPTIONS_RANDOMIZER_SEEDTYPE_" + Enum.GetNames(typeof(SeedType))[i].ToUpperInvariant()));
            }, 0, (int)SeedType.Last - 1, (int)Settings.SeedType).Change((i) => {
                Settings.SeedType  = (SeedType)i;
                seedbutton.Visible = Settings.SeedType == SeedType.Custom;
                // just in case...
                seedbutton.Label = Dialog.Clean("MODOPTIONS_RANDOMIZER_SEED") + ": " + Settings.Seed;
                updateHashText();
            });

            var mapbutton = new TextMenu.Button(Dialog.Clean("MODOPTIONS_RANDOMIZER_MAPPICKER")).Pressed(() => {
                Audio.Play(SFX.ui_main_button_select);
                menu.SceneAs <Overworld>().Goto <OuiMapPicker>();
            });

            var mapcountlbl = new TextMenuExt.SubHeaderExt(Settings.LevelCount.ToString() + " " + Dialog.Clean("MODOPTIONS_RANDOMIZER_MAPPICKER_LEVELS"))
            {
                HeightExtra = -10f,
                Offset      = new Vector2(30, -5),
            };

            var logictoggle = new TextMenu.Slider(Dialog.Clean("MODOPTIONS_RANDOMIZER_LOGIC"), (i) => {
                return(Dialog.Clean("MODOPTIONS_RANDOMIZER_LOGIC_" + Enum.GetNames(typeof(LogicType))[i].ToUpperInvariant()));
            }, 0, (int)LogicType.Last - 1, (int)Settings.Algorithm).Change((i) => {
                Settings.Algorithm = (LogicType)i;
                updateHashText();
            });

            var lengthtoggle = new TextMenu.Slider(Dialog.Clean("MODOPTIONS_RANDOMIZER_LENGTH"), (i) => {
                return(Dialog.Clean("MODOPTIONS_RANDOMIZER_LENGTH_" + Enum.GetNames(typeof(MapLength))[i].ToUpperInvariant()));
            }, 0, (int)MapLength.Last - 1, (int)Settings.Length).Change((i) => {
                Settings.Length = (MapLength)i;
                updateHashText();
            });

            var numdashestoggle = new TextMenu.Slider(Dialog.Clean("MODOPTIONS_RANDOMIZER_NUMDASHES"), (i) => {
                return(Dialog.Clean("MODOPTIONS_RANDOMIZER_NUMDASHES_" + Enum.GetNames(typeof(NumDashes))[i].ToUpperInvariant()));
            }, 0, (int)NumDashes.Last - 1, (int)Settings.Dashes).Change((i) => {
                Settings.Dashes = (NumDashes)i;
                updateHashText();
            });

            var difficultytoggle = new TextMenu.Slider(Dialog.Clean("MODOPTIONS_RANDOMIZER_DIFFICULTY"), (i) => {
                return(Dialog.Clean("MODOPTIONS_RANDOMIZER_DIFFICULTY_" + Enum.GetNames(typeof(Difficulty))[i].ToUpperInvariant()));
            }, 0, (int)Difficulty.Last - 1, (int)Settings.Difficulty).Change((i) => {
                Settings.Difficulty = (Difficulty)i;
                updateHashText();
            });

            var repeatroomstoggle = new TextMenu.OnOff(Dialog.Clean("MODOPTIONS_RANDOMIZER_REPEATROOMS"), Settings.RepeatRooms).Change((val) => {
                Settings.RepeatRooms = val;
                updateHashText();
            });

            var enterunknowntext = new TextMenuExt.EaseInSubHeaderExt(Dialog.Clean("MODOPTIONS_RANDOMIZER_ENTERUNKNOWN_EXPLAIN"), false, menu)
            {
                HeightExtra = 17f,
                Offset      = new Vector2(30, -5),
            };

            var enterunknowntoggle = new TextMenu.OnOff(Dialog.Clean("MODOPTIONS_RANDOMIZER_ENTERUNKNOWN"), Settings.EnterUnknown).Change((val) => {
                Settings.EnterUnknown = val;
                updateHashText();
            });

            enterunknowntoggle.OnEnter += () => { enterunknowntext.FadeVisible = true; };
            enterunknowntoggle.OnLeave += () => { enterunknowntext.FadeVisible = false; };

            var shinetoggle = new TextMenu.Slider(Dialog.Clean("MODOPTIONS_RANDOMIZER_SHINE"), (i) => {
                return(Dialog.Clean("MODOPTIONS_RANDOMIZER_SHINE_" + Enum.GetNames(typeof(ShineLights))[i].ToUpperInvariant()));
            }, 0, (int)ShineLights.Last - 1, (int)Settings.Lights).Change((i) => {
                Settings.Lights = (ShineLights)i;
                updateHashText();
            });

            var darktoggle = new TextMenu.Slider(Dialog.Clean("MODOPTIONS_RANDOMIZER_DARK"), (i) => {
                return(Dialog.Clean("MODOPTIONS_RANDOMIZER_DARK_" + Enum.GetNames(typeof(Darkness))[i].ToUpperInvariant()));
            }, 0, (int)Darkness.Last - 1, (int)Settings.Darkness).Change((i) => {
                Settings.Darkness = (Darkness)i;
                updateHashText();
            });

            var goldentoggle = new TextMenu.OnOff(Dialog.Clean("MODOPTIONS_RANDOMIZER_GOLDENBERRY"), Settings.SpawnGolden).Change((val) => {
                Settings.SpawnGolden = val;
            });

            var moreoptions = false;

            repeatroomstoggle.Visible  = false;
            enterunknowntoggle.Visible = false;
            goldentoggle.Visible       = false;
            shinetoggle.Visible        = false;
            darktoggle.Visible         = false;

            var moreoptionsbtn = new TextMenu.Button(Dialog.Clean("MODOPTIONS_RANDOMIZER_MOREOPTIONS"));

            moreoptionsbtn.Pressed(() => {
                moreoptions          = !moreoptions;
                moreoptionsbtn.Label = moreoptions ? Dialog.Clean("MODOPTIONS_RANDOMIZER_FEWEROPTIONS") : Dialog.Clean("MODOPTIONS_RANDOMIZER_MOREOPTIONS");

                repeatroomstoggle.Visible  = moreoptions;
                enterunknowntoggle.Visible = moreoptions;
                goldentoggle.Visible       = moreoptions;
                shinetoggle.Visible        = moreoptions;
                darktoggle.Visible         = moreoptions;
            });

            void syncModel()
            {
                repeatroomstoggle.Index  = Settings.RepeatRooms ? 1 : 0;
                enterunknowntoggle.Index = Settings.EnterUnknown ? 1 : 0;
                logictoggle.Index        = (int)Settings.Algorithm;
                lengthtoggle.Index       = (int)Settings.Length;
                numdashestoggle.Index    = (int)Settings.Dashes;
                difficultytoggle.Index   = (int)Settings.Difficulty;
                shinetoggle.Index        = (int)Settings.Lights;
                darktoggle.Index         = (int)Settings.Darkness;
                mapcountlbl.Title        = Settings.LevelCount.ToString() + " " + Dialog.Clean("MODOPTIONS_RANDOMIZER_MAPPICKER_LEVELS");

                var locked = Settings.Rules != Ruleset.Custom;

                mapbutton.Disabled          = locked;
                repeatroomstoggle.Disabled  = locked;
                enterunknowntoggle.Disabled = locked;
                logictoggle.Disabled        = locked;
                lengthtoggle.Disabled       = locked;
                numdashestoggle.Disabled    = locked;
                difficultytoggle.Disabled   = locked;
                shinetoggle.Disabled        = locked;
                darktoggle.Disabled         = locked;
            }

            syncModel();

            var rulestoggle = new TextMenu.Slider(Dialog.Clean("MODOPTIONS_RANDOMIZER_RULES"), (i) => {
                return(Dialog.Clean("MODOPTIONS_RANDOMIZER_RULES_" + Enum.GetNames(typeof(Ruleset))[i].ToUpperInvariant()));
            }, 0, (int)Ruleset.Last - 1, (int)Settings.Rules).Change((i) => {
                Settings.Rules = (Ruleset)i;
                Settings.Enforce();
                syncModel();
                updateHashText();
            });

            var startbutton = new TextMenu.Button(Dialog.Clean("MODOPTIONS_RANDOMIZER_START"));

            startbutton.Pressed(() => {
                if (this.entering)
                {
                    return;
                }

                void reenableMenu()
                {
                    this.builderThread = null;

                    startbutton.Label = Dialog.Clean("MODOPTIONS_RANDOMIZER_START");
                    updateHashText();
                    menu.DisableMovement = false;
                }

                if (this.builderThread == null)
                {
                    errortext.FadeVisible = false;
                    startbutton.Label     = Dialog.Clean("MODOPTIONS_RANDOMIZER_CANCEL");
                    hashtext.Title       += " " + Dialog.Clean("MODOPTIONS_RANDOMIZER_GENERATING");
                    menu.DisableMovement  = true;

                    this.builderThread = new Thread(() => {
                        Settings.Enforce();
                        AreaKey newArea;
                        try {
                            newArea = RandoLogic.GenerateMap(Settings);
                        } catch (ThreadAbortException) {
                            return;
                        } catch (Exception e) {
                            if (e.Message == "Could not generate map")
                            {
                                errortext.Title = e.Message;
                            }
                            else
                            {
                                errortext.Title = "Encountered an error - Check log.txt for details";
                                Logger.LogDetailed(e, "randomizer");
                            }
                            errortext.FadeVisible = true;
                            reenableMenu();
                            return;
                        }
                        this.entering = true;

                        Audio.SetMusic((string)null, true, true);
                        Audio.SetAmbience((string)null, true);
                        Audio.Play("event:/ui/main/savefile_begin");

                        // use the debug file
                        SaveData.InitializeDebugMode();
                        // turn on variants mode
                        SaveData.Instance.VariantMode = true;
                        SaveData.Instance.AssistMode  = false;
                        // clear summit gems, just in case!
                        SaveData.Instance.SummitGems = new bool[6];
                        // mark as completed to spawn golden berry
                        SaveData.Instance.Areas[newArea.ID].Modes[0].Completed = true;

                        var fade = new FadeWipe(this.Scene, false, () => {   // assign to variable to suppress compiler warning
                            var session = new Session(newArea, null, null);
                            //session.FirstLevel = false;   // setting this value here prevents the wakeup animation. set it in a hook.
                            LevelEnter.Go(session, true);
                            this.builderThread = null;
                            this.entering      = false;
                        });

                        /*foreach (AreaData area in AreaData.Areas) {
                         *  Logger.Log("randomizer", $"Skeleton for {area.GetSID()}");
                         *  RandoConfigFile.YamlSkeleton(area);
                         *
                         * }*/
                    });
                    this.builderThread.Start();
                }
                else
                {
                    this.builderThread.Abort();
                    reenableMenu();
                }
            });

            menu.Add(seedtypetoggle);
            menu.Add(seedbutton);
            menu.Add(rulestoggle);
            menu.Add(mapbutton);
            menu.Add(mapcountlbl);
            menu.Add(logictoggle);
            menu.Add(lengthtoggle);
            menu.Add(numdashestoggle);
            menu.Add(difficultytoggle);
            menu.Add(moreoptionsbtn);
            menu.Add(repeatroomstoggle);
            menu.Add(enterunknowntoggle);
            menu.Add(enterunknowntext);
            menu.Add(shinetoggle);
            menu.Add(darktoggle);
            menu.Add(goldentoggle);
            menu.Add(startbutton);
            menu.Add(hashtext);
            menu.Add(errortext);

            Scene.Add(menu);
        }
Ejemplo n.º 19
0
        public override void Update()
        {
            orig_Update();

            // Slightly dirty place to perform this, but oh well...
            if (CoreModule.Settings.QuickRestart != null)
            {
                int slot = CoreModule.Settings.QuickRestart.Value;
                CoreModule.Settings.QuickRestart = null;
                if (CoreModule.Settings.SaveDataFlush ?? false)
                {
                    CoreModule.Instance.ForceSaveDataFlush++;
                }
                CoreModule.Instance.SaveSettings();
                SaveData save = UserIO.Load <SaveData>(SaveData.GetFilename(slot));
                if (save != null)
                {
                    SaveData.Start(save, slot);
                    if (slot == -1)
                    {
                        save.DebugMode = true;
                    }
                    if (save.CurrentSession?.InArea ?? false)
                    {
                        LevelEnter.Go(save.CurrentSession, true);
                    }
                    else
                    {
                        Overworld.Goto <OuiChapterSelect>();
                    }
                }
            }

            if (!updateChecked && Everest.Updater.HasUpdate && Everest.Updater.Newest != null && alpha >= 1f)
            {
                updateChecked = true;
                updateTex     = Everest.Updater.Newest.Branch == "stable" ? GFX.Gui["areas/new"] : GFX.Gui["areas/new-yellow"];
                Tween tween = Tween.Create(Tween.TweenMode.Oneshot, Ease.CubeInOut, 0.3f, true);
                tween.OnUpdate = t => {
                    updateAlpha = t.Percent;
                };
                Add(tween);
            }

            if (alpha >= 1f && Selected && Input.MenuRight && arrowToVanilla != null)
            {
                switchingToVanillaBack = Math.Max(0f, switchingToVanillaBack - Engine.DeltaTime * 8f);
                switchingToVanilla    += Engine.DeltaTime;

                if (switchingToVanilla >= switchingToVanillaDuration && !Everest.RestartVanilla)
                {
                    Everest.RestartVanilla = true;
                    new FadeWipe(Scene, false, () => {
                        Engine.Scene = new Scene();
                        if (Everest.Flags.IsXNA && Engine.Graphics.IsFullScreen)
                        {
                            Engine.SetWindowed(320 * Settings.Instance.WindowScale, 180 * Settings.Instance.WindowScale);
                        }
                        Engine.Instance.Exit();
                    });
                }
            }
            else if (switchingToVanilla < switchingToVanillaDuration)
            {
                if (switchingToVanilla > 0f)
                {
                    switchingToVanillaBack = Math.Max(switchingToVanilla, switchingToVanillaBack);
                }
                switchingToVanillaBack = Math.Max(0f, switchingToVanillaBack - Engine.DeltaTime * 4f);
                switchingToVanilla     = 0f;
            }
        }
Ejemplo n.º 20
0
        private IEnumerator AddAltSideRemixTitle(On.Celeste.LevelEnter.orig_Routine orig, LevelEnter self)
        {
            var data    = new DynData <LevelEnter>(self);
            var session = data.Get <Session>("session");

            if (session.StartedFromBeginning && !data.Get <bool>("fromSaveData") && (GetModeMetaForAltSide(AreaData.Get(session.Area))?.ShowBSideRemixIntro ?? false))
            {
                AltSideTitle title = new AltSideTitle(session);
                self.Add(title);
                Audio.Play("event:/ui/main/bside_intro_text");
                yield return(title.EaseIn());

                yield return(0.25f);

                yield return(title.EaseOut());

                yield return(0.25f);
            }

            yield return(new SwapImmediately(orig(self)));
        }
Ejemplo n.º 21
0
        public override void Update()
        {
            orig_Update();

            // Slightly dirty place to perform this, but oh well...
            if (CoreModule.Settings.QuickRestart != null)
            {
                int slot = CoreModule.Settings.QuickRestart.Value;
                CoreModule.Settings.QuickRestart = null;
                CoreModule.Instance.SaveSettings();
                SaveData save = UserIO.Load <SaveData>(SaveData.GetFilename(slot));
                if (save != null)
                {
                    SaveData.Start(save, slot);
                    if (slot == -1)
                    {
                        save.DebugMode = true;
                    }
                    if (save.CurrentSession?.InArea ?? false)
                    {
                        LevelEnter.Go(save.CurrentSession, true);
                    }
                    else
                    {
                        Overworld.Goto <OuiChapterSelect>();
                    }
                }
            }

            if (!updateChecked && Everest.Updater.HasUpdate && Everest.Updater.Newest != null && alpha >= 1f)
            {
                updateChecked = true;
                updateTex     = Everest.Updater.Newest.Branch == "stable" ? GFX.Gui["areas/new"] : GFX.Gui["areas/new-yellow"];
                Tween tween = Tween.Create(Tween.TweenMode.Oneshot, Ease.CubeInOut, 0.3f, true);
                tween.OnUpdate = t => {
                    updateAlpha = t.Percent;
                };
                Add(tween);
            }

            if (alpha >= 1f && Selected && Input.MenuRight && arrowToVanilla != null && warningMessageMenu == null)
            {
                switchingToVanillaBack = Math.Max(0f, switchingToVanillaBack - Engine.DeltaTime * 8f);
                switchingToVanilla    += Engine.DeltaTime;

                if (switchingToVanilla >= switchingToVanillaDuration && !Everest.RestartVanilla)
                {
                    if (CoreModule.Settings.RestartIntoVanillaWarningShown)
                    {
                        restartIntoVanilla();
                    }
                    else
                    {
                        warningMessageMenu = new TextMenu();
                        Action onCancel = () => {
                            // remove the menu
                            Scene.Remove(warningMessageMenu);
                            warningMessageMenu.Visible = false;
                            warningMessageMenu         = null;
                            hideConfirmButton          = false;

                            // revert the "switch to vanilla" animation
                            switchingToVanilla     = 0f;
                            switchingToVanillaBack = 0f;

                            // fade the vanilla title screen back in
                            alpha = 0f;
                            Tween tween = Tween.Create(Tween.TweenMode.Oneshot, Ease.CubeInOut, 0.6f, start: true);
                            tween.OnUpdate = t => {
                                alpha = t.Percent;
                                textY = MathHelper.Lerp(1200f, 1000f, t.Eased);
                            };
                            Add(tween);
                        };
                        warningMessageMenu.OnESC = warningMessageMenu.OnCancel = () => {
                            Audio.Play(SFX.ui_main_button_back);
                            onCancel();
                        };
                        warningMessageMenu.Add(new TextMenu.Button(Dialog.Clean("MENU_TITLESCREEN_OK")).Pressed(() => {
                            if (!CoreModule.Settings.RestartIntoVanillaWarningShown)
                            {
                                CoreModule.Settings.RestartIntoVanillaWarningShown = true;
                                CoreModule.Instance.SaveSettings();
                            }
                            warningMessageMenu.Focused = false;
                            restartIntoVanilla();
                        }));
                        warningMessageMenu.Add(new TextMenu.Button(Dialog.Clean("MENU_TITLESCREEN_CANCEL")).Pressed(onCancel));
                        Scene.Add(warningMessageMenu);
                        hideConfirmButton = true;
                    }
                }
            }
            else if (switchingToVanilla < switchingToVanillaDuration)
            {
                if (switchingToVanilla > 0f)
                {
                    switchingToVanillaBack = Math.Max(switchingToVanilla, switchingToVanillaBack);
                }
                switchingToVanillaBack = Math.Max(0f, switchingToVanillaBack - Engine.DeltaTime * 4f);
                switchingToVanilla     = 0f;
            }

            warningEase = Calc.Approach(warningEase, warningMessageMenu != null ? 1f : 0f, Engine.DeltaTime);
        }