tweak world-ready events to handle edge cases
In particular: - world was never considered ready if the player's name was blank; - AfterReturnToTitle didn't trigger after being disconnected in multiplayer (#545).
This commit is contained in:
parent
d67690ea3e
commit
79ad322a8e
|
@ -26,6 +26,7 @@
|
||||||
* Fixed `world_settime` sometimes breaking NPC schedules (e.g. so they stay in bed).
|
* Fixed `world_settime` sometimes breaking NPC schedules (e.g. so they stay in bed).
|
||||||
* Fixed launch issue for Linux players with some terminals. (Thanks to HanFox and kurumushi!)
|
* Fixed launch issue for Linux players with some terminals. (Thanks to HanFox and kurumushi!)
|
||||||
* Fixed issue where a mod crashing in `CanEdit` or `CanLoad` could cause an abort-retry loop.
|
* Fixed issue where a mod crashing in `CanEdit` or `CanLoad` could cause an abort-retry loop.
|
||||||
|
* Fixed many mods not working if the player name is blank.
|
||||||
* Renamed `install.exe` to `install on Windows.exe` to avoid confusion.
|
* Renamed `install.exe` to `install on Windows.exe` to avoid confusion.
|
||||||
* Updated compatibility list.
|
* Updated compatibility list.
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace StardewModdingAPI
|
||||||
** Internal
|
** Internal
|
||||||
****/
|
****/
|
||||||
/// <summary>Whether a player save has been loaded.</summary>
|
/// <summary>Whether a player save has been loaded.</summary>
|
||||||
internal static bool IsSaveLoaded => Game1.hasLoadedGame && !string.IsNullOrEmpty(Game1.player.Name);
|
internal static bool IsSaveLoaded => Game1.hasLoadedGame && !(Game1.activeClickableMenu is TitleMenu);
|
||||||
|
|
||||||
/// <summary>Whether the game is currently writing to the save file.</summary>
|
/// <summary>Whether the game is currently writing to the save file.</summary>
|
||||||
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
|
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
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace StardewModdingAPI.Framework
|
||||||
|
|
||||||
/// <summary>The number of ticks until SMAPI should notify mods that the game has loaded.</summary>
|
/// <summary>The number of ticks until SMAPI should notify mods that the game has loaded.</summary>
|
||||||
/// <remarks>Skipping a few frames ensures the game finishes initialising the world before mods try to change it.</remarks>
|
/// <remarks>Skipping a few frames ensures the game finishes initialising the world before mods try to change it.</remarks>
|
||||||
private int AfterLoadTimer = 5;
|
private readonly Countdown AfterLoadTimer = new Countdown(5);
|
||||||
|
|
||||||
/// <summary>Whether the after-load events were raised for this session.</summary>
|
/// <summary>Whether the after-load events were raised for this session.</summary>
|
||||||
private bool RaisedAfterLoadEvent;
|
private bool RaisedAfterLoadEvent;
|
||||||
|
@ -313,13 +313,14 @@ namespace StardewModdingAPI.Framework
|
||||||
/*********
|
/*********
|
||||||
** Update context
|
** Update context
|
||||||
*********/
|
*********/
|
||||||
if (Context.IsWorldReady && !Context.IsSaveLoaded)
|
bool wasWorldReady = Context.IsWorldReady;
|
||||||
|
if ((Context.IsWorldReady && !Context.IsSaveLoaded) || Game1.exitToTitle)
|
||||||
this.MarkWorldNotReady();
|
this.MarkWorldNotReady();
|
||||||
else if (Context.IsSaveLoaded && !SaveGame.IsProcessing /*still loading save*/ && this.AfterLoadTimer >= 0 && Game1.currentLocation != null)
|
else if (Context.IsSaveLoaded && !SaveGame.IsProcessing /*still loading save*/ && this.AfterLoadTimer.Current > 0 && Game1.currentLocation != null)
|
||||||
{
|
{
|
||||||
if (Game1.dayOfMonth != 0) // wait until new-game intro finishes (world not fully initialised yet)
|
if (Game1.dayOfMonth != 0) // wait until new-game intro finishes (world not fully initialised yet)
|
||||||
this.AfterLoadTimer--;
|
this.AfterLoadTimer.Decrement();
|
||||||
Context.IsWorldReady = this.AfterLoadTimer <= 0;
|
Context.IsWorldReady = this.AfterLoadTimer.Current == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********
|
/*********
|
||||||
|
@ -342,9 +343,14 @@ namespace StardewModdingAPI.Framework
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********
|
/*********
|
||||||
** After load events
|
** Load / return-to-title events
|
||||||
*********/
|
*********/
|
||||||
if (!this.RaisedAfterLoadEvent && Context.IsWorldReady)
|
if (wasWorldReady && !Context.IsWorldReady)
|
||||||
|
{
|
||||||
|
this.Monitor.Log("Context: returned to title", LogLevel.Trace);
|
||||||
|
this.Events.Save_AfterReturnToTitle.Raise();
|
||||||
|
}
|
||||||
|
else if (!this.RaisedAfterLoadEvent && Context.IsWorldReady)
|
||||||
{
|
{
|
||||||
// print context
|
// print context
|
||||||
string context = $"Context: loaded saved game '{Constants.SaveFolderName}', starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.";
|
string context = $"Context: loaded saved game '{Constants.SaveFolderName}', starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.";
|
||||||
|
@ -363,15 +369,6 @@ namespace StardewModdingAPI.Framework
|
||||||
this.Events.Time_AfterDayStarted.Raise();
|
this.Events.Time_AfterDayStarted.Raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********
|
|
||||||
** Exit to title events
|
|
||||||
*********/
|
|
||||||
if (Game1.exitToTitle)
|
|
||||||
{
|
|
||||||
this.Monitor.Log("Context: returned to title", LogLevel.Trace);
|
|
||||||
this.Events.Save_AfterReturnToTitle.Raise();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*********
|
/*********
|
||||||
** Window events
|
** Window events
|
||||||
*********/
|
*********/
|
||||||
|
@ -1342,7 +1339,7 @@ namespace StardewModdingAPI.Framework
|
||||||
private void MarkWorldNotReady()
|
private void MarkWorldNotReady()
|
||||||
{
|
{
|
||||||
Context.IsWorldReady = false;
|
Context.IsWorldReady = false;
|
||||||
this.AfterLoadTimer = 5;
|
this.AfterLoadTimer.Reset();
|
||||||
this.RaisedAfterLoadEvent = false;
|
this.RaisedAfterLoadEvent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue