Inheritance: RelayObjectTwo
        public override void Update(float dt)
        {
            if(_branchNodeCache == null) {
                _branchNodeCache = _dialogueRunner.GetDialogueNode(conversation, branchNode);
            }

            _branchNodeCache.Start();
        }
        private void SwitchOnNode(DialogueNode pDialogueNode)
        {
            D.isNull(pDialogueNode);

            if (pDialogueNode.isOn)
            {
                _output.Append("ON ---> ");
            }

#if WRITE_DEBUG
            Console.WriteLine("Switching on node " + pDialogueNode.name + " with indentation level " + _indentationLevel);
#endif

            if (pDialogueNode is BranchingDialogueNode)
            {
                PrintBranchingDialogueNode(pDialogueNode as BranchingDialogueNode);
            }
            else if (pDialogueNode is ConversationEndDialogueNode)
            {
                PrintConversationEndDialogueNode(pDialogueNode as ConversationEndDialogueNode);
            }
            else if (pDialogueNode is ConversationStartDialogueNode)
            {
                PrintConversationStartDialogueNode(pDialogueNode as ConversationStartDialogueNode);
            }
            else if (pDialogueNode is TimedDialogueNode)
            {
                PrintTimedDialogueNode(pDialogueNode as TimedDialogueNode);
            }
            else if (pDialogueNode is UnifiedEndNodeForScope)
            {
                PrintUnifiedEndNodeForScope(pDialogueNode as UnifiedEndNodeForScope);
            }
            else if (pDialogueNode is GotoDialogueNode)
            {
                PrintGotoNode(pDialogueNode as GotoDialogueNode);
            }
            else if (pDialogueNode is IfDialogueNode)
            {
                PrintIfNode(pDialogueNode as IfDialogueNode);
            }
            else if (pDialogueNode is ImmediateNode)
            {
                PrintImmediateNode(pDialogueNode as ImmediateNode);
            }
            else if (pDialogueNode is StartCommandoDialogueNode)
            {
                PrintStartCommandoDialogueNode(pDialogueNode as StartCommandoDialogueNode);
            }
            else if (pDialogueNode is StopDialogueNode)
            {
                PrintStopCommandoDialogueNode(pDialogueNode as StopDialogueNode);
            }
            else if (pDialogueNode is InterruptDialogueNode)
            {
                PrintInterruptDialogueNode(pDialogueNode as InterruptDialogueNode);
            }
            else if (pDialogueNode is WaitDialogueNode)
            {
                PrintWaitDialogueNode(pDialogueNode as WaitDialogueNode);
            }
            else if (pDialogueNode is CallFunctionDialogueNode)
            {
                PrintCallFunctionDialogueNode(pDialogueNode as CallFunctionDialogueNode);
            }
            else if (pDialogueNode is AssertDialogueNode)
            {
                PrintAssertDialogueNode(pDialogueNode as AssertDialogueNode);
            }
            else if (pDialogueNode is ListeningDialogueNode)
            {
                PrintListeningDialogueNode(pDialogueNode as ListeningDialogueNode);
            }
            else if (pDialogueNode is SilentDialogueNode)
            {
                PrintSilentDialogueNode(pDialogueNode as SilentDialogueNode);
            }
            else if (pDialogueNode is BroadcastDialogueNode)
            {
                PrintBroadcastDialogueNode(pDialogueNode as BroadcastDialogueNode);
            }
            else if (pDialogueNode is CancelDialogueNode)
            {
                PrintCancelDialogueNode(pDialogueNode as CancelDialogueNode);
            }
            else if (pDialogueNode is FocusDialogueNode)
            {
                PrintFocusNode(pDialogueNode as FocusDialogueNode);
            }
            else if (pDialogueNode is DefocusDialogueNode)
            {
                PrintDefocusNode(pDialogueNode as FocusDialogueNode);
            }
            else if (pDialogueNode is LoopDialogueNode)
            {
                PrintLoopDialogueNode(pDialogueNode as LoopDialogueNode);
            }
            else if (pDialogueNode is BreakDialogueNode)
            {
                PrintBreakDialogueNode(pDialogueNode as BreakDialogueNode);
            }
            else if (pDialogueNode is ExpressionDialogueNode)
            {
                PrintExpressionDialogueNode(pDialogueNode as ExpressionDialogueNode);
            }
            else if (pDialogueNode is TimedWaitDialogueNode)
            {
                PrintTimedWaitDialogueNode(pDialogueNode as TimedWaitDialogueNode);
            }
            else
            {
                throw new GrimmException("Don't understand node type " + pDialogueNode.GetType());
            }
        }
        private TimedDialogueNode VisitTimedDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("VisitTimedDialogueNode()");
            #endif

            Token speakerToken = match(Token.TokenType.NAME);
            string speaker = speakerToken.getTokenString();

            Token lineToken = match(Token.TokenType.QUOTED_STRING);
            string line = lineToken.getTokenString();

            TimedDialogueNode n = _dialogueRunner.Create<TimedDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + "_line_" + lineToken.LineNr); // + " (" + line + ")");
            n.speaker = speaker;
            n.line = line;
            n.CalculateAndSetTimeBasedOnLineLength(false);

            if(lookAheadType(1) == Token.TokenType.BRACKET_LEFT) {
                match(Token.TokenType.BRACKET_LEFT);
                string nodeCustomName = match(Token.TokenType.NAME).getTokenString();
                n.name = nodeCustomName;
                match(Token.TokenType.BRACKET_RIGHT);
            }

            #if DEBUG_WRITE
            Console.WriteLine("Added TimedDialogueNode with name '" + n.name + "' and line '" + n.line + "'");
            #endif

            AddLinkFromPreviousNode(pPrevious, n);

            return n;
        }
        private StartCommandoDialogueNode VisitStartCommandoDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("StartCommandoDialogueNode()");
            #endif

            match(Token.TokenType.START);
            string commandoName = GetAStringFromNextToken(false, false);

            StartCommandoDialogueNode n = _dialogueRunner.Create<StartCommandoDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (start commando)");
            n.commando = commandoName;

            #if DEBUG_WRITE
            Console.WriteLine("Added StartCommandoDialogueNode() with name '" + n.name + "'");
            #endif

            AddLinkFromPreviousNode(pPrevious, n);

            return n;
        }
        private DialogueNode VisitLoopDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("VisitLoopDialogueNode()");
            #endif

            match(Token.TokenType.LOOP);

            LoopDialogueNode n = _dialogueRunner.Create<LoopDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + " (loop)");
            AddLinkFromPreviousNode(pPrevious, n);

            //ImmediateNode finalNode = _dialogueRunner.Create<ImmediateNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(final node)");
            //n.nextNode = finalNode.name;

            AllowLineBreak();

            _loopStack.Push(n);
            match(Token.TokenType.BLOCK_BEGIN);

            ImmediateNode branchStartNode = _dialogueRunner.Create<ImmediateNode>(_conversationName, _language, (_nodeCounter++).ToString() + " (loop branch node)");
            n.branchNode = branchStartNode.name;

            SilentDialogueNode unifiedEndNode = _dialogueRunner.Create<SilentDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + " (unified end node for loop)");
            Nodes(branchStartNode, unifiedEndNode);

            match(Token.TokenType.BLOCK_END);
            _loopStack.Pop();

            return n;
        }
        private InterruptDialogueNode VisitInterruptDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("InterruptDialogueNode()");
            #endif

            match(Token.TokenType.INTERRUPT);
            string interruptingConversation = GetAStringFromNextToken(false, false);

            InterruptDialogueNode n = _dialogueRunner.Create<InterruptDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (interrupt commando)");
            n.interruptingConversation = interruptingConversation;

            #if DEBUG_WRITE
            Console.WriteLine("Added InterruptDialogueNode() with name '" + n.name + "'");
            #endif

            AddLinkFromPreviousNode(pPrevious, n);

            return n;
        }
        private GotoDialogueNode VisitGotoDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("GotoDialogueNode()");
            #endif

            match(Token.TokenType.GOTO);
            Token targetNameToken = match(Token.TokenType.NAME);

            GotoDialogueNode n = _dialogueRunner.Create<GotoDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (goto)");
            n.linkedNode = targetNameToken.getTokenString();

            #if DEBUG_WRITE
            Console.WriteLine("Added GotoDialogueNode() with name '" + n.name + "'");
            #endif

            AddLinkFromPreviousNode(pPrevious, n);

            return n;
        }
        private FocusDialogueNode VisitFocusDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("FocusConversationNode()");
            #endif

            match(Token.TokenType.FOCUS);

            FocusDialogueNode n = _dialogueRunner.Create<FocusDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (focus)");

            #if DEBUG_WRITE
            Console.WriteLine("Added FocusConversationNode() with name '" + n.name + "'");
            #endif

            AddLinkFromPreviousNode(pPrevious, n);

            return n;
        }
        private WaitDialogueNode VisitWaitDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("WaitDialogueNode()");
            #endif

            match(Token.TokenType.WAIT);

            WaitDialogueNode n = _dialogueRunner.Create<WaitDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (start commando)");

            List<ExpressionDialogueNode> expressionNodes = new List<ExpressionDialogueNode>();

            bool hasEventListener = false;

            while(true) {

                if(lookAheadType(1) == Token.TokenType.NAME)
                {
                    string expressionName = "";
                    string[] args = VisitFunctionCall(out expressionName);

                    ExpressionDialogueNode expressionNode = _dialogueRunner.Create<ExpressionDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (expression)");
                    expressionNode.expression = expressionName;
                    expressionNode.args = args;
                    expressionNodes.Add(expressionNode);
                }
                else if(lookAheadType(1) == Token.TokenType.AND)
                {
                    ConsumeCurrentToken();
                }
                else if(lookAheadType(1) == Token.TokenType.LISTEN)
                {
                    if(hasEventListener) {
                        throw new GrimmException(_conversationName + " already has a event listener attached to the wait statement on line " + lookAhead(1).LineNr);
                    }
                    ConsumeCurrentToken();
                    n.eventName = match(Token.TokenType.NAME).getTokenString();
                    hasEventListener = true;
                    #if DEBUG_WRITE
                    Console.WriteLine("This WaitDialogueNode has an event called " + n.eventName);
                    #endif
                }
                else {
                    break;
                }
            }

            n.expressions = expressionNodes.ToArray();

            string handleName = "";
            if(lookAheadType(1) == Token.TokenType.BRACKET_LEFT) {
                match(Token.TokenType.BRACKET_LEFT);
                Token handleToken = match(Token.TokenType.NAME);
                handleName = handleToken.getTokenString();
                match(Token.TokenType.BRACKET_RIGHT);
            }

            n.handle = handleName;

            if(_loopStack.Count > 0) {
                // Add this listening dialogue node to the scope of the loop so that it is automatically removed when the loop ends
                n.scopeNode = _loopStack.Peek().name;
            }

            #if DEBUG_WRITE
            Console.WriteLine("Added WaitDialogueNode() with name '" + n.name + "'");
            #endif

            //if(!_dialogueRunner.HasExpression(expressionName)) {
                //throw new GrimmException("There is no '" + expressionName + "' expression registered in the dialogue runner");
            //}

            SilentDialogueNode silentEndNode = _dialogueRunner.Create<SilentDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(silent stop node)");

            AllowLineBreak();

            if(lookAheadType(1) == Token.TokenType.BLOCK_BEGIN) {
                _loopStack.Push(n);

                ImmediateNode eventBranchStartNode = _dialogueRunner.Create<ImmediateNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(waitBranchStartNode)");
                n.branchNode = eventBranchStartNode.name;
                n.hasBranch = true;
                match(Token.TokenType.BLOCK_BEGIN);
                Nodes(eventBranchStartNode, silentEndNode);
                match(Token.TokenType.BLOCK_END);

                _loopStack.Pop ();
            }
            else {
                #if DEBUG_WRITE
                Console.WriteLine("this wait dialogue node had no body");
                #endif
            }

            AddLinkFromPreviousNode(pPrevious, n);

            return n;
        }
        private TimedWaitDialogueNode VisitTimedWaitDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("TimedWaitDialogueNode()");
            #endif

            match(Token.TokenType.WAIT);
            Token time = match(Token.TokenType.NUMBER);

            TimedWaitDialogueNode node = _dialogueRunner.Create<TimedWaitDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (timed wait node)");
            node.timer = node.timerStartValue = Convert.ToSingle(time.getTokenString());

            #if DEBUG_WRITE
            Console.WriteLine("Added TimedWaitDialogueNode() with name '" + node.name + "'");
            #endif

            AddLinkFromPreviousNode(pPrevious, node);

            return node;
        }
 void AddLinkFromPreviousNode(DialogueNode pPreviousNode, DialogueNode pNewNode)
 {
     D.isNull(pPreviousNode);
     D.isNull(pNewNode);
     pPreviousNode.nextNode = pNewNode.name;
     #if WRITE_NODE_LINKS
     Console.WriteLine(pPreviousNode.name + ".nextNode = '" + pNewNode.name + "'");
     #endif
 }
