From 065859408f4e88ea1154b1fc76f7df5288e51b53 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 18 Feb 2022 12:31:14 -0500 Subject: Fix support for custom locale codes in asset names (#766) --- src/SMAPI/Framework/ContentCoordinator.cs | 33 ++++++++++++++++++++++++------- src/SMAPI/Framework/SCore.cs | 11 +++++++++++ 2 files changed, 37 insertions(+), 7 deletions(-) (limited to 'src/SMAPI/Framework') 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>(this.GetLocaleCodes); + this.LocaleCodes = new Lazy>(() => this.GetLocaleCodes(includeCustomLanguages: false)); } /// Get a new content manager which handles reading files from the game content folder with support for interception. @@ -196,12 +197,17 @@ namespace StardewModdingAPI.Framework return this.MainContentManager.GetLocale(LocalizedContentManager.CurrentLanguageCode); } - /// Perform any cleanup needed when the locale changes. - public void OnLocaleChanged() + /// Perform any updates needed when the game loads custom languages from Data/AdditionalLanguages. + public void OnAdditionalLanguagesInitialized() { - // rebuild locale cache (which may change due to custom mod languages) - this.LocaleCodes = new Lazy>(this.GetLocaleCodes); + // update locale cache for custom languages, and load it now (since languages added later won't work) + this.LocaleCodes = new Lazy>(() => this.GetLocaleCodes(includeCustomLanguages: true)); + _ = this.LocaleCodes.Value; + } + /// Perform any updates needed when the locale changes. + public void OnLocaleChanged() + { // reload affected content this.ContentManagerLock.InReadLock(() => { @@ -486,9 +492,22 @@ namespace StardewModdingAPI.Framework } /// Get the language enums (like ) indexed by locale code (like ja-JP). - private Dictionary GetLocaleCodes() + /// Whether to read custom languages from Data/AdditionalLanguages. + private Dictionary GetLocaleCodes(bool includeCustomLanguages) { - var map = new Dictionary(); + var map = new Dictionary(StringComparer.OrdinalIgnoreCase); + + // custom languages + if (includeCustomLanguages) + { + foreach (ModLanguage language in Game1.content.Load>("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 /// Whether post-game-startup initialization has been performed. private bool IsInitialized; + /// Whether the game has initialized for any custom languages from Data/AdditionalLanguages. + private bool AreCustomLanguagesInitialized; + /// Whether the player just returned to the title screen. 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(); + } } /********* -- cgit