From c5be446701d4e24a03d8464e9b080ce74d158223 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 6 Jan 2021 00:29:39 -0500 Subject: rework vanilla tilesheet checking to avoid keeping a copy of the vanilla maps in memory --- .../ContentManagers/GameContentManager.cs | 32 ++++++++-------------- 1 file changed, 11 insertions(+), 21 deletions(-) (limited to 'src/SMAPI/Framework/ContentManagers') diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs index 424d6ff3..540475f1 100644 --- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs @@ -11,7 +11,6 @@ using StardewModdingAPI.Framework.Reflection; using StardewModdingAPI.Framework.Utilities; using StardewValley; using xTile; -using xTile.Tiles; namespace StardewModdingAPI.Framework.ContentManagers { @@ -398,14 +397,13 @@ namespace StardewModdingAPI.Framework.ContentManagers } // when replacing a map, the vanilla tilesheets must have the same order and IDs - if (data is Map loadedMap && this.Coordinator.TryLoadVanillaAsset(info.AssetName, out Map vanillaMap)) + if (data is Map loadedMap) { - for (int i = 0; i < vanillaMap.TileSheets.Count; i++) + TilesheetReference[] vanillaTilesheetRefs = this.Coordinator.GetVanillaTilesheetIds(info.AssetName); + foreach (TilesheetReference vanillaSheet in vanillaTilesheetRefs) { - // check for match - TileSheet vanillaSheet = vanillaMap.TileSheets[i]; - bool found = this.TryFindTilesheet(loadedMap, vanillaSheet.Id, out int loadedIndex, out TileSheet loadedSheet); - if (found && loadedIndex == i) + // skip if match + if (loadedMap.TileSheets.Count > vanillaSheet.Index && loadedMap.TileSheets[vanillaSheet.Index].Id == vanillaSheet.Id) continue; // handle mismatch @@ -414,9 +412,9 @@ namespace StardewModdingAPI.Framework.ContentManagers // This is temporary: mods shouldn't do this for any vanilla map, but these are the ones we know will crash. Showing a warning for others instead gives modders time to update their mods, while still simplifying troubleshooting. bool isFarmMap = info.AssetNameEquals("Maps/Farm") || info.AssetNameEquals("Maps/Farm_Combat") || info.AssetNameEquals("Maps/Farm_Fishing") || info.AssetNameEquals("Maps/Farm_Foraging") || info.AssetNameEquals("Maps/Farm_FourCorners") || info.AssetNameEquals("Maps/Farm_Island") || info.AssetNameEquals("Maps/Farm_Mining"); - - string reason = found - ? $"mod reordered the original tilesheets, which {(isFarmMap ? "would cause a crash" : "often causes crashes")}.\n\nTechnical details for mod author:\nExpected order [{string.Join(", ", vanillaMap.TileSheets.Select(p => $"'{p.ImageSource}' (id: {p.Id})"))}], but found tilesheet '{vanillaSheet.Id}' at index {loadedIndex} instead of {i}. Make sure custom tilesheet IDs are prefixed with 'z_' to avoid reordering tilesheets." + int loadedIndex = this.TryFindTilesheet(loadedMap, vanillaSheet.Id); + string reason = loadedIndex != -1 + ? $"mod reordered the original tilesheets, which {(isFarmMap ? "would cause a crash" : "often causes crashes")}.\n\nTechnical details for mod author:\nExpected order [{string.Join(", ", vanillaTilesheetRefs.Select(p => $"'{p.ImageSource}' (id: {p.Id})"))}], but found tilesheet '{vanillaSheet.Id}' at index {loadedIndex} instead of {vanillaSheet.Index}. Make sure custom tilesheet IDs are prefixed with 'z_' to avoid reordering tilesheets." : $"mod has no tilesheet with ID '{vanillaSheet.Id}'. Map replacements must keep the original tilesheets to avoid errors or crashes."; SCore.DeprecationManager.PlaceholderWarn("3.8.2", DeprecationLevel.PendingRemoval); @@ -436,23 +434,15 @@ namespace StardewModdingAPI.Framework.ContentManagers /// Find a map tilesheet by ID. /// The map whose tilesheets to search. /// The tilesheet ID to match. - /// The matched tilesheet index, if any. - /// The matched tilesheet, if any. - private bool TryFindTilesheet(Map map, string id, out int index, out TileSheet tilesheet) + private int TryFindTilesheet(Map map, string id) { for (int i = 0; i < map.TileSheets.Count; i++) { if (map.TileSheets[i].Id == id) - { - index = i; - tilesheet = map.TileSheets[i]; - return true; - } + return i; } - index = -1; - tilesheet = null; - return false; + return -1; } } } -- cgit From d5b00bec84fca94ebd94bea509af060928585cc8 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 6 Jan 2021 02:14:44 -0500 Subject: simplify tilesheet order warning --- docs/release-notes.md | 3 +++ src/SMAPI/Framework/ContentManagers/GameContentManager.cs | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src/SMAPI/Framework/ContentManagers') diff --git a/docs/release-notes.md b/docs/release-notes.md index 4c548924..d4702dd5 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -11,6 +11,9 @@ * For players: * Reduced memory usage. +* For modders: + * Simplified tilesheet order warning added in 3.8.2. + * For the Console Commands mod: * Removed experimental `performance` command. Unfortunately this impacted SMAPI's memory usage and the data was often misinterpreted. This may be replaced with more automatic performance alerts in a future version. diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs index 540475f1..3db3856f 100644 --- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs @@ -414,16 +414,16 @@ namespace StardewModdingAPI.Framework.ContentManagers int loadedIndex = this.TryFindTilesheet(loadedMap, vanillaSheet.Id); string reason = loadedIndex != -1 - ? $"mod reordered the original tilesheets, which {(isFarmMap ? "would cause a crash" : "often causes crashes")}.\n\nTechnical details for mod author:\nExpected order [{string.Join(", ", vanillaTilesheetRefs.Select(p => $"'{p.ImageSource}' (id: {p.Id})"))}], but found tilesheet '{vanillaSheet.Id}' at index {loadedIndex} instead of {vanillaSheet.Index}. Make sure custom tilesheet IDs are prefixed with 'z_' to avoid reordering tilesheets." + ? $"mod reordered the original tilesheets, which {(isFarmMap ? "would cause a crash" : "often causes crashes")}.\nTechnical details for mod author: Expected order: {string.Join(", ", vanillaTilesheetRefs.Select(p => p.Id))}. See https://stardewcommunitywiki.com/Modding:Maps#Tilesheet_order for help." : $"mod has no tilesheet with ID '{vanillaSheet.Id}'. Map replacements must keep the original tilesheets to avoid errors or crashes."; SCore.DeprecationManager.PlaceholderWarn("3.8.2", DeprecationLevel.PendingRemoval); if (isFarmMap) { - mod.LogAsMod($"SMAPI blocked asset replacement for '{info.AssetName}': {reason}", LogLevel.Error); + mod.LogAsMod($"SMAPI blocked '{info.AssetName}' map load: {reason}", LogLevel.Error); return false; } - mod.LogAsMod($"SMAPI detected a potential issue with asset replacement for '{info.AssetName}' map: {reason}", LogLevel.Warn); + mod.LogAsMod($"SMAPI found an issue with '{info.AssetName}' map load: {reason}", LogLevel.Warn); } } } -- cgit