From bca78cd682c0d583913811f632815db142fbde8b Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Mon, 15 May 2017 22:51:49 -0400 Subject: [PATCH] add Context.IsWorldReady flag --- release-notes.md | 2 ++ src/StardewModdingAPI/Context.cs | 17 +++++++++++++---- src/StardewModdingAPI/Framework/SGame.cs | 10 +++++----- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/release-notes.md b/release-notes.md index d9d6a12a..507fb1af 100644 --- a/release-notes.md +++ b/release-notes.md @@ -22,6 +22,8 @@ For players: * Updated mod compatibility list for Stardew Valley 1.2. For mod developers: +* Added a `Context.IsWorldReady` flag. + _This is set to `true` when the player has loaded a save and the world is finished initialising. This is set at the same point that `SaveEvents.AfterLoad` and `TimeEvents.AfterDayStarted` are raised, and is mainly useful with events which can be raised before the world is loaded._ * Added log entries for basic context changes (e.g. loaded save) to simplify troubleshooting. * Added a `debug` console command to TrainerMod which lets you pass debug commands to the game (e.g. `debug warp FarmHouse 1 1` warps the player to the farmhouse). * Added a deprecation warning for mods that don't set the `UniqueID` manifest field, which will be required in SMAPI 2.0. diff --git a/src/StardewModdingAPI/Context.cs b/src/StardewModdingAPI/Context.cs index 45f6a05f..6bc5ae56 100644 --- a/src/StardewModdingAPI/Context.cs +++ b/src/StardewModdingAPI/Context.cs @@ -4,18 +4,27 @@ using StardewValley.Menus; namespace StardewModdingAPI { /// Provides information about the current game state. - internal static class Context + public static class Context { /********* ** Accessors *********/ + /**** + ** Public + ****/ + /// Whether the player has loaded a save and the world has finished initialising. + public static bool IsWorldReady { get; internal set; } + + /**** + ** Internal + ****/ /// Whether a player save has been loaded. - public static bool IsSaveLoaded => Game1.hasLoadedGame && !string.IsNullOrEmpty(Game1.player.name); + internal static bool IsSaveLoaded => Game1.hasLoadedGame && !string.IsNullOrEmpty(Game1.player.name); /// Whether the game is currently writing to the save file. - public static bool IsSaving => Game1.activeClickableMenu is SaveGameMenu || Game1.activeClickableMenu is ShippingMenu; // saving is performed by SaveGameMenu, but it's wrapped by ShippingMenu on days when the player shipping something + internal static bool IsSaving => Game1.activeClickableMenu is SaveGameMenu || Game1.activeClickableMenu is ShippingMenu; // saving is performed by SaveGameMenu, but it's wrapped by ShippingMenu on days when the player shipping something /// Whether the game is currently running the draw loop. - public static bool IsInDrawLoop { get; set; } + internal static bool IsInDrawLoop { get; set; } } } diff --git a/src/StardewModdingAPI/Framework/SGame.cs b/src/StardewModdingAPI/Framework/SGame.cs index f318517d..4f3a29fc 100644 --- a/src/StardewModdingAPI/Framework/SGame.cs +++ b/src/StardewModdingAPI/Framework/SGame.cs @@ -39,9 +39,6 @@ namespace StardewModdingAPI.Framework /// The number of consecutive failed draws. private int FailedDraws; - /// Whether the player has loaded a save and the world has finished initialising. - private bool IsWorldReady => this.AfterLoadTimer < 0; - /// Whether the game is returning to the menu. private bool IsExiting; @@ -309,6 +306,7 @@ namespace StardewModdingAPI.Framework if (this.AfterLoadTimer == 0) { this.Monitor.Log($"Context: loaded saved game '{Constants.SaveFolderName}', starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.", LogLevel.Trace); + Context.IsWorldReady = true; SaveEvents.InvokeAfterLoad(this.Monitor); PlayerEvents.InvokeLoadedGame(this.Monitor, new EventArgsLoadedGameChanged(Game1.hasLoadedGame)); @@ -325,9 +323,11 @@ namespace StardewModdingAPI.Framework this.IsExiting = true; // after exit to title - if (this.IsWorldReady && this.IsExiting && Game1.activeClickableMenu is TitleMenu) + if (Context.IsWorldReady && this.IsExiting && Game1.activeClickableMenu is TitleMenu) { this.Monitor.Log("Context: returned to title", LogLevel.Trace); + Context.IsWorldReady = false; + SaveEvents.InvokeAfterReturnToTitle(this.Monitor); this.AfterLoadTimer = 5; this.IsExiting = false; @@ -421,7 +421,7 @@ namespace StardewModdingAPI.Framework /********* ** World & player events *********/ - if (this.IsWorldReady) + if (Context.IsWorldReady) { // raise events (only when something changes, not on the initial load) if (Game1.uniqueIDForThisGame == this.PreviousSaveID)