I was getting annoyed by not being able to get things to work, so I decided to do tests to figure out how exactly the system works. Here is what I've learned so far. Maybe it can help someone, or someone has something else to add to this. My testing continues (in orientation, what happens if there is an enemy, or a closed door between the first speaker and listener when conversation starts, ...), after it's done I will update this text and then it should probably go into the tutorial section.
Everything below is about TSL.
When the dialog starts, these roles need to be determined:
- DEFAULT_SPEAKER or OWNER
The terms OWNER and PLAYER may actually be used in the Listener (but not Speaker) field in the dialog editor (and also for dialog animations). In scripts fired through the dialog, OBJECT_SELF refers to OWNER. To explain how they are determined we also need to define oStarter and oOwner. They are defined by the script that fires the dialog:
AssignCommand(oStarter, ActionStartConversation(oOwner, "some_dialog"));
PLAYER always represents the first PC (GetFirstPC() in scripts).
DEFAULT_LISTENER is generally oStarter.
RULE 1: This is always true if oStarter is PLAYER.
RULE 2: If oOwner is PLAYER, then DEFAULT_LISTENER is always PLAYER (green and purple). If oStarter is a party member, then control is given to PLAYER after the dialog (green).
RULE 3: If oStarter is a party member and oOwner is a creature, then DEFAULT_LISTENER is PLAYER (red). In addition to that, before the dialog, PLAYER and oStarter exchange locations and control is given to PLAYER. After the dialog, control over the original party member is regained.
RULE 4: If oStarter is not a party member and oOwner is a party member, then DEFAULT_LISTENER is oOwner, the party member (blue).
OWNER is generally oOwner.
RULE 1: If oOwner is PLAYER, then OWNER is oStarter (green and purple).
RULE 2: If oOwner is a party member and oStarter is not a party member, OWNER is oStarter (blue).
All of this is summarized in the following table:
1 Controlled character changes to PLAYER after dialog.
2 Controlled character changes to PLAYER before dialog, but changes back afterwards.
Notes: STARTER in this table refers to DEFAULT_LISTENER. Shaded cells represent combinations where the roles of oStarter and oOwner may be reversed with the same effect. More attention should be paid to the white cells, especially a combination of a party member with another party member or creature. Bold font weight indicates that OWNER is oOwner or STARTER is oStarter, that is, no special rules have applied.
A node in this text means every entry and every instance of the player choosing a reply. Every node has the following roles, which need to be determined:
In determining them, we need to make use of OWNER, DEFAULT_LISTENER and PLAYER (defined above).
SPEAKER is the object with the tag in the Speaker field of the current entry. If the Speaker field is empty, SPEAKER is OWNER. If the field is not empty, but no object with that tag exists, the entry is skipped; if after that no other entries are available, the dialog ends.
In replies, SPEAKER is automatically PLAYER.
The keywords 'OWNER' and 'PLAYER' may NOT be used in the Speaker field. Doing this will end the conversation.
LISTENER is the object with the tag in the Listener field of the current node. If the field is empty, it is the object with the tag in the Speaker field of the previous node. If that object is invalid or the same as SPEAKER, or if this is the first node, then LISTENER is DEFAULT_LISTENER.
The keywords 'OWNER' and 'PLAYER' may be used in the Listener field.
At the beginning of every node, SPEAKER and LISTENER reorient on each other, unless SetLockOrientationInDialog() is TRUE. In that case the creature for which it is TRUE does not reorient.
There are two ways of reorienting in dialog. One is head-tracking, where the head is turned towards the target, and the body only turns as much as it needs to for the head to face the target. The creatures that do not use head-tracking instead turn entirely to face the target. For head-tracking to work, it must be enabled in appearance.2da under column 'headtrack'. The creatures that use head-tracking can turn it off by setting SetLockHeadFollowInDialog() to TRUE. However, if 'headtrack' is 0 in appearance.2da, then SetLockHeadFollowInDialog() cannot be used to enable head-tracking; these creatures will always turn entirely to face the target.