Exemple #1
0
        /// <summary>Remove NPCs which don't exist in the game data.</summary>
        /// <param name="locations">The current game locations.</param>
        private static bool RemoveInvalidNpcs(IEnumerable <GameLocation> locations)
        {
            bool removedAny = false;

            IDictionary <string, string> data = Game1.content.Load <Dictionary <string, string> >("Data\\NPCDispositions");

            foreach (GameLocation location in LoadErrorPatch.GetAllLocations(locations))
            {
                foreach (NPC npc in location.characters.ToArray())
                {
                    if (npc.isVillager() && !data.ContainsKey(npc.Name))
                    {
                        try
                        {
                            npc.reloadSprite(); // this won't crash for special villagers like Bouncer
                        }
                        catch
                        {
                            LoadErrorPatch.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;
                        }
                    }
                }
            }

            return(removedAny);
        }
        /*********
        ** 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_SaveGame_LoadDataToLocations(List <GameLocation> gamelocations)
        {
            bool removedAny = false;

            // remove invalid locations
            foreach (GameLocation location in gamelocations.ToArray())
            {
                if (location is Cellar)
                {
                    continue; // missing cellars will be added by the game code
                }
                if (Game1.getLocationFromName(location.name) == null)
                {
                    LoadErrorPatch.Monitor.Log($"Removed invalid location '{location.Name}' to avoid a crash when loading save '{Constants.SaveFolderName}'. (Did you remove a custom location mod?)", LogLevel.Warn);
                    gamelocations.Remove(location);
                    removedAny = true;
                }
            }

            // get building interiors
            var interiors =
                (
                    from location in gamelocations.OfType <BuildableGameLocation>()
                    from building in location.buildings
                    where building.indoors.Value != null
                    select building.indoors.Value
                );

            // remove custom NPCs which no longer exist
            IDictionary <string, string> data = Game1.content.Load <Dictionary <string, string> >("Data\\NPCDispositions");

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

            if (removedAny)
            {
                LoadErrorPatch.OnContentRemoved();
            }

            return(true);
        }
Exemple #3
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_SaveGame_LoadDataToLocations(List <GameLocation> gamelocations)
        {
            bool removedAny =
                LoadErrorPatch.RemoveBrokenBuildings(gamelocations)
                | LoadErrorPatch.RemoveInvalidNpcs(gamelocations);

            if (removedAny)
            {
                LoadErrorPatch.OnContentRemoved();
            }

            return(true);
        }