// Same as below, but for slideshows private static void SlideShow_ctor(On.Menu.SlideShow.orig_ctor orig, SlideShow self, ProcessManager manager, SlideShow.SlideShowID slideShowID) { // Automatically override slideshows if the current character has a slideshow by the same name SlugBaseCharacter currentPlayer; if (PlayerManager.UsingCustomCharacter) { currentPlayer = PlayerManager.CurrentCharacter; } else { int index; if (manager.currentMainLoop is RainWorldGame rwg) { index = rwg.StoryCharacter; } else { index = manager.rainWorld.progression.PlayingAsSlugcat; } currentPlayer = PlayerManager.GetCustomPlayer(index); } if (currentPlayer != null) { string slideshowName = self.slideShowID.ToString(); if (slideshowOverride == null && currentPlayer.HasSlideshow(slideshowName)) { OverrideNextSlideshow(currentPlayer, slideshowName); } } if (slideshowOverride == null) { orig(self, manager, slideShowID); return; } try { // Call the original constructor, save a reference to the loading label // This will always be empty, due to the ID of -1 FLabel loadingLabel = manager.loadingLabel; orig(self, manager, (SlideShow.SlideShowID)(-1)); // Undo RemoveLoadingLabel and NextScene manager.loadingLabel = loadingLabel; Futile.stage.AddChild(loadingLabel); self.current = -1; // Load a custom scene SlugBaseCharacter owner = slideshowOverride.Owner; List <SlideshowSlide> slides = slideshowOverride.Slides; // Chose a destination process if (slideshowOverride.NextProcess == null) { switch (slideShowID) { case SlideShow.SlideShowID.WhiteIntro: case SlideShow.SlideShowID.YellowIntro: self.nextProcess = ProcessManager.ProcessID.Game; break; case SlideShow.SlideShowID.WhiteOutro: case SlideShow.SlideShowID.YellowOutro: case SlideShow.SlideShowID.RedOutro: self.nextProcess = ProcessManager.ProcessID.Credits; break; default: // Take a best guess // Accidentally going to the game is better than accidentally going to the credits self.nextProcess = ProcessManager.ProcessID.Game; break; } } else { self.nextProcess = slideshowOverride.NextProcess.Value; } // Custom music if (manager.musicPlayer != null) { self.waitForMusic = slideshowOverride.Music; self.stall = true; manager.musicPlayer.MenuRequestsSong(self.waitForMusic, 1.5f, 40f); } // Custom playlist float time = 0f; float endTime; self.playList.Clear(); foreach (SlideshowSlide slide in slides) { if (!slide.Enabled) { continue; } endTime = time + slide.Duration; self.playList.Add(new SlideShow.Scene(MenuScene.SceneID.Empty, time, time + slide.FadeIn, endTime - slide.FadeOut)); time = endTime; } // Preload the scenes self.preloadedScenes = new SlideShowMenuScene[self.playList.Count]; try { for (int i = 0; i < self.preloadedScenes.Length; i++) { MenuScene.SceneID id = MenuScene.SceneID.Empty; if (slideshowOverride.Owner.HasScene(slides[i].SceneName)) { // Prioritize this character's scenes OverrideNextScene(slideshowOverride.Owner, slideshowOverride.Slides[i].SceneName); } else { ClearSceneOverride(); try { // ... then try existing scenes id = Custom.ParseEnum <MenuScene.SceneID>(slides[i].SceneName); } catch (Exception) { // ... and default to Empty id = MenuScene.SceneID.Empty; } } self.preloadedScenes[i] = new SlideShowMenuScene(self, self.pages[0], id); self.preloadedScenes[i].Hide(); List <Vector3> camPath = self.preloadedScenes[i].cameraMovementPoints; camPath.Clear(); camPath.AddRange(slides[i].CameraPath); } } finally { ClearSceneOverride(); } } finally { ClearSlideshowOverride(); } manager.RemoveLoadingLabel(); self.NextScene(); }