Difference between revisions of "Conversation Looping"

From The DarkMod Wiki
Jump to navigationJump to search
m (Add For More and Template)
Line 42: Line 42:
where Stanza_1 has "Pange, lingua, gloriósi [etc]". And so on for the other 10 conversations.
where Stanza_1 has "Pange, lingua, gloriósi [etc]". And so on for the other 10 conversations.


The start of the scripting look like:
The scripting looks like:
   
   
  void ConversationTransition() {
  void ConversationTransition() {
Line 63: Line 63:
  }
  }
  ...
  ...
void Conversation12Done()
{
  ConversationTransition();
  sys.trigger($startconversation_hall_1); // BIG LOOP
}
Out of the way, there is a stack of 12 atdm:target_startconverstaion entities. The one called "startconversation_hall_2" has spawnarg "conversation" "music_hall_2"; and so on.
Out of the way, there is a stack of 12 atdm:target_startconverstaion entities. The one called "startconversation_hall_2" has spawnarg "conversation" "music_hall_2"; and so on.



Revision as of 16:32, 31 December 2021

by Geep 2021. First 2 sections from a Conversation Editor thread

While typical TDM conversations are "one and done", occasionally there's one you want to loop, making it more like an ambient track.

Of Fixed Duration

Conversations of a fixed duration can be restarted repeatedly with trigger_multiple or trigger_timer, with the wait time set to the conversation duration. It triggers a atdm:target_startconversation entity, whose "conversation" spawnarg names the conversation of interest.

To interrupt that looping when an AI is alerted, suppose you arrange that a trigger_once_entityname fires at that time. Use it to fire a func_remove configured to eliminate the trigger_timer that's looping the conversation repeatedly. (The AI then follow the paths with alert_idle_only 1 set on them, and no more conversing.)

Of Variable Duration

Long conversations with complex multichoice sound shaders can have variable durations.

As the last command in the conversation, use ActivateTrigger, with the final speaking actor as the agent. Have it target a trigger_relay that has a "delay" of a few seconds and targets the atdm:target_startconversation.

Or alternatively, and particularly for more complex behavior, use RunScript, as in the next example.

As a Looped Set of Conversations - An Example

Consider the music-hall rehearsal between vocal coach and singer in "Away 0: Stolen Heart". This is implemented by 12 individual conversations, where:

  • the odd-numbered ones are spoken, with a call from the coach followed by response from the singer;
  • the even-numbered ones each contain 1 stanza of a song in Latin.

The overall flow starts with conversation "music_hall_1", and at the end, loops back to it, forever. At the end of each conversation, a script function is called, which decides which conversation to call next. By design, generally there's a 50% chance that a given call/response conversation is skipped. Each particular call, response, or stanza is represented by a custom sound shader. There are multiple possibilities within each call or response sound shader, and one phrase is randomly chosen each time it’s entered.

To be specific, commands for conversation "music_hall_1" are:

Coach.Talk (Coach_Begin_Stanza_1)
Singer.Talk (Singer_Acknowledgement)
Singer.RunScript (Conversation1Done)		// Script says: go to Conversation 2

where

  • commands such as Talk() generally have "Wait until Finished" checked;
  • Coach_Begin_Stanza_1 has phrases like "Begin" and "Strive to calm thy thoughts, Brother. Begin again, from the start".
  • Singer_Acknowledgement has phrases like "I shall, master!" and "I see!".

As a typical "even-numbered" conversation, "music_hall_2" has:

Singer.Talk (Stanza_1)
Singer.RunScript (Conversation2Done)			// Script says: go to Conversation 3 or 4 (50% chance each)

where Stanza_1 has "Pange, lingua, gloriósi [etc]". And so on for the other 10 conversations.

The scripting looks like:

void ConversationTransition() {
 $singer.setAlertLevel(0); // If alerted, conversations never resume, so suppress.
 $coach_grayman.setAlertLevel(0); // See also: raised singer & coach alert_threshold spawnargs.
 sys.wait(0.01); // Some minimal wait needed or else audio doesn't replay
}

void Conversation1Done() {
 ConversationTransition();
 sys.trigger($startconversation_hall_2);
}

void Conversation2Done() {
 ConversationTransition();
 if(sys.random(1) < 0.5)
  sys.trigger($startconversation_hall_3);
 else
  sys.trigger($startconversation_hall_4);	
}
...
void Conversation12Done()
{
 ConversationTransition();
 sys.trigger($startconversation_hall_1); // BIG LOOP
}

Out of the way, there is a stack of 12 atdm:target_startconverstaion entities. The one called "startconversation_hall_2" has spawnarg "conversation" "music_hall_2"; and so on.

For More

  • Conversations
  • About the example, see the Word doc distributed with this FM: "Away 0 Maintenance Guide", chapter "Music Hall Conversations with Singing"