diff --git a/SleepyEye/Framework/ModConfig.cs b/SleepyEye/Framework/ModConfig.cs new file mode 100644 index 000000000..2213a1445 --- /dev/null +++ b/SleepyEye/Framework/ModConfig.cs @@ -0,0 +1,12 @@ +namespace SleepyEye.Framework +{ + /// The mod configuration. + internal class ModConfig + { + /********* + ** Accessors + *********/ + /// The number of seconds until the tent tool should trigger a save. + public int SecondsUntilSave { get; set; } = 7; + } +} diff --git a/SleepyEye/Mod.cs b/SleepyEye/Mod.cs index 7c764dd8d..2396e173e 100644 --- a/SleepyEye/Mod.cs +++ b/SleepyEye/Mod.cs @@ -1,20 +1,46 @@ +using System; +using SleepyEye.Framework; using SpaceShared; +using SpaceShared.APIs; using StardewModdingAPI; using StardewModdingAPI.Events; using StardewValley.Menus; namespace SleepyEye { + /// The mod entry point. internal class Mod : StardewModdingAPI.Mod { + /********* + ** Accessors + *********/ + /// The static mod instance. public static Mod Instance; + /// public override void Entry(IModHelper helper) { + // load config + this.ApplyConfig(helper.ReadConfig()); + + // init Mod.Instance = this; Log.Monitor = this.Monitor; - helper.Events.Display.MenuChanged += this.OnMenuChanged; + helper.Events.GameLoop.GameLaunched += this.OnGameLaunched; + } + + /// Raised after the game is launched, right before the first update tick. This happens once per game session (unrelated to loading saves). All mods are loaded and initialised at this point, so this is a good time to set up mod integrations. + /// The event sender. + /// The event arguments. + private void OnGameLaunched(object sender, GameLaunchedEventArgs e) + { + var gmcm = this.Helper.ModRegistry.GetApi("spacechase0.GenericModConfigMenu"); + if (gmcm != null) + { + gmcm.RegisterModConfig(this.ModManifest, revertToDefault: () => this.ApplyConfig(new ModConfig()), saveToFile: this.SaveConfig); + gmcm.RegisterSimpleOption(this.ModManifest, "Seconds until save", "The number of seconds until the tent tool should trigger a save.", () => (int)TentTool.UseDelay.TotalSeconds, (int val) => TentTool.UseDelay = TimeSpan.FromSeconds(val)); + } } /// Raised after a game menu is opened, closed, or replaced. @@ -22,7 +48,7 @@ public override void Entry(IModHelper helper) /// The event arguments. private void OnMenuChanged(object sender, MenuChangedEventArgs e) { - if (!(e.NewMenu is ShopMenu menu) || menu.portraitPerson.Name != "Pierre") + if (e.NewMenu is not ShopMenu menu || menu.portraitPerson.Name != "Pierre") return; Log.Debug("Adding tent to shop"); @@ -34,5 +60,21 @@ private void OnMenuChanged(object sender, MenuChangedEventArgs e) forSale.Add(item); itemPriceAndStock.Add(item, new[] { item.salePrice(), item.Stack }); } + + /// Apply the given mod configuration. + /// The configuration model. + private void ApplyConfig(ModConfig config) + { + TentTool.UseDelay = TimeSpan.FromSeconds(config.SecondsUntilSave); + } + + /// Save the current mod configuration. + private void SaveConfig() + { + this.Helper.WriteConfig(new ModConfig + { + SecondsUntilSave = (int)TentTool.UseDelay.TotalSeconds + }); + } } } diff --git a/SleepyEye/TentTool.cs b/SleepyEye/TentTool.cs index 25252123f..728e1c80d 100644 --- a/SleepyEye/TentTool.cs +++ b/SleepyEye/TentTool.cs @@ -27,13 +27,17 @@ public class TentTool : Tool, ISaveElement /// Whether the tent triggered an ongoing save. private bool IsSaving => this.StartedSaving != null; - /// How long the tent must be used before a save is triggered. - private readonly TimeSpan UseDelay = TimeSpan.FromSeconds(7); - /// How long after a save is triggered before resetting the tool's use and save flags. private readonly TimeSpan ResetDelay = TimeSpan.FromSeconds(3); + /********* + ** Accessors + *********/ + /// How long the tent must be used before a save is triggered. + internal static TimeSpan UseDelay { get; set; } + + /********* ** Public methods *********/ @@ -116,7 +120,7 @@ public override void tickUpdate(GameTime time, SFarmer who) // save if done TimeSpan useTime = this.GetTimeSince(this.StartedUsing!.Value); - if (useTime > this.UseDelay) + if (useTime > TentTool.UseDelay) { this.CancelUse(who); @@ -141,10 +145,10 @@ public override void draw(SpriteBatch b) { // get transparency Color color = Color.White; - if (!this.IsSaving && this.IsUsing && this.GetTimeSince(this.StartedUsing!.Value) < this.UseDelay) + if (!this.IsSaving && this.IsUsing && this.GetTimeSince(this.StartedUsing!.Value) < TentTool.UseDelay) { var useTime = this.GetTimeSince(this.StartedUsing!.Value); - color *= (0.2f + (float)useTime.TotalSeconds / 7f * 0.6f); + color *= (0.2f + (float)useTime.TotalSeconds / (float)TentTool.UseDelay.TotalSeconds * 0.6f); } // draw diff --git a/SleepyEye/docs/release-notes.md b/SleepyEye/docs/release-notes.md index f356e2745..06be98bed 100644 --- a/SleepyEye/docs/release-notes.md +++ b/SleepyEye/docs/release-notes.md @@ -3,7 +3,8 @@ # Release notes ## Upcoming release * Updated for Stardew Valley 1.5. -* Holding the tent button now triggers a save after seven seconds without waiting for you to release the button. +* The time you need to hold the tent button is now configurable. +* Holding the tent button now triggers a save after the delay without waiting for you to release the button. * Fixed compatibility with [unofficial 64-bit mode](https://stardewvalleywiki.com/Modding:Migrate_to_64-bit_on_Windows). * Improved documentation. * Internal refactoring.