diff options
Diffstat (limited to 'src/SMAPI/Framework')
-rw-r--r-- | src/SMAPI/Framework/ContentCoordinator.cs | 24 | ||||
-rw-r--r-- | src/SMAPI/Framework/ContentManagers/BaseContentManager.cs | 12 |
2 files changed, 26 insertions, 10 deletions
diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs index fc61b44b..cfeb35c8 100644 --- a/src/SMAPI/Framework/ContentCoordinator.cs +++ b/src/SMAPI/Framework/ContentCoordinator.cs @@ -15,8 +15,8 @@ using StardewModdingAPI.Framework.Utilities; using StardewModdingAPI.Internal; using StardewModdingAPI.Metadata; using StardewModdingAPI.Toolkit.Serialization; -using StardewModdingAPI.Toolkit.Utilities; using StardewModdingAPI.Toolkit.Utilities.PathLookups; +using StardewModdingAPI.Utilities; using StardewValley; using StardewValley.GameData; using xTile; @@ -110,6 +110,10 @@ namespace StardewModdingAPI.Framework /// <summary>The absolute path to the <see cref="ContentManager.RootDirectory"/>.</summary> public string FullRootDirectory { get; } + /// <summary>A lookup which tracks whether each given asset name has a localized form.</summary> + /// <remarks>This is a per-screen equivalent to the base game's <see cref="LocalizedContentManager.localizedAssetNames"/> field, since mods may provide different assets per-screen.</remarks> + public PerScreen<Dictionary<string, string>> LocalizedAssetNames { get; } = new(() => new()); + /********* ** Public methods @@ -245,6 +249,9 @@ namespace StardewModdingAPI.Framework { this.VanillaContentManager.Unload(); }); + + // forget localized flags (to match the logic in Game1.TranslateFields, which is called on language change) + this.LocalizedAssetNames.Value.Clear(); } /// <summary>Clean up when the player is returning to the title screen.</summary> @@ -275,6 +282,10 @@ namespace StardewModdingAPI.Framework // their changes, the assets won't be found in the cache so no changes will be propagated. if (LocalizedContentManager.CurrentLanguageCode != LocalizedContentManager.LanguageCode.en) this.InvalidateCache((contentManager, _, _) => contentManager is GameContentManager); + + // clear the localized assets lookup (to match the logic in Game1.CleanupReturningToTitle) + foreach ((_, Dictionary<string, string> localizedAssets) in this.LocalizedAssetNames.GetActiveValues()) + localizedAssets.Clear(); } /// <summary>Parse a raw asset name.</summary> @@ -411,12 +422,15 @@ namespace StardewModdingAPI.Framework // A mod might provide a localized variant of a normally non-localized asset (like // `Maps/MovieTheater.fr-FR`). When the asset is invalidated, we need to recheck // whether the asset is localized in case it stops providing it. - foreach (IAssetName assetName in invalidatedAssets.Keys) { - LocalizedContentManager.localizedAssetNames.Remove(assetName.Name); + Dictionary<string, string> localizedAssetNames = this.LocalizedAssetNames.Value; + foreach (IAssetName assetName in invalidatedAssets.Keys) + { + localizedAssetNames.Remove(assetName.Name); - if (LocalizedContentManager.localizedAssetNames.TryGetValue(assetName.BaseName, out string? targetForBaseKey) && targetForBaseKey == assetName.Name) - LocalizedContentManager.localizedAssetNames.Remove(assetName.BaseName); + if (localizedAssetNames.TryGetValue(assetName.BaseName, out string? targetForBaseKey) && targetForBaseKey == assetName.Name) + localizedAssetNames.Remove(assetName.BaseName); + } } // special case: maps may be loaded through a temporary content manager that's removed while the map is still in use. diff --git a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs index ddc02a8c..d7be0c37 100644 --- a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs @@ -153,7 +153,9 @@ namespace StardewModdingAPI.Framework.ContentManagers return this.LoadExact<T>(assetName, useCache: useCache); // check for localized asset - if (!LocalizedContentManager.localizedAssetNames.TryGetValue(assetName.Name, out _)) + // ReSharper disable once LocalVariableHidesMember -- this is deliberate + Dictionary<string, string> localizedAssetNames = this.Coordinator.LocalizedAssetNames.Value; + if (!localizedAssetNames.TryGetValue(assetName.Name, out _)) { string localeCode = this.LanguageCodeString(language); IAssetName localizedName = new AssetName(baseName: assetName.BaseName, localeCode: localeCode, languageCode: language); @@ -161,7 +163,7 @@ namespace StardewModdingAPI.Framework.ContentManagers try { T data = this.LoadExact<T>(localizedName, useCache: useCache); - LocalizedContentManager.localizedAssetNames[assetName.Name] = localizedName.Name; + localizedAssetNames[assetName.Name] = localizedName.Name; return data; } catch (ContentLoadException) @@ -170,18 +172,18 @@ namespace StardewModdingAPI.Framework.ContentManagers try { T data = this.LoadExact<T>(localizedName, useCache: useCache); - LocalizedContentManager.localizedAssetNames[assetName.Name] = localizedName.Name; + localizedAssetNames[assetName.Name] = localizedName.Name; return data; } catch (ContentLoadException) { - LocalizedContentManager.localizedAssetNames[assetName.Name] = assetName.Name; + localizedAssetNames[assetName.Name] = assetName.Name; } } } // use cached key - string rawName = LocalizedContentManager.localizedAssetNames[assetName.Name]; + string rawName = localizedAssetNames[assetName.Name]; if (assetName.Name != rawName) assetName = this.Coordinator.ParseAssetName(rawName, allowLocales: this.TryLocalizeKeys); return this.LoadExact<T>(assetName, useCache: useCache); |