diff options
author | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-03-25 22:49:14 -0400 |
---|---|---|
committer | Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com> | 2022-03-25 22:49:14 -0400 |
commit | 021891ff0ceb6b327bc196c336aa56ddfaf99b0e (patch) | |
tree | ea7c185bd2ecaccd34114e10440d818b5f52d8b7 /src/SMAPI/Framework | |
parent | 0e0c1356041915a4668b76da9eacc986953392d2 (diff) | |
download | SMAPI-021891ff0ceb6b327bc196c336aa56ddfaf99b0e.tar.gz SMAPI-021891ff0ceb6b327bc196c336aa56ddfaf99b0e.tar.bz2 SMAPI-021891ff0ceb6b327bc196c336aa56ddfaf99b0e.zip |
add load conflict resolution option (#766)
Diffstat (limited to 'src/SMAPI/Framework')
-rw-r--r-- | src/SMAPI/Framework/Content/AssetLoadOperation.cs | 7 | ||||
-rw-r--r-- | src/SMAPI/Framework/ContentCoordinator.cs | 1 | ||||
-rw-r--r-- | src/SMAPI/Framework/ContentManagers/GameContentManager.cs | 17 |
3 files changed, 17 insertions, 8 deletions
diff --git a/src/SMAPI/Framework/Content/AssetLoadOperation.cs b/src/SMAPI/Framework/Content/AssetLoadOperation.cs index 29bf1518..36baf1aa 100644 --- a/src/SMAPI/Framework/Content/AssetLoadOperation.cs +++ b/src/SMAPI/Framework/Content/AssetLoadOperation.cs @@ -14,6 +14,9 @@ namespace StardewModdingAPI.Framework.Content /// <summary>The content pack on whose behalf the asset is being loaded, if any.</summary> public IModMetadata OnBehalfOf { get; } + /// <summary>Whether to allow skipping this operation to resolve a load conflict.</summary> + public bool AllowSkipOnConflict { get; } + /// <summary>Load the initial value for an asset.</summary> public Func<IAssetInfo, object> GetData { get; } @@ -23,11 +26,13 @@ namespace StardewModdingAPI.Framework.Content *********/ /// <summary>Construct an instance.</summary> /// <param name="mod">The mod applying the edit.</param> + /// <param name="allowSkipOnConflict">Whether to allow skipping this operation to resolve a load conflict.</param> /// <param name="onBehalfOf">The content pack on whose behalf the asset is being loaded, if any.</param> /// <param name="getData">Load the initial value for an asset.</param> - public AssetLoadOperation(IModMetadata mod, IModMetadata onBehalfOf, Func<IAssetInfo, object> getData) + public AssetLoadOperation(IModMetadata mod, bool allowSkipOnConflict, IModMetadata onBehalfOf, Func<IAssetInfo, object> getData) { this.Mod = mod; + this.AllowSkipOnConflict = allowSkipOnConflict; this.OnBehalfOf = onBehalfOf; this.GetData = getData; } diff --git a/src/SMAPI/Framework/ContentCoordinator.cs b/src/SMAPI/Framework/ContentCoordinator.cs index 3b304f0d..43cebcbe 100644 --- a/src/SMAPI/Framework/ContentCoordinator.cs +++ b/src/SMAPI/Framework/ContentCoordinator.cs @@ -608,6 +608,7 @@ namespace StardewModdingAPI.Framework { new AssetLoadOperation( mod: loader.Mod, + allowSkipOnConflict: false, onBehalfOf: null, getData: assetInfo => loader.Data.Load<T>(assetInfo) ) diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs index 1d9c8b4c..b3e98648 100644 --- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs +++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs @@ -80,7 +80,7 @@ namespace StardewModdingAPI.Framework.ContentManagers IAssetInfo info = new AssetInfo(locale, assetName, typeof(object), this.AssertAndNormalizeAssetName); AssetLoadOperation[] loaders = this.GetLoaders<object>(info).ToArray(); - if (!this.AssertMaxOneLoader(info, loaders, out string error)) + if (!this.AssertMaxOneRequiredLoader(info, loaders, out string error)) this.Monitor.Log(error, LogLevel.Warn); return loaders.Length == 1; @@ -277,13 +277,15 @@ namespace StardewModdingAPI.Framework.ContentManagers { AssetLoadOperation[] loaders = this.GetLoaders<T>(info).ToArray(); - if (!this.AssertMaxOneLoader(info, loaders, out string error)) + if (!this.AssertMaxOneRequiredLoader(info, loaders, out string error)) { this.Monitor.Log(error, LogLevel.Warn); return null; } - loader = loaders.FirstOrDefault(); + loader = + loaders.FirstOrDefault(p => !p.AllowSkipOnConflict) + ?? loaders.FirstOrDefault(); } // no loader found @@ -392,20 +394,21 @@ namespace StardewModdingAPI.Framework.ContentManagers /// <param name="loaders">The asset loaders to apply.</param> /// <param name="error">The error message to show to the user, if the method returns false.</param> /// <returns>Returns true if only one loader will apply, else false.</returns> - private bool AssertMaxOneLoader(IAssetInfo info, AssetLoadOperation[] loaders, out string error) + private bool AssertMaxOneRequiredLoader(IAssetInfo info, AssetLoadOperation[] loaders, out string error) { - if (loaders.Length <= 1) + AssetLoadOperation[] required = loaders.Where(p => !p.AllowSkipOnConflict).ToArray(); + if (required.Length <= 1) { error = null; return true; } - string[] loaderNames = loaders + string[] loaderNames = required .Select(p => p.Mod.DisplayName + this.GetOnBehalfOfLabel(p.OnBehalfOf)) .Distinct() .ToArray(); string errorPhrase = loaderNames.Length > 1 - ? $"Multiple mods want to provide '{info.Name}' asset: {string.Join(", ", loaderNames)}" + ? $"Multiple mods want to provide the '{info.Name}' asset: {string.Join(", ", loaderNames)}" : $"The '{loaderNames[0]}' mod wants to provide the '{info.Name}' asset multiple times"; error = $"{errorPhrase}. An asset can't be loaded multiple times, so SMAPI will use the default asset instead. Uninstall one of the mods to fix this. (Message for modders: you should usually use {typeof(IAssetEditor)} instead to avoid conflicts.)"; |