Exemple #12
0
        private DialogueNode VisitIfDialogueNode(DialogueNode pPrevious)
        {
                        #if DEBUG_WRITE
            Console.WriteLine("IfDialogueNode()");
                        #endif

            match(Token.TokenType.IF);

            string   expressionName = "";
            string[] args           = VisitFunctionCall(out expressionName);

            AllowLineBreak();
            match(Token.TokenType.BLOCK_BEGIN);

            UnifiedEndNodeForScope unifiedEndNode =
                _dialogueRunner.Create <UnifiedEndNodeForScope>(_conversationName, _language, (_nodeCounter++) + " (unified end of if)");

            ExpressionDialogueNode ifTrue = _dialogueRunner.Create <ExpressionDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (if true)");
            Nodes(ifTrue, unifiedEndNode);
            ifTrue.expression = expressionName;
            ifTrue.args       = args;

                        #if DEBUG_WRITE
            Console.WriteLine("Added IfTrue node with expression '" + ifTrue.expression + "'");
                        #endif

            match(Token.TokenType.BLOCK_END);
            AllowLineBreak();

            ImmediateNode ifFalse = null;

            List <ExpressionDialogueNode> elifNodes = new List <ExpressionDialogueNode>();

            while (lookAheadType(1) == Token.TokenType.ELIF)
            {
                match(Token.TokenType.ELIF);

                string   elifExpressionName = "";
                string[] elifArgs           = VisitFunctionCall(out elifExpressionName);

                AllowLineBreak();
                match(Token.TokenType.BLOCK_BEGIN);

                ExpressionDialogueNode elifNode = _dialogueRunner.Create <ExpressionDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (elif)");
                Nodes(elifNode, unifiedEndNode);
                elifNode.expression = elifExpressionName;
                elifNode.args       = elifArgs;

                elifNodes.Add(elifNode);

                                #if DEBUG_WRITE
                Console.WriteLine("Added Elif node with expression '" + elifNode.expression + "'");
                                #endif

                match(Token.TokenType.BLOCK_END);
                AllowLineBreak();
            }

            if (lookAheadType(1) == Token.TokenType.ELSE)
            {
                match(Token.TokenType.ELSE);
                AllowLineBreak();
                match(Token.TokenType.BLOCK_BEGIN);

                ifFalse = _dialogueRunner.Create <ImmediateNode>(_conversationName, _language, (_nodeCounter++) + " (if false)");
                Nodes(ifFalse, unifiedEndNode);

                match(Token.TokenType.BLOCK_END);
            }

            IfDialogueNode ifNode = _dialogueRunner.Create <IfDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (if)");

                        #if DEBUG_WRITE
            Console.WriteLine("Added IfDialogueNode() with name '" + ifNode.name + "'");
            //foreach(DialogueNode elif in elifNodes) {
            //	Console.WriteLine("Added ElifDialogueNode() with name '" + elif.name + "'");
            //}
                        #endif

            AddLinkFromPreviousNode(pPrevious, ifNode);

            ifNode.nextNode   = unifiedEndNode.name;
            ifNode.ifTrueNode = ifTrue;
            ifNode.elifNodes  = elifNodes.ToArray();
            if (ifFalse != null)
            {
                ifNode.ifFalseNode = ifFalse;
            }
            else
            {
                ifNode.ifFalseNode = null;
            }

            if (!_dialogueRunner.HasExpression(expressionName))
            {
                //throw new GrimmException("There is no '" + expressionName + "' expression registered in the dialogue runner");
            }

            return(unifiedEndNode);
        }
