summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2020-04-25 20:05:15 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2020-04-25 20:05:15 -0400
commitcf7bba5453f87e666759c70a892f76f7dae44dc2 (patch)
tree9bdc68ca617720049564763e9196b018300927a2
parentbeccea7efdd61d6417217eb3f40ca452373ac3d6 (diff)
downloadSMAPI-cf7bba5453f87e666759c70a892f76f7dae44dc2.tar.gz
SMAPI-cf7bba5453f87e666759c70a892f76f7dae44dc2.tar.bz2
SMAPI-cf7bba5453f87e666759c70a892f76f7dae44dc2.zip
fix asset propagation for maps loaded through a temporary content manager
-rw-r--r--docs/release-notes.md1
-rw-r--r--src/SMAPI/Framework/ContentCoordinator.cs27
2 files changed, 23 insertions, 5 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 1eac1d62..c708133a 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -20,6 +20,7 @@
* Added support for using patch helpers (e.g. for image/map patching) with arbitrary data (via `helper.Content.GetPatchHelper`).
* Added `SDate` fields/methods: `SeasonIndex`, `FromDaysSinceStart`, `FromWorldDate`, `ToWorldDate`, and `ToLocaleString` (thanks to kdau!).
* Added `SDate` translations taken from the Lookup Anything mod.ยน
+ * Fixed asset propagation for certain maps loaded through temporarily content managers (notably the farmhouse and town).
* Fixed asset propagation on Linux/Mac for monster sprites, NPC dialogue, and NPC schedules.
* Fixed asset propagation for NPC dialogue sometimes causing a spouse to skip marriage dialogue or not allow kisses.
diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs
index 0b1ccc3c..47ef30d4 100644
--- a/src/SMAPI/Framework/ContentCoordinator.cs
+++ b/src/SMAPI/Framework/ContentCoordinator.cs
@@ -14,6 +14,7 @@ using StardewModdingAPI.Metadata;
using StardewModdingAPI.Toolkit.Serialization;
using StardewModdingAPI.Toolkit.Utilities;
using StardewValley;
+using xTile;
namespace StardewModdingAPI.Framework
{
@@ -228,16 +229,32 @@ namespace StardewModdingAPI.Framework
public IEnumerable<string> InvalidateCache(Func<string, Type, bool> predicate, bool dispose = false)
{
// invalidate cache & track removed assets
- IDictionary<string, ISet<object>> removedAssets = new Dictionary<string, ISet<object>>(StringComparer.InvariantCultureIgnoreCase);
+ IDictionary<string, Type> removedAssets = new Dictionary<string, Type>(StringComparer.InvariantCultureIgnoreCase);
this.ContentManagerLock.InReadLock(() =>
{
+ // cached assets
foreach (IContentManager contentManager in this.ContentManagers)
{
foreach (var entry in contentManager.InvalidateCache(predicate, dispose))
{
- if (!removedAssets.TryGetValue(entry.Key, out ISet<object> assets))
- removedAssets[entry.Key] = assets = new HashSet<object>(new ObjectReferenceComparer<object>());
- assets.Add(entry.Value);
+ if (!removedAssets.TryGetValue(entry.Key, out Type type))
+ removedAssets[entry.Key] = entry.Value.GetType();
+ }
+ }
+
+ // special case: maps may be loaded through a temporary content manager that's removed while the map is still in use.
+ // This notably affects the town and farmhouse maps.
+ if (Game1.locations != null)
+ {
+ foreach (GameLocation location in Game1.locations)
+ {
+ if (location.map == null || string.IsNullOrWhiteSpace(location.mapPath.Value))
+ continue;
+
+ // get map path
+ string mapPath = this.MainContentManager.AssertAndNormalizeAssetName(location.mapPath.Value);
+ if (!removedAssets.ContainsKey(mapPath) && predicate(mapPath, typeof(Map)))
+ removedAssets[mapPath] = typeof(Map);
}
}
});
@@ -245,7 +262,7 @@ namespace StardewModdingAPI.Framework
// reload core game assets
if (removedAssets.Any())
{
- IDictionary<string, bool> propagated = this.CoreAssets.Propagate(this.MainContentManager, removedAssets.ToDictionary(p => p.Key, p => p.Value.First().GetType())); // use an intercepted content manager
+ IDictionary<string, bool> propagated = this.CoreAssets.Propagate(this.MainContentManager, removedAssets.ToDictionary(p => p.Key, p => p.Value)); // use an intercepted content manager
this.Monitor.Log($"Invalidated {removedAssets.Count} asset names ({string.Join(", ", removedAssets.Keys.OrderBy(p => p, StringComparer.InvariantCultureIgnoreCase))}); propagated {propagated.Count(p => p.Value)} core assets.", LogLevel.Trace);
}
else