summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/release-notes.md1
-rw-r--r--src/SMAPI/Framework/ContentCoordinator.cs33
-rw-r--r--src/SMAPI/Framework/SCore.cs11
3 files changed, 38 insertions, 7 deletions
diff --git a/docs/release-notes.md b/docs/release-notes.md
index 5e004227..d549b99c 100644
--- a/docs/release-notes.md
+++ b/docs/release-notes.md
@@ -8,6 +8,7 @@
* For mod authors:
* The `SDate` constructor is no longer case-sensitive for season names.
* Fixed issue where suppressing `[Left|Right]Thumbstick[Down|Left]` keys would suppress the opposite direction instead.
+ * Fixed support for using locale codes from custom languages in asset names (e.g. `Data/Achievements.eo-EU`).
* For console commands:
* Fixed `player_add` with Journal Scraps and Secret Notes.
diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs
index 49578046..61cefd12 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 StardewValley.GameData;
using xTile;
namespace StardewModdingAPI.Framework
@@ -136,7 +137,7 @@ namespace StardewModdingAPI.Framework
this.ContentManagers.Add(contentManagerForAssetPropagation);
this.VanillaContentManager = new LocalizedContentManager(serviceProvider, rootDirectory);
this.CoreAssets = new CoreAssetPropagator(this.MainContentManager, contentManagerForAssetPropagation, this.Monitor, reflection, aggressiveMemoryOptimizations);
- this.LocaleCodes = new Lazy<Dictionary<string, LocalizedContentManager.LanguageCode>>(this.GetLocaleCodes);
+ this.LocaleCodes = new Lazy<Dictionary<string, LocalizedContentManager.LanguageCode>>(() => this.GetLocaleCodes(includeCustomLanguages: false));
}
/// <summary>Get a new content manager which handles reading files from the game content folder with support for interception.</summary>
@@ -196,12 +197,17 @@ namespace StardewModdingAPI.Framework
return this.MainContentManager.GetLocale(LocalizedContentManager.CurrentLanguageCode);
}
- /// <summary>Perform any cleanup needed when the locale changes.</summary>
- public void OnLocaleChanged()
+ /// <summary>Perform any updates needed when the game loads custom languages from <c>Data/AdditionalLanguages</c>.</summary>
+ public void OnAdditionalLanguagesInitialized()
{
- // rebuild locale cache (which may change due to custom mod languages)
- this.LocaleCodes = new Lazy<Dictionary<string, LocalizedContentManager.LanguageCode>>(this.GetLocaleCodes);
+ // update locale cache for custom languages, and load it now (since languages added later won't work)
+ this.LocaleCodes = new Lazy<Dictionary<string, LocalizedContentManager.LanguageCode>>(() => this.GetLocaleCodes(includeCustomLanguages: true));
+ _ = this.LocaleCodes.Value;
+ }
+ /// <summary>Perform any updates needed when the locale changes.</summary>
+ public void OnLocaleChanged()
+ {
// reload affected content
this.ContentManagerLock.InReadLock(() =>
{
@@ -486,9 +492,22 @@ namespace StardewModdingAPI.Framework
}
/// <summary>Get the language enums (like <see cref="LocalizedContentManager.LanguageCode.ja"/>) indexed by locale code (like <c>ja-JP</c>).</summary>
- private Dictionary<string, LocalizedContentManager.LanguageCode> GetLocaleCodes()
+ /// <param name="includeCustomLanguages">Whether to read custom languages from <c>Data/AdditionalLanguages</c>.</param>
+ private Dictionary<string, LocalizedContentManager.LanguageCode> GetLocaleCodes(bool includeCustomLanguages)
{
- var map = new Dictionary<string, LocalizedContentManager.LanguageCode>();
+ var map = new Dictionary<string, LocalizedContentManager.LanguageCode>(StringComparer.OrdinalIgnoreCase);
+
+ // custom languages
+ if (includeCustomLanguages)
+ {
+ foreach (ModLanguage language in Game1.content.Load<List<ModLanguage>>("Data/AdditionalLanguages"))
+ {
+ if (!string.IsNullOrWhiteSpace(language?.LanguageCode))
+ map[language.LanguageCode] = LocalizedContentManager.LanguageCode.mod;
+ }
+ }
+
+ // vanilla languages (override custom language if they conflict)
foreach (LocalizedContentManager.LanguageCode code in Enum.GetValues(typeof(LocalizedContentManager.LanguageCode)))
{
string locale = this.GetLocaleCode(code);
diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index ef1f12fd..bfbd64ca 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -43,6 +43,7 @@ using StardewModdingAPI.Toolkit.Serialization;
using StardewModdingAPI.Toolkit.Utilities;
using StardewModdingAPI.Utilities;
using StardewValley;
+using StardewValley.Menus;
using xTile.Display;
using MiniMonoModHotfix = MonoMod.Utils.MiniMonoModHotfix;
using PathUtilities = StardewModdingAPI.Toolkit.Utilities.PathUtilities;
@@ -121,6 +122,9 @@ namespace StardewModdingAPI.Framework
/// <summary>Whether post-game-startup initialization has been performed.</summary>
private bool IsInitialized;
+ /// <summary>Whether the game has initialized for any custom languages from <c>Data/AdditionalLanguages</c>.</summary>
+ private bool AreCustomLanguagesInitialized;
+
/// <summary>Whether the player just returned to the title screen.</summary>
public bool JustReturnedToTitle { get; set; }
@@ -986,6 +990,13 @@ namespace StardewModdingAPI.Framework
// preloaded
if (Context.IsSaveLoaded && Context.LoadStage != LoadStage.Loaded && Context.LoadStage != LoadStage.Ready && Game1.dayOfMonth != 0)
this.OnLoadStageChanged(LoadStage.Loaded);
+
+ // additional languages initialized
+ if (!this.AreCustomLanguagesInitialized && TitleMenu.ticksUntilLanguageLoad < 0)
+ {
+ this.AreCustomLanguagesInitialized = true;
+ this.ContentCore.OnAdditionalLanguagesInitialized();
+ }
}
/*********