Exemple #13
0
        private WaitDialogueNode VisitWaitDialogueNode(DialogueNode pPrevious)
        {
                        #if DEBUG_WRITE
            Console.WriteLine("WaitDialogueNode()");
                        #endif

            match(Token.TokenType.WAIT);

            WaitDialogueNode n = _dialogueRunner.Create <WaitDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (start commando)");

            List <ExpressionDialogueNode> expressionNodes = new List <ExpressionDialogueNode>();

            bool hasEventListener = false;

            while (true)
            {
                if (lookAheadType(1) == Token.TokenType.NAME)
                {
                    string   expressionName = "";
                    string[] args           = VisitFunctionCall(out expressionName);

                    ExpressionDialogueNode expressionNode = _dialogueRunner.Create <ExpressionDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (expression)");
                    expressionNode.expression = expressionName;
                    expressionNode.args       = args;
                    expressionNodes.Add(expressionNode);
                }
                else if (lookAheadType(1) == Token.TokenType.AND)
                {
                    ConsumeCurrentToken();
                }
                else if (lookAheadType(1) == Token.TokenType.LISTEN)
                {
                    if (hasEventListener)
                    {
                        throw new GrimmException(_conversationName + " already has a event listener attached to the wait statement on line " + lookAhead(1).LineNr);
                    }
                    ConsumeCurrentToken();
                    n.eventName      = match(Token.TokenType.NAME).getTokenString();
                    hasEventListener = true;
                                        #if DEBUG_WRITE
                    Console.WriteLine("This WaitDialogueNode has an event called " + n.eventName);
                                        #endif
                }
                else
                {
                    break;
                }
            }

            n.expressions = expressionNodes.ToArray();

            string handleName = "";
            if (lookAheadType(1) == Token.TokenType.BRACKET_LEFT)
            {
                match(Token.TokenType.BRACKET_LEFT);
                Token handleToken = match(Token.TokenType.NAME);
                handleName = handleToken.getTokenString();
                match(Token.TokenType.BRACKET_RIGHT);
            }

            n.handle = handleName;

            if (_loopStack.Count > 0)
            {
                // Add this listening dialogue node to the scope of the loop so that it is automatically removed when the loop ends
                n.scopeNode = _loopStack.Peek().name;
            }

                        #if DEBUG_WRITE
            Console.WriteLine("Added WaitDialogueNode() with name '" + n.name + "'");
                        #endif

            //if(!_dialogueRunner.HasExpression(expressionName)) {
            //throw new GrimmException("There is no '" + expressionName + "' expression registered in the dialogue runner");
            //}

            SilentDialogueNode silentEndNode = _dialogueRunner.Create <SilentDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(silent stop node)");

            AllowLineBreak();

            if (lookAheadType(1) == Token.TokenType.BLOCK_BEGIN)
            {
                _loopStack.Push(n);

                ImmediateNode eventBranchStartNode = _dialogueRunner.Create <ImmediateNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(waitBranchStartNode)");
                n.branchNode = eventBranchStartNode.name;
                n.hasBranch  = true;
                match(Token.TokenType.BLOCK_BEGIN);
                Nodes(eventBranchStartNode, silentEndNode);
                match(Token.TokenType.BLOCK_END);

                _loopStack.Pop();
            }
            else
            {
                                #if DEBUG_WRITE
                Console.WriteLine("this wait dialogue node had no body");
                                #endif
            }

            AddLinkFromPreviousNode(pPrevious, n);

            return(n);
        }
