Beispiel #1
0
        /*********
        ** Private methods
        *********/
        /// <summary>The method to call instead of <see cref="SaveGame.loadDataToLocations"/>.</summary>
        /// <param name="gamelocations">The game locations being loaded.</param>
        /// <returns>Returns whether to execute the original method.</returns>
        private static bool Before_LoadDataToLocations(List <GameLocation> gamelocations)
        {
            IDictionary <string, string> npcs = Game1.content.Load <Dictionary <string, string> >("Data\\NPCDispositions");

            if (SaveGamePatcher.RemoveBrokenContent(gamelocations, npcs))
            {
                SaveGamePatcher.OnContentRemoved();
            }

            return(true);
        }
Beispiel #2
0
        /// <summary>Remove content which no longer exists in the game data.</summary>
        /// <param name="locations">The current game locations.</param>
        /// <param name="npcs">The NPC data.</param>
        private static bool RemoveBrokenContent(IEnumerable <GameLocation> locations, IDictionary <string, string> npcs)
        {
            bool removedAny = false;

            foreach (GameLocation location in locations)
            {
                removedAny |= SaveGamePatcher.RemoveBrokenContent(location, npcs);
            }

            return(removedAny);
        }
Beispiel #3
0
        /// <summary>The method to call after <see cref="SaveGame.LoadFarmType"/> throws an exception.</summary>
        /// <param name="__exception">The exception thrown by the wrapped method, if any.</param>
        /// <returns>Returns the exception to throw, if any.</returns>
        private static Exception Finalize_LoadFarmType(Exception __exception)
        {
            // missing custom farm type
            if (__exception?.Message?.Contains("not a valid farm type") == true && !int.TryParse(SaveGame.loaded.whichFarm, out _))
            {
                SaveGamePatcher.Monitor.Log(__exception.GetLogSummary(), LogLevel.Error);
                SaveGamePatcher.Monitor.Log($"Removed invalid custom farm type '{SaveGame.loaded.whichFarm}' to avoid a crash when loading save '{Constants.SaveFolderName}'. (Did you remove a custom farm type mod?)", LogLevel.Warn);

                SaveGame.loaded.whichFarm = Farm.default_layout.ToString();
                SaveGame.LoadFarmType();
                SaveGamePatcher.OnContentRemoved();

                __exception = null;
            }

            return(__exception);
        }
Beispiel #4
0
        /// <summary>Remove content which no longer exists in the game data.</summary>
        /// <param name="location">The current game location.</param>
        /// <param name="npcs">The NPC data.</param>
        private static bool RemoveBrokenContent(GameLocation location, IDictionary <string, string> npcs)
        {
            bool removedAny = false;

            if (location == null)
            {
                return(false);
            }

            // check buildings
            if (location is BuildableGameLocation buildableLocation)
            {
                foreach (Building building in buildableLocation.buildings.ToArray())
                {
                    try
                    {
                        BluePrint _ = new BluePrint(building.buildingType.Value);
                    }
                    catch (ContentLoadException)
                    {
                        SaveGamePatcher.Monitor.Log($"Removed invalid building type '{building.buildingType.Value}' in {location.Name} ({building.tileX}, {building.tileY}) to avoid a crash when loading save '{Constants.SaveFolderName}'. (Did you remove a custom building mod?)", LogLevel.Warn);
                        buildableLocation.buildings.Remove(building);
                        removedAny = true;
                        continue;
                    }

                    SaveGamePatcher.RemoveBrokenContent(building.indoors.Value, npcs);
                }
            }

            // check NPCs
            foreach (NPC npc in location.characters.ToArray())
            {
                if (npc.isVillager() && !npcs.ContainsKey(npc.Name))
                {
                    try
                    {
                        npc.reloadSprite(); // this won't crash for special villagers like Bouncer
                    }
                    catch
                    {
                        SaveGamePatcher.Monitor.Log($"Removed invalid villager '{npc.Name}' in {location.Name} ({npc.getTileLocation()}) to avoid a crash when loading save '{Constants.SaveFolderName}'. (Did you remove a custom NPC mod?)", LogLevel.Warn);
                        location.characters.Remove(npc);
                        removedAny = true;
                    }
                }
            }

            // check objects
            foreach (var pair in location.objects.Pairs.ToArray())
            {
                // SpaceCore can leave null values when removing its custom content
                if (pair.Value == null)
                {
                    location.Objects.Remove(pair.Key);
                    SaveGamePatcher.Monitor.Log($"Removed invalid null object in {location.Name} ({pair.Key}) to avoid a crash when loading save '{Constants.SaveFolderName}'. (Did you remove a custom item mod?)", LogLevel.Warn);
                    removedAny = true;
                }
            }

            return(removedAny);
        }