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); } }); }
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); }
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); }
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); } }
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); } } }
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); } }
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); }
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); }
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); * * }*/ } }
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>(); }
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); }
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); }); }
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); } }
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); }
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; } }
// 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; } }
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); }