Modding Help How to get NPC to say specific dialogue entry in SMAPI

Discussion in 'Mods' started by trunip190, Apr 25, 2020.

Tags:
  1. trunip190

    trunip190 Orbital Explorer

    Hey,

    I'm trying to create a mod that pulls up custom dialogue responses when players hit npc's with tools (i thought by accident, but i'm sure some people do it intentionally at times).

    Something along the lines of: when you hit someone with the watering can they respond about needing an umbrella etc.

    I'm working visual studio (c#) and i have my dialogue in a seperate content patch mod ( i got started in that and was struggling to add dialogue in to my dll so i've left it there for now, but i can't figure out a way of referencing a dialogue string by location and code.

    I'm looking for something like this: (I know GetDialogueByID doesn't exist)

    Code:
    private void ActionOnNPC(NPC npc)
    {
           string s = Game1.GetDialogueByID("Wed2") ;
           npc.facePlayer(Game1.player);
           npc.addExtraDialogues(s);
           Game1.player.talkToFriend(npc);
    }
    I also looked at

    Game1.currentLocation.performAction("Talk", Game1.player, new xTile.Dimensions.Location((int)npc.getTileX(), (int)npc.getTileY()));

    but that doesn't seem to do anything.
     
    • trunip190

      trunip190 Orbital Explorer

      Well, I have partial answers at least.

      I can add new text, and have the npc speak it.
      Code:
      npc.addExtraDialogues($"Text to be spoken.");
      npc.checkAction(Game1.player, Game1.currentLocation);
      I can also have questions go through this in normal dialogue style:
      Code:
      npc.addExtraDialogues($"I wonder what would happen if I spent all night in the graveyard?#$q 17/18 Sun_old#@, What do you think happens to us after we die?#$r 17 0 Sun_17#I have no idea.#$r 18 40 Sun_18#We come back as spooky ghosts.#$r 17 0 Sun_17#We go to Heaven.#$r 18 0 Sun_17#Our energy bodies enter the astral plane.#$r 17 30 Sun_nothing#Nothing. We just cease to exist.");
      
      But this only seems to work for vanilla dialogue responses to questions - if i try and reference a new one, that fails even though it works in Content Patcher. (Eg. "Wed7")
       
      • trunip190

        trunip190 Orbital Explorer

        And here is the rest of it, from what I can tell. This is now more of a guide to editing/inserting text (mostly covered elsewhere but included here for completeness) and then recalling text:

        To start with, this is API focussed, so usuing visual studio. I am using Visual Studio 2019 which was free when i installed it, and i believe still is for the community version. Project is a "Class Library (.NET Framework) and I'm editing dialogue for Abigail (she seems the go-to girl).

        Code:
         public class DialogueEditor : IAssetEditor
            {
                private IModHelper modHelper;
                public IDictionary<string, string> data;
        
                public DialogueEditor(IModHelper helper)
                {
                    modHelper = helper;
                }
        
                public bool CanEdit<T>(IAssetInfo asset)
                {
                    return asset.AssetNameEquals("Characters/Dialogue/Abigail");
                }
        
               public void Edit<T>(IAssetData asset)
                {
               if (asset.AssetNameEquals("Characters/Dialogue/Abigail"))
                    {
                       data= asset.AsDictionary<string, string>().Data;
                       data["Introduction"] = "Oh, that's right... I heard someone new was moving onto that old farm. This is my new intro"; //replacing existing
                       data["new topic"] = "Hey, I have something new to say here"; //Adding a new topic with text
                }
        }
        This lets you change or insert topics into their list of things to say, similarly to Content Patcher mods. Nothing spectacular here, but i wanted to cover it.

        Next on to the tricky bit - pulling the text out of the character when you want them to say something. Maybe you want Abigail to say her tuesday text on wednesday? Or maybe you want her to say something when you stand in front of her computer? I won't cover the "trigger" here, but this is how you pull the text and get her to say it. You have to know which npc you want to say the line, but i grabbed mine by cycling through all of the npc's in the map until i found the one right next to me, and then assigned "NPC speaker" to it.

        Code:
        private void SpeakToPlayer(NPC speaker)
        {
                       npc.facePlayer(Game1.player);
                        string s;
                        if (speaker.Dialogue.TryGetValue("Wed2", out s))
                        {
                            speaker.addExtraDialogues(s);
                        }
                        else
                        {
                            speaker.addExtraDialogues($"Hey there @. What's up with me not having 'Wed2' text?");
                        }
        
                        speaker.checkAction(Game1.player, Game1.currentLocation);
        }
        Strictly speaking you don't need to have them face the player, but i like looking at people when talking to them.

        I hope this helps - I really struggled finding this online.

        Edit: changed formatting on the first code block to be more readable
         

        Share This Page