From e5407417a0cc80f9cb3d7eb7b43bdb207322a4ec Mon Sep 17 00:00:00 2001
From: Jesse Plamondon-Willard <Pathoschild@users.noreply.github.com>
Date: Sun, 8 Jan 2023 22:05:22 -0500
Subject: add delegating mod hooks for mod use

---
 src/SMAPI/Framework/SCore.cs     | 10 +++++++---
 src/SMAPI/Framework/SModHooks.cs | 18 ++++++++----------
 2 files changed, 15 insertions(+), 13 deletions(-)

(limited to 'src/SMAPI/Framework')

diff --git a/src/SMAPI/Framework/SCore.cs b/src/SMAPI/Framework/SCore.cs
index c977ad65..1d146d5f 100644
--- a/src/SMAPI/Framework/SCore.cs
+++ b/src/SMAPI/Framework/SCore.cs
@@ -258,7 +258,11 @@ namespace StardewModdingAPI.Framework
                     monitor: this.Monitor,
                     reflection: this.Reflection,
                     eventManager: this.EventManager,
-                    modHooks: new SModHooks(this.OnNewDayAfterFade, this.Monitor),
+                    modHooks: new SModHooks(
+                        parent: new ModHooks(),
+                        beforeNewDayAfterFade: this.OnNewDayAfterFade,
+                        monitor: this.Monitor
+                    ),
                     multiplayer: this.Multiplayer,
                     exitGameImmediately: this.ExitGameImmediately,
 
@@ -1795,7 +1799,7 @@ namespace StardewModdingAPI.Framework
                     // call entry method
                     try
                     {
-                        mod.Entry(mod.Helper!);
+                        mod.Entry(mod.Helper);
                     }
                     catch (Exception ex)
                     {
@@ -1822,7 +1826,7 @@ namespace StardewModdingAPI.Framework
                     }
 
                     // validate mod doesn't implement both GetApi() and GetApi(mod)
-                    if (metadata.Api != null && mod.GetType().GetMethod(nameof(Mod.GetApi), new Type[] { typeof(IModInfo) })!.DeclaringType != typeof(Mod))
+                    if (metadata.Api != null && mod.GetType().GetMethod(nameof(Mod.GetApi), new[] { typeof(IModInfo) })!.DeclaringType != typeof(Mod))
                         metadata.LogAsMod($"Mod implements both {nameof(Mod.GetApi)}() and {nameof(Mod.GetApi)}({nameof(IModInfo)}), which isn't allowed. The latter will be ignored.", LogLevel.Error);
                 }
                 Context.HeuristicModsRunningCode.TryPop(out _);
diff --git a/src/SMAPI/Framework/SModHooks.cs b/src/SMAPI/Framework/SModHooks.cs
index a7736c8b..ac4f242c 100644
--- a/src/SMAPI/Framework/SModHooks.cs
+++ b/src/SMAPI/Framework/SModHooks.cs
@@ -1,11 +1,12 @@
 using System;
 using System.Threading.Tasks;
+using StardewModdingAPI.Utilities;
 using StardewValley;
 
 namespace StardewModdingAPI.Framework
 {
     /// <summary>Invokes callbacks for mod hooks provided by the game.</summary>
-    internal class SModHooks : ModHooks
+    internal class SModHooks : DelegatingModHooks
     {
         /*********
         ** Fields
@@ -21,25 +22,24 @@ namespace StardewModdingAPI.Framework
         ** Public methods
         *********/
         /// <summary>Construct an instance.</summary>
+        /// <param name="parent">The underlying hooks to call by default.</param>
         /// <param name="beforeNewDayAfterFade">A callback to invoke before <see cref="Game1.newDayAfterFade"/> runs.</param>
         /// <param name="monitor">Writes messages to the console.</param>
-        public SModHooks(Action beforeNewDayAfterFade, IMonitor monitor)
+        public SModHooks(ModHooks parent, Action beforeNewDayAfterFade, IMonitor monitor)
+            : base(parent)
         {
             this.BeforeNewDayAfterFade = beforeNewDayAfterFade;
             this.Monitor = monitor;
         }
 
-        /// <summary>A hook invoked when <see cref="Game1.newDayAfterFade"/> is called.</summary>
-        /// <param name="action">The vanilla <see cref="Game1.newDayAfterFade"/> logic.</param>
+        /// <inheritdoc />
         public override void OnGame1_NewDayAfterFade(Action action)
         {
             this.BeforeNewDayAfterFade();
             action();
         }
 
-        /// <summary>Start an asynchronous task for the game.</summary>
-        /// <param name="task">The task to start.</param>
-        /// <param name="id">A unique key which identifies the task.</param>
+        /// <inheritdoc />
         public override Task StartTask(Task task, string id)
         {
             this.Monitor.Log($"Synchronizing '{id}' task...");
@@ -48,9 +48,7 @@ namespace StardewModdingAPI.Framework
             return task;
         }
 
-        /// <summary>Start an asynchronous task for the game.</summary>
-        /// <param name="task">The task to start.</param>
-        /// <param name="id">A unique key which identifies the task.</param>
+        /// <inheritdoc />
         public override Task<T> StartTask<T>(Task<T> task, string id)
         {
             this.Monitor.Log($"Synchronizing '{id}' task...");
-- 
cgit