Dialogs
Note: This is an automatic translation from Russian. It looks good enough, but there may be inaccuracies. We are sorry for the inconvenience.
In this article, we will implement the dialogue of the elf with the main character, as a result of which he will have the key to the cave. However, to begin with, let's perform some preparatory steps. Add one more property to the MyGame class:
using TeravQuest;
namespace MyGame
{
[Serializable]
public class MyGame : Game
{
public int QuestStage { get; set; }
public Container PlayerInventory { get; set; }
public MyGame()
{
Name = "Shortest quest";
PlayerInventory = new Container();
InventoryVewSource = PlayerInventory.Objects;
QuestStage = 0;
AddLocation(new Home());
AddLocation(new Forest());
AddLocation(new ElvenHouse());
GoTo("Home");
}
}
}
This creates a PlayerInventory property of the Container type, in which we will store the player's inventory. More about the Container class will be discussed in the following articles. Note only that it was created for storing in-game items and has a method for grouped display of content. In the constructor, in the lines PlayerInventory = new Container (); and InventoryVewSource = PlayerInventory.Objects; the PlayerInventory property is initialized (an object is created), then the collection of container objects is set as the source for rendering objects in the inventory panel.
The InventoryVewSource property of the Game class is used to display objects in the inventory panel. It accepts a GameObjectsCollection, the contents of which will be displayed in the inventory panel when the location is rendered. In this case, this property will store the same collection that the PlayerInventory container also stores, therefore, by changing its contents, we will immediately see the changes in the inventory panel.
Dialog class
To create dialogs, TeravQuest provides the Dialog class, which already implements the logic for organizing auxiliary locations for a dialog and advancing through its stages. Basic properties:
Name. Will be displayed when displaying a list of NPC dialogues, when clicking on which the player will start a specific dialog.
Caption. Stores content that will be displayed throughout the entire dialogue. This can be the name of a character, an image, etc.
Text. Stores the contents of the current stage of the dialogue. In the overwhelming majority of cases, this will be the character's response to the line chosen by the player at the previous stage.
Basic methods:
OnStart. Called when the dialog starts. Here you need to set the contents of the Caption and Text fields for the first stage of the dialogue, as well as add actions leading to the next stages.
AddOption. Similar to the method in the Location class, adds an action that the player can click on. But now this action should lead to the next stage of the dialogue.
Say. Must be called at each stage of the dialogue to move to the next stage and update the contents of the game panels.
Finish. Contains the logic for ending the dialogue. Must be passed as the second parameter to the Option constructor when creating the action that ends the dialog.
Thus, to add dialogue to the game, you must:
- Create a new class, inheriting from the Dialog class.
- Set the dialog name in the class constructor.
- Implement the OnStart method by setting the contents of the Caption and Text properties, adding actions leading to the next stages using the AddOption method, and calling the Say method.
- Implement the methods of the next stages by setting the contents of the Text property, adding new actions, and calling the Say method.
- To complete the dialog, when creating the corresponding action, pass the Finish method as the second parameter to the constructor of the Option class.
We are implementing a dialogue between the protagonist and the elf, in which they will talk about a mysterious cave. Create an ElfDialogAboutCave class with the following content:
using TeravQuest;
namespace MyGame
{
[Serializable]
class ElfDialogAboutCave : Dialog
{
public ElfDialogAboutCave()
{
Name = "Talk about the cave";
}
protected override void OnStart(Game game)
{
Caption = $"<h2>{game.ActiveSpeaker.Description}</h2>";
Text = "What do you want to know?";
AddOption(new Option("What is this cave near our homes?", AboutCave));
if ((game as MyGame).QuestStage < 1) AddOption(new Option("How to get to the cave?", GetInside));
AddOption(new Option("No, nothing ...", Finish));
Say(game);
}
private void AboutCave(Game game)
{
Text = "I don't know ... Something seems to live there, as it seemed to me. So I hung the lock on the entrance.";
AddOption(new Option("Clear...", OnStart));
Say(game);
}
private void GetInside(Game game)
{
Text = "So I have a key. Here, if necessary.";
Key key = (Key)game.ActiveSpeaker.Inventory.Objects.GetObjectByName("Shabby key");
if (key == null) game.IO.Error("The elf did not find the key.");
else
{
game.MoveItem(key, game.ActiveSpeaker.Inventory, (game as MyGame).PlayerInventory);
(game as MyGame).QuestStage = 1;
}
AddOption(new Option("thanks", Finish));
Say(game);
game.AppendAdditionalView("The elf gave me the key.");
}
}
}
The name of the dialog is set in the constructor: Name = "Talk about the cave" ;. Next, the OnStart method is implemented.
First, the value of the Caption field is set: Caption = $ "<h2> {game.ActiveSpeaker.Description} </h2>"; When a player clicks on an NPC at a location, the object of this character is assigned to the ActiveSpeaker property of the Game class, so in the dialogue we can access the character with whom the player is currently talking. In this case, we get a description of this character.
Then we set the property value Text = "What do you want to know?" ;.
After that, we add actions for the first stage of the dialogue.
AddOption(new Option("What is this cave near our homes?", AboutCave));
if ((game as MyGame).QuestStage < 1) AddOption(new Option("How to get to the cave?", GetInside));
AddOption(new Option("No, nothing ...", Finish));
Note that there is a condition before the second action. During the dialogue, the elf will give the hero the key, and he will advance along the quest. After that, asking how to get into the cave will not make sense again. Therefore, this thread of dialogue will no longer be displayed. The condition uses the value of the QuestStage property that we created in previous articles.
When we add a third action to the constructor of the Option object, we pass the Finish method. This means that when a player clicks on this action, the dialog will end. Finally, the Say method is invoked to display this stage of the dialog.
Next, the AboutCave and GetInside methods are implemented, which represent the next stages of the dialog. AboutCave Method:
Text = "I don't know ... Something seems to live there, as it seemed to me. So I hung the lock on the entrance.";
AddOption(new Option("Clear...", OnStart));
Say(game);
Here the elf provides information about the cave, and the dialogue no longer continues along this thread. Therefore, the OnStart method is passed to the action constructor, which will return us to the beginning of the dialogue, and the player can choose another option. Don't forget the Say method.
GetInside method:
Text = "So I have a key. Here, if necessary."; Key key = (Key)game.ActiveSpeaker.Inventory.Objects.GetObjectByName("Shabby key"); if (key == null) game.IO.Error("The elf did not find the key."); else { game.MoveItem(key, game.ActiveSpeaker.Inventory, (game as MyGame).PlayerInventory); (game as MyGame).QuestStage = 1; } AddOption(new Option("Thanks", Finish)); Say(game); game.AppendAdditionalView("The elf gave me the key.");
In response to the player's question about how to get into the cave, the elf says that he has the key and gives it to the player.
A variable of type Key is created and the key object from the elf's inventory is stored in it.
Key key = (Key)game.ActiveSpeaker.Inventory.Objects.GetObjectByName("Shabby key");
Since the GetObjectByName method returns an object of type GameObject, you must explicitly convert it to a key object: (Key).
Then we check if we actually received the key and, if not, show an error message.
if (key == null) game.IO.Error("The elf did not find the key.");
This check is done at the development stage, in case, for example, if we typed the object name incorrectly. Then this check can be deleted, or you can leave it.
If the key is successfully found at the elf, we transfer it to the player and increase the quest stage.
game.MoveItem(key, game.ActiveSpeaker.Inventory, (game as MyGame).PlayerInventory);
(game as MyGame).QuestStage = 1;
The MoveItem method takes three parameters. The object to be moved, and two containers: from which to move, and the one to which you want to move. Since the PlayerInventory property was previously bound to the InventoryViewSource property, the key will immediately be displayed in the inventory panel.
And finally, an action is added that ends the dialog, the Say method is called, and a message is displayed in the additional game panel that the key has been received.
AddOption(new Option("Thanks", Finish));
Say(game);
game.AppendAdditionalView("The elf gave me the key.");
Let's add the created dialogue to the elf. Add the following line to the Elf class constructor:
Dialogs.Add(new ElfDialogAboutCave());
Summarizing this and the previous article, after all the actions taken, in the ElvenHouse location we now have a character with whom the player can talk about the cave. By choosing the second branch in this dialogue, the player receives the key and moves along the quest, and the corresponding branch in the dialogue no longer appears.