Exemple #14
0
        DialogueNode VisitListeningDialogueNode(DialogueNode pPrevious)
        {
                        #if DEBUG_WRITE
            Console.WriteLine("VisitListeningDialogueNode()");
                        #endif

            match(Token.TokenType.LISTEN);

            string eventName = GetAStringFromNextToken(false, false);

            string handleName = "";
            if (lookAheadType(1) == Token.TokenType.BRACKET_LEFT)
            {
                match(Token.TokenType.BRACKET_LEFT);
                Token handleToken = match(Token.TokenType.NAME);
                handleName = handleToken.getTokenString();
                match(Token.TokenType.BRACKET_RIGHT);
            }
            else if (
                (lookAheadType(1) != Token.TokenType.EOF) &&
                (lookAheadType(1) != Token.TokenType.NEW_LINE) &&
                (lookAheadType(1) != Token.TokenType.BLOCK_BEGIN))
            {
                throw new GrimmException("Can't follow LISTEN statement with token of type " + lookAheadType(1) + " at line " + lookAhead(1).LineNr + " and position " + lookAhead(1).LinePosition + " in " + _conversationName);
            }

            ListeningDialogueNode n = _dialogueRunner.Create <ListeningDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(event listener)");
            n.eventName = eventName;
            n.handle    = handleName;

            if (_loopStack.Count > 0)
            {
                // Add this listening dialogue node to the scope of the loop so that it is automatically removed as a listener when the loop ends
                n.scopeNode = _loopStack.Peek().name;
            }
            SilentDialogueNode silentNode = _dialogueRunner.Create <SilentDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(silent stop node)");

            AllowLineBreak();

            if (lookAheadType(1) == Token.TokenType.BLOCK_BEGIN)
            {
                _loopStack.Push(n);

                ImmediateNode eventBranchStartNode = _dialogueRunner.Create <ImmediateNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(eventBranchStartNode)");
                n.branchNode = eventBranchStartNode.name;
                n.hasBranch  = true;
                match(Token.TokenType.BLOCK_BEGIN);
                Nodes(eventBranchStartNode, silentNode);
                match(Token.TokenType.BLOCK_END);

                _loopStack.Pop();
            }
            else
            {
                                #if DEBUG_WRITE
                Console.WriteLine("this listening dialogue node had no body");
                                #endif
            }

            AddLinkFromPreviousNode(pPrevious, n);
            return(n);
        }
