Set "IsPlayer" at runtime, and how to have more than 2 participants in a conversation
Posted: Fri Nov 12, 2021 6:13 am
Hello!
I'm trying to set up my dialogue database with several conversations that I try to keep as generic as possible. By "generic" I mean the actors should not be named at design-time: I have "A", "B", "C", "D" and "E" defined in the Actors table of the dialogue database for the time being and that's it. The important takeaway is that none of these actors is to be defined as a player at design-time because the player may change character at any time (they can detach the camera from a character, fly to another character then take control of it).
To identify which "generic actor" is talking (A, B etc) in the conversation editor, I assigned a different color to all five of them, but of course none of the nodes is blue since none of the actors is defined as being a player in advance.
Here is an example of such a generic conversation. This is a test with two actors, "A" (dark green) and "B" (yellowish green), and tokens like "[@a.nn]" and "[@b.nn]" are to be replaced at runtime by A's nickname and B's nickname respectively. The condition in the "Welcome to the company" node is 'IdentFaction("@b.uid", "@a.uid", "office worker") >= 0.5' which means "does actor B identify actor A as an office worker with at least 50% confidence?" (knowing that actor A may or may not be dressed like an employee, may or may not be an actual employee, which may or may not be known by B, so it goes a little further than just "is A wearing the appropriate outfit?"). A or B may be a player, or neither of them.
When it comes to starting an actual conversation during play, the game assigns the actors by calling (*), then I don't even bother setting the Actor and Conversant in that call, so I assume the first two registered actors become them respectively. Problem is, I don't see a way to tell Dialogue System that one of them is supposed to be a player so the game plays the conversations without ever giving the player a choice.
Please note that I make extensive use of conditions and scripts in conversations (I have an internal dictionary linking an active conversation to a set of data so I can get data in real time from my own characters, such as their name or their disguises or anything you can think of, without ever needing Lua), so a conversation has a lot of branches that still make sense whether one of the actors is a player or not.
An example of this would be a situation like in Hitman where a character wants to walk into a restricted area. If the character is wearing the proper outfit or is properly searched by the guard, the guard will say "go ahead" whether the character is a player or not. If not, the guard will deny passage or even become hostile. It is the same conversation, it doesn't matter who's actually controlling any of the characters, a player or an AI.
I can't set "isPlayer" to an actor in the database at design-time because as I pointed out above, any of these actors may be a player. I can't set it at runtime either because I could have two conversations running at the same time, both using the actors A and B and in one of the conversations A is a player but not in the other conversation.
So I'm at a loss about how to do this. How to tell DS at runtime that an actor is a player?
(*) This leads to a second question actually. If I have more than one conversation running at the same time, I call then a little later (while the first conversation is still running), and suddenly the first conversation's actor "A" will be different. I know that conversations hold their own Actor and Conversant but I don't see a way to have more than two participants proper to the conversation. If I want more than two, the third one is global if I'm not mistaken. I know someone managed to do that but they never explained how and I can't find the post. Is there a way to make those actors A, B, C etc be local to the conversation so I can have two different characters be labeled "A" (for example) in two different conversations without one stepping on the other's toes?
I'm trying to set up my dialogue database with several conversations that I try to keep as generic as possible. By "generic" I mean the actors should not be named at design-time: I have "A", "B", "C", "D" and "E" defined in the Actors table of the dialogue database for the time being and that's it. The important takeaway is that none of these actors is to be defined as a player at design-time because the player may change character at any time (they can detach the camera from a character, fly to another character then take control of it).
To identify which "generic actor" is talking (A, B etc) in the conversation editor, I assigned a different color to all five of them, but of course none of the nodes is blue since none of the actors is defined as being a player in advance.
Here is an example of such a generic conversation. This is a test with two actors, "A" (dark green) and "B" (yellowish green), and tokens like "[@a.nn]" and "[@b.nn]" are to be replaced at runtime by A's nickname and B's nickname respectively. The condition in the "Welcome to the company" node is 'IdentFaction("@b.uid", "@a.uid", "office worker") >= 0.5' which means "does actor B identify actor A as an office worker with at least 50% confidence?" (knowing that actor A may or may not be dressed like an employee, may or may not be an actual employee, which may or may not be known by B, so it goes a little further than just "is A wearing the appropriate outfit?"). A or B may be a player, or neither of them.
When it comes to starting an actual conversation during play, the game assigns the actors by calling
Code: Select all
CharacterInfo.RegisterActorTransform (alias, transform)
Code: Select all
DialogueManager.StartConversation (conversationName)
Please note that I make extensive use of conditions and scripts in conversations (I have an internal dictionary linking an active conversation to a set of data so I can get data in real time from my own characters, such as their name or their disguises or anything you can think of, without ever needing Lua), so a conversation has a lot of branches that still make sense whether one of the actors is a player or not.
An example of this would be a situation like in Hitman where a character wants to walk into a restricted area. If the character is wearing the proper outfit or is properly searched by the guard, the guard will say "go ahead" whether the character is a player or not. If not, the guard will deny passage or even become hostile. It is the same conversation, it doesn't matter who's actually controlling any of the characters, a player or an AI.
I can't set "isPlayer" to an actor in the database at design-time because as I pointed out above, any of these actors may be a player. I can't set it at runtime either because I could have two conversations running at the same time, both using the actors A and B and in one of the conversations A is a player but not in the other conversation.
So I'm at a loss about how to do this. How to tell DS at runtime that an actor is a player?
(*) This leads to a second question actually. If I have more than one conversation running at the same time, I call
Code: Select all
CharacterInfo.RegisterActorTransform ("A", transform1)
Code: Select all
CharacterInfo.RegisterActorTransform ("A", transform2)