From 584725bb8e554e314843315facca1fd15868bee4 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 23 Mar 2022 01:06:11 -0400 Subject: add initial AssetRequested content event (#766) --- src/SMAPI/Events/AssetRequestedEventArgs.cs | 94 +++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/SMAPI/Events/AssetRequestedEventArgs.cs (limited to 'src/SMAPI/Events/AssetRequestedEventArgs.cs') diff --git a/src/SMAPI/Events/AssetRequestedEventArgs.cs b/src/SMAPI/Events/AssetRequestedEventArgs.cs new file mode 100644 index 00000000..b17250b0 --- /dev/null +++ b/src/SMAPI/Events/AssetRequestedEventArgs.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using Microsoft.Xna.Framework.Graphics; +using StardewModdingAPI.Framework; +using StardewModdingAPI.Framework.Content; +using xTile; + +namespace StardewModdingAPI.Events +{ + /// Event arguments for an event. + public class AssetRequestedEventArgs : EventArgs + { + /********* + ** Fields + *********/ + /// The mod handling the event. + private readonly IModMetadata Mod; + + + /********* + ** Accessors + *********/ + /// The name of the asset being requested. + public IAssetName Name { get; } + + /// The load operations requested by the event handler. + internal IList LoadOperations { get; } = new List(); + + /// The edit operations requested by the event handler. + internal IList EditOperations { get; } = new List(); + + + /********* + ** Public methods + *********/ + /// Construct an instance. + /// The mod handling the event. + /// The name of the asset being requested. + internal AssetRequestedEventArgs(IModMetadata mod, IAssetName name) + { + this.Mod = mod; + this.Name = name; + } + + /// Provide the initial instance for the asset, instead of trying to load it from the game's Content folder. + /// Get the initial instance of an asset. + /// + /// Usage notes: + /// + /// The asset doesn't need to exist in the game's Content folder. If any mod loads the asset, the game will see it as an existing asset as if it was in that folder. + /// Each asset can logically only have one initial instance. If multiple loads apply at the same time, SMAPI will raise an error and ignore all of them. If you're making changes to the existing asset instead of replacing it, you should use instead to avoid those limitations and improve mod compatibility. + /// + /// + public void LoadFrom(Func load) + { + this.LoadOperations.Add( + new AssetLoadOperation(this.Mod, _ => load()) + ); + } + + /// Provide the initial instance for the asset from a file in your mod folder, instead of trying to load it from the game's Content folder. + /// The expected data type. The main supported types are , , dictionaries, and lists; other types may be supported by the game's content pipeline. + /// The relative path to the file in your mod folder. + /// + /// Usage notes: + /// + /// The asset doesn't need to exist in the game's Content folder. If any mod loads the asset, the game will see it as an existing asset as if it was in that folder. + /// Each asset can logically only have one initial instance. If multiple loads apply at the same time, SMAPI will raise an error and ignore all of them. If you're making changes to the existing asset instead of replacing it, you should use instead to avoid those limitations and improve mod compatibility. + /// + /// + public void LoadFromModFile(string relativePath) + { + this.LoadOperations.Add( + new AssetLoadOperation(this.Mod, _ => this.Mod.Mod.Helper.Content.Load(relativePath)) + ); + } + + /// Edit the asset after it's loaded. + /// Apply changes to the asset. + /// + /// Usage notes: + /// + /// Editing an asset which doesn't exist has no effect. This is applied after the asset is loaded from the game's Content folder, or from any mod's or . + /// You can apply any number of edits to the asset. Each edit will be applied on top of the previous one (i.e. it'll see the merged asset from all previous edits as its input). + /// + /// + public void Edit(Action apply) + { + this.EditOperations.Add( + new AssetEditOperation(this.Mod, apply) + ); + } + } +} -- cgit From e1fc566e0afeb6eb92418bb039365611abd33829 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 25 Mar 2022 21:46:37 -0400 Subject: add content pack labels (#766) --- src/SMAPI/Events/AssetRequestedEventArgs.cs | 30 +++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'src/SMAPI/Events/AssetRequestedEventArgs.cs') diff --git a/src/SMAPI/Events/AssetRequestedEventArgs.cs b/src/SMAPI/Events/AssetRequestedEventArgs.cs index b17250b0..774ab808 100644 --- a/src/SMAPI/Events/AssetRequestedEventArgs.cs +++ b/src/SMAPI/Events/AssetRequestedEventArgs.cs @@ -16,6 +16,9 @@ namespace StardewModdingAPI.Events /// The mod handling the event. private readonly IModMetadata Mod; + /// Get the mod metadata for a content pack, if it's a valid content pack for the mod. + private readonly Func GetOnBehalfOf; + /********* ** Accessors @@ -36,14 +39,17 @@ namespace StardewModdingAPI.Events /// Construct an instance. /// The mod handling the event. /// The name of the asset being requested. - internal AssetRequestedEventArgs(IModMetadata mod, IAssetName name) + /// Get the mod metadata for a content pack, if it's a valid content pack for the mod. + internal AssetRequestedEventArgs(IModMetadata mod, IAssetName name, Func getOnBehalfOf) { this.Mod = mod; this.Name = name; + this.GetOnBehalfOf = getOnBehalfOf; } /// Provide the initial instance for the asset, instead of trying to load it from the game's Content folder. /// Get the initial instance of an asset. + /// The content pack ID on whose behalf you're applying the change. This is only valid for content packs for your mod. /// /// Usage notes: /// @@ -51,10 +57,14 @@ namespace StardewModdingAPI.Events /// Each asset can logically only have one initial instance. If multiple loads apply at the same time, SMAPI will raise an error and ignore all of them. If you're making changes to the existing asset instead of replacing it, you should use instead to avoid those limitations and improve mod compatibility. /// /// - public void LoadFrom(Func load) + public void LoadFrom(Func load, string onBehalfOf = null) { this.LoadOperations.Add( - new AssetLoadOperation(this.Mod, _ => load()) + new AssetLoadOperation( + mod: this.Mod, + onBehalfOf: this.GetOnBehalfOf(this.Mod, onBehalfOf, "load assets"), + getData: _ => load() + ) ); } @@ -71,12 +81,16 @@ namespace StardewModdingAPI.Events public void LoadFromModFile(string relativePath) { this.LoadOperations.Add( - new AssetLoadOperation(this.Mod, _ => this.Mod.Mod.Helper.Content.Load(relativePath)) + new AssetLoadOperation( + mod: this.Mod, + onBehalfOf: null, + _ => this.Mod.Mod.Helper.Content.Load(relativePath)) ); } /// Edit the asset after it's loaded. /// Apply changes to the asset. + /// The content pack ID on whose behalf you're applying the change. This is only valid for content packs for your mod. /// /// Usage notes: /// @@ -84,10 +98,14 @@ namespace StardewModdingAPI.Events /// You can apply any number of edits to the asset. Each edit will be applied on top of the previous one (i.e. it'll see the merged asset from all previous edits as its input). /// /// - public void Edit(Action apply) + public void Edit(Action apply, string onBehalfOf = null) { this.EditOperations.Add( - new AssetEditOperation(this.Mod, apply) + new AssetEditOperation( + mod: this.Mod, + onBehalfOf: this.GetOnBehalfOf(this.Mod, onBehalfOf, "edit assets"), + apply + ) ); } } -- cgit From 021891ff0ceb6b327bc196c336aa56ddfaf99b0e Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 25 Mar 2022 22:49:14 -0400 Subject: add load conflict resolution option (#766) --- src/SMAPI/Events/AssetRequestedEventArgs.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/SMAPI/Events/AssetRequestedEventArgs.cs') diff --git a/src/SMAPI/Events/AssetRequestedEventArgs.cs b/src/SMAPI/Events/AssetRequestedEventArgs.cs index 774ab808..9942079b 100644 --- a/src/SMAPI/Events/AssetRequestedEventArgs.cs +++ b/src/SMAPI/Events/AssetRequestedEventArgs.cs @@ -50,18 +50,20 @@ namespace StardewModdingAPI.Events /// Provide the initial instance for the asset, instead of trying to load it from the game's Content folder. /// Get the initial instance of an asset. /// The content pack ID on whose behalf you're applying the change. This is only valid for content packs for your mod. + /// When there are multiple loads that apply to the same asset, this indicates whether this one can be skipped to resolve the conflict. If all loads allow skipping, the first one that was registered will be applied. If this is false, SMAPI will raise an error and apply none of them. /// /// Usage notes: /// /// The asset doesn't need to exist in the game's Content folder. If any mod loads the asset, the game will see it as an existing asset as if it was in that folder. - /// Each asset can logically only have one initial instance. If multiple loads apply at the same time, SMAPI will raise an error and ignore all of them. If you're making changes to the existing asset instead of replacing it, you should use instead to avoid those limitations and improve mod compatibility. + /// Each asset can logically only have one initial instance. If multiple loads apply at the same time, SMAPI will use the parameter to decide what happens. If you're making changes to the existing asset instead of replacing it, you should use instead to avoid those limitations and improve mod compatibility. /// /// - public void LoadFrom(Func load, string onBehalfOf = null) + public void LoadFrom(Func load, string onBehalfOf = null, bool allowSkipOnConflict = false) { this.LoadOperations.Add( new AssetLoadOperation( mod: this.Mod, + allowSkipOnConflict: allowSkipOnConflict, onBehalfOf: this.GetOnBehalfOf(this.Mod, onBehalfOf, "load assets"), getData: _ => load() ) @@ -71,6 +73,7 @@ namespace StardewModdingAPI.Events /// Provide the initial instance for the asset from a file in your mod folder, instead of trying to load it from the game's Content folder. /// The expected data type. The main supported types are , , dictionaries, and lists; other types may be supported by the game's content pipeline. /// The relative path to the file in your mod folder. + /// When there are multiple loads that apply to the same asset, this indicates whether this one can be skipped to resolve the conflict. If all loads allow skipping, the first one that was registered will be applied. If this is false, SMAPI will raise an error and apply none of them. /// /// Usage notes: /// @@ -78,11 +81,12 @@ namespace StardewModdingAPI.Events /// Each asset can logically only have one initial instance. If multiple loads apply at the same time, SMAPI will raise an error and ignore all of them. If you're making changes to the existing asset instead of replacing it, you should use instead to avoid those limitations and improve mod compatibility. /// /// - public void LoadFromModFile(string relativePath) + public void LoadFromModFile(string relativePath, bool allowSkipOnConflict = false) { this.LoadOperations.Add( new AssetLoadOperation( mod: this.Mod, + allowSkipOnConflict: allowSkipOnConflict, onBehalfOf: null, _ => this.Mod.Mod.Helper.Content.Load(relativePath)) ); -- cgit From 3707f481a567df5149aea00ffb14cddb7b14fccb Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Fri, 25 Mar 2022 23:53:30 -0400 Subject: extend load conflict resolution into load priority (#766) --- src/SMAPI/Events/AssetRequestedEventArgs.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/SMAPI/Events/AssetRequestedEventArgs.cs') diff --git a/src/SMAPI/Events/AssetRequestedEventArgs.cs b/src/SMAPI/Events/AssetRequestedEventArgs.cs index 9942079b..d022a4de 100644 --- a/src/SMAPI/Events/AssetRequestedEventArgs.cs +++ b/src/SMAPI/Events/AssetRequestedEventArgs.cs @@ -49,21 +49,21 @@ namespace StardewModdingAPI.Events /// Provide the initial instance for the asset, instead of trying to load it from the game's Content folder. /// Get the initial instance of an asset. + /// If there are multiple loads that apply to the same asset, the priority with which this one should be applied. /// The content pack ID on whose behalf you're applying the change. This is only valid for content packs for your mod. - /// When there are multiple loads that apply to the same asset, this indicates whether this one can be skipped to resolve the conflict. If all loads allow skipping, the first one that was registered will be applied. If this is false, SMAPI will raise an error and apply none of them. /// /// Usage notes: /// /// The asset doesn't need to exist in the game's Content folder. If any mod loads the asset, the game will see it as an existing asset as if it was in that folder. - /// Each asset can logically only have one initial instance. If multiple loads apply at the same time, SMAPI will use the parameter to decide what happens. If you're making changes to the existing asset instead of replacing it, you should use instead to avoid those limitations and improve mod compatibility. + /// Each asset can logically only have one initial instance. If multiple loads apply at the same time, SMAPI will use the parameter to decide what happens. If you're making changes to the existing asset instead of replacing it, you should use instead to avoid those limitations and improve mod compatibility. /// /// - public void LoadFrom(Func load, string onBehalfOf = null, bool allowSkipOnConflict = false) + public void LoadFrom(Func load, AssetLoadPriority priority, string onBehalfOf = null) { this.LoadOperations.Add( new AssetLoadOperation( mod: this.Mod, - allowSkipOnConflict: allowSkipOnConflict, + priority: priority, onBehalfOf: this.GetOnBehalfOf(this.Mod, onBehalfOf, "load assets"), getData: _ => load() ) @@ -73,7 +73,7 @@ namespace StardewModdingAPI.Events /// Provide the initial instance for the asset from a file in your mod folder, instead of trying to load it from the game's Content folder. /// The expected data type. The main supported types are , , dictionaries, and lists; other types may be supported by the game's content pipeline. /// The relative path to the file in your mod folder. - /// When there are multiple loads that apply to the same asset, this indicates whether this one can be skipped to resolve the conflict. If all loads allow skipping, the first one that was registered will be applied. If this is false, SMAPI will raise an error and apply none of them. + /// If there are multiple loads that apply to the same asset, the priority with which this one should be applied. /// /// Usage notes: /// @@ -81,12 +81,12 @@ namespace StardewModdingAPI.Events /// Each asset can logically only have one initial instance. If multiple loads apply at the same time, SMAPI will raise an error and ignore all of them. If you're making changes to the existing asset instead of replacing it, you should use instead to avoid those limitations and improve mod compatibility. /// /// - public void LoadFromModFile(string relativePath, bool allowSkipOnConflict = false) + public void LoadFromModFile(string relativePath, AssetLoadPriority priority) { this.LoadOperations.Add( new AssetLoadOperation( mod: this.Mod, - allowSkipOnConflict: allowSkipOnConflict, + priority: priority, onBehalfOf: null, _ => this.Mod.Mod.Helper.Content.Load(relativePath)) ); -- cgit From e40907ab8b97bd8a557adf683a406413646b1fc5 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 26 Mar 2022 01:19:44 -0400 Subject: add NameWithoutLocale fields (#766) --- src/SMAPI/Events/AssetRequestedEventArgs.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/SMAPI/Events/AssetRequestedEventArgs.cs') diff --git a/src/SMAPI/Events/AssetRequestedEventArgs.cs b/src/SMAPI/Events/AssetRequestedEventArgs.cs index d022a4de..9e2cde7f 100644 --- a/src/SMAPI/Events/AssetRequestedEventArgs.cs +++ b/src/SMAPI/Events/AssetRequestedEventArgs.cs @@ -26,6 +26,10 @@ namespace StardewModdingAPI.Events /// The name of the asset being requested. public IAssetName Name { get; } + /// The with any locale codes stripped. + /// For example, if contains a locale like Data/Bundles.fr-FR, this will be the name without locale like Data/Bundles. If the name has no locale, this field is equivalent. + public IAssetName NameWithoutLocale { get; } + /// The load operations requested by the event handler. internal IList LoadOperations { get; } = new List(); @@ -39,11 +43,13 @@ namespace StardewModdingAPI.Events /// Construct an instance. /// The mod handling the event. /// The name of the asset being requested. + /// The with any locale codes stripped. /// Get the mod metadata for a content pack, if it's a valid content pack for the mod. - internal AssetRequestedEventArgs(IModMetadata mod, IAssetName name, Func getOnBehalfOf) + internal AssetRequestedEventArgs(IModMetadata mod, IAssetName name, IAssetName nameWithoutLocale, Func getOnBehalfOf) { this.Mod = mod; this.Name = name; + this.NameWithoutLocale = nameWithoutLocale; this.GetOnBehalfOf = getOnBehalfOf; } -- cgit From ad8912047beaf84ce34f4918703d55841be13ff0 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 26 Mar 2022 01:43:40 -0400 Subject: add asset edit priority (#766) --- src/SMAPI/Events/AssetRequestedEventArgs.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/SMAPI/Events/AssetRequestedEventArgs.cs') diff --git a/src/SMAPI/Events/AssetRequestedEventArgs.cs b/src/SMAPI/Events/AssetRequestedEventArgs.cs index 9e2cde7f..4d9ee236 100644 --- a/src/SMAPI/Events/AssetRequestedEventArgs.cs +++ b/src/SMAPI/Events/AssetRequestedEventArgs.cs @@ -100,6 +100,7 @@ namespace StardewModdingAPI.Events /// Edit the asset after it's loaded. /// Apply changes to the asset. + /// If there are multiple edits that apply to the same asset, the priority with which this one should be applied. /// The content pack ID on whose behalf you're applying the change. This is only valid for content packs for your mod. /// /// Usage notes: @@ -108,11 +109,12 @@ namespace StardewModdingAPI.Events /// You can apply any number of edits to the asset. Each edit will be applied on top of the previous one (i.e. it'll see the merged asset from all previous edits as its input). /// /// - public void Edit(Action apply, string onBehalfOf = null) + public void Edit(Action apply, AssetEditPriority priority = AssetEditPriority.Default, string onBehalfOf = null) { this.EditOperations.Add( new AssetEditOperation( mod: this.Mod, + priority: priority, onBehalfOf: this.GetOnBehalfOf(this.Mod, onBehalfOf, "edit assets"), apply ) -- cgit From d864f2ed775dfd5843b9e1cdd1da96ade5dd1068 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 27 Mar 2022 12:16:28 -0400 Subject: add asset type to AssetRequested event (#766) --- src/SMAPI/Events/AssetRequestedEventArgs.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/SMAPI/Events/AssetRequestedEventArgs.cs') diff --git a/src/SMAPI/Events/AssetRequestedEventArgs.cs b/src/SMAPI/Events/AssetRequestedEventArgs.cs index 4d9ee236..c0cbd8fb 100644 --- a/src/SMAPI/Events/AssetRequestedEventArgs.cs +++ b/src/SMAPI/Events/AssetRequestedEventArgs.cs @@ -30,6 +30,9 @@ namespace StardewModdingAPI.Events /// For example, if contains a locale like Data/Bundles.fr-FR, this will be the name without locale like Data/Bundles. If the name has no locale, this field is equivalent. public IAssetName NameWithoutLocale { get; } + /// The requested data type. + public Type DataType { get; } + /// The load operations requested by the event handler. internal IList LoadOperations { get; } = new List(); @@ -43,13 +46,15 @@ namespace StardewModdingAPI.Events /// Construct an instance. /// The mod handling the event. /// The name of the asset being requested. + /// The requested data type. /// The with any locale codes stripped. /// Get the mod metadata for a content pack, if it's a valid content pack for the mod. - internal AssetRequestedEventArgs(IModMetadata mod, IAssetName name, IAssetName nameWithoutLocale, Func getOnBehalfOf) + internal AssetRequestedEventArgs(IModMetadata mod, IAssetName name, IAssetName nameWithoutLocale, Type dataType, Func getOnBehalfOf) { this.Mod = mod; this.Name = name; this.NameWithoutLocale = nameWithoutLocale; + this.DataType = dataType; this.GetOnBehalfOf = getOnBehalfOf; } -- cgit From 2e7c233f6c9bf6430672b39f970a3324deba79dd Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 6 Apr 2022 21:48:55 -0400 Subject: enable nullable annotations by default (#837) This adds `#nullable disable` to all existing code (except where null is impossible like enum files), so it can be migrated incrementally. --- src/SMAPI/Events/AssetRequestedEventArgs.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/SMAPI/Events/AssetRequestedEventArgs.cs') diff --git a/src/SMAPI/Events/AssetRequestedEventArgs.cs b/src/SMAPI/Events/AssetRequestedEventArgs.cs index c0cbd8fb..82b59290 100644 --- a/src/SMAPI/Events/AssetRequestedEventArgs.cs +++ b/src/SMAPI/Events/AssetRequestedEventArgs.cs @@ -1,3 +1,5 @@ +#nullable disable + using System; using System.Collections.Generic; using Microsoft.Xna.Framework.Graphics; -- cgit From 5ae87fbc01a8829a1a23f90efc25a5dbaada6e68 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sat, 9 Apr 2022 11:42:49 -0400 Subject: fix deprecation warning when a mod uses LoadFromModFile --- src/SMAPI/Events/AssetRequestedEventArgs.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/SMAPI/Events/AssetRequestedEventArgs.cs') diff --git a/src/SMAPI/Events/AssetRequestedEventArgs.cs b/src/SMAPI/Events/AssetRequestedEventArgs.cs index 82b59290..3c51c95d 100644 --- a/src/SMAPI/Events/AssetRequestedEventArgs.cs +++ b/src/SMAPI/Events/AssetRequestedEventArgs.cs @@ -101,7 +101,7 @@ namespace StardewModdingAPI.Events mod: this.Mod, priority: priority, onBehalfOf: null, - _ => this.Mod.Mod.Helper.Content.Load(relativePath)) + _ => this.Mod.Mod.Helper.ModContent.Load(relativePath)) ); } -- cgit From f39da383a17b368e92fd243cf155b27ba42671f3 Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Wed, 13 Apr 2022 20:24:14 -0400 Subject: enable nullable annotations in SMAPI where no logic changes are needed (#837) --- src/SMAPI/Events/AssetRequestedEventArgs.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/SMAPI/Events/AssetRequestedEventArgs.cs') diff --git a/src/SMAPI/Events/AssetRequestedEventArgs.cs b/src/SMAPI/Events/AssetRequestedEventArgs.cs index 3c51c95d..3bcf83b9 100644 --- a/src/SMAPI/Events/AssetRequestedEventArgs.cs +++ b/src/SMAPI/Events/AssetRequestedEventArgs.cs @@ -1,5 +1,3 @@ -#nullable disable - using System; using System.Collections.Generic; using Microsoft.Xna.Framework.Graphics; @@ -19,7 +17,7 @@ namespace StardewModdingAPI.Events private readonly IModMetadata Mod; /// Get the mod metadata for a content pack, if it's a valid content pack for the mod. - private readonly Func GetOnBehalfOf; + private readonly Func GetOnBehalfOf; /********* @@ -51,7 +49,7 @@ namespace StardewModdingAPI.Events /// The requested data type. /// The with any locale codes stripped. /// Get the mod metadata for a content pack, if it's a valid content pack for the mod. - internal AssetRequestedEventArgs(IModMetadata mod, IAssetName name, IAssetName nameWithoutLocale, Type dataType, Func getOnBehalfOf) + internal AssetRequestedEventArgs(IModMetadata mod, IAssetName name, IAssetName nameWithoutLocale, Type dataType, Func getOnBehalfOf) { this.Mod = mod; this.Name = name; @@ -71,7 +69,7 @@ namespace StardewModdingAPI.Events /// Each asset can logically only have one initial instance. If multiple loads apply at the same time, SMAPI will use the parameter to decide what happens. If you're making changes to the existing asset instead of replacing it, you should use instead to avoid those limitations and improve mod compatibility. /// /// - public void LoadFrom(Func load, AssetLoadPriority priority, string onBehalfOf = null) + public void LoadFrom(Func load, AssetLoadPriority priority, string? onBehalfOf = null) { this.LoadOperations.Add( new AssetLoadOperation( @@ -95,13 +93,15 @@ namespace StardewModdingAPI.Events /// /// public void LoadFromModFile(string relativePath, AssetLoadPriority priority) + where TAsset : notnull { this.LoadOperations.Add( new AssetLoadOperation( mod: this.Mod, priority: priority, onBehalfOf: null, - _ => this.Mod.Mod.Helper.ModContent.Load(relativePath)) + _ => this.Mod.Mod!.Helper.ModContent.Load(relativePath) + ) ); } @@ -116,7 +116,7 @@ namespace StardewModdingAPI.Events /// You can apply any number of edits to the asset. Each edit will be applied on top of the previous one (i.e. it'll see the merged asset from all previous edits as its input). /// /// - public void Edit(Action apply, AssetEditPriority priority = AssetEditPriority.Default, string onBehalfOf = null) + public void Edit(Action apply, AssetEditPriority priority = AssetEditPriority.Default, string? onBehalfOf = null) { this.EditOperations.Add( new AssetEditOperation( -- cgit