Exemple #15
0
        private DialogueNode Statement(DialogueNode pPrevious)
        {
                        #if DEBUG_WRITE
            //Console.WriteLine("Statement() Lookahead: " + lookAhead(1).getTokenString());
                        #endif

            if (lookAheadType(1) == Token.TokenType.NEW_LINE)
            {
                match(Token.TokenType.NEW_LINE);
            }
            else if (lookAheadType(1) == Token.TokenType.EOF)
            {
                match(Token.TokenType.EOF);
            }
            else if (lookAheadType(1) == Token.TokenType.NAME &&
                     lookAheadType(2) == Token.TokenType.QUOTED_STRING)
            {
                return(VisitTimedDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.NAME &&
                     lookAheadType(2) == Token.TokenType.PARANTHESIS_LEFT)
            {
                return(VisitFunctionDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.NAME &&
                     lookAheadType(2) == Token.TokenType.DOT)
            {
                return(VisitFunctionDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.GOTO)
            {
                return(VisitGotoDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.START)
            {
                return(VisitStartCommandoDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.INTERRUPT)
            {
                return(VisitInterruptDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.IF)
            {
                return(VisitIfDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.ASSERT)
            {
                return(VisitAssertDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.STOP)
            {
                return(VisitStopDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.BROADCAST)
            {
                return(VisitBroadcastDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.LISTEN)
            {
                return(VisitListeningDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.CANCEL)
            {
                return(VisitCancelDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.WAIT)
            {
                if (lookAheadType(2) == Token.TokenType.NUMBER)
                {
                    return(VisitTimedWaitDialogueNode(pPrevious));
                }
                else
                {
                    return(VisitWaitDialogueNode(pPrevious));
                }
            }
            else if (lookAheadType(1) == Token.TokenType.FOCUS)
            {
                return(VisitFocusDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.DEFOCUS)
            {
                return(VisitDefocusDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.LOOP)
            {
                return(VisitLoopDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.BREAK)
            {
                return(VisitBreakDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.BLOCK_BEGIN)
            {
                return(VisitBranchingDialogueNode(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.BRACKET_LEFT)
            {
                return(VisitEmptyNodeWithName(pPrevious));
            }
            else if (lookAheadType(1) == Token.TokenType.CHOICE)
            {
                return(VisitBranchingDialogueNode(pPrevious));
            }
            else
            {
                throw new GrimmException("Can't figure out statement type of token " +
                                         lookAheadType(1) + " with string " +
                                         lookAhead(1).getTokenString() + " on line " +
                                         lookAhead(1).LineNr + " and position" + lookAhead(1).LinePosition +
                                         " in conversation " + _conversationName
                                         );
            }

            return(null);
        }
        DialogueNode VisitCancelDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("VisitCancelDialogueNode()");
            #endif

            match(Token.TokenType.CANCEL);
            Token handleNameToken = match(Token.TokenType.NAME);

            CancelDialogueNode n = _dialogueRunner.Create<CancelDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(cancel)");
            n.handle = handleNameToken.getTokenString();

            AddLinkFromPreviousNode(pPrevious, n);
            return n;
        }
 private DialogueNode VisitEmptyNodeWithName(DialogueNode pPreviousNode)
 {
     match(Token.TokenType.BRACKET_LEFT);
     string nodeCustomName = match(Token.TokenType.NAME).getTokenString();
     ImmediateNode n = _dialogueRunner.Create<ImmediateNode>(_conversationName, _language, (_nodeCounter++).ToString());
     n.name = nodeCustomName;
     match(Token.TokenType.BRACKET_RIGHT);
     AddLinkFromPreviousNode(pPreviousNode, n);
     return n;
 }
        private DialogueNode FigureOutOptionStatement(DialogueNode pScopeEndNode)
        {
            #if DEBUG_WRITE
            Console.WriteLine("FigureOutOptionStatement()");
            #endif

            if (lookAheadType(1) == Token.TokenType.NEW_LINE) {
                match(Token.TokenType.NEW_LINE);
                #if DEBUG_WRITE
                Console.Write(" (newline)");
                #endif
            }
            else if (lookAheadType(1) == Token.TokenType.EOF) {
                match(Token.TokenType.EOF);
            }
            else if ( lookAheadType(1) == Token.TokenType.QUOTED_STRING &&
                      lookAheadType(2) == Token.TokenType.COLON )
            {
                return VisitOption(pScopeEndNode);
            }
            else {
                throw new GrimmException("Can't figure out player option statement type of token " +
                                    lookAheadType(1) + " with string " +
                                    lookAhead(1).getTokenString() + " on line " +
                                    lookAhead(1).LineNr + " and position" + lookAhead(1).LinePosition + " in conversation " +
                                         _conversationName);
            }

            return null;
        }
        private CallFunctionDialogueNode VisitFunctionDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("VisitFunctionDialogueNode()");
            #endif

            string functionName = "";

            string[] args = VisitFunctionCall(out functionName);

            CallFunctionDialogueNode n = _dialogueRunner.Create<CallFunctionDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + "_" + functionName);
            n.function = functionName;
            n.args = args;

            if(!_dialogueRunner.HasFunction(functionName)) {
                //throw new GrimmException("There is no '" + functionName + "' function registered in the dialogue runner");
            }

            #if DEBUG_WRITE
            Console.WriteLine("Added CallFunctionDialogueNode() with name '" + n.name + "'");
            #endif

            AddLinkFromPreviousNode(pPrevious, n);

            return n;
        }
        private void Nodes(DialogueNode pPrevious, DialogueNode pScopeEndNode)
        {
            #if DEBUG_WRITE
            Console.WriteLine("Nodes()");
            #endif

            while(	lookAheadType(1) != Token.TokenType.EOF &&
                   	lookAheadType(1) != Token.TokenType.BLOCK_END &&
                   	lookAheadType(1) != Token.TokenType.QUOTED_STRING &&
                  	lookAheadType(1) != Token.TokenType.LANGUAGE)
            {
                DialogueNode n = Statement(pPrevious);

                if(n != null) {
                    pPrevious = n;
                }
            }

            AddLinkFromPreviousNode(pPrevious, pScopeEndNode);
        }
        private DialogueNode VisitIfDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("IfDialogueNode()");
            #endif

            match(Token.TokenType.IF);

            string expressionName = "";
            string[] args = VisitFunctionCall(out expressionName);

            AllowLineBreak();
            match(Token.TokenType.BLOCK_BEGIN);

            UnifiedEndNodeForScope unifiedEndNode =
                _dialogueRunner.Create<UnifiedEndNodeForScope>(_conversationName, _language, (_nodeCounter++) + " (unified end of if)");

            ExpressionDialogueNode ifTrue = _dialogueRunner.Create<ExpressionDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (if true)");
            Nodes(ifTrue, unifiedEndNode);
            ifTrue.expression = expressionName;
            ifTrue.args = args;

            #if DEBUG_WRITE
            Console.WriteLine("Added IfTrue node with expression '" + ifTrue.expression + "'");
            #endif

            match(Token.TokenType.BLOCK_END);
            AllowLineBreak();

            ImmediateNode ifFalse = null;

            List<ExpressionDialogueNode> elifNodes = new List<ExpressionDialogueNode>();

            while(lookAheadType(1) == Token.TokenType.ELIF)
            {
                match(Token.TokenType.ELIF);

                string elifExpressionName = "";
                string[] elifArgs = VisitFunctionCall(out elifExpressionName);

                AllowLineBreak();
                match(Token.TokenType.BLOCK_BEGIN);

                ExpressionDialogueNode elifNode = _dialogueRunner.Create<ExpressionDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (elif)");
                Nodes(elifNode, unifiedEndNode);
                elifNode.expression = elifExpressionName;
                elifNode.args = elifArgs;

                elifNodes.Add(elifNode);

                #if DEBUG_WRITE
                Console.WriteLine("Added Elif node with expression '" + elifNode.expression + "'");
                #endif

                match(Token.TokenType.BLOCK_END);
                AllowLineBreak();
            }

            if(lookAheadType(1) == Token.TokenType.ELSE) {
                match(Token.TokenType.ELSE);
                AllowLineBreak();
                match(Token.TokenType.BLOCK_BEGIN);

                ifFalse = _dialogueRunner.Create<ImmediateNode>(_conversationName, _language, (_nodeCounter++) + " (if false)");
                Nodes(ifFalse, unifiedEndNode);

                match(Token.TokenType.BLOCK_END);
            }

            IfDialogueNode ifNode = _dialogueRunner.Create<IfDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (if)");

            #if DEBUG_WRITE
            Console.WriteLine("Added IfDialogueNode() with name '" + ifNode.name + "'");
            //foreach(DialogueNode elif in elifNodes) {
            //	Console.WriteLine("Added ElifDialogueNode() with name '" + elif.name + "'");
            //}
            #endif

            AddLinkFromPreviousNode(pPrevious, ifNode);

            ifNode.nextNode = unifiedEndNode.name;
            ifNode.ifTrueNode = ifTrue;
            ifNode.elifNodes = elifNodes.ToArray();
            if(ifFalse != null) {
                ifNode.ifFalseNode = ifFalse;
            }
            else {
                ifNode.ifFalseNode = null;
            }

            if(!_dialogueRunner.HasExpression(expressionName)) {
                //throw new GrimmException("There is no '" + expressionName + "' expression registered in the dialogue runner");
            }

            return unifiedEndNode;
        }
        private DialogueNode Statement(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            //Console.WriteLine("Statement() Lookahead: " + lookAhead(1).getTokenString());
            #endif

            if (lookAheadType(1) == Token.TokenType.NEW_LINE) {
                match(Token.TokenType.NEW_LINE);
            }
            else if (lookAheadType(1) == Token.TokenType.EOF) {
                match(Token.TokenType.EOF);
            }
            else if (lookAheadType(1) == Token.TokenType.NAME &&
                     lookAheadType(2) == Token.TokenType.QUOTED_STRING)
            {
                return VisitTimedDialogueNode(pPrevious);
            }
            else if (lookAheadType(1) == Token.TokenType.NAME &&
                     lookAheadType(2) == Token.TokenType.PARANTHESIS_LEFT)
            {
                return VisitFunctionDialogueNode(pPrevious);
            }
            else if (lookAheadType(1) == Token.TokenType.NAME &&
                     lookAheadType(2) == Token.TokenType.DOT)
            {
                return VisitFunctionDialogueNode(pPrevious);
            }
            else if( lookAheadType(1) == Token.TokenType.GOTO) {
                return VisitGotoDialogueNode(pPrevious);
            }
            else if( lookAheadType(1) == Token.TokenType.START) {
                return VisitStartCommandoDialogueNode(pPrevious);
            }
            else if( lookAheadType(1) == Token.TokenType.INTERRUPT) {
                return VisitInterruptDialogueNode(pPrevious);
            }
            else if( lookAheadType(1) == Token.TokenType.IF) {
                return VisitIfDialogueNode(pPrevious);
            }
            else if( lookAheadType(1) == Token.TokenType.ASSERT) {
                return VisitAssertDialogueNode(pPrevious);
            }
            else if( lookAheadType(1) == Token.TokenType.STOP) {
                return VisitStopDialogueNode(pPrevious);
            }
            else if( lookAheadType(1) == Token.TokenType.BROADCAST) {
                return VisitBroadcastDialogueNode(pPrevious);
            }
            else if( lookAheadType(1) == Token.TokenType.LISTEN) {
                return VisitListeningDialogueNode(pPrevious);
            }
            else if( lookAheadType(1) == Token.TokenType.CANCEL) {
                return VisitCancelDialogueNode(pPrevious);
            }
            else if( lookAheadType(1) == Token.TokenType.WAIT) {
                if(lookAheadType(2) == Token.TokenType.NUMBER) {
                    return VisitTimedWaitDialogueNode(pPrevious);
                }
                else {
                    return VisitWaitDialogueNode(pPrevious);
                }
            }
            else if( lookAheadType(1) == Token.TokenType.FOCUS) {
                return VisitFocusDialogueNode(pPrevious);
            }
            else if( lookAheadType(1) == Token.TokenType.DEFOCUS) {
                return VisitDefocusDialogueNode(pPrevious);
            }
            else if ( lookAheadType(1) == Token.TokenType.LOOP )
            {
                return VisitLoopDialogueNode(pPrevious);
            }
            else if(lookAheadType(1) == Token.TokenType.BREAK)
            {
                return VisitBreakDialogueNode(pPrevious);
            }
            else if ( lookAheadType(1) == Token.TokenType.BLOCK_BEGIN )
            {
                return VisitBranchingDialogueNode(pPrevious);
            }
            else if(lookAheadType(1) == Token.TokenType.BRACKET_LEFT) {
                return VisitEmptyNodeWithName(pPrevious);
            }
            else if ( lookAheadType(1) == Token.TokenType.CHOICE )
            {
                return VisitBranchingDialogueNode(pPrevious);
            }
            else
            {
                throw new GrimmException("Can't figure out statement type of token " +
                                        lookAheadType(1) + " with string " +
                                        lookAhead(1).getTokenString() + " on line " +
                                        lookAhead(1).LineNr + " and position" + lookAhead(1).LinePosition +
                                         " in conversation " + _conversationName
                                         );
            }

            return null;
        }
        DialogueNode VisitListeningDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("VisitListeningDialogueNode()");
            #endif

            match(Token.TokenType.LISTEN);

            string eventName = GetAStringFromNextToken(false, false);

            string handleName = "";
            if (lookAheadType (1) == Token.TokenType.BRACKET_LEFT) {
                match (Token.TokenType.BRACKET_LEFT);
                Token handleToken = match (Token.TokenType.NAME);
                handleName = handleToken.getTokenString ();
                match (Token.TokenType.BRACKET_RIGHT);
            } else if (
                (lookAheadType (1) != Token.TokenType.EOF) &&
                (lookAheadType (1) != Token.TokenType.NEW_LINE) &&
                (lookAheadType (1) != Token.TokenType.BLOCK_BEGIN)) {
                throw new GrimmException ("Can't follow LISTEN statement with token of type " + lookAheadType (1) + " at line " + lookAhead(1).LineNr + " and position " + lookAhead(1).LinePosition + " in " + _conversationName);
            }

            ListeningDialogueNode n = _dialogueRunner.Create<ListeningDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(event listener)");
            n.eventName = eventName;
            n.handle = handleName;

            if(_loopStack.Count > 0) {
                // Add this listening dialogue node to the scope of the loop so that it is automatically removed as a listener when the loop ends
                n.scopeNode = _loopStack.Peek().name;
            }
                SilentDialogueNode silentNode = _dialogueRunner.Create<SilentDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(silent stop node)");

            AllowLineBreak();

            if(lookAheadType(1) == Token.TokenType.BLOCK_BEGIN) {
                _loopStack.Push(n);

                ImmediateNode eventBranchStartNode = _dialogueRunner.Create<ImmediateNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(eventBranchStartNode)");
                n.branchNode = eventBranchStartNode.name;
                n.hasBranch = true;
                match(Token.TokenType.BLOCK_BEGIN);
                Nodes(eventBranchStartNode, silentNode);
                match(Token.TokenType.BLOCK_END);

                _loopStack.Pop ();
            }
            else {
                #if DEBUG_WRITE
                Console.WriteLine("this listening dialogue node had no body");
                #endif
            }

            AddLinkFromPreviousNode(pPrevious, n);
            return n;
        }
        private DialogueNode VisitAssertDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("VisitAssertDialogueNode()");
            #endif

            match(Token.TokenType.ASSERT);

            string expressionName = "";
            string[] args = VisitFunctionCall(out expressionName);

            AssertDialogueNode n = _dialogueRunner.Create<AssertDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (assert)");
            n.expression = expressionName;
            n.args = args;

            if(!_dialogueRunner.HasExpression(expressionName)) {
                throw new GrimmException("There is no '" + expressionName + "' expression registered in the dialogue runner");
            }

            AddLinkFromPreviousNode(pPrevious, n);

            return n;
        }
        private DialogueNode VisitOption(DialogueNode pScopeEndNode)
        {
            #if DEBUG_WRITE
            Console.WriteLine("VisitOption()");
            #endif

            Token t = match(Token.TokenType.QUOTED_STRING);
            match(Token.TokenType.COLON);

            TimedDialogueNode optionNode = _dialogueRunner.Create<TimedDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString());
            optionNode.line = t.getTokenString();
            optionNode.speaker = _playerCharacterName;
            optionNode.CalculateAndSetTimeBasedOnLineLength(true);

            #if DEBUG_WRITE
            Console.WriteLine("Created an option node with the name '" + optionNode.name + "'" + " and line " + "'" + optionNode.line + "'");
            #endif

            Nodes(optionNode, pScopeEndNode);

            return optionNode;
        }
        private DialogueNode VisitBranchingDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("NodesWithPlayerChoiceLinks()");
            #endif

            if(lookAheadType(1) == Token.TokenType.CHOICE) {
                match(Token.TokenType.CHOICE);
            }

            bool eternal = lookAheadType(1) == Token.TokenType.ETERNAL;
            if(eternal) {
                match(Token.TokenType.ETERNAL);
            }

            match(Token.TokenType.BLOCK_BEGIN);

            BranchingDialogueNode bn = _dialogueRunner.Create<BranchingDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + " (branching node)");
            pPrevious.nextNode = bn.name;

            UnifiedEndNodeForScope unifiedEndNodeForScope = _dialogueRunner.Create<UnifiedEndNodeForScope>(_conversationName, _language, (_nodeCounter++) + " (unified end of options)");

            bn.unifiedEndNodeForScope = unifiedEndNodeForScope.name;

            #if DEBUG_WRITE
            Console.WriteLine("Created a branching node with name '" + bn.name + "'");
            #endif

            List<string> nameOfPossibleOptions = new List<string>();

            while (lookAheadType(1) != Token.TokenType.EOF &&
                   lookAheadType(1) != Token.TokenType.BLOCK_END)
            {
                DialogueNode n = FigureOutOptionStatement(unifiedEndNodeForScope);
                if(n != null)
                {
                    nameOfPossibleOptions.Add(n.name);
                }
            }

            bn.nextNodes = nameOfPossibleOptions.ToArray();
            bn.eternal = eternal;

            if (bn.nextNodes.Length < 2) {
                Console.WriteLine("\nWarning! Branching node " + bn.name + " with only " + bn.nextNodes.Length + " nodes in " + _conversationName);
            }

            match(Token.TokenType.BLOCK_END);

            return unifiedEndNodeForScope;
        }
        private DialogueNode VisitStopDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("VisitStopDialogueNode()");
            #endif

            match(Token.TokenType.STOP);

            StopDialogueNode n = null;
            string nameOfConversationToStop = "";

            if(lookAheadType(1) == Token.TokenType.NAME || lookAheadType(1) == Token.TokenType.QUOTED_STRING) {
                nameOfConversationToStop = GetAStringFromNextToken(true, false);
            }
            else {
                nameOfConversationToStop = _conversationName;
            }

            n = _dialogueRunner.Create<StopDialogueNode>(_conversationName, _language, (_nodeCounter++) + " (stop)");
            n.conversationToStop = nameOfConversationToStop;

            #if DEBUG_WRITE
            Console.WriteLine("Added stopping node with name '" + n.name + "'");
            #endif

            AddLinkFromPreviousNode(pPrevious, n);

            return n;
        }
        private DialogueNode VisitBreakDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("VisitBreakDialogueNode()");
            #endif

            Token breakToken = match(Token.TokenType.BREAK);

            BreakDialogueNode n = _dialogueRunner.Create<BreakDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(break)");

            if(_loopStack.Count > 0) {
                n.breakTargetLoop = _loopStack.Peek().name;
            }
            else {
                throw new GrimmException("Trying to break at weird position? Line: " + breakToken.LineNr + " in conversation '" + _conversationName + "'");
            }

            AddLinkFromPreviousNode(pPrevious, n);

            return n;
        }
        private void SwitchOnNode(DialogueNode pDialogueNode)
        {
            D.isNull(pDialogueNode);

            if(pDialogueNode.isOn) {
                _output.Append("ON ---> ");
            }

            #if WRITE_DEBUG
            Console.WriteLine("Switching on node " + pDialogueNode.name + " with indentation level " + _indentationLevel);
            #endif

            if(pDialogueNode is BranchingDialogueNode)
            {
                PrintBranchingDialogueNode(pDialogueNode as BranchingDialogueNode);
            }
            else if(pDialogueNode is ConversationEndDialogueNode)
            {
                PrintConversationEndDialogueNode(pDialogueNode as ConversationEndDialogueNode);
            }
            else if(pDialogueNode is ConversationStartDialogueNode)
            {
                PrintConversationStartDialogueNode(pDialogueNode as ConversationStartDialogueNode);
            }
            else if(pDialogueNode is TimedDialogueNode)
            {
                PrintTimedDialogueNode(pDialogueNode as TimedDialogueNode);
            }
            else if(pDialogueNode is UnifiedEndNodeForScope)
            {
                PrintUnifiedEndNodeForScope(pDialogueNode as UnifiedEndNodeForScope);
            }
            else if(pDialogueNode is GotoDialogueNode)
            {
                PrintGotoNode(pDialogueNode as GotoDialogueNode);
            }
            else if(pDialogueNode is IfDialogueNode)
            {
                PrintIfNode(pDialogueNode as IfDialogueNode);
            }
            else if(pDialogueNode is ImmediateNode)
            {
                PrintImmediateNode(pDialogueNode as ImmediateNode);
            }
            else if(pDialogueNode is StartCommandoDialogueNode)
            {
                PrintStartCommandoDialogueNode(pDialogueNode as StartCommandoDialogueNode);
            }
            else if(pDialogueNode is StopDialogueNode)
            {
                PrintStopCommandoDialogueNode(pDialogueNode as StopDialogueNode);
            }
            else if(pDialogueNode is InterruptDialogueNode)
            {
                PrintInterruptDialogueNode(pDialogueNode as InterruptDialogueNode);
            }
            else if(pDialogueNode is WaitDialogueNode)
            {
                PrintWaitDialogueNode(pDialogueNode as WaitDialogueNode);
            }
            else if(pDialogueNode is CallFunctionDialogueNode)
            {
                PrintCallFunctionDialogueNode(pDialogueNode as CallFunctionDialogueNode);
            }
            else if(pDialogueNode is AssertDialogueNode)
            {
                PrintAssertDialogueNode(pDialogueNode as AssertDialogueNode);
            }
            else if(pDialogueNode is ListeningDialogueNode)
            {
                PrintListeningDialogueNode(pDialogueNode as ListeningDialogueNode);
            }
            else if(pDialogueNode is SilentDialogueNode)
            {
                PrintSilentDialogueNode(pDialogueNode as SilentDialogueNode);
            }
            else if(pDialogueNode is BroadcastDialogueNode)
            {
                PrintBroadcastDialogueNode(pDialogueNode as BroadcastDialogueNode);
            }
            else if(pDialogueNode is CancelDialogueNode)
            {
                PrintCancelDialogueNode(pDialogueNode as CancelDialogueNode);
            }
            else if(pDialogueNode is FocusDialogueNode)
            {
                PrintFocusNode(pDialogueNode as FocusDialogueNode);
            }
            else if(pDialogueNode is DefocusDialogueNode)
            {
                PrintDefocusNode(pDialogueNode as FocusDialogueNode);
            }
            else if(pDialogueNode is LoopDialogueNode)
            {
                PrintLoopDialogueNode(pDialogueNode as LoopDialogueNode);
            }
            else if(pDialogueNode is BreakDialogueNode)
            {
                PrintBreakDialogueNode(pDialogueNode as BreakDialogueNode);
            }
            else if(pDialogueNode is ExpressionDialogueNode)
            {
                PrintExpressionDialogueNode(pDialogueNode as ExpressionDialogueNode);
            }
            else if(pDialogueNode is TimedWaitDialogueNode)
            {
                PrintTimedWaitDialogueNode(pDialogueNode as TimedWaitDialogueNode);
            }
            else
            {
                throw new GrimmException("Don't understand node type " + pDialogueNode.GetType());
            }
        }
        DialogueNode VisitBroadcastDialogueNode(DialogueNode pPrevious)
        {
            #if DEBUG_WRITE
            Console.WriteLine("VisitBroadcastDialogueNode()");
            #endif

            match(Token.TokenType.BROADCAST);
            string eventName = GetAStringFromNextToken(false, false);

            BroadcastDialogueNode n = _dialogueRunner.Create<BroadcastDialogueNode>(_conversationName, _language, (_nodeCounter++).ToString() + "(broadcaster)");
            n.eventName = eventName;

            AddLinkFromPreviousNode(pPrevious, n);
            return n;
        }