Tutorial Creating Hero Dialogue / Conversations

Users who are viewing this thread

Danqna

Recruit
Background:
I thought I'd post what I've found out so far about creating dialogue in a tutorial form. This is accurate on this day of our Lord 21st February 2022. Get some medieval up in ya. If you've got contributions to make this better or corrections to make it more accurate, let's do it. I'm certainly no always-right-Danqna-guy.

Required Knowledge: Basic
If you can set up your environment as below, you have the willpower and intelligence stats to make conversations in game.

Prerequisites:
You must have set up an environment, such as the one specified here: https://docs.bannerlordmodding.com/_tutorials/basic-csharp-mod.html#preparation

This means you know how to create a SubModule that works before you get into conversations specifically.

The disclaimer:
This is entirely based on what I found while testing. If you have updates or more accurate info, I love increasing my knowledge.

The code:
https://github.com/Danqna/NobleKiller

Yes I don’t know how to Github, but it’s there.

The setup:
So this was the real gotcha for me, because…frankly, I’m not very good at my job. You need to have your submodule set up, and then call the code from a class inheriting CampaignBehaviorBase. Game crashes if you … you know what, I’m not even going to explain any further. You want two classes, that’s it. I swear if you laugh out loud right now...

So I created two classes, the MySubModule, and a “noblekillerdialogue”.

(If you’re recreating this and simply copying and pasting from the github, and also aren’t good at your job, note that the noblekillerdialogue is in a different namespace)

General Overview:

Conversations have two people. You need a player dialogue and a response dialogue, or nothing happens. You specify the “next” dialogue in the definition of your dialogue, always making sure your dialogue returns to a TaleWorlds dialogue. You can set up filters for when dialogue should be shown, or don’t and always display the dialogue. Each conversation also has a consequence which is where you can make the world react to the conversation.

PLAYER dialogue:

Let’s put that in code, so we start with calling the conversation function with the PLAYER dialogue:

starter.AddPlayerLine(

OK, now we need to give our conversation topic a name to identify it in the future for localization or if we ever want to call it from a different dialogue. I named this conversation:

"assassin_target_start",

That is now how we will always identify the TEXT of our conversation in the future. That’s its name. Now I need to tell the game when I want this dialogue to show, so I tell the game, put it in the main hero options when I talk to a Hero:

"hero_main_options",

Next, I need to define what line of dialogue we are going to call when we’re done here, think of this as calling for a response. In this case I’ve called a line I named:

"assassin_noble_response",

Re-cap: we’ve named our line, we’ve told the game where to put our line, and we’ve told the game what line to call if the player clicks this line. This is where the fun begins! Add your text for the line.

"(Select for Assassination) You have made a poor choice in enemies.",

You could pass “null” in for both the next options (we won’t), run this code and every Hero you talk to you’ll get to give them a free character assessment. Instead of that, though, let’s add our condition for when this line should show, or not show:

new ConversationSentence.OnConditionDelegate(this.noble_killer_hero_check),

Alright let me break this down real quick. This is where I’m going to call a BOOL class with some “return true/false” that I’ll define elsewhere in the code, please jump ahead to CONDITIONS if this is what you’re here for, otherwise let’s look at the next bit which is going to EXECUTE code if we want to for when the player selects this option:

this.noble_killer_select,

This is going to be a new VOID class you create and add code into it. I expect for many people this is where they’re going to be calling their real objectives or making their real changes, but remember you might want your conversation to have several outcomes so you don’t have to put anything here and let the conversation simply continue and you can enter “null” here because there’s nothing to do. Now we’re going to give the conversation a priority, this is an advanced feature and beyond my current understanding, zero testing. I gave it 100/three flying chipmunks.

100,

I don’t even remember what this null is, but this is the name “ConversationSentence.OnPersuasionOptionDelegate” and here’s the documentation for the code: https://butr.github.io/Bannerlord.R...orlds.CampaignSystem.CampaignGameStarter.html

null);

So that whole line we’ve just created looks like this:

starter.AddPlayerLine("assassin_target_start", "hero_main_options", "assassin_noble_response","(Select for Assassination) You have made a poor choice in enemies.",new ConversationSentence.OnConditionDelegate(this.noble_killer_hero_check), this.noble_killer_select, 100, null);

NPC Dialogue
Remember back at the beginning, I said there must be a NPC dialogue following the PLAYER dialogue or it won't work? Well all the same rules apply, except you probably don't want to give NPC's optional responses until you figure out more than I have so far. So continuing the example above, to have the NPC respond, you create almost the same dialogue:

starter.AddDialogLine("assassin_noble_response", "assassin_noble_response", "hero_main_options","I am rubber, you are glue.", null, null, 100, null);

Note how this has the name "assassin_noble_response" which we set in the PLAYER conversation as the option to call?

56063561.jpg


Conditions:
Here’s a “condition” for the:

new ConversationSentence.OnConditionDelegate(this.noble_killer_hero_check),”

C#:
        /// <summary>
        /// This is where we just make sure the conversation is with a Hero
        /// </summary>
        /// <returns></returns>
        private bool noble_killer_hero_check()
        {
            if (Hero.OneToOneConversationHero != null && Hero.OneToOneConversationHero != NobleKillerTarget)
            {               
                return true;
            }
            return false;
        }

Your conditions may vary, may depend on other code, but this one just checks that we’re not talking to a notable or some other person with dialogue and it’s not the same person we’ve targeted to kill.

It's been 48 hours and they still haven't unlocked my account here, they're probably afraid of what I'd do if I could achieve my full potential here.
 
Back
Top Bottom