Esempio n. 1
0
        // Automatically override intro cutscenes
        private static void SlugcatSelectMenu_StartGame(On.Menu.SlugcatSelectMenu.orig_StartGame orig, SlugcatSelectMenu self, int storyGameCharacter)
        {
            orig(self, storyGameCharacter);

            if (!self.restartChecked && self.manager.rainWorld.progression.IsThereASavedGame(storyGameCharacter))
            {
                return;
            }

            // Only continue to the slideshow if this character has an intro slideshow
            SlugBaseCharacter ply = PlayerManager.GetCustomPlayer(storyGameCharacter);

            if (ply == null)
            {
                return;
            }
            if (ply.HasSlideshow("Intro") && !Input.GetKey("s"))
            {
                OverrideNextSlideshow(ply, "Intro");
                self.manager.upcomingProcess = null;
                self.manager.RequestMainProcessSwitch(ProcessManager.ProcessID.SlideShow);
            }
            else
            {
                self.manager.upcomingProcess = null;
                self.manager.RequestMainProcessSwitch(ProcessManager.ProcessID.Game);
            }
        }
Esempio n. 2
0
 /// <summary>
 /// Creates a scene from a JSON object.
 /// </summary>
 public CustomScene(SlugBaseCharacter owner, string name, JsonObj data) : this(owner, name)
 {
     foreach (var pair in data)
     {
         LoadValue(pair.Key, pair.Value);
     }
 }
Esempio n. 3
0
 /// <summary>
 /// Creates an empty slideshow.
 /// </summary>
 /// <param name="owner"></param>
 /// <param name="name"></param>
 public CustomSlideshow(SlugBaseCharacter owner, string name)
 {
     NextProcess = null;
     Owner       = owner;
     Name        = name;
     Slides      = new List <SlideshowSlide>();
 }
Esempio n. 4
0
        // The select menu relies on a manifest of save information
        // In vanilla, this is either pulled from the current game or mined from the progression file
        // If the indicated slugcat is added by slugbase, instead mine from the custom save file
        private static SlugcatSelectMenu.SaveGameData SlugcatSelectMenu_MineForSaveData(On.Menu.SlugcatSelectMenu.orig_MineForSaveData orig, ProcessManager manager, int slugcat)
        {
            SlugBaseCharacter ply = PlayerManager.GetCustomPlayer(slugcat);

            if (ply != null)
            {
                SaveState save = manager.rainWorld.progression.currentSaveState;
                if (save != null && save.saveStateNumber == slugcat)
                {
                    return(new SlugcatSelectMenu.SaveGameData
                    {
                        karmaCap = save.deathPersistentSaveData.karmaCap,
                        karma = save.deathPersistentSaveData.karma,
                        karmaReinforced = save.deathPersistentSaveData.reinforcedKarma,
                        shelterName = save.denPosition,
                        cycle = save.cycleNumber,
                        hasGlow = save.theGlow,
                        hasMark = save.deathPersistentSaveData.theMark,
                        redsExtraCycles = save.redExtraCycles,
                        food = save.food,
                        redsDeath = save.deathPersistentSaveData.redsDeath,
                        ascended = save.deathPersistentSaveData.ascended
                    });
                }
                int slot = manager.rainWorld.options.saveSlot;
                return(SaveManager.GetCustomSaveData(manager.rainWorld, ply.Name, slot));
            }
            return(orig(manager, slugcat));
        }
Esempio n. 5
0
 /// <summary>
 /// Creates a representation of a SlugBase character.
 /// </summary>
 /// <param name="customPlayer">The character to represent.</param>
 public PlayerDescriptor(SlugBaseCharacter customPlayer)
 {
     type   = Type.SlugBase;
     name   = customPlayer.DisplayName;
     player = customPlayer;
     index  = -1;
 }
Esempio n. 6
0
 internal static CustomScene OverrideNextScene(SlugBaseCharacter ply, string customSceneName, SceneImageFilter filter = null)
 {
     sceneOverride = ply.BuildScene(customSceneName);
     if (filter != null)
     {
         sceneOverride.ApplyFilter(filter);
     }
     return(sceneOverride);
 }
Esempio n. 7
0
        private static bool PlayerProgression_IsThereASavedGame(On.PlayerProgression.orig_IsThereASavedGame orig, PlayerProgression self, int saveStateNumber)
        {
            SlugBaseCharacter ply = PlayerManager.GetCustomPlayer(saveStateNumber);

            if (ply != null)
            {
                return(HasCustomSaveData(ply.Name, self.rainWorld.options.saveSlot));
            }
            return(orig(self, saveStateNumber));
        }
Esempio n. 8
0
        private static void PlayerProgression_WipeSaveState(On.PlayerProgression.orig_WipeSaveState orig, PlayerProgression self, int saveStateNumber)
        {
            orig(self, saveStateNumber);
            SlugBaseCharacter ply = PlayerManager.GetCustomPlayer(saveStateNumber);

            if (ply != null)
            {
                File.Delete(GetSaveFilePath(ply.Name, self.rainWorld.options.saveSlot));
            }
        }
Esempio n. 9
0
        // Change some data associated with custom slugcat pages
        private static void SlugcatPage_ctor(On.Menu.SlugcatSelectMenu.SlugcatPage.orig_ctor orig, SlugcatSelectMenu.SlugcatPage self, Menu.Menu menu, MenuObject owner, int pageIndex, int slugcatNumber)
        {
            orig(self, menu, owner, pageIndex, slugcatNumber);
            SlugBaseCharacter ply = PlayerManager.GetCustomPlayer(pageIndex);

            if (ply != null)
            {
                self.colorName   = ply.Name;
                self.effectColor = ply.SlugcatColor() ?? Color.white;
            }
        }
Esempio n. 10
0
        // Change select screen name and description
        private static void SlugcatPageNewGame_ctor(On.Menu.SlugcatSelectMenu.SlugcatPageNewGame.orig_ctor orig, SlugcatSelectMenu.SlugcatPageNewGame self, Menu.Menu menu, MenuObject owner, int pageIndex, int slugcatNumber)
        {
            orig(self, menu, owner, pageIndex, slugcatNumber);

            SlugBaseCharacter ply = PlayerManager.GetCustomPlayer(slugcatNumber);

            if (ply != null)
            {
                self.difficultyLabel.text = ply.DisplayName.ToUpper();
                self.infoLabel.text       = ply.Description.Replace("<LINE>", Environment.NewLine);
            }
        }
Esempio n. 11
0
        /// <summary>
        /// Creates a new representation of a SlugBase character's save state.
        /// </summary>
        /// <param name="progression">The <see cref="PlayerProgression"/> instance to attach this save state to.</param>
        /// <param name="character">The SlugBase character that owns this save state.</param>
        /// <exception cref="ArgumentException">Thrown when <paramref name="character"/> is null.</exception>
        public CustomSaveState(PlayerProgression progression, SlugBaseCharacter character) : base(character.slugcatIndex, progression)
        {
            if (character == null)
            {
                throw new ArgumentException("Character may not be null.", nameof(character));
            }
            Character = character;

            if (!appliedHooks)
            {
                appliedHooks = true;
                ApplyHooks();
            }
        }
