diff --git a/GeneralMods/SaveAnywhere/API/ISaveAnywhereAPI.cs b/GeneralMods/SaveAnywhere/API/ISaveAnywhereAPI.cs new file mode 100644 index 00000000..55033c0a --- /dev/null +++ b/GeneralMods/SaveAnywhere/API/ISaveAnywhereAPI.cs @@ -0,0 +1,28 @@ +using System; + +namespace Omegasis.SaveAnywhere.API +{ + /// + /// Interface for the Save Anywhere API + /// Other mods can use this interface to get the + /// API from the SMAPI helper + /// + public interface ISaveAnywhereAPI + { + /********* + ** Events + *********/ + /// + /// Event that fires before game save + /// + event EventHandler BeforeSave; + /// + /// Event that fires after game save + /// + event EventHandler AfterSave; + /// + /// Event that fires after game load + /// + event EventHandler AfterLoad; + } +} diff --git a/GeneralMods/SaveAnywhere/API/SaveAnywhereAPI.cs b/GeneralMods/SaveAnywhere/API/SaveAnywhereAPI.cs new file mode 100644 index 00000000..ec34bb97 --- /dev/null +++ b/GeneralMods/SaveAnywhere/API/SaveAnywhereAPI.cs @@ -0,0 +1,19 @@ +using System; +using Omegasis.SaveAnywhere.Framework; + +namespace Omegasis.SaveAnywhere.API +{ + public class SaveAnywhereAPI : ISaveAnywhereAPI + { + public event EventHandler BeforeSave; + public event EventHandler AfterSave; + public event EventHandler AfterLoad; + + public SaveAnywhereAPI(SaveManager manager) + { + manager.BeforeSave += (sender, e) => { BeforeSave.Invoke(sender, e); }; + manager.AfterSave += (sender, e) => { AfterSave.Invoke(sender, e); }; + manager.AfterLoad += (sender, e) => { AfterLoad.Invoke(sender, e); }; + } + } +} diff --git a/GeneralMods/SaveAnywhere/Framework/Models/CharacterType.cs b/GeneralMods/SaveAnywhere/Framework/Models/CharacterType.cs index ef94f702..da6e2530 100644 --- a/GeneralMods/SaveAnywhere/Framework/Models/CharacterType.cs +++ b/GeneralMods/SaveAnywhere/Framework/Models/CharacterType.cs @@ -1,7 +1,7 @@ namespace Omegasis.SaveAnywhere.Framework.Models { /// The character type for an NPC. - internal enum CharacterType + public enum CharacterType { /// The player. Player = 1, diff --git a/GeneralMods/SaveAnywhere/Framework/Models/PlayerData.cs b/GeneralMods/SaveAnywhere/Framework/Models/PlayerData.cs index 49fbdd87..2bb7287c 100644 --- a/GeneralMods/SaveAnywhere/Framework/Models/PlayerData.cs +++ b/GeneralMods/SaveAnywhere/Framework/Models/PlayerData.cs @@ -1,7 +1,7 @@ namespace Omegasis.SaveAnywhere.Framework.Models { /// The data for the current player. - internal class PlayerData + public class PlayerData { /// The current time. public int Time { get; set; } diff --git a/GeneralMods/SaveAnywhere/Framework/Models/PositionData.cs b/GeneralMods/SaveAnywhere/Framework/Models/PositionData.cs index 2f8ad8cc..5708b451 100644 --- a/GeneralMods/SaveAnywhere/Framework/Models/PositionData.cs +++ b/GeneralMods/SaveAnywhere/Framework/Models/PositionData.cs @@ -3,7 +3,7 @@ namespace Omegasis.SaveAnywhere.Framework.Models { /// Represents saved data for an NPC. - internal class CharacterData + public class CharacterData { /********* ** Accessors diff --git a/GeneralMods/SaveAnywhere/Framework/NewSaveMenu.cs b/GeneralMods/SaveAnywhere/Framework/NewSaveGameMenu.cs similarity index 98% rename from GeneralMods/SaveAnywhere/Framework/NewSaveMenu.cs rename to GeneralMods/SaveAnywhere/Framework/NewSaveGameMenu.cs index 10c00854..509529cd 100644 --- a/GeneralMods/SaveAnywhere/Framework/NewSaveMenu.cs +++ b/GeneralMods/SaveAnywhere/Framework/NewSaveGameMenu.cs @@ -5,7 +5,6 @@ using StardewValley.BellsAndWhistles; using StardewValley.Menus; using System; using System.Collections.Generic; -using System.Linq; using System.Text; namespace Omegasis.SaveAnywhere.Framework @@ -13,6 +12,8 @@ namespace Omegasis.SaveAnywhere.Framework /// A marker subclass to detect when a custom save is in progress. internal class NewSaveGameMenu : IClickableMenu { + public event EventHandler SaveComplete; + private int completePause = -1; private int margin = 500; private StringBuilder _stringBuilder = new StringBuilder(); @@ -38,6 +39,8 @@ namespace Omegasis.SaveAnywhere.Framework this.completePause = 1500; this.loader = (IEnumerator)null; Game1.game1.IsSaving = false; + + SaveComplete.Invoke(this, EventArgs.Empty); } public override void update(GameTime time) diff --git a/GeneralMods/SaveAnywhere/Framework/NewShippingMenu.cs b/GeneralMods/SaveAnywhere/Framework/NewShippingMenu.cs index b21fc994..87dd59e6 100644 --- a/GeneralMods/SaveAnywhere/Framework/NewShippingMenu.cs +++ b/GeneralMods/SaveAnywhere/Framework/NewShippingMenu.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework; using Netcode; using StardewModdingAPI; using StardewValley; diff --git a/GeneralMods/SaveAnywhere/Framework/SaveManager.cs b/GeneralMods/SaveAnywhere/Framework/SaveManager.cs index f6c10f89..fc1a1ef4 100644 --- a/GeneralMods/SaveAnywhere/Framework/SaveManager.cs +++ b/GeneralMods/SaveAnywhere/Framework/SaveManager.cs @@ -12,7 +12,7 @@ using StardewValley.Monsters; namespace Omegasis.SaveAnywhere.Framework { /// Provides methods for saving and loading game data. - internal class SaveManager + public class SaveManager { /********* ** Properties @@ -32,6 +32,24 @@ namespace Omegasis.SaveAnywhere.Framework /// Whether we should save at the next opportunity. private bool WaitingToSave; + /// Currently displayed save menu (null if no menu is displayed) + private NewSaveGameMenu currentSaveMenu; + + /********* + ** Events + *********/ + /// + /// Event that fires before game save + /// + public event EventHandler BeforeSave; + /// + /// Event that fires after game save + /// + public event EventHandler AfterSave; + /// + /// Event that fires after game load + /// + public event EventHandler AfterLoad; /********* ** Public methods @@ -53,11 +71,26 @@ namespace Omegasis.SaveAnywhere.Framework // perform passive save if (this.WaitingToSave && Game1.activeClickableMenu == null) { - Game1.activeClickableMenu = new NewSaveGameMenu(); + currentSaveMenu = new NewSaveGameMenu(); + currentSaveMenu.SaveComplete += CurrentSaveMenu_SaveComplete; + Game1.activeClickableMenu = currentSaveMenu; this.WaitingToSave = false; } } + /// + /// Event function for NewSaveGameMenu event SaveComplete + /// + /// + /// + private void CurrentSaveMenu_SaveComplete(object sender, EventArgs e) + { + currentSaveMenu.SaveComplete -= CurrentSaveMenu_SaveComplete; + currentSaveMenu = null; + + AfterSave.Invoke(this, EventArgs.Empty); + } + /// Clear saved data. public void ClearData() { @@ -68,6 +101,9 @@ namespace Omegasis.SaveAnywhere.Framework /// Initiate a game save. public void BeginSaveData() { + // Fire Event before saving data + BeforeSave.Invoke(this, EventArgs.Empty); + // save game data Farm farm = Game1.getFarm(); if (farm.shippingBin.Any()) @@ -79,7 +115,12 @@ namespace Omegasis.SaveAnywhere.Framework this.WaitingToSave = true; } else - Game1.activeClickableMenu = new NewSaveGameMenu(); + { + currentSaveMenu = new NewSaveGameMenu(); + currentSaveMenu.SaveComplete += CurrentSaveMenu_SaveComplete; + Game1.activeClickableMenu = currentSaveMenu; + } + // get data PlayerData data = new PlayerData @@ -112,6 +153,8 @@ namespace Omegasis.SaveAnywhere.Framework this.SetPositions(data.Characters); this.OnLoaded?.Invoke(); + // Notify other mods that load is complete + AfterLoad.Invoke(this, EventArgs.Empty); } /// diff --git a/GeneralMods/SaveAnywhere/SaveAnywhere.cs b/GeneralMods/SaveAnywhere/SaveAnywhere.cs index 99e32f40..3fbd84f0 100644 --- a/GeneralMods/SaveAnywhere/SaveAnywhere.cs +++ b/GeneralMods/SaveAnywhere/SaveAnywhere.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Omegasis.SaveAnywhere.API; using Omegasis.SaveAnywhere.Framework; using StardewModdingAPI; using StardewModdingAPI.Events; @@ -47,9 +48,10 @@ namespace Omegasis.SaveAnywhere /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { - this.Config = helper.ReadConfig(); + this.SaveManager = new SaveManager(this.Helper, this.Helper.Reflection, onLoaded: () => this.ShouldResetSchedules = true); + SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; SaveEvents.AfterSave += this.SaveEvents_AfterSave; MenuEvents.MenuChanged += this.MenuEvents_MenuChanged; @@ -60,6 +62,16 @@ namespace Omegasis.SaveAnywhere ModMonitor = Monitor; } + /// + /// Exposes the SaveAnywhere API to other SMAPI mods + /// + /// + public override object GetApi() + { + SaveAnywhereAPI api = new SaveAnywhereAPI(SaveManager); + return api; + } + /********* ** Private methods @@ -74,7 +86,6 @@ namespace Omegasis.SaveAnywhere this.ShouldResetSchedules = false; // load positions - this.SaveManager = new SaveManager(this.Helper, this.Helper.Reflection, onLoaded: () => this.ShouldResetSchedules = true); this.SaveManager.LoadData(); } diff --git a/GeneralMods/SaveAnywhere/SaveAnywhere.csproj b/GeneralMods/SaveAnywhere/SaveAnywhere.csproj index 69f8c90d..2da3321b 100644 --- a/GeneralMods/SaveAnywhere/SaveAnywhere.csproj +++ b/GeneralMods/SaveAnywhere/SaveAnywhere.csproj @@ -75,10 +75,12 @@ Properties\GlobalAssemblyInfo.cs + + - +