/// <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 = LoadErrorPatch.RemoveBrokenBuildings(gamelocations) | LoadErrorPatch.RemoveInvalidNpcs(gamelocations); if (removedAny) { LoadErrorPatch.OnContentRemoved(); } return(true); }