Line 3: |
Line 3: |
| | | |
| This page covers how to do common tasks in SMAPI mods. '''Before reading this page, see the [[Modding:Modder Guide|Modder Guide]] and [[Modding:Modder Guide/Game Fundamentals|Game Fundamentals]].''' | | This page covers how to do common tasks in SMAPI mods. '''Before reading this page, see the [[Modding:Modder Guide|Modder Guide]] and [[Modding:Modder Guide/Game Fundamentals|Game Fundamentals]].''' |
| + | |
| + | ==Basic techniques== |
| + | ===Tracking changes to a value=== |
| + | Mods often need to know when a value changed. If there's no SMAPI event for the value, you can create a private [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/fields field] to track the value, and update it using the update tick event. For example, here's a full functional mod which prints a console message when the player's stamina changes: |
| + | |
| + | <source lang="c#"> |
| + | /// <summary>The mod entry point.</summary> |
| + | internal class ModEntry : Mod |
| + | { |
| + | /********* |
| + | ** Properties |
| + | *********/ |
| + | /// <summary>The player's last stamina value.</summary> |
| + | private float LastStamina; |
| + | |
| + | |
| + | /********* |
| + | ** Public methods |
| + | *********/ |
| + | /// <summary>The mod entry point, called after the mod is first loaded.</summary> |
| + | /// <param name="helper">Provides simplified APIs for writing mods.</param> |
| + | public override void Entry(IModHelper helper) |
| + | { |
| + | SaveEvents.AfterLoad += this.SaveEvents_AfterLoad; |
| + | GameEvents.UpdateTick += this.GameEvents_UpdateTick; |
| + | } |
| + | |
| + | |
| + | /********* |
| + | ** Private methods |
| + | *********/ |
| + | /// <summary>The method invoked when the player loads a save.</summary> |
| + | /// <param name="sender">The event sender.</param> |
| + | /// <param name="e">The event arguments.</param> |
| + | private void SaveEvents_AfterLoad(object sender, EventArgs e) |
| + | { |
| + | this.LastStamina = Game1.player.Stamina; |
| + | } |
| + | |
| + | /// <summary>The method invoked after the game updates (roughly 60 times per second).</summary> |
| + | /// <param name="sender">The event sender.</param> |
| + | /// <param name="e">The event arguments.</param> |
| + | private void GameEvents_UpdateTick(object sender, EventArgs e) |
| + | { |
| + | // skip if save not loaded yet |
| + | if (!Context.IsWorldReady) |
| + | return; |
| + | |
| + | // skip if stamina not changed |
| + | float currentStamina = Game1.player.Stamina; |
| + | if (currentStamina == this.LastStamina) |
| + | return; |
| + | |
| + | // print message & update stamina |
| + | this.Monitor.Log($"Player stamina changed from {currentStamina} to {this.LastStamina}"); |
| + | this.LastStamina = currentStamina; |
| + | } |
| + | } |
| + | </source> |
| | | |
| ==Items== | | ==Items== |