/// <summary>
 /// Initializes a new ConversationController and starts the conversation in the model.
 /// Also sends OnConversationStart messages to the participants.
 /// </summary>
 /// <param name='model'>
 /// Data model of the conversation.
 /// </param>
 /// <param name='view'>
 /// View to use to provide a user interface for the conversation.
 /// </param>
 /// <param name='endConversationHandler'>
 /// Handler to call to inform when the conversation is done.
 /// </param>
 public ConversationController(ConversationModel model, ConversationView view, bool alwaysForceResponseMenu, Action endConversationHandler)
 {
     IsActive   = true;
     this.model = model;
     this.view  = view;
     this.alwaysForceResponseMenu = alwaysForceResponseMenu;
     this.endConversationHandler  = endConversationHandler;
     model.InformParticipants("OnConversationStart");
     view.FinishedSubtitleHandler += OnFinishedSubtitle;
     view.SelectedResponseHandler += OnSelectedResponse;
     GotoState(model.FirstState);
 }
 /// <summary>
 /// Initializes a new ConversationController and starts the conversation in the model.
 /// Also sends OnConversationStart messages to the participants.
 /// </summary>
 /// <param name='model'>
 /// Data model of the conversation.
 /// </param>
 /// <param name='view'>
 /// View to use to provide a user interface for the conversation.
 /// </param>
 /// <param name='endConversationHandler'>
 /// Handler to call to inform when the conversation is done.
 /// </param>
 public ConversationController(ConversationModel model, ConversationView view, bool alwaysForceResponseMenu, Action endConversationHandler)
 {
     IsActive = true;
     this.model = model;
     this.view = view;
     this.alwaysForceResponseMenu = alwaysForceResponseMenu;
     this.endConversationHandler = endConversationHandler;
     model.InformParticipants("OnConversationStart");
     view.FinishedSubtitleHandler += OnFinishedSubtitle;
     view.SelectedResponseHandler += OnSelectedResponse;
     GotoState(model.FirstState);
 }
 /// <summary>
 /// Initializes a new ConversationController and starts the conversation in the model.
 /// Also sends OnConversationStart messages to the participants.
 /// </summary>
 /// <param name='model'>
 /// Data model of the conversation.
 /// </param>
 /// <param name='view'>
 /// View to use to provide a user interface for the conversation.
 /// </param>
 /// <param name='endConversationHandler'>
 /// Handler to call to inform when the conversation is done.
 /// </param>
 public ConversationController(ConversationModel model, ConversationView view, bool alwaysForceResponseMenu, EndConversationDelegate endConversationHandler)
 {
     isActive     = true;
     this.m_model = model;
     this.m_view  = view;
     this.m_endConversationHandler = endConversationHandler;
     model.InformParticipants(DialogueSystemMessages.OnConversationStart);
     view.FinishedSubtitleHandler += OnFinishedSubtitle;
     view.SelectedResponseHandler += OnSelectedResponse;
     m_currentConversationID       = model.GetConversationID(model.firstState);
     SetConversationOverride(model.firstState);
     GotoState(model.firstState);
 }
