Changes

Jump to navigation Jump to search
3,504 bytes added ,  20:21, 14 September 2019
→‎Send a letter: - add working example
Line 352: Line 352:  
===Send a letter===
 
===Send a letter===
   −
Use IAssetEditor to inject new mail into Data\Mail.xnb. Then use Game1.addMailForTomorrow to send it to the player.
+
Before you can send any of your own custom mail you must use a class that implements (derives from) IAssetEditor to inject new mail content into Data\Mail.xnb. An example using SMAPI is shown below:
    
<source lang="c#">
 
<source lang="c#">
public static void addMailForTomorrow(string mailName, bool noLetter = false, bool sendToEveryone = false);
+
using StardewModdingAPI;
 +
 
 +
namespace MyMod
 +
{
 +
    public class MyModMail : IAssetEditor
 +
    {
 +
        public MyModMail()
 +
        {
 +
        }
 +
 
 +
        public bool CanEdit<T>(IAssetInfo asset)
 +
        {
 +
            return asset.AssetNameEquals("Data\\mail");
 +
        }
 +
 
 +
        public void Edit<T>(IAssetData asset)
 +
        {
 +
            var data = asset.AsDictionary<string, string>().Data;
 +
 
 +
            // "MyModMail1" is referred to as the mail Id.  It is how you will uniquely identify and reference your mail.
 +
            // The @ will be replaced with the player's name.  Other items do not seem to work (i.e. %pet or %farm)
 +
            // %item object 388 50 %%  - this adds 50 pieces of wood when added to the end of a letter.
 +
            // %item money 250 601  %%  - this sends money (did not try it myself)
 +
            // %item cookingRecipe %%  - this is for recipes (did not try myself)  Not sure how it know which recipe.
 +
            data["MyModMail1"] = "Hello @... ^A single carat is a new line ^^Two carats will double space.";
 +
            data["MyModMail2"] = "This is how you send an existing item via email! %item object 388 50 %%";
 +
            data["MyWizardMail"] = "Include Wizard in the mail Id to use the special background on a letter";
 +
        }
 +
    }
 +
}
 +
</source>
 +
 
 +
To make uses of this class in your own project, thereby making the mail data available, hook into the OnGameLaunch event, for example
 +
 
 +
<source lang="c#">
 +
        /// <summary>
 +
        /// Fires after game is launched, right before first update tick. Happens once per game session (unrelated to loading saves).
 +
        /// All mods are loaded and initialized at this point, so this is a good time to set up mod integrations.
 +
        /// </summary>
 +
        private void OnGameLaunched(object sender, GameLaunchedEventArgs e)
 +
        {
 +
            Helper.Content.AssetEditors.Add(new MyModMail());
 +
        }
 +
</source>
 +
 
 +
To actually put one of your custom letters into the player's in-game mailbox, you can use a couple different methods, depending on your need.  Two examples are shown below.  The distinction between the two methods will be explained below:
 +
 
 +
<source lang="c#">
 +
        Game1.player.mailbox.Add("MyModMail1");
 +
        Game1.addMailForTomorrow("MyModMail2");
 +
</source>
 +
 
 +
The first method (Game1.player.mailbox.Add) adds the letter directly into the mailbox for the current day.  This is best accomplished in your OnNewDay event code.  Mail added directly to the mailbox does not seem to be remembered even after a save.  This is from my personal observation.  Each time Stardew Valley started, my mod would send the letter again.  That has some uses.
 +
 
 +
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) making it possible not to send the same letter over and over.  Again this is very useful as well.
 +
 
 +
There may be a way to put the letter directly into the mailbox and have it be remembered, maybe using the next collection (mailRecieved) to be covered, but that has not been confirmed so I don't want to lead you astray.  Presumption is you have to add your mail manually if you want it to be remembered.
 +
 
 +
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.
 +
 
 +
<source lang="c#">
 +
          Game1.player.mailReceived.Remove("MyModMail1");
 
</source>
 
</source>
   −
Where mailName is the letter key in Mail.xnb. If you use the string '''wizard''' anywhere in the letter key, the letter will have the Wizard's new background (since 1.3) automatically.
+
That is all there is to send a simple letter.   Attaching items, although mentioned in the source code comments above, will need some additional explanation at a future time.
    
==Open source==
 
==Open source==
49

edits

Navigation menu