Changes

Jump to navigation Jump to search
607 bytes added ,  21:50, 28 September 2019
Line 478: Line 478:  
Notice the additional code in the Edit method, where any mail in the dynamicMail collection is injected into Stardew Valley's content.  There will be no mail in the dynamicMail collection when the MOD is loaded (in this case) the first time.  If you add mail after the original load, then the content will have to be reloaded by invalidating the cache.  Refer to [https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Content#Advanced Invalidating Cache] for more details.
 
Notice the additional code in the Edit method, where any mail in the dynamicMail collection is injected into Stardew Valley's content.  There will be no mail in the dynamicMail collection when the MOD is loaded (in this case) the first time.  If you add mail after the original load, then the content will have to be reloaded by invalidating the cache.  Refer to [https://stardewvalleywiki.com/Modding:Modder_Guide/APIs/Content#Advanced Invalidating Cache] for more details.
   −
===Send a letter (using static content)===
+
===Send a letter (using dynamic content)===
   −
To make uses of this class in your own project, thereby making the static mail data available, hook into the OnGameLaunch event, for example.
+
To make uses of this class in your own project, thereby making the dynamic mail available, hook into the OnGameLaunch event, for example.
    
<source lang="c#">
 
<source lang="c#">
 +
    // Make this available to other methods in the class to access
 +
    private MailData mailData = new MailData();
 +
 
     /// <summary>
 
     /// <summary>
 
     /// Fires after game is launched, right before first update tick. Happens once per game session (unrelated to loading saves).
 
     /// Fires after game is launched, right before first update tick. Happens once per game session (unrelated to loading saves).
Line 489: Line 492:  
     private void OnGameLaunched(object sender, GameLaunchedEventArgs e)
 
     private void OnGameLaunched(object sender, GameLaunchedEventArgs e)
 
     {
 
     {
         Helper.Content.AssetEditors.Add(new MyModMail());
+
         Helper.Content.AssetEditors.Add(mailData);
 
     }
 
     }
 
</source>
 
</source>
   −
Now that you have your letter loaded, it's time to send it to the playerThere are a couple different methods available to accomplish this as well, depending on your need.  Two examples are shown below. The distinction between the two methods will be explained below:
+
You can hook into other events, such as "Day Starting" or "Day Ending" to generate the letter you want to send.  Consider this simple example, that is only for illustration purposes.
    
<source lang="c#">
 
<source lang="c#">
     Game1.player.mailbox.Add("MyModMail1");
+
     private void OnDayStarting(object sender, DayStartedEventArgs e)
     Game1.addMailForTomorrow("MyModMail2");
+
     {
</source>
+
        string mailMessage = $"@, you have gathered {Game1.stats.rabbitWoolProduced} units of rabbit wool!";
   −
The first method (Game1.player.mailbox.Add) adds the letter directly into the mailbox for the current day.  This can be accomplished in your "DayStaring" event code, for example.  Mail added directly to the mailbox is not "remembered" as being sent even after a save.  This is useful in some scenarios depending on your need.
+
        mailData.Add("MyModMailWool", mailMessage);      // Add this new letter to the mail collection (for next refresh).
   −
The second method (Game1.addMailForTomorrow) will, as the name implies, add the letter to the player's mailbox on the next day. This method remembers the mail (Id) sent making it possible not to send the same letter over and over.  This can be handled in "DayStaring", "DayEnding" or other events, as dictated by your need.
+
        Game1.mailbox.Add("MyModMailWool");              // Add to mailbox and we don't need to track it
   −
You may be able to put the letter directly into the mailbox and also have it be remembered using the mailRecieved collection. You can simply add your mailId manually if you want it to be remembered when using the add directly to mailbox method.
+
        modHelper.Content.InvalidateCache("Data\\mail"); // (modHelper was assigned in ModEntry for use throughout the class)
 +
    }
 +
</source>
   −
If you want Stardew Valley to forget that a specific letter has already been sent, you can remove it from the mailReceived collection.  You can iterate through the collection as well using a foreach should you need to remove mail en mass.
+
This example formats a letter, showing the up-to-date count of rabbit wool, makes it available to the mail collection, places that letter in the mailbox, and then invalidates the cache so that this new letter will be injected during the cache refreshIn this case there is no need to remember mailId as the letter will be recreated each time it needs to be sent, which in this example is everyday.  Again, this code is only for illustration of the concept.
   −
<source lang="c#">
+
There is an important caveat to understand when injecting mail in this simple fashion. The various mail frameworks available handle this issue, and this section will be expanded to explain how to overcome the issue, but it is being covered here to ensure you have a complete understanding of how MODs work with Stardew Valley and SMAPI.
    Game1.player.mailReceived.Remove("MyModMail1");
  −
</source>
     −
That is all there is to sending a simple letter.   Attaching objects and sending money via letter is straight-forward, but sending recipes is more complicated  and will need some additional explanation at a future time.
+
If you add a dynamic letter and inject it into the content at Day Ending, you have to add the mail for display tomorrow obviously.  That means the game will be saved with a reference to the dynamic letter ("MyMailModWool" in this example) pending in the mail box.  If the player quits the game at that point and returns later to continue playing, then that dynamic letter is not available, resulting in a "phantom letter". The mailbox will show a letter is available but when clicked on nothing will display.  This can be handled in several ways, including by saving the custom letters and loading them when the player continues, but again this example code does not cover that yet.  That is why the example uses On Day Starting and makes the letter available right away.
    
==Harmony==
 
==Harmony==
49

edits

Navigation menu