Esempio n. 12
0
        private static Texture2D LoadTextureFromResources(string fileName)
        {
            string[] args = fileName.Split('\\');
            if (args.Length < 2)
            {
                return(null);
            }
            SlugBaseCharacter ply = PlayerManager.GetCustomPlayer(args[0]);

            if (ply == null)
            {
                return(null);
            }

            string[] resourcePath = new string[args.Length - 1];
            for (int i = 0; i < resourcePath.Length; i++)
            {
                resourcePath[i] = args[i + 1];
            }

            if (resourcePath.Length > 0)
            {
                resourcePath[resourcePath.Length - 1] = Path.ChangeExtension(resourcePath[resourcePath.Length - 1], "png");
            }

            // Load the image resource from disk
            Texture2D tex = new Texture2D(1, 1);

            using (Stream imageData = ply.GetResource(resourcePath))
            {
                if (imageData == null)
                {
                    Debug.LogException(new FileNotFoundException($"Could not find image for SlugBase character: \"{ply.Name}:{string.Join("\\", resourcePath)}\"."));
                    return(null);
                }

                if (imageData.Length > int.MaxValue)
                {
                    throw new FormatException($"Image resource may not be more than {int.MaxValue} bytes!");
                }

                BinaryReader br     = new BinaryReader(imageData);
                byte[]       buffer = br.ReadBytes((int)imageData.Length);

                tex.LoadImage(buffer);
            }

            return(tex);
        }
Esempio n. 13
0
        // Automatically override outro cutscenes
        private static void RainWorldGame_ExitToVoidSeaSlideShow(On.RainWorldGame.orig_ExitToVoidSeaSlideShow orig, RainWorldGame self)
        {
            orig(self);

            // Override the outro if this character has the corresponding slideshow
            SlugBaseCharacter ply = PlayerManager.GetCustomPlayer(self.StoryCharacter);

            if (ply == null)
            {
                return;
            }
            if (ply.HasSlideshow("Outro"))
            {
                OverrideNextSlideshow(ply, "Outro");
            }
        }
Esempio n. 14
0
        // Read the shelter name from a separate file
        private static string PlayerProgression_ShelterOfSaveGame(On.PlayerProgression.orig_ShelterOfSaveGame orig, PlayerProgression self, int saveStateNumber)
        {
            SlugBaseCharacter ply = PlayerManager.GetCustomPlayer(saveStateNumber);

            if (ply == null)
            {
                return(orig(self, saveStateNumber));
            }

            if (self.currentSaveState != null && self.currentSaveState.saveStateNumber == saveStateNumber)
            {
                return(self.currentSaveState.denPosition);
            }

            string startRoom = ply.StartRoom;

            int slot = self.rainWorld.options.saveSlot;

            if (!HasCustomSaveData(ply.Name, slot) && startRoom != null)
            {
                return(startRoom);
            }

            string saveText = File.ReadAllText(GetSaveFilePath(ply.Name, slot));

            List <SaveStateMiner.Target> targets = new List <SaveStateMiner.Target>();

            targets.Add(new SaveStateMiner.Target(">DENPOS", "<svB>", "<svA>", 20));

            List <SaveStateMiner.Result> results = SaveStateMiner.Mine(self.rainWorld, saveText, targets);

            if (results.Count > 0 && results[0].data != null)
            {
                return(results[0].data);
            }

            return(startRoom ?? "SU_S01");
        }
Esempio n. 15
0
        private static void MenuScene_AddIllustration(On.Menu.MenuScene.orig_AddIllustration orig, MenuScene self, MenuIllustration newIllu)
        {
            SlugBaseCharacter chara = PlayerManager.GetCustomPlayer(self.menu.manager.rainWorld.progression.miscProgressionData.currentlySelectedSinglePlayerSlugcat);

            if (newIllu.fileName == "Sleep - 2 - Red" &&
                chara != null &&
                !chara.HasScene("SleepScreen") &&
                ((self.menu as SleepAndDeathScreen)?.IsSleepScreen ?? false) &&
                newIllu is MenuDepthIllustration mdi)
            {
                string folder = string.Concat(new object[]
                {
                    "Scenes",
                    Path.DirectorySeparatorChar,
                    "Sleep Screen - White",
                });
                newIllu.RemoveSprites();
                newIllu = new MenuDepthIllustration(newIllu.menu, newIllu.owner, folder, "Sleep - 2 - White", new Vector2(677f, 63f), mdi.depth, mdi.shader);
                moveImages.Add(new KeyValuePair <MenuDepthIllustration, Vector2>((MenuDepthIllustration)newIllu, new Vector2(677f, 63f)));
            }

            orig(self, newIllu);
        }