Example #4
0
        protected void PopulateCache(Transform speaker, Transform listener)
        {
            if (string.IsNullOrEmpty(barkConversation) && DialogueDebug.logWarnings)
            {
                Debug.Log(string.Format("{0}: Bark (speaker={1}, listener={2}): conversation title is blank", new System.Object[] { DialogueDebug.Prefix, speaker, listener }), speaker);
            }
            ConversationModel conversationModel = new ConversationModel(DialogueManager.masterDatabase, barkConversation, speaker, listener, DialogueManager.allowLuaExceptions, DialogueManager.isDialogueEntryValid);

            cachedState = conversationModel.firstState;
            if ((cachedState == null) && DialogueDebug.logWarnings)
            {
                Debug.Log(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' has no START entry", new System.Object[] { DialogueDebug.Prefix, speaker, listener, barkConversation }), speaker);
            }
            if (!cachedState.hasAnyResponses && DialogueDebug.logWarnings)
            {
                Debug.Log(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' has no valid bark lines", new System.Object[] { DialogueDebug.Prefix, speaker, listener, barkConversation }), speaker);
            }
        }
Example #5
0
        /// <summary>
        /// Attempts to make a character bark. This is a coroutine; you must start it using
        /// StartCoroutine() or Unity will hang. Shows a line from the named conversation, plays
        /// the sequence, and sends OnBarkStart/OnBarkEnd messages to the participants.
        /// </summary>
        /// <param name='conversationTitle'>
        /// Title of conversation to pull bark lines from.
        /// </param>
        /// <param name='speaker'>
        /// Speaker performing the bark.
        /// </param>
        /// <param name='listener'>
        /// Listener that the bark is directed to; may be <c>null</c>.
        /// </param>
        /// <param name='barkHistory'>
        /// Bark history used to keep track of the most recent bark so this method can iterate
        /// through them in a specified order.
        /// </param>
        /// <param name='database'>
        /// The dialogue database to use. If <c>null</c>, uses DialogueManager.MasterDatabase.
        /// </param>
        public static IEnumerator Bark(string conversationTitle, Transform speaker, Transform listener, BarkHistory barkHistory, DialogueDatabase database = null, bool stopAtFirstValid = false)
        {
            if (CheckDontBarkDuringConversation())
            {
                yield break;
            }
            bool barked = false;

            if (string.IsNullOrEmpty(conversationTitle) && DialogueDebug.logWarnings)
            {
                Debug.Log(string.Format("{0}: Bark (speaker={1}, listener={2}): conversation title is blank", new System.Object[] { DialogueDebug.Prefix, speaker, listener }), speaker);
            }
            if (speaker == null)
            {
                speaker = DialogueManager.instance.FindActorTransformFromConversation(conversationTitle, "Actor");
            }
            if ((speaker == null) && DialogueDebug.logWarnings)
            {
                Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' speaker is null", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }));
            }
            if (string.IsNullOrEmpty(conversationTitle) || (speaker == null))
            {
                yield break;
            }
            IBarkUI barkUI = DialogueActor.GetBarkUI(speaker); //speaker.GetComponentInChildren(typeof(IBarkUI)) as IBarkUI;

            if ((barkUI == null) && DialogueDebug.logWarnings)
            {
                Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' speaker has no bark UI", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }), speaker);
            }
            var firstValid = stopAtFirstValid || ((barkHistory == null) ? false : barkHistory.order == (BarkOrder.FirstValid));
            ConversationModel conversationModel = new ConversationModel(database ?? DialogueManager.masterDatabase, conversationTitle, speaker, listener, DialogueManager.allowLuaExceptions, DialogueManager.isDialogueEntryValid, -1, firstValid);
            ConversationState firstState        = conversationModel.firstState;

            if ((firstState == null) && DialogueDebug.logWarnings)
            {
                Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' has no START entry", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }), speaker);
            }
            if ((firstState != null) && !firstState.hasAnyResponses && DialogueDebug.logWarnings)
            {
                Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' has no valid bark at this time", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }), speaker);
            }
            if ((firstState != null) && firstState.hasAnyResponses)
            {
                try
                {
                    Response[]    responses = firstState.hasNPCResponse ? firstState.npcResponses : firstState.pcResponses;
                    int           index     = (barkHistory ?? new BarkHistory(BarkOrder.Random)).GetNextIndex(responses.Length);
                    DialogueEntry barkEntry = responses[index].destinationEntry;
                    if ((barkEntry == null) && DialogueDebug.logWarnings)
                    {
                        Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' bark entry is null", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }), speaker);
                    }
                    if (barkEntry != null)
                    {
                        var priority = GetEntryBarkPriority(barkEntry);
                        if (priority < GetSpeakerCurrentBarkPriority(speaker))
                        {
                            if (DialogueDebug.logInfo)
                            {
                                Debug.Log(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' currently barking a higher priority bark", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }), speaker);
                            }
                            yield break;
                        }
                        SetSpeakerCurrentBarkPriority(speaker, priority);
                        barked = true;
                        InformParticipants(DialogueSystemMessages.OnBarkStart, speaker, listener);
                        ConversationState barkState = conversationModel.GetState(barkEntry, false);
                        if (barkState == null)
                        {
                            if (DialogueDebug.logWarnings)
                            {
                                Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' can't find a valid dialogue entry", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }), speaker);
                            }
                            yield break;
                        }
                        if (firstState.hasNPCResponse)
                        {
                            CharacterInfo tempInfo = barkState.subtitle.speakerInfo;
                            barkState.subtitle.speakerInfo  = barkState.subtitle.listenerInfo;
                            barkState.subtitle.listenerInfo = tempInfo;
                        }
                        if (DialogueDebug.logInfo)
                        {
                            Debug.Log(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}'", new System.Object[] { DialogueDebug.Prefix, speaker, listener, barkState.subtitle.formattedText.text }), speaker);
                        }
                        InformParticipantsLine(DialogueSystemMessages.OnBarkLine, speaker, barkState.subtitle);

                        // Show the bark subtitle:
                        if (((barkUI == null) || !(barkUI as MonoBehaviour).enabled) && DialogueDebug.logWarnings)
                        {
                            Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' bark UI is null or disabled", new System.Object[] { DialogueDebug.Prefix, speaker, listener, barkState.subtitle.formattedText.text }), speaker);
                        }
                        if ((barkUI != null) && (barkUI as MonoBehaviour).enabled)
                        {
                            barkUI.Bark(barkState.subtitle);
                        }

                        // Start the sequence:
                        var sequencer = PlayBarkSequence(barkState.subtitle, speaker, listener);
                        LastSequencer = sequencer;

                        // Wait until the sequence and subtitle are done:
                        while (((sequencer != null) && sequencer.isPlaying) || ((barkUI != null) && barkUI.isPlaying))
                        {
                            yield return(null);
                        }
                        if (sequencer != null)
                        {
                            GameObject.Destroy(sequencer);
                        }
                    }
                }
                finally
                {
                    if (barked)
                    {
                        InformParticipants(DialogueSystemMessages.OnBarkEnd, speaker, listener);
                        SetSpeakerCurrentBarkPriority(speaker, 0);
                    }
                }
            }
        }
Example #6
0
        /// <summary>
        /// Attempts to make a character bark. This is a coroutine; you must start it using
        /// StartCoroutine() or Unity will hang. Shows a line from the named conversation, plays 
        /// the sequence, and sends OnBarkStart/OnBarkEnd messages to the participants.
        /// </summary>
        /// <param name='conversationTitle'>
        /// Title of conversation to pull bark lines from.
        /// </param>
        /// <param name='speaker'>
        /// Speaker performing the bark.
        /// </param>
        /// <param name='listener'>
        /// Listener that the bark is directed to; may be <c>null</c>.
        /// </param>
        /// <param name='barkHistory'>
        /// Bark history used to keep track of the most recent bark so this method can iterate 
        /// through them in a specified order.
        /// </param>
        /// <param name='database'>
        /// The dialogue database to use. If <c>null</c>, uses DialogueManager.MasterDatabase.
        /// </param>
        public static IEnumerator Bark(string conversationTitle, Transform speaker, Transform listener, BarkHistory barkHistory, DialogueDatabase database = null, bool stopAtFirstValid = false)
        {
            if (string.IsNullOrEmpty(conversationTitle) && DialogueDebug.LogWarnings) Debug.Log(string.Format("{0}: Bark (speaker={1}, listener={2}): conversation title is blank", new System.Object[] { DialogueDebug.Prefix, speaker, listener }), speaker);
            if ((speaker == null) && DialogueDebug.LogWarnings) Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' speaker is null", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }));
            if (string.IsNullOrEmpty(conversationTitle) || (speaker == null)) yield break;
            IBarkUI barkUI = speaker.GetComponentInChildren(typeof(IBarkUI)) as IBarkUI;
            if ((barkUI == null) && DialogueDebug.LogWarnings) Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' speaker has no bark UI", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }), speaker);
            var firstValid = stopAtFirstValid || ((barkHistory == null) ? false : barkHistory.order == (BarkOrder.FirstValid));
            ConversationModel conversationModel = new ConversationModel(database ?? DialogueManager.MasterDatabase, conversationTitle, speaker, listener, DialogueManager.AllowLuaExceptions, DialogueManager.IsDialogueEntryValid, -1, firstValid);
            ConversationState firstState = conversationModel.FirstState;
            if ((firstState == null) && DialogueDebug.LogWarnings) Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' has no START entry", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }), speaker);
            if ((firstState != null) && !firstState.HasAnyResponses && DialogueDebug.LogWarnings) Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' has no valid bark at this time", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }), speaker);
            if ((firstState != null) && firstState.HasAnyResponses) {
                try {
                    InformParticipants("OnBarkStart", speaker, listener);
                    Response[] responses = firstState.HasNPCResponse ? firstState.npcResponses : firstState.pcResponses;
                    int index = (barkHistory ?? new BarkHistory(BarkOrder.Random)).GetNextIndex(responses.Length);
                    DialogueEntry barkEntry = responses[index].destinationEntry;
                    if ((barkEntry == null) && DialogueDebug.LogWarnings) Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' bark entry is null", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }), speaker);
                    if (barkEntry != null) {
                        ConversationState barkState = conversationModel.GetState(barkEntry, false);
                        if (barkState == null) {
                            if (DialogueDebug.LogWarnings) Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' can't find a valid dialogue entry", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }), speaker);
                            yield break;
                        }
                        if (firstState.HasNPCResponse) {
                            CharacterInfo tempInfo = barkState.subtitle.speakerInfo;
                            barkState.subtitle.speakerInfo = barkState.subtitle.listenerInfo;
                            barkState.subtitle.listenerInfo = tempInfo;
                        }
                        if (DialogueDebug.LogInfo) Debug.Log(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}'", new System.Object[] { DialogueDebug.Prefix, speaker, listener, barkState.subtitle.formattedText.text }), speaker);

                        // Show the bark subtitle:
                        if (((barkUI == null) || !(barkUI as MonoBehaviour).enabled) && DialogueDebug.LogWarnings) Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' bark UI is null or disabled", new System.Object[] { DialogueDebug.Prefix, speaker, listener, barkState.subtitle.formattedText.text }), speaker);
                        if ((barkUI != null) && (barkUI as MonoBehaviour).enabled) {
                            barkUI.Bark(barkState.subtitle);
                        }

                        // Run Lua:
                        if (!string.IsNullOrEmpty(barkState.subtitle.dialogueEntry.userScript)) {
                            Lua.Run(barkState.subtitle.dialogueEntry.userScript, DialogueDebug.LogInfo, false);
                        }

                        // Play the sequence:
                        Sequencer sequencer = null;
                        if (!string.IsNullOrEmpty(barkState.subtitle.sequence)) {
                            sequencer = DialogueManager.PlaySequence(barkState.subtitle.sequence, speaker, listener, false, false);
                            sequencer.entrytag = barkState.subtitle.entrytag;
                        }
                        LastSequencer = sequencer;
                        while (((sequencer != null) && sequencer.IsPlaying) || ((barkUI != null) && barkUI.IsPlaying)) {
                            yield return null;
                        }
                        if (sequencer != null) GameObject.Destroy(sequencer);
                    }
                } finally {
                    InformParticipants("OnBarkEnd", speaker, listener);
                }
            }
        }
Example #7
0
        /// <summary>
        /// Attempts to make a character bark. This is a coroutine; you must start it using
        /// StartCoroutine() or Unity will hang. Shows a line from the named conversation, plays
        /// the sequence, and sends OnBarkStart/OnBarkEnd messages to the participants.
        /// </summary>
        /// <param name='conversationTitle'>
        /// Title of conversation to pull bark lines from.
        /// </param>
        /// <param name='speaker'>
        /// Speaker performing the bark.
        /// </param>
        /// <param name='listener'>
        /// Listener that the bark is directed to; may be <c>null</c>.
        /// </param>
        /// <param name='barkHistory'>
        /// Bark history used to keep track of the most recent bark so this method can iterate
        /// through them in a specified order.
        /// </param>
        /// <param name='database'>
        /// The dialogue database to use. If <c>null</c>, uses DialogueManager.MasterDatabase.
        /// </param>
        public static IEnumerator Bark(string conversationTitle, Transform speaker, Transform listener, BarkHistory barkHistory, DialogueDatabase database = null)
        {
            if (string.IsNullOrEmpty(conversationTitle) && DialogueDebug.LogWarnings)
            {
                Debug.Log(string.Format("{0}: Bark (speaker={1}, listener={2}): conversation title is blank", new System.Object[] { DialogueDebug.Prefix, speaker, listener }), speaker);
            }
            if ((speaker == null) && DialogueDebug.LogWarnings)
            {
                Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' speaker is null", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }));
            }
            if (string.IsNullOrEmpty(conversationTitle) || (speaker == null))
            {
                yield break;
            }
            IBarkUI barkUI = speaker.GetComponentInChildren(typeof(IBarkUI)) as IBarkUI;

            if ((barkUI == null) && DialogueDebug.LogWarnings)
            {
                Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' speaker has no bark UI", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }), speaker);
            }
            ConversationModel conversationModel = new ConversationModel(database ?? DialogueManager.MasterDatabase, conversationTitle, speaker, listener, DialogueManager.AllowLuaExceptions, DialogueManager.IsDialogueEntryValid);
            ConversationState firstState        = conversationModel.FirstState;

            if ((firstState == null) && DialogueDebug.LogWarnings)
            {
                Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' has no START entry", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }), speaker);
            }
            if (!firstState.HasAnyResponses && DialogueDebug.LogWarnings)
            {
                Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' has no valid bark at this time", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversationTitle }), speaker);
            }
            if ((firstState != null) && firstState.HasAnyResponses)
            {
                try {
                    InformParticipants("OnBarkStart", speaker, listener);
                    Response[]    responses = firstState.HasNPCResponse ? firstState.npcResponses : firstState.pcResponses;
                    int           index     = (barkHistory ?? new BarkHistory(BarkOrder.Random)).GetNextIndex(responses.Length);
                    DialogueEntry barkEntry = responses[index].destinationEntry;
                    if ((barkEntry == null) && DialogueDebug.LogWarnings)
                    {
                        Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' bark entry is null", DialogueDebug.Prefix, speaker, listener, conversationTitle), speaker);
                    }
                    if (barkEntry != null)
                    {
                        ConversationState barkState = conversationModel.GetState(barkEntry, false);
                        if (firstState.HasNPCResponse)
                        {
                            CharacterInfo tempInfo = barkState.subtitle.speakerInfo;
                            barkState.subtitle.speakerInfo  = barkState.subtitle.listenerInfo;
                            barkState.subtitle.listenerInfo = tempInfo;
                        }
                        if (DialogueDebug.LogInfo)
                        {
                            Debug.Log(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}'", DialogueDebug.Prefix, speaker, listener, barkState.subtitle.formattedText.text), speaker);
                        }

                        // Show the bark subtitle:
                        if (((barkUI == null) || !(barkUI as MonoBehaviour).enabled) && DialogueDebug.LogWarnings)
                        {
                            Debug.LogWarning(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' bark UI is null or disabled", new System.Object[] { DialogueDebug.Prefix, speaker, listener, barkState.subtitle.formattedText.text }), speaker);
                        }
                        if ((barkUI != null) && (barkUI as MonoBehaviour).enabled)
                        {
                            barkUI.Bark(barkState.subtitle);
                        }

                        // Run Lua:
                        if (!string.IsNullOrEmpty(barkState.subtitle.dialogueEntry.userScript))
                        {
                            Lua.Run(barkState.subtitle.dialogueEntry.userScript, DialogueDebug.LogInfo, false);
                        }

                        // Play the sequence:
                        Sequencer sequencer = null;
                        if (!string.IsNullOrEmpty(barkState.subtitle.sequence))
                        {
                            sequencer          = DialogueManager.PlaySequence(barkState.subtitle.sequence, speaker, listener, false, false);
                            sequencer.entrytag = barkState.subtitle.entrytag;
                        }
                        LastSequencer = sequencer;
                        while (((sequencer != null) && sequencer.IsPlaying) || ((barkUI != null) && barkUI.IsPlaying))
                        {
                            yield return(null);
                        }
                        if (sequencer != null)
                        {
                            GameObject.Destroy(sequencer);
                        }
                    }
                } finally {
                    InformParticipants("OnBarkEnd", speaker, listener);
                }
            }
        }
Example #8
0
 private void PopulateCache(Transform speaker, Transform listener)
 {
     if (string.IsNullOrEmpty(conversation) && DialogueDebug.LogWarnings) Debug.Log(string.Format("{0}: Bark (speaker={1}, listener={2}): conversation title is blank", new System.Object[] { DialogueDebug.Prefix, speaker, listener }), speaker);
     ConversationModel conversationModel = new ConversationModel(DialogueManager.MasterDatabase, conversation, speaker, listener, DialogueManager.AllowLuaExceptions, DialogueManager.IsDialogueEntryValid);
     cachedState = conversationModel.FirstState;
     if ((cachedState == null) && DialogueDebug.LogWarnings) Debug.Log(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' has no START entry", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversation }), speaker);
     if (!cachedState.HasAnyResponses && DialogueDebug.LogWarnings) Debug.Log(string.Format("{0}: Bark (speaker={1}, listener={2}): '{3}' has no valid bark lines", new System.Object[] { DialogueDebug.Prefix, speaker, listener, conversation }), speaker);
 }
 /// <summary>
 /// Starts a conversation, which also broadcasts an OnConversationStart message to the 
 /// actor and conversant. Your scripts can listen for OnConversationStart to do anything
 /// necessary at the beginning of a conversation, such as pausing other gameplay or 
 /// temporarily disabling player control. See the Feature Demo scene, which uses the
 /// SetEnabledOnDialogueEvent component to disable player control during conversations.
 /// </summary>
 /// <param name='title'>
 /// The title of the conversation to look up in the master database.
 /// </param>
 /// <param name='actor'>
 /// The transform of the actor (primary participant). The sequencer uses this to direct 
 /// camera angles and perform other actions. In PC-NPC conversations, the actor is usually
 /// the PC.
 /// </param>
 /// <param name='conversant'>
 /// The transform of the conversant (the other participant). The sequencer uses this to 
 /// direct camera angles and perform other actions. In PC-NPC conversations, the conversant
 /// is usually the NPC.
 /// </param>
 /// <param name='initialDialogueEntryID'> 
 /// The initial dialogue entry ID, or -1 to start from the beginning.
 /// </param>
 /// <example>
 /// Example:
 /// <code>StartConversation("Shopkeeper Conversation", player, shopkeeper, 8);</code>
 /// </example>
 public void StartConversation(string title, Transform actor, Transform conversant, int initialDialogueEntryID)
 {
     if (!IsConversationActive) {
         if (DialogueUI != null) {
             if (DialogueDebug.LogInfo) Debug.Log(string.Format("{0}: Starting conversation '{1}', actor={2}, conversant={3}.", new System.Object[] { DialogueDebug.Prefix, title, actor, conversant }));
             if (WarnIfActorAndConversantSame && (actor != null) && (actor == conversant)) {
                 if (DialogueDebug.LogWarnings) Debug.LogWarning(string.Format("{0}: Actor and conversant are the same GameObject.", new System.Object[] { DialogueDebug.Prefix }));
             }
             CheckDebugLevel();
             CurrentActor = actor;
             CurrentConversant = conversant;
             LastConversationStarted = title;
             SetConversationUI(conversant);
             ConversationModel model = new ConversationModel(databaseManager.MasterDatabase, title, actor, conversant, AllowLuaExceptions, IsDialogueEntryValid, initialDialogueEntryID);
             if (!model.HasValidEntry) return;
             ConversationView view = this.gameObject.AddComponent<ConversationView>();
             view.Initialize(DialogueUI, GetNewSequencer(), displaySettings, OnDialogueEntrySpoken);
             view.SetPCPortrait(model.GetPCTexture(), model.GetPCName());
             conversationController = new ConversationController(model, view, displaySettings.inputSettings.alwaysForceResponseMenu, OnEndConversation);
             var target = (actor != null) ? actor : this.transform;
             if (actor != this.transform) gameObject.BroadcastMessage("OnConversationStart", target, SendMessageOptions.DontRequireReceiver);
         } else {
             if (DialogueDebug.LogErrors) Debug.LogError(string.Format("{0}: No Dialogue UI is assigned. Can't start conversation '{1}'.", new System.Object[] { DialogueDebug.Prefix, title }));
         }
     } else {
             if (DialogueDebug.LogWarnings) Debug.LogWarning(string.Format("{0}: Another conversation is already active. Not starting '{1}'.", new System.Object[] { DialogueDebug.Prefix, title }));
     }
 }
 /// <summary>
 /// Preloads the resources used by the Dialogue System to avoid delays caused by lazy loading.
 /// </summary>
 public void PreloadResources()
 {
     PreloadMasterDatabase();
     PreloadDialogueUI();
     var originalDebugLevel = DialogueDebug.Level;
     try {
         DialogueDebug.Level = DialogueDebug.DebugLevel.None;
         PlaySequence("None()");
         if (databaseManager.MasterDatabase == null || databaseManager.MasterDatabase.conversations == null ||
             databaseManager.MasterDatabase.conversations.Count < 1) return;
         ConversationModel model = new ConversationModel(databaseManager.MasterDatabase, databaseManager.MasterDatabase.conversations[0].Title, null, null, AllowLuaExceptions, IsDialogueEntryValid);
         ConversationView view = this.gameObject.AddComponent<ConversationView>();
         view.Initialize(DialogueUI, GetNewSequencer(), displaySettings, OnDialogueEntrySpoken);
         view.SetPCPortrait(model.GetPCTexture(), model.GetPCName());
         conversationController = new ConversationController(model, view, displaySettings.inputSettings.alwaysForceResponseMenu, OnEndConversation);
         conversationController.Close();
     } finally {
         DialogueDebug.Level = originalDebugLevel;
     }
 }
 /// <summary>
 /// Checks whether a conversation has any valid entries linked from the start entry, since it's possible that
 /// the conditions of all entries could be false.
 /// </summary>
 /// <returns>
 /// <c>true</c>, if the conversation has a valid entry, <c>false</c> otherwise.
 /// </returns>
 /// <param name="title">
 /// The title of the conversation to look up in the master database.
 /// </param>
 /// <param name='actor'>
 /// The transform of the actor (primary participant). The sequencer uses this to direct 
 /// camera angles and perform other actions. In PC-NPC conversations, the actor is usually
 /// the PC.
 /// </param>
 /// <param name='conversant'>
 /// The transform of the conversant (the other participant). The sequencer uses this to 
 /// direct camera angles and perform other actions. In PC-NPC conversations, the conversant
 /// is usually the NPC.
 /// </param>
 public bool ConversationHasValidEntry(string title, Transform actor, Transform conversant)
 {
     if (string.IsNullOrEmpty(title)) return false;
     ConversationModel model = new ConversationModel(databaseManager.MasterDatabase, title, actor, conversant,
                                                     AllowLuaExceptions, IsDialogueEntryValid);
     return model.HasValidEntry;
 }