fix save folder constants not available during early load stages
This commit is contained in:
parent
79c6166005
commit
9240bdbf9b
|
@ -1,4 +1,9 @@
|
|||
# Release notes
|
||||
## Upcoming
|
||||
|
||||
* For modders:
|
||||
* Fixed `Constants.SaveFolderName` and `CurrentSavePath` not available during early load stages when using `Specialised.LoadStageChanged` event.
|
||||
|
||||
## 2.10.1
|
||||
Released 30 December 2018 for Stardew Valley 1.3.32.
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using StardewModdingAPI.Enums;
|
||||
using StardewModdingAPI.Framework;
|
||||
using StardewModdingAPI.Framework.ModLoading;
|
||||
using StardewModdingAPI.Internal;
|
||||
|
@ -12,16 +13,6 @@ namespace StardewModdingAPI
|
|||
/// <summary>Contains SMAPI's constants and assumptions.</summary>
|
||||
public static class Constants
|
||||
{
|
||||
/*********
|
||||
** Fields
|
||||
*********/
|
||||
/// <summary>The directory path containing the current save's data (if a save is loaded).</summary>
|
||||
private static string RawSavePath => Context.IsSaveLoaded ? Path.Combine(Constants.SavesPath, Constants.GetSaveFolderName()) : null;
|
||||
|
||||
/// <summary>Whether the directory containing the current save's data exists on disk.</summary>
|
||||
private static bool SavePathReady => Context.IsSaveLoaded && Directory.Exists(Constants.RawSavePath);
|
||||
|
||||
|
||||
/*********
|
||||
** Accessors
|
||||
*********/
|
||||
|
@ -52,11 +43,33 @@ namespace StardewModdingAPI
|
|||
/// <summary>The directory path where all saves are stored.</summary>
|
||||
public static string SavesPath { get; } = Path.Combine(Constants.DataPath, "Saves");
|
||||
|
||||
/// <summary>The directory name containing the current save's data (if a save is loaded and the directory exists).</summary>
|
||||
public static string SaveFolderName => Context.IsSaveLoaded ? Constants.GetSaveFolderName() : "";
|
||||
/// <summary>The name of the current save folder (if save info is available, regardless of whether the save file exists yet).</summary>
|
||||
public static string SaveFolderName
|
||||
{
|
||||
get
|
||||
{
|
||||
return Constants.GetSaveFolderName()
|
||||
#if SMAPI_3_0_STRICT
|
||||
;
|
||||
#else
|
||||
?? "";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>The directory path containing the current save's data (if a save is loaded and the directory exists).</summary>
|
||||
public static string CurrentSavePath => Constants.SavePathReady ? Path.Combine(Constants.SavesPath, Constants.GetSaveFolderName()) : "";
|
||||
/// <summary>The absolute path to the current save folder (if save info is available and the save file exists).</summary>
|
||||
public static string CurrentSavePath
|
||||
{
|
||||
get
|
||||
{
|
||||
return Constants.GetSaveFolderPathIfExists()
|
||||
#if SMAPI_3_0_STRICT
|
||||
;
|
||||
#else
|
||||
?? "";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/****
|
||||
** Internal
|
||||
|
@ -184,13 +197,6 @@ namespace StardewModdingAPI
|
|||
/*********
|
||||
** Private methods
|
||||
*********/
|
||||
/// <summary>Get the name of a save directory for the current player.</summary>
|
||||
private static string GetSaveFolderName()
|
||||
{
|
||||
string prefix = new string(Game1.player.Name.Where(char.IsLetterOrDigit).ToArray());
|
||||
return $"{prefix}_{Game1.uniqueIDForThisGame}";
|
||||
}
|
||||
|
||||
/// <summary>Get the game's current version string.</summary>
|
||||
private static string GetGameVersion()
|
||||
{
|
||||
|
@ -200,5 +206,43 @@ namespace StardewModdingAPI
|
|||
throw new InvalidOperationException($"The {nameof(Game1)}.{nameof(Game1.version)} field could not be found.");
|
||||
return (string)field.GetValue(null);
|
||||
}
|
||||
|
||||
/// <summary>Get the name of the save folder, if any.</summary>
|
||||
internal static string GetSaveFolderName()
|
||||
{
|
||||
// save not available
|
||||
if (Context.LoadStage == LoadStage.None)
|
||||
return null;
|
||||
|
||||
// get basic info
|
||||
string playerName;
|
||||
ulong saveID;
|
||||
if (Context.LoadStage == LoadStage.SaveParsed)
|
||||
{
|
||||
playerName = SaveGame.loaded.player.Name;
|
||||
saveID = SaveGame.loaded.uniqueIDForThisGame;
|
||||
}
|
||||
else
|
||||
{
|
||||
playerName = Game1.player.Name;
|
||||
saveID = Game1.uniqueIDForThisGame;
|
||||
}
|
||||
|
||||
// build folder name
|
||||
return $"{new string(playerName.Where(char.IsLetterOrDigit).ToArray())}_{saveID}";
|
||||
}
|
||||
|
||||
/// <summary>Get the path to the current save folder, if any.</summary>
|
||||
internal static string GetSaveFolderPathIfExists()
|
||||
{
|
||||
string folderName = Constants.GetSaveFolderName();
|
||||
if (folderName == null)
|
||||
return null;
|
||||
|
||||
string path = Path.Combine(Constants.SavesPath, folderName);
|
||||
return Directory.Exists(path)
|
||||
? path
|
||||
: null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using StardewModdingAPI.Enums;
|
||||
using StardewModdingAPI.Events;
|
||||
using StardewValley;
|
||||
using StardewValley.Menus;
|
||||
|
@ -39,5 +40,8 @@ namespace StardewModdingAPI
|
|||
|
||||
/// <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
|
||||
|
||||
/// <summary>The current stage in the game's loading process.</summary>
|
||||
internal static LoadStage LoadStage { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,9 +69,6 @@ namespace StardewModdingAPI.Framework
|
|||
/// <remarks>Skipping a few frames ensures the game finishes initialising the world before mods try to change it.</remarks>
|
||||
private readonly Countdown AfterLoadTimer = new Countdown(5);
|
||||
|
||||
/// <summary>The current stage in the game's loading process.</summary>
|
||||
private LoadStage LoadStage = LoadStage.None;
|
||||
|
||||
/// <summary>Whether the game is saving and SMAPI has already raised <see cref="IGameLoopEvents.Saving"/>.</summary>
|
||||
private bool IsBetweenSaveEvents;
|
||||
|
||||
|
@ -215,12 +212,12 @@ namespace StardewModdingAPI.Framework
|
|||
internal void OnLoadStageChanged(LoadStage newStage)
|
||||
{
|
||||
// nothing to do
|
||||
if (newStage == this.LoadStage)
|
||||
if (newStage == Context.LoadStage)
|
||||
return;
|
||||
|
||||
// update data
|
||||
LoadStage oldStage = this.LoadStage;
|
||||
this.LoadStage = newStage;
|
||||
LoadStage oldStage = Context.LoadStage;
|
||||
Context.LoadStage = newStage;
|
||||
if (newStage == LoadStage.None)
|
||||
{
|
||||
this.Monitor.Log("Context: returned to title", LogLevel.Trace);
|
||||
|
@ -511,7 +508,7 @@ namespace StardewModdingAPI.Framework
|
|||
*********/
|
||||
if (wasWorldReady && !Context.IsWorldReady)
|
||||
this.OnLoadStageChanged(LoadStage.None);
|
||||
else if (Context.IsWorldReady && this.LoadStage != LoadStage.Ready)
|
||||
else if (Context.IsWorldReady && Context.LoadStage != LoadStage.Ready)
|
||||
{
|
||||
// print context
|
||||
string context = $"Context: loaded saved game '{Constants.SaveFolderName}', starting {Game1.currentSeason} {Game1.dayOfMonth} Y{Game1.year}.";
|
||||
|
@ -884,7 +881,7 @@ namespace StardewModdingAPI.Framework
|
|||
events.GameLaunched.Raise(new GameLaunchedEventArgs());
|
||||
|
||||
// preloaded
|
||||
if (Context.IsSaveLoaded && this.LoadStage != LoadStage.Loaded && this.LoadStage != LoadStage.Ready)
|
||||
if (Context.IsSaveLoaded && Context.LoadStage != LoadStage.Loaded && Context.LoadStage != LoadStage.Ready)
|
||||
this.OnLoadStageChanged(LoadStage.Loaded);
|
||||
|
||||
// update tick
|
||||
|
|
Loading…
Reference in New Issue