Esempio n. 16
0
            /// <summary>
            ///
            /// </summary>
            /// <param name="input"></param>
            /// <returns></returns>
            public static PlayerDescriptor FromString(string input)
            {
                try
                {
                    // Find type
                    int typeSplit = input.IndexOf('-');
                    if (typeSplit == -1)
                    {
                        return(new PlayerDescriptor(0));
                    }
                    Type t = Custom.ParseEnum <Type>(input.Substring(0, typeSplit));

                    // Fill data
                    switch (t)
                    {
                    case Type.Vanilla:
                        return(new PlayerDescriptor((int)Custom.ParseEnum <SlugcatStats.Name>(input.Substring(typeSplit + 1))));

                    case Type.SlugBase:
                    {
                        SlugBaseCharacter ply = PlayerManager.GetCustomPlayer(input.Substring(typeSplit + 1));
                        if (ply == null)
                        {
                            return(new PlayerDescriptor(0));
                        }
                        return(new PlayerDescriptor(ply));
                    }

                    default:
                        return(new PlayerDescriptor(0));
                    }
                }
                catch (Exception e)
                {
                    throw new ArgumentException("Failed to parse character descriptor string.", nameof(input), e);
                }
            }
Esempio n. 17
0
        private static void MenuScene_GrafUpdate(On.Menu.MenuScene.orig_GrafUpdate orig, MenuScene self, float timeStacker)
        {
            orig(self, timeStacker);

            if (editor.TryGet(self, out SceneEditor se))
            {
                se.Update(self);
                if (Input.GetKeyDown(KeyCode.RightBracket))
                {
                    se.Remove();
                    editor.Unset(self);
                }
            }
            else
            {
                if (self.sceneFolder == resourceFolderName && Input.GetKeyDown(KeyCode.RightBracket))
                {
                    SlugBaseCharacter ply = null;
                    foreach (MenuObject subObj in self.subObjects)
                    {
                        if (subObj is MenuIllustration illust)
                        {
                            ply = customRep[illust]?.Owner.Owner;
                            if (ply != null)
                            {
                                break;
                            }
                        }
                    }
                    if (ply.DevMode)
                    {
                        editor[self] = new SceneEditor(self);
                    }
                }
            }
        }
Esempio n. 18
0
 /// <summary>
 /// Creates an empty scene.
 /// </summary>
 public CustomScene(SlugBaseCharacter owner, string name)
 {
     Images = new List <SceneImage>();
     Owner  = owner;
     Name   = name;
 }
