fix split-screen error when a mod provides a localized asset in one screen but not another
This commit is contained in:
parent
5083b65c87
commit
064346594d
|
@ -1,6 +1,10 @@
|
|||
← [README](README.md)
|
||||
|
||||
# Release notes
|
||||
## Upcoming release
|
||||
* For players:
|
||||
* Fixed error in split-screen mode when a mod provides a localized asset in one screen but not another.
|
||||
|
||||
## 3.14.5
|
||||
Released 22 May 2022 for Stardew Valley 1.5.6 or later.
|
||||
|
||||
|
|
|
@ -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.
|
||||
{
|
||||
Dictionary<string, string> localizedAssetNames = this.LocalizedAssetNames.Value;
|
||||
foreach (IAssetName assetName in invalidatedAssets.Keys)
|
||||
{
|
||||
LocalizedContentManager.localizedAssetNames.Remove(assetName.Name);
|
||||
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.
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue