diff --git a/docs/release-notes.md b/docs/release-notes.md
index cfcaf65c..2f5ecf5d 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -8,6 +8,7 @@
* For modders:
* Reloading a map asset will now update affected locations.
* Reloading the `Data\NPCDispositions` asset will now update affected NPCs.
+ * Fixed some map tilesheets not editable if not playing in English.
* Fixed newlines in most manifest fields not being ignored.
* For the web UI:
diff --git a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
index ed08f11c..724a6e1c 100644
--- a/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/BaseContentManager.cs
@@ -32,12 +32,12 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// Whether the content coordinator has been disposed.
private bool IsDisposed;
- /// The language enum values indexed by locale code.
- private readonly IDictionary LanguageCodes;
-
/// A callback to invoke when the content manager is being disposed.
private readonly Action OnDisposing;
+ /// The language enum values indexed by locale code.
+ protected IDictionary LanguageCodes { get; }
+
/*********
** Accessors
diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
index a53840bc..4f3b6fbc 100644
--- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using StardewModdingAPI.Framework.Content;
+using StardewModdingAPI.Framework.Exceptions;
using StardewModdingAPI.Framework.Reflection;
using StardewModdingAPI.Framework.Utilities;
using StardewValley;
@@ -52,7 +53,10 @@ namespace StardewModdingAPI.Framework.ContentManagers
/// The language code for which to load content.
public override T Load(string assetName, LanguageCode language)
{
+ // normalise asset name
assetName = this.AssertAndNormaliseAssetName(assetName);
+ if (this.TryParseExplicitLanguageAssetKey(assetName, out string newAssetName, out LanguageCode newLanguage))
+ return this.Load(newAssetName, newLanguage);
// get from cache
if (this.IsLoaded(assetName))
@@ -124,6 +128,29 @@ namespace StardewModdingAPI.Framework.ContentManagers
return false;
}
+ /// Parse an asset key that contains an explicit language into its asset name and language, if applicable.
+ /// The asset key to parse.
+ /// The asset name without the language code.
+ /// The language code removed from the asset name.
+ private bool TryParseExplicitLanguageAssetKey(string rawAsset, out string assetName, out LanguageCode language)
+ {
+ if (string.IsNullOrWhiteSpace(rawAsset))
+ throw new SContentLoadException("The asset key is empty.");
+
+ // extract language code
+ int splitIndex = rawAsset.LastIndexOf('.');
+ if (splitIndex != -1 && this.LanguageCodes.TryGetValue(rawAsset.Substring(splitIndex + 1), out language))
+ {
+ assetName = rawAsset.Substring(0, splitIndex);
+ return true;
+ }
+
+ // no explicit language code found
+ assetName = rawAsset;
+ language = this.Language;
+ return false;
+ }
+
/// Load the initial asset from the registered .
/// The basic asset metadata.
/// Returns the loaded asset metadata, or null if no loader matched.