Esempio n. 19
0
        // Override select scenes for SlugBase characters
        private static void SlugcatPage_AddImage(On.Menu.SlugcatSelectMenu.SlugcatPage.orig_AddImage orig, SlugcatSelectMenu.SlugcatPage self, bool ascended)
        {
            SlugBaseCharacter ply = PlayerManager.GetCustomPlayer(self.slugcatNumber);

            // Do not modify scenes for any non-SlugBase slugcats
            if (ply == null)
            {
                orig(self, ascended);
                return;
            }

            // Use Survivor's default scenes on the select menu
            string sceneName = ascended ? "SelectMenuAscended" : "SelectMenu";

            if (!ply.HasScene(sceneName))
            {
                orig(self, ascended);

                // Fix the scene position being off
                if (self.sceneOffset == default(Vector2))
                {
                    self.sceneOffset = new Vector2(-10f, 100f);
                }

                // Fix the wrong scene loading in when ascended
                if (ascended && self.slugcatImage.sceneID == MenuScene.SceneID.Slugcat_White)
                {
                    self.slugcatImage.RemoveSprites();
                    self.RemoveSubObject(self.slugcatImage);

                    self.slugcatImage = new InteractiveMenuScene(self.menu, self, MenuScene.SceneID.Ghost_White);
                    self.subObjects.Add(self.slugcatImage);
                }

                return;
            }

            // Make sure it doesn't crash if the mark or glow is missing
            self.markSquare = new FSprite("pixel")
            {
                isVisible = false
            };
            self.markGlow = new FSprite("pixel")
            {
                isVisible = false
            };
            self.glowSpriteA = new FSprite("pixel")
            {
                isVisible = false
            };
            self.glowSpriteB = new FSprite("pixel")
            {
                isVisible = false
            };


            // This function intentionally does not call the original
            // If this mod has claimed a slot, it seems best to not let other mods try to change this screen

            // Taken from SlugcatPage.AddImage
            self.imagePos    = new Vector2(683f, 484f);
            self.sceneOffset = new Vector2(0f, 0f);


            // Load a custom character's select screen from resources
            CustomScene scene = OverrideNextScene(ply, sceneName, img =>
            {
                if (img.HasTag("MARK") && !self.HasMark)
                {
                    return(false);
                }
                if (img.HasTag("GLOW") && !self.HasGlow)
                {
                    return(false);
                }
                return(true);
            });

            // Parse selectmenux and selectmenuy
            self.sceneOffset.x = scene.GetProperty <float?>("selectmenux") ?? 0f;
            self.sceneOffset.y = scene.GetProperty <float?>("selectmenuy") ?? 0f;
            Debug.Log($"Scene offset for {ply.Name}: {self.sceneOffset}");

            // Slugcat depth, used for positioning the glow and mark
            self.slugcatDepth = scene.GetProperty <float?>("slugcatdepth") ?? 3f;

            // Add mark
            MarkImage mark = new MarkImage(scene, self.slugcatDepth + 0.1f);

            scene.InsertImage(mark);

            // Add glow
            GlowImage glow = new GlowImage(scene, self.slugcatDepth + 0.1f);

            scene.InsertImage(glow);

            try
            {
                self.slugcatImage = new InteractiveMenuScene(self.menu, self, MenuScene.SceneID.Slugcat_White); // This scene will be immediately overwritten
            } finally { ClearSceneOverride(); }
            self.subObjects.Add(self.slugcatImage);

            // Find the relative mark and glow positions
            self.markOffset = mark.Pos - new Vector2(self.MidXpos, self.imagePos.y + 150f) + self.sceneOffset;
            self.glowOffset = glow.Pos - new Vector2(self.MidXpos, self.imagePos.y) + self.sceneOffset;
        }
Esempio n. 20
0
        // 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();
        }
Esempio n. 21
0
 internal static CustomSlideshow OverrideNextSlideshow(SlugBaseCharacter ply, string customSlideshowName)
 {
     slideshowOverride = ply.BuildSlideshow(customSlideshowName);
     return(slideshowOverride);
 }
Esempio n. 22
0
 /// <summary>
 /// Creates a scene from a JSON string.
 /// </summary>
 public CustomScene(SlugBaseCharacter owner, string name, string json) : this(owner, name, json.dictionaryFromJson())
 {
 }
Esempio n. 23
0
        private static SaveState PlayerProgression_GetOrInitiateSaveState(On.PlayerProgression.orig_GetOrInitiateSaveState orig, PlayerProgression self, int saveStateNumber, RainWorldGame game, ProcessManager.MenuSetup setup, bool saveAsDeathOrQuit)
        {
            int slot = self.rainWorld.options.saveSlot;
            SlugBaseCharacter ply = PlayerManager.GetCustomPlayer(saveStateNumber);

            if (ply == null)
            {
                return(orig(self, saveStateNumber, game, setup, saveAsDeathOrQuit));
            }


            // Copied from PlayerProgression.GetOrInitiateSaveState

            if (self.currentSaveState == null && self.starvedSaveState != null)
            {
                Debug.Log("LOADING STARVED STATE");
                self.currentSaveState = self.starvedSaveState;
                self.currentSaveState.deathPersistentSaveData.winState.ResetLastShownValues();
                self.starvedSaveState = null;
            }
            if (self.currentSaveState != null && self.currentSaveState.saveStateNumber == saveStateNumber)
            {
                if (saveAsDeathOrQuit)
                {
                    self.SaveDeathPersistentDataOfCurrentState(true, true);
                }
                return(self.currentSaveState);
            }

            // Create a CustomSaveState instance instead
            self.currentSaveState = ply.CreateNewSave(self);

            if (!File.Exists(self.saveFilePath) || !setup.LoadInitCondition)
            {
                self.currentSaveState.LoadGame(string.Empty, game);
            }
            else
            {
                // Read the save state from a separate file instead of from prog lines
                CustomSaveState css = self.currentSaveState as CustomSaveState;
                if (css != null && HasCustomSaveData(ply.Name, slot))
                {
                    string inSave = File.ReadAllText(GetSaveFilePath(ply.Name, slot));
                    self.currentSaveState.LoadGame(inSave, game);
                    if (saveAsDeathOrQuit)
                    {
                        self.SaveDeathPersistentDataOfCurrentState(true, true);
                    }
                    return(self.currentSaveState);
                }

                // By default, load an empty string
                self.currentSaveState.LoadGame(string.Empty, game);
            }
            if (saveAsDeathOrQuit)
            {
                self.SaveDeathPersistentDataOfCurrentState(true, true);
            }
            return(self.currentSaveState);
            // End copied section
        }
Esempio n. 24
0
        // Update a file on the disk with the current save-persistent data
        private static void PlayerProgression_SaveDeathPersistentDataOfCurrentState(On.PlayerProgression.orig_SaveDeathPersistentDataOfCurrentState orig, PlayerProgression self, bool saveAsIfPlayerDied, bool saveAsIfPlayerQuit)
        {
            int slot = self.rainWorld.options.saveSlot;
            SlugBaseCharacter ply = null;

            if (self.currentSaveState != null)
            {
                ply = PlayerManager.GetCustomPlayer(self.currentSaveState.saveStateNumber);
            }
            if (ply == null || !(self.currentSaveState is CustomSaveState css))
            {
                orig(self, saveAsIfPlayerDied, saveAsIfPlayerQuit);
                return;
            }

            // Copied from PlayerProgression.SaveDeathPersistentDataOfCurrentState

            Debug.Log(string.Concat(new object[]
            {
                "save slugbase deathPersistent data ",
                self.currentSaveState.deathPersistentSaveData.karma,
                " sub karma: ",
                saveAsIfPlayerDied,
                " (quit:",
                saveAsIfPlayerQuit,
                ")"
            }));

            string savePath    = GetSaveFilePath(ply.Name, slot);
            string vanillaDPSD = self.currentSaveState.deathPersistentSaveData.SaveToString(saveAsIfPlayerDied, saveAsIfPlayerQuit);
            string customDPSD  = css.SaveCustomPermanentToString(saveAsIfPlayerDied, saveAsIfPlayerQuit);

            string inSave;

            try
            {
                inSave = File.ReadAllText(savePath);
            }
            catch (Exception)
            {
                // Consider changing to handle FileNotFound only
                return;
            }
            StringBuilder outSave = new StringBuilder();

            string[] array2 = Regex.Split(inSave, "<svA>");
            for (int j = 0; j < array2.Length; j++)
            {
                string[] pair = Regex.Split(array2[j], "<svB>");
                // Save vanilla DPSD
                if (pair[0] == "DEATHPERSISTENTSAVEDATA" && !string.IsNullOrEmpty(vanillaDPSD))
                {
                    outSave.Append("DEATHPERSISTENTSAVEDATA<svB>" + vanillaDPSD + "<svA>");
                }
                // Save custom DPSD
                else if (pair[0] == "SLUGBASEPERSISTENT" && !string.IsNullOrEmpty(customDPSD))
                {
                    outSave.Append("SLUGBASEPERSISTENT<svB>" + customDPSD + "<svA>");
                }
                // Echo any other data
                else
                {
                    outSave.Append(array2[j] + "<svA>");
                }
            }

            File.WriteAllText(savePath, outSave.ToString());
        }