summaryrefslogtreecommitdiff
path: root/src/SMAPI
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI')
-rw-r--r--src/SMAPI/Framework/ContentManagers/GameContentManager.cs32
1 files changed, 19 insertions, 13 deletions
diff --git a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
index 8bdb39d0..1d9c8b4c 100644
--- a/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
+++ b/src/SMAPI/Framework/ContentManagers/GameContentManager.cs
@@ -305,7 +305,7 @@ namespace StardewModdingAPI.Framework.ContentManagers
}
// return matched asset
- return this.TryFixAndValidateLoadedAsset(info, data, mod)
+ return this.TryFixAndValidateLoadedAsset(info, data, loader)
? new AssetDataForObject(info, data, this.AssertAndNormalizeAssetName)
: null;
}
@@ -401,39 +401,45 @@ namespace StardewModdingAPI.Framework.ContentManagers
}
string[] loaderNames = loaders
- .Select(p => p.Mod.DisplayName)
+ .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 '{info.Name}' asset: {string.Join(", ", loaderNames)}"
: $"The '{loaderNames[0]}' mod wants to provide the '{info.Name}' asset multiple times";
- error = $"{errorPhrase}, but an asset can't be loaded multiple times. 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.)";
+ 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.)";
return false;
}
/// <summary>Get a parenthetical label for log messages for the content pack on whose behalf the action is being performed, if any.</summary>
/// <param name="onBehalfOf">The content pack on whose behalf the action is being performed.</param>
- private string GetOnBehalfOfLabel(IModMetadata onBehalfOf)
+ /// <param name="parenthetical">whether to format the label as a parenthetical shown after the mod name like <c> (for the 'X' content pack)</c>, instead of a standalone label like <c>the 'X' content pack</c>.</param>
+ /// <returns>Returns the on-behalf-of label if applicable, else <c>null</c>.</returns>
+ private string GetOnBehalfOfLabel(IModMetadata onBehalfOf, bool parenthetical = true)
{
if (onBehalfOf == null)
- return string.Empty;
+ return null;
- return $" (for the '{onBehalfOf.Manifest.Name}' content pack)";
+ return parenthetical
+ ? $" (for the '{onBehalfOf.Manifest.Name}' content pack)"
+ : $"the '{onBehalfOf.Manifest.Name}' content pack";
}
/// <summary>Validate that an asset loaded by a mod is valid and won't cause issues, and fix issues if possible.</summary>
/// <typeparam name="T">The asset type.</typeparam>
/// <param name="info">The basic asset metadata.</param>
/// <param name="data">The loaded asset data.</param>
- /// <param name="mod">The mod which loaded the asset.</param>
+ /// <param name="loader">The loader which loaded the asset.</param>
/// <returns>Returns whether the asset passed validation checks (after any fixes were applied).</returns>
- private bool TryFixAndValidateLoadedAsset<T>(IAssetInfo info, T data, IModMetadata mod)
+ private bool TryFixAndValidateLoadedAsset<T>(IAssetInfo info, T data, AssetLoadOperation loader)
{
+ IModMetadata mod = loader.Mod;
+
// can't load a null asset
if (data == null)
{
- mod.LogAsMod($"SMAPI blocked asset replacement for '{info.Name}': mod incorrectly set asset to a null value.", LogLevel.Error);
+ mod.LogAsMod($"SMAPI blocked asset replacement for '{info.Name}': {this.GetOnBehalfOfLabel(loader.OnBehalfOf, parenthetical: false) ?? "mod"} incorrectly set asset to a null value.", LogLevel.Error);
return false;
}
@@ -459,15 +465,15 @@ namespace StardewModdingAPI.Framework.ContentManagers
// This is temporary: mods shouldn't do this for any vanilla map, but these are the ones we know will crash. Showing a warning for others instead gives modders time to update their mods, while still simplifying troubleshooting.
bool isFarmMap = info.Name.IsEquivalentTo("Maps/Farm") || info.Name.IsEquivalentTo("Maps/Farm_Combat") || info.Name.IsEquivalentTo("Maps/Farm_Fishing") || info.Name.IsEquivalentTo("Maps/Farm_Foraging") || info.Name.IsEquivalentTo("Maps/Farm_FourCorners") || info.Name.IsEquivalentTo("Maps/Farm_Island") || info.Name.IsEquivalentTo("Maps/Farm_Mining");
- string reason = $"mod reordered the original tilesheets, which {(isFarmMap ? "would cause a crash" : "often causes crashes")}.\nTechnical details for mod author: Expected order: {string.Join(", ", vanillaTilesheetRefs.Select(p => p.Id))}. See https://stardewvalleywiki.com/Modding:Maps#Tilesheet_order for help.";
+ string reason = $"{this.GetOnBehalfOfLabel(loader.OnBehalfOf, parenthetical: false) ?? "mod"} reordered the original tilesheets, which {(isFarmMap ? "would cause a crash" : "often causes crashes")}.\nTechnical details for mod author: Expected order: {string.Join(", ", vanillaTilesheetRefs.Select(p => p.Id))}. See https://stardewvalleywiki.com/Modding:Maps#Tilesheet_order for help.";
SCore.DeprecationManager.PlaceholderWarn("3.8.2", DeprecationLevel.PendingRemoval);
if (isFarmMap)
{
- mod.LogAsMod($"SMAPI blocked '{info.Name}' map load: {reason}", LogLevel.Error);
+ mod.LogAsMod($"SMAPI blocked a '{info.Name}' map load: {reason}", LogLevel.Error);
return false;
}
- mod.LogAsMod($"SMAPI found an issue with '{info.Name}' map load: {reason}", LogLevel.Warn);
+ mod.LogAsMod($"SMAPI found an issue with a '{info.Name}' map load: {reason}", LogLevel.Warn);
}
}
}