summaryrefslogtreecommitdiff
path: root/src/SMAPI/Patches/LoadContextPatch.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/SMAPI/Patches/LoadContextPatch.cs')
-rw-r--r--src/SMAPI/Patches/LoadContextPatch.cs73
1 files changed, 62 insertions, 11 deletions
diff --git a/src/SMAPI/Patches/LoadContextPatch.cs b/src/SMAPI/Patches/LoadContextPatch.cs
index ceda061b..c43d7071 100644
--- a/src/SMAPI/Patches/LoadContextPatch.cs
+++ b/src/SMAPI/Patches/LoadContextPatch.cs
@@ -29,12 +29,8 @@ namespace StardewModdingAPI.Patches
/// <summary>A callback to invoke when the load stage changes.</summary>
private static Action<LoadStage> OnStageChanged;
-
- /*********
- ** Accessors
- *********/
- /// <inheritdoc />
- public string Name => nameof(LoadContextPatch);
+ /// <summary>Whether the game is running running the code in <see cref="Game1.loadForNewGame"/>.</summary>
+ private static bool IsInLoadForNewGame;
/*********
@@ -62,11 +58,24 @@ namespace StardewModdingAPI.Patches
prefix: new HarmonyMethod(this.GetType(), nameof(LoadContextPatch.Before_TitleMenu_CreatedNewCharacter))
);
- // detect CreatedLocations
+ // detect CreatedInitialLocations and SaveAddedLocations
+ harmony.Patch(
+ original: AccessTools.Method(typeof(Game1), nameof(Game1.AddModNPCs)),
+ prefix: new HarmonyMethod(this.GetType(), nameof(LoadContextPatch.Before_Game1_AddModNPCs))
+ );
+
+ // detect CreatedLocations, and track IsInLoadForNewGame
harmony.Patch(
original: AccessTools.Method(typeof(Game1), nameof(Game1.loadForNewGame)),
+ prefix: new HarmonyMethod(this.GetType(), nameof(LoadContextPatch.Before_Game1_LoadForNewGame)),
postfix: new HarmonyMethod(this.GetType(), nameof(LoadContextPatch.After_Game1_LoadForNewGame))
);
+
+ // detect ReturningToTitle
+ harmony.Patch(
+ original: AccessTools.Method(typeof(Game1), nameof(Game1.CleanupReturningToTitle)),
+ prefix: new HarmonyMethod(this.GetType(), nameof(LoadContextPatch.Before_Game1_CleanupReturningToTitle))
+ );
}
@@ -82,16 +91,58 @@ namespace StardewModdingAPI.Patches
return true;
}
+ /// <summary>Called before <see cref="Game1.AddModNPCs"/>.</summary>
+ /// <returns>Returns whether to execute the original method.</returns>
+ /// <remarks>This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments.</remarks>
+ private static bool Before_Game1_AddModNPCs()
+ {
+ // When this method is called from Game1.loadForNewGame, it happens right after adding the vanilla
+ // locations but before initializing them.
+ if (LoadContextPatch.IsInLoadForNewGame)
+ {
+ LoadContextPatch.OnStageChanged(LoadContextPatch.IsCreating()
+ ? LoadStage.CreatedInitialLocations
+ : LoadStage.SaveAddedLocations
+ );
+ }
+
+ return true;
+ }
+
+ /// <summary>Called before <see cref="Game1.CleanupReturningToTitle"/>.</summary>
+ /// <returns>Returns whether to execute the original method.</returns>
+ /// <remarks>This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments.</remarks>
+ private static bool Before_Game1_CleanupReturningToTitle()
+ {
+ LoadContextPatch.OnStageChanged(LoadStage.ReturningToTitle);
+ return true;
+ }
+
+ /// <summary>Called before <see cref="Game1.loadForNewGame"/>.</summary>
+ /// <returns>Returns whether to execute the original method.</returns>
+ /// <remarks>This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments.</remarks>
+ private static bool Before_Game1_LoadForNewGame()
+ {
+ LoadContextPatch.IsInLoadForNewGame = true;
+ return true;
+ }
+
/// <summary>Called after <see cref="Game1.loadForNewGame"/>.</summary>
/// <remarks>This method must be static for Harmony to work correctly. See the Harmony documentation before renaming arguments.</remarks>
private static void After_Game1_LoadForNewGame()
{
- bool creating =
- (Game1.currentMinigame is Intro) // creating save with intro
- || (Game1.activeClickableMenu is TitleMenu menu && LoadContextPatch.Reflection.GetField<bool>(menu, "transitioningCharacterCreationMenu").GetValue()); // creating save, skipped intro
+ LoadContextPatch.IsInLoadForNewGame = false;
- if (creating)
+ if (LoadContextPatch.IsCreating())
LoadContextPatch.OnStageChanged(LoadStage.CreatedLocations);
}
+
+ /// <summary>Get whether the save file is currently being created.</summary>
+ private static bool IsCreating()
+ {
+ return
+ (Game1.currentMinigame is Intro) // creating save with intro
+ || (Game1.activeClickableMenu is TitleMenu menu && LoadContextPatch.Reflection.GetField<bool>(menu, "transitioningCharacterCreationMenu").GetValue()); // creating save, skipped intro
+ }
}
}