public void OnLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level level, Player.IntroTypes playerIntro, bool isFromLoader) { orig(level, playerIntro, isFromLoader); if (isFromLoader) { GhostManager?.RemoveSelf(); GhostManager = null; GhostRecorder?.RemoveSelf(); GhostRecorder = null; Run = Guid.NewGuid(); } Player player = level.Tracker.GetEntity <Player>(); if (player == null) { level.Add(new Entity { new Coroutine(WaitForPlayer(level)) }); } else { Step(level); } }
/// <summary> /// Mods the lighting of a new room being loaded. /// </summary> /// <param name="self">The level we are in</param> /// <param name="introType">How the player enters the level</param> private void modLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); if (Settings.RoomLighting != -1) { float lightingTarget = 1 - Settings.RoomLighting / 10f; if (playerIntro == Player.IntroTypes.Transition) { // we force the game into thinking this is not a dark room, so that it uses the BaseLightingAlpha + LightingAlphaAdd formula // (this change is not permanent, exiting and re-entering will reset this flag) self.DarkRoom = false; // we mod BaseLightingAlpha temporarily so that it adds up with LightingAlphaAdd to the right value: the transition routine will smoothly switch to it // (we are sure BaseLightingAlpha will not move for the entire session: it's only set when the map is loaded) initialBaseLightingAlpha = self.BaseLightingAlpha; self.BaseLightingAlpha = lightingTarget - self.Session.LightingAlphaAdd; } else { // just set the initial value self.Lighting.Alpha = lightingTarget; } } }
private void OnLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { BGModeToggle.BGMode = BGModeToggle.Persist; BGModeToggle.OldBGMode = !BGModeToggle.Persist; orig(self, playerIntro, isFromLoader); if (self != null) { if (self.Tracker != null) { if (self.Tracker.GetEntity <Player>() != null) { if (self.Entities.Any(entity => (entity is BGModeToggle)) || BGModeToggle.BGMode) { self.Tracker.GetEntity <Player>().Sprite.Position = new Vector2(); if (!BGModeToggle.Persist) { self.Tracker.GetEntity <Player>().Sprite.Position += new Vector2(0, +2); } BGModeToggle.Setup(self); BGModeToggle.UpdateBG(self); } } } } }
private static void onLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); if (MaxHelpingHandModule.Instance.Session.RainbowSpinnerCurrentColors != null && self.Session.LevelData != null && // happens if we are loading a save in a room that got deleted !self.Session.LevelData.Entities.Any(entity => entity.Name == "MaxHelpingHand/RainbowSpinnerColorController" || entity.Name == "MaxHelpingHand/RainbowSpinnerColorControllerDisabler")) { // we have spinner colors in session, and are entering a room with no controller: spawn one. EntityData restoredData = new EntityData(); restoredData.Values = new Dictionary <string, object>() { { "colors", MaxHelpingHandModule.Instance.Session.RainbowSpinnerCurrentColors.Colors }, { "gradientSize", MaxHelpingHandModule.Instance.Session.RainbowSpinnerCurrentColors.GradientSize }, { "loopColors", MaxHelpingHandModule.Instance.Session.RainbowSpinnerCurrentColors.LoopColors }, { "centerX", MaxHelpingHandModule.Instance.Session.RainbowSpinnerCurrentColors.Center.X }, { "centerY", MaxHelpingHandModule.Instance.Session.RainbowSpinnerCurrentColors.Center.Y }, { "gradientSpeed", MaxHelpingHandModule.Instance.Session.RainbowSpinnerCurrentColors.GradientSpeed }, { "persistent", true } }; self.Add(new RainbowSpinnerColorController(restoredData, Vector2.Zero)); self.Entities.UpdateLists(); } }
private void OnLoadLevelHook(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool fromLoader) { var settings = this.InRandomizerSettings; if (fromLoader && settings != null) { // Don't restart the timer on retry self.Session.FirstLevel = false; } orig(self, playerIntro, fromLoader); // also, set the core mode right if (fromLoader && this.InRandomizer) { var leveldata = self.Session.LevelData; var dyn = new DynData <LevelData>(leveldata); RandoConfigCoreMode modes = dyn.Get <RandoConfigCoreMode>("coreModes"); self.CoreMode = modes?.All ?? Session.CoreModes.None; self.Session.CoreMode = self.CoreMode; } if (settings != null && settings.Algorithm == LogicType.Labyrinth && Everest.Loader.DependencyLoaded(new EverestModuleMetadata() { Name = "BingoUI" })) { var ui = LoadGemUI(fromLoader); // must be a separate method or the jit will be very sad :( self.Add(ui); // lord f*****g help us } }
private void onLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { // strawberries weren't made golden yet, they were just spawned. strawberriesWereMadeGolden = false; orig(self, playerIntro, isFromLoader); }
private static void LevelOnLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); if (self.Tracker.GetEntity <SelectedAreaEntity>() == null) { self.Add(new SelectedAreaEntity()); } }
private static void HookLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerintro, bool isfromloader) { orig(self, playerintro, isfromloader); if (!isfromloader && playerintro != Player.IntroTypes.Transition) { OnTransition(self, self.Session.LevelData, Vector2.Zero); } }
public void DontRestartTimer(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool fromLoader) { if (fromLoader && this.InRandomizer) { self.Session.FirstLevel = false; } orig(self, playerIntro, fromLoader); }
// cancel when changing rooms internal static void LoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { if (PlayerModule.GetPlayer() != null && EmoteModMain.anim_by_game == 1) { cancelEmote(); } orig(self, playerIntro, isFromLoader); }
private void Level_LoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { if (playerIntro != Player.IntroTypes.Respawn) { deaths.Clear(); } orig(self, playerIntro, isFromLoader); }
private void modLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); if (playerIntro != Player.IntroTypes.Transition) { applyWind(self); } }
private static void onLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); if (MaxHelpingHandModule.Instance.Session.GradientDustImagePath != null && !hooked) { applyGradient(MaxHelpingHandModule.Instance.Session.GradientDustImagePath, MaxHelpingHandModule.Instance.Session.GradientDustScrollSpeed); } }
private void modLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); // if we killed the slowdown earlier, stop now! killSeekerSlowdownToFixHeart = false; Level level = self; Player player = level.Tracker.GetEntity <Player>(); if (player != null && Settings.AddSeekers != 0) { // make the seeker barriers temporarily collidable so that they are taken in account in Solid collide checks // and seekers can't spawn in them // (... yes, this is also what vanilla does in the seekers' Update method.) foreach (Entity entity in self.Tracker.GetEntities <SeekerBarrier>()) { entity.Collidable = true; } for (int seekerCount = 0; seekerCount < Settings.AddSeekers; seekerCount++) { for (int i = 0; i < 100; i++) { // roll a seeker position in the room int x = randomGenerator.Next(level.Bounds.Width) + level.Bounds.X; int y = randomGenerator.Next(level.Bounds.Height) + level.Bounds.Y; // should be at least 100 pixels from the player double playerDistance = Math.Sqrt(Math.Pow(MathHelper.Distance(x, player.X), 2) + Math.Pow(MathHelper.Distance(y, player.Y), 2)); // also check if we are not spawning in a wall, that would be a shame Rectangle collideRectangle = new Rectangle(x - 8, y - 8, 16, 16); if (playerDistance > 100 && !level.CollideCheck <Solid>(collideRectangle) && !level.CollideCheck <Seeker>(collideRectangle)) { // build a Seeker with a proper EntityID to make Speedrun Tool happy (this is useless in vanilla Celeste but the constructor call is intercepted by Speedrun Tool) EntityData seekerData = ExtendedVariantsModule.GenerateBasicEntityData(level, 10 + seekerCount); seekerData.Position = new Vector2(x, y); Seeker seeker = new AutoDestroyingSeeker(seekerData, Vector2.Zero); level.Add(seeker); break; } } } foreach (Entity entity in self.Tracker.GetEntities <SeekerBarrier>()) { entity.Collidable = false; } if (playerIntro != Player.IntroTypes.Transition) { level.Entities.UpdateLists(); } } }
private static void OnLoadLevelHook(On.Celeste.Level.orig_LoadLevel orig, Level level, Player.IntroTypes introType, bool isFromLoader) { orig(level, introType, isFromLoader); if (SpringCollab2020Module.Instance.Session.SpikeJumpThroughHooked && !level.Session.LevelData.Entities.Any(entity => entity.Name == "SpringCollab2020/SpikeJumpThroughController")) { level.Add(new SpikeJumpThroughController(SpringCollab2020Module.Instance.Session.SpikeJumpThroughHooked, Vector2.Zero)); level.Entities.UpdateLists(); } }
private static void OnLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); if (playerIntro != Player.IntroTypes.Transition) { // do not fade and set the alpha right away when spawning into the level. alphaFade = SpringCollab2020Module.Instance.Session.LightSourcesDisabled ? 0f : 1f; } }
private void onLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Celeste.Level self, Celeste.Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); if (!self.Entities.Any(entity => entity is DashCountIndicator)) { // add the entity showing the dash count (it will be invisible unless the option is enabled) self.Add(new DashCountIndicator()); self.Entities.UpdateLists(); } }
private void onLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); Player player = self.Tracker.GetEntity <Player>(); if (Settings.FriendlyBadelineFollower && player != null && self.Tracker.CountEntities <FriendlyBaddy>() == 0) { self.Add(new FriendlyBaddy(player.Center + new Vector2(-16f * (int)player.Facing, -16f))); } }
private void RestoreEndPoint(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); EndPoint end = self.Entities.FindFirst <EndPoint>(); if (end == null && SavedEndPoint != null && self.Session.Level == SavedEndPoint.LevelName) { SavedEndPoint.ReAdded(self); } }
private void modLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); // failsafe: kill the glitch effect. Glitch.Value = 0; if (Settings.BadelineBossesEverywhere && playerIntro != Player.IntroTypes.Transition) { injectBadelineBosses(self); } }
private static void onLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); DynData <Session> sessionData = new DynData <Session>(self.Session); if (sessionData.Data.ContainsKey("pauseTimerUntilAction") && sessionData.Get <bool>("pauseTimerUntilAction")) { sessionData["pauseTimerUntilAction"] = false; self.TimerStopped = true; unpauseTimerOnNextAction = true; } }
private static void LoadLevel(On.Celeste.Level.orig_LoadLevel orig, Celeste.Level self, Celeste.Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); if (playerIntro != Celeste.Player.IntroTypes.Transition || isFromLoader) { Celeste.Player player = self.Tracker.GetEntity <Celeste.Player>(); foreach (Celeste.EntityID key in (FactoryHelperModule.Instance._Session as FactoryHelperSession).Batteries) { self.Add(new Battery(player, key)); } } }
private static void onLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); // if the player spawned in a Block Jelly Spawn Trigger... if (playerIntro == Player.IntroTypes.Respawn && (self.Tracker.GetEntity <Player>()?.CollideCheck <BlockJellySpawnTrigger>() ?? false)) { // remove all jellyfish from the room. foreach (Glider jelly in self.Entities.OfType <Glider>()) { jelly.RemoveSelf(); } self.Entities.UpdateLists(); } }
public void OnLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level level, Player.IntroTypes playerIntro, bool isFromLoader) { orig(level, playerIntro, isFromLoader); if (isFromLoader) { GhostManager?.RemoveSelf(); GhostManager = null; GhostRecorder?.RemoveSelf(); GhostRecorder = null; Run = Guid.NewGuid(); } Step(level); }
private void onLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); if (!self.Session?.LevelData?.Underwater ?? false) { // inject a controller that will spawn/despawn water depending on the extended variant setting. self.Add(new UnderwaterSwitchController(Settings)); // when transitioning, don't update lists. this messes with sandwich lava, and the hook below will take care of updating lists. if (playerIntro != Player.IntroTypes.Transition) { self.Entities.UpdateLists(); } } }
private static void LevelOnLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); if (!isFromLoader && playerIntro != Player.IntroTypes.Respawn) { return; } // entities with Tags.Global will not be removed after level reloading, so we need to remove them manually self.Entities.Remove(self.Entities.FindAll <CollectablePointer>()); var entities = self.Session.MapData.Levels.SelectMany(data => data.Entities); foreach (EntityData entityData in entities) { TryAddPointer(self, entityData); } }
private void modLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); if (playerIntro != Player.IntroTypes.Transition) { injectTheoCrystal(self); } else if ((Settings.AllowLeavingTheoBehind || Settings.AllowThrowingTheoOffscreen) && !(self.Tracker.GetEntity<Player>()?.Holding?.Entity is TheoCrystal)) { // player is transitioning into a new room, but doesn't have Theo with them. injectTheoCrystalAfterTransition(self); } else if (self.Tracker.CountEntities<ExtendedVariantTheoCrystal>() == 0) { // player is transitioning into a new room, and no Theo crystal is in the room: we should add one if the variant is enabled. injectTheoCrystalAfterTransition(self); } }
private void modLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); if (playerIntro != Player.IntroTypes.Transition) { // always reset the jump count when the player enters a new level (respawn, new map, etc... everything but a transition) RefillJumpBuffer(); } if (!self.Entities.Any(entity => entity is JumpIndicator)) { // add the entity showing the jump count self.Add(new JumpIndicator()); self.Entities.UpdateLists(); } }
private void OnLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level level, Player.IntroTypes playerIntro, bool isFromLoader) { orig(level, playerIntro, isFromLoader); Debug.WriteLine($"OnLoadLevel called, intro type {playerIntro}, isFromLoader {isFromLoader}"); if (isFromLoader) { List <Monocle.Entity> e = level.Tracker.GetEntities <CounterEntity>(); if (e.Count == 1) { Debug.WriteLine("counter already exists"); } else { Debug.WriteLine("Creating counter entity"); level.Add(new CounterEntity(level)); } } }
private void onLoadLevel(On.Celeste.Level.orig_LoadLevel orig, Level self, Player.IntroTypes playerIntro, bool isFromLoader) { orig(self, playerIntro, isFromLoader); if (!self.Session?.LevelData?.Underwater ?? false) { // inject a controller that will spawn/despawn water depending on the extended variant setting. self.Add(new UnderwaterSwitchController(Settings)); // when transitioning, don't update lists right away, but on the end of the frame. if (playerIntro != Player.IntroTypes.Transition) { self.Entities.UpdateLists(); } else { self.OnEndOfFrame += () => self.Entities.UpdateLists(); } } }