summaryrefslogtreecommitdiff
path: root/src/SMAPI/Framework
diff options
context:
space:
mode:
authorJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-03-25 22:49:14 -0400
committerJesse Plamondon-Willard <Pathoschild@users.noreply.github.com>2022-03-25 22:49:14 -0400
commit021891ff0ceb6b327bc196c336aa56ddfaf99b0e (patch)
treeea7c185bd2ecaccd34114e10440d818b5f52d8b7 /src/SMAPI/Framework
parent0e0c1356041915a4668b76da9eacc986953392d2 (diff)
downloadSMAPI-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.cs7
-rw-r--r--src/SMAPI/Framework/ContentCoordinator.cs1
-rw-r--r--src/SMAPI/Framework/ContentManagers/GameContentManager.cs17
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.)";