public override bool doTool()
        {
            // By default, add the child
            bool addChild = true;

            // If it's sure to add the child
            if (addChild)
            {
                // Create the requested node (only accept dialogue and option node)
                if (nodeType == (int)ConversationNodeViewEnum.DIALOGUE)
                {
                    newChild = new DialogueConversationNode();
                }
                if (nodeType == (int)ConversationNodeViewEnum.OPTION)
                {
                    newChild = new OptionConversationNode();
                }

                // If a child has been created
                if (newChild != null)
                {
                    // Add the child to the given node
                    parent.addChild(newChild);

                    // Add to Conditions controller
                    allConditions.Add(newChild, new List <ConditionsController>());

                    // If the node was an option node, add a new line
                    if (parent.getType() == ConversationNodeViewEnum.OPTION)
                    {
                        parent.addLine(new ConversationLine(ConversationLine.PLAYER, TC.get("ConversationLine.NewOption")));
                        allConditions[parent].Add(new ConditionsController(new Conditions(),
                                                                           Controller.CONVERSATION_OPTION_LINE, "0"));
                    }
                    // Save the index of the newChild
                    index = -1;
                    for (int i = 0; i < parent.getChildCount(); i++)
                    {
                        if (parent.getChild(i) == newChild)
                        {
                            index = i;
                            break;
                        }
                    }
                }
            }

            return(newChild != null);
        }
        public void addChild(ConversationNode parent, ConversationNode child)
        {
            ConversationNodeEditor editor = editors[parent];

            tmpRects.Add(child, new Rect(editor.Window.x + editor.Window.width + 35, editor.Window.y, 0, 0));
            parent.addChild(child);
        }
        protected bool moveDown()
        {
            bool lineMoved = false;

            // Cannot move the line down if it is the last position
            if (lineIndex < parent.getLineCount() - 1)
            {
                // Remove the line and insert it in the lower position
                parent.addLine(lineIndex + 1, parent.removeLine(lineIndex));

                // If the node is a OptionNode, move the respective child along the line
                if (parent.getType() == ConversationNodeViewEnum.OPTION)
                {
                    ConversationNode nodeMoved = parent.removeChild(lineIndex);
                    parent.addChild(lineIndex + 1, nodeMoved);
                }

                lineMoved = true;
            }

            return(lineMoved);
        }
Esempio n. 4
0
    public override bool undoTool()
    {
        parentNode.addChild(index, deletedNode);
        allConditions.Add(deletedNode, deletedConditions);
        // If the current node is an option node, delete the line too
        if (parentNode.getType() == ConversationNodeViewEnum.OPTION)
        {
            parentNode.addLine(index, deletedLine);
            allConditions[deletedNode].Insert(index, deletedCondition);
        }

        controller.reloadPanel();
        return(true);
    }
Esempio n. 5
0
    /**
     * Set the links between the conversational nodes, taking the indexes of
     * their children, stored in nodeLinks
     */
    private void setNodeLinks()
    {
        // The size of graphNodes and nodeLinks should be the same
        for (int i = 0; i < graphNodes.Count; i++)
        {
            // Extract the node and its links
            ConversationNode node  = graphNodes[i];
            List <int>       links = nodeLinks[i];

            // For each reference, insert the referenced node into the father node
            for (int j = 0; j < links.Count; j++)
            {
                node.addChild(graphNodes[links[j]]);
            }
        }
    }
        public override bool redoTool()
        {
            // Take the complete nodes
            ConversationNode father = (ConversationNode)fatherView;
            ConversationNode child  = (ConversationNode)childView;

            // Add the new child
            father.addChild(child);
            // If the father is an option node, add a new line
            if (father.getType() == ConversationNodeViewEnum.OPTION)
            {
                father.addLine(new ConversationLine(ConversationLine.PLAYER, TC.get("ConversationLine.DefaultText")));
            }
            dataControl.updateAllConditions();
            controller.updatePanel();
            return(true);
        }
Esempio n. 7
0
    public virtual object Clone()
    {
        Conversation c = (Conversation)this.MemberwiseClone();

        c.conversationId   = (conversationId != null ? conversationId : null);
        c.conversationType = conversationType;

        Dictionary <ConversationNode, ConversationNode> clonedNodes =
            new Dictionary <ConversationNode, ConversationNode>();

        c.root = (root != null ? (ConversationNode)root.Clone() : null);

        clonedNodes.Add(root, c.root);
        List <ConversationNode> nodes   = new List <ConversationNode>();
        List <ConversationNode> visited = new List <ConversationNode>();

        nodes.Add(root);

        while (nodes.Count > 0)
        {
            ConversationNode temp   = nodes[0];
            ConversationNode cloned = clonedNodes[temp];
            nodes.RemoveAt(0);
            visited.Add(temp);

            for (int i = 0; i < temp.getChildCount(); i++)
            {
                ConversationNode tempCloned = clonedNodes[temp.getChild(i)];
                if (tempCloned == null)
                {
                    tempCloned = (ConversationNode)temp.getChild(i).Clone();
                    clonedNodes.Add(temp.getChild(i), tempCloned);
                }
                cloned.addChild(tempCloned);

                if (!visited.Contains(temp.getChild(i)) && !nodes.Contains(temp.getChild(i)))
                {
                    nodes.Add(temp.getChild(i));
                }
            }
        }
        return(c);
    }
        public override bool doTool()
        {
            bool nodeLinked = false;

            // If it is not possible to link the node to the given one, show a message
            if (!dataControl.canLinkNodeTo(fatherView, childView))
            {
                controller.showErrorDialog(TC.get("Conversation.OperationLinkNode"), TC.get("Conversation.ErrorLinkNode"));
            }

            // If it can be linked
            else
            {
                bool linkNode = true;

                // If the node has an effect, ask for confirmation (for the effect will be deleted)
                //if( fatherView.hasEffects( ) )
                //linkNode = controller.showStrictConfirmDialog( TextConstants.getText( "Conversation.OperationLinkNode" ), TextConstants.getText( "Conversation.ErrorLinkNode" ) );

                // If the node must be linked
                if (linkNode)
                {
                    // Take the complete nodes
                    ConversationNode father = (ConversationNode)fatherView;
                    ConversationNode child  = (ConversationNode)childView;

                    // Add the new child
                    father.addChild(child);

                    // If the father is an option node, add a new line
                    if (father.getType() == ConversationNodeViewEnum.OPTION)
                    {
                        father.addLine(new ConversationLine(ConversationLine.PLAYER, TC.get("ConversationLine.DefaultText")));
                    }

                    // The node was successfully linked
                    nodeLinked = true;
                    dataControl.updateAllConditions();
                }
            }

            return(nodeLinked);
        }
        private int setNode(ConversationNode oldNode, ConversationNode newNode, ConversationNode rootnode = null)
        {
            if (rootnode == null)
            {
                rootnode = conversation.getRootNode();
            }

            if (oldNode == rootnode)
            {
                if (conversation.getRootNode() == rootnode)
                {
                    conversation = new GraphConversation(conversation.getId(), newNode);
                    return(1);
                }
                else
                {
                    return(2);
                }
            }
            else
            {
                for (int i = 0; i < rootnode.getChildCount(); i++)
                {
                    int result = setNode(oldNode, newNode, rootnode.getChild(i));

                    if (result == 2)
                    {
                        rootnode.removeChild(i);
                        rootnode.addChild(newNode);
                    }

                    if (result != 0)
                    {
                        return(1);
                    }
                }
            }
            return(0);
        }
        void nodeWindow(int id)
        {
            ConversationNode myNode = conversation.getAllNodes()[id];

            ConversationNodeEditor editor = null;

            editors.TryGetValue(myNode, out editor);

            if (editor != null && editor.Collapsed)
            {
                GUIContent bttext = new GUIContent(TC.get("GeneralText.Open"));
                Rect       btrect = GUILayoutUtility.GetRect(bttext, buttonstyle);

                GUILayout.BeginHorizontal();
                if (GUI.Button(btrect, bttext))
                {
                    editor.Collapsed = false;
                }
                ;
                GUILayout.EndHorizontal();
            }
            else
            {
                string[] editorNames = ConversationNodeEditorFactory.Intance.CurrentConversationNodeEditors;

                GUILayout.BeginHorizontal();
                int preEditorSelected = ConversationNodeEditorFactory.Intance.ConversationNodeEditorIndex(myNode);
                int editorSelected    = EditorGUILayout.Popup(preEditorSelected, editorNames);

                if (GUILayout.Button("-", collapseStyle, GUILayout.Width(15), GUILayout.Height(15)))
                {
                    editor.Collapsed = true;
                    GUIContent bttext = new GUIContent(TC.get("GeneralText.Open"));
                    Rect       btrect = GUILayoutUtility.GetRect(bttext, buttonstyle);
                    editor.Window = new Rect(editor.Window.x, editor.Window.y, btrect.width, btrect.height);
                }
                if (GUILayout.Button("X", closeStyle, GUILayout.Width(15), GUILayout.Height(15)))
                {
                }
                //effects.getEffects().Remove(myEffect);

                GUILayout.EndHorizontal();

                GUILayout.BeginVertical();

                if (editor == null || preEditorSelected != editorSelected)
                {
                    bool firstEditor = (editor == null);
                    editor =
                        ConversationNodeEditorFactory.Intance.createConversationNodeEditorFor(editorNames[editorSelected]);
                    editor.setParent(this);
                    if (firstEditor)
                    {
                        editor.Node = myNode;
                    }
                    else
                    {
                        setNode(myNode, editor.Node);
                    }

                    if (editors.ContainsKey(myNode))
                    {
                        editor.Window = editors[myNode].Window;
                    }
                    else
                    {
                        editor.Window = tmpRects[myNode];
                    }

                    editors.Remove(myNode);
                    editors.Add(editor.Node, editor);
                }

                editor.draw();

                GUILayout.EndVertical();
            }


            if (Event.current.type != EventType.layout)
            {
                Rect lastRect = GUILayoutUtility.GetLastRect();
                Rect myRect   = editors[myNode].Window;
                myRect.height          = lastRect.y + lastRect.height;
                editors[myNode].Window = myRect;
                this.Repaint();
            }

            if (Event.current.type == EventType.mouseMove)
            {
                if (
                    new Rect(0, 0, editors[myNode].Window.width, editors[myNode].Window.height).Contains(
                        Event.current.mousePosition))
                {
                    hovering = id;
                }
            }

            if (Event.current.type == EventType.mouseDown)
            {
                if (hovering == id)
                {
                    focusing = hovering;
                }
                if (lookingChildNode != null)
                {
                    // link creation between nodes
                    if (lookingChildNode.getChildCount() > 0)
                    {
                        lookingChildNode.removeChild(lookingChildSlot);
                    }
                    lookingChildNode.addChild(lookingChildSlot, myNode);
                    // finishing search
                    lookingChildNode = null;
                }
            }

            GUI.DragWindow();
        }
    public override void ParseElement(XmlElement element)
    {
        XmlNodeList
            speakschar = element.SelectNodes("speak-char"),
            speaksplayer = element.SelectNodes("speak-player"),
            responses = element.SelectNodes("response"),
            options = element.SelectNodes("option"),
            effects = element.SelectNodes("effect"),
            gosback = element.SelectNodes("go-back");

        string tmpArgVal;

        // Store the name
        string conversationName = "";

        tmpArgVal = element.GetAttribute("id");
        if (!string.IsNullOrEmpty(tmpArgVal))
        {
            conversationName = tmpArgVal;
        }

        // Create a dialogue node (which will be the root node) and add it to a new tree
        // The content of the tree will be built adding nodes directly to the root
        currentNode = new DialogueConversationNode();
        conversation = new TreeConversation(conversationName, currentNode);
        pastOptionNodes = new List<ConversationNode>();

        foreach (XmlElement el in speakschar)
        {
            // Set default name to "NPC"
            characterName = "NPC";
            audioPath = "";

            // If there is a "idTarget" attribute, store it
            tmpArgVal = el.GetAttribute("idTarget");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                characterName = tmpArgVal;
            }

            // If there is a "uri" attribute, store it as audio path
            tmpArgVal = el.GetAttribute("uri");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                audioPath = tmpArgVal;
            }

            // If there is a "uri" attribute, store it as audio path
            tmpArgVal = el.GetAttribute("synthesize");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                string response = tmpArgVal;
                if (response.Equals("yes"))
                    synthesizerVoice = true;
                else
                    synthesizerVoice = false;
            }

            // Store the read string into the current node, and then delete the string. The trim is performed so we
            // don't
            // have to worry with indentations or leading/trailing spaces
            ConversationLine line = new ConversationLine(characterName, el.InnerText);
            if (audioPath != null && !this.audioPath.Equals(""))
            {
                line.setAudioPath(audioPath);
            }

            if (synthesizerVoice != null)
                line.setSynthesizerVoice(synthesizerVoice);
            currentNode.addLine(line);

        }

        foreach (XmlElement el in speaksplayer)
        {
            audioPath = "";

            // If there is a "uri" attribute, store it as audio path
            tmpArgVal = el.GetAttribute("uri");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                audioPath = tmpArgVal;
            }
            // If there is a "uri" attribute, store it as audio path
            tmpArgVal = el.GetAttribute("synthesize");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                string response = tmpArgVal;
                if (response.Equals("yes"))
                    synthesizerVoice = true;
                else
                    synthesizerVoice = false;
            }

            // Store the read string into the current node, and then delete the string. The trim is performed so we
            // don't have to worry with indentations or leading/trailing spaces
            ConversationLine line = new ConversationLine(ConversationLine.PLAYER, el.InnerText);
            if (audioPath != null && !this.audioPath.Equals(""))
            {
                line.setAudioPath(audioPath);
            }
            if (synthesizerVoice != null)
                line.setSynthesizerVoice(synthesizerVoice);

            currentNode.addLine(line);
        }

        foreach (XmlElement el in responses)
        {

            //If there is a "random" attribute, store is the options will be random
            tmpArgVal = el.GetAttribute("random");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                if (tmpArgVal.Equals("yes"))
                    random = true;
                else
                    random = false;
            }

            //If there is a "keepShowing" attribute, keep the previous conversation line showing
            tmpArgVal = el.GetAttribute("keepShowing");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                if (tmpArgVal.Equals("yes"))
                    keepShowing = true;
                else
                    keepShowing = false;
            }

            //If there is a "showUserOption" attribute, identify if show the user response at option node
            tmpArgVal = el.GetAttribute("showUserOption");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                if (tmpArgVal.Equals("yes"))
                    showUserOption = true;
                else
                    showUserOption = false;
            }

            //If there is a "showUserOption" attribute, identify if show the user response at option node
            tmpArgVal = el.GetAttribute("preListening");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                if (tmpArgVal.Equals("yes"))
                    preListening = true;
                else
                    preListening = false;
            }

            //If there is a "x" and "y" attributes with the position where the option node has to be painted,
            tmpArgVal = el.GetAttribute("preListening");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                if (tmpArgVal.Equals("yes"))
                    preListening = true;
                else
                    preListening = false;
            }

            //If there is a "x" and "y" attributes with the position where the option node has to be painted
            tmpArgVal = el.GetAttribute("x");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                x = int.Parse(tmpArgVal);
            }
            tmpArgVal = el.GetAttribute("y");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                y = int.Parse(tmpArgVal);
            }

            // Create a new OptionNode, and link it to the current node
            ConversationNode nuevoNodoOpcion = new OptionConversationNode(random, keepShowing, showUserOption, preListening, x, y);
            currentNode.addChild(nuevoNodoOpcion);

            // Change the actual node for the option node recently created
            currentNode = nuevoNodoOpcion;
        }
        foreach (XmlElement el in options)
        {
            currentNode = pastOptionNodes[pastOptionNodes.Count - 1];
            pastOptionNodes.RemoveAt(pastOptionNodes.Count - 1);
        }
        foreach (XmlElement el in effects)
        {
            currentEffects = new Effects();
            new EffectSubParser_(currentEffects, chapter).ParseElement(el);
            currentNode.setEffects(currentEffects);
        }
        foreach (XmlElement el in gosback)
        {
            currentNode.addChild(pastOptionNodes[pastOptionNodes.Count - 1]);
        }

        chapter.addConversation(new GraphConversation((TreeConversation)conversation));
    }
    public override void ParseElement(XmlElement element)
    {
        XmlNodeList
            speakschar   = element.SelectNodes("speak-char"),
            speaksplayer = element.SelectNodes("speak-player"),
            responses    = element.SelectNodes("response"),
            options      = element.SelectNodes("option"),
            effects      = element.SelectNodes("effect"),
            gosback      = element.SelectNodes("go-back");


        string tmpArgVal;

        // Store the name
        string conversationName = "";

        tmpArgVal = element.GetAttribute("id");
        if (!string.IsNullOrEmpty(tmpArgVal))
        {
            conversationName = tmpArgVal;
        }

        // Create a dialogue node (which will be the root node) and add it to a new tree
        // The content of the tree will be built adding nodes directly to the root
        currentNode     = new DialogueConversationNode();
        conversation    = new TreeConversation(conversationName, currentNode);
        pastOptionNodes = new List <ConversationNode>();

        foreach (XmlElement el in speakschar)
        {
            // Set default name to "NPC"
            characterName = "NPC";
            audioPath     = "";

            // If there is a "idTarget" attribute, store it
            tmpArgVal = el.GetAttribute("idTarget");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                characterName = tmpArgVal;
            }

            // If there is a "uri" attribute, store it as audio path
            tmpArgVal = el.GetAttribute("uri");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                audioPath = tmpArgVal;
            }

            // If there is a "uri" attribute, store it as audio path
            tmpArgVal = el.GetAttribute("synthesize");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                string response = tmpArgVal;
                if (response.Equals("yes"))
                {
                    synthesizerVoice = true;
                }
                else
                {
                    synthesizerVoice = false;
                }
            }

            // Store the read string into the current node, and then delete the string. The trim is performed so we
            // don't
            // have to worry with indentations or leading/trailing spaces
            ConversationLine line = new ConversationLine(characterName, el.InnerText);
            if (audioPath != null && !this.audioPath.Equals(""))
            {
                line.setAudioPath(audioPath);
            }

            if (synthesizerVoice != null)
            {
                line.setSynthesizerVoice(synthesizerVoice);
            }
            currentNode.addLine(line);
        }

        foreach (XmlElement el in speaksplayer)
        {
            audioPath = "";

            // If there is a "uri" attribute, store it as audio path
            tmpArgVal = el.GetAttribute("uri");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                audioPath = tmpArgVal;
            }
            // If there is a "uri" attribute, store it as audio path
            tmpArgVal = el.GetAttribute("synthesize");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                string response = tmpArgVal;
                if (response.Equals("yes"))
                {
                    synthesizerVoice = true;
                }
                else
                {
                    synthesizerVoice = false;
                }
            }

            // Store the read string into the current node, and then delete the string. The trim is performed so we
            // don't have to worry with indentations or leading/trailing spaces
            ConversationLine line = new ConversationLine(ConversationLine.PLAYER, el.InnerText);
            if (audioPath != null && !this.audioPath.Equals(""))
            {
                line.setAudioPath(audioPath);
            }
            if (synthesizerVoice != null)
            {
                line.setSynthesizerVoice(synthesizerVoice);
            }

            currentNode.addLine(line);
        }

        foreach (XmlElement el in responses)
        {
            //If there is a "random" attribute, store is the options will be random
            tmpArgVal = el.GetAttribute("random");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                if (tmpArgVal.Equals("yes"))
                {
                    random = true;
                }
                else
                {
                    random = false;
                }
            }

            //If there is a "keepShowing" attribute, keep the previous conversation line showing
            tmpArgVal = el.GetAttribute("keepShowing");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                if (tmpArgVal.Equals("yes"))
                {
                    keepShowing = true;
                }
                else
                {
                    keepShowing = false;
                }
            }

            //If there is a "showUserOption" attribute, identify if show the user response at option node
            tmpArgVal = el.GetAttribute("showUserOption");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                if (tmpArgVal.Equals("yes"))
                {
                    showUserOption = true;
                }
                else
                {
                    showUserOption = false;
                }
            }


            //If there is a "showUserOption" attribute, identify if show the user response at option node
            tmpArgVal = el.GetAttribute("preListening");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                if (tmpArgVal.Equals("yes"))
                {
                    preListening = true;
                }
                else
                {
                    preListening = false;
                }
            }

            //If there is a "x" and "y" attributes with the position where the option node has to be painted,
            tmpArgVal = el.GetAttribute("preListening");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                if (tmpArgVal.Equals("yes"))
                {
                    preListening = true;
                }
                else
                {
                    preListening = false;
                }
            }

            //If there is a "x" and "y" attributes with the position where the option node has to be painted
            tmpArgVal = el.GetAttribute("x");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                x = int.Parse(tmpArgVal);
            }
            tmpArgVal = el.GetAttribute("y");
            if (!string.IsNullOrEmpty(tmpArgVal))
            {
                y = int.Parse(tmpArgVal);
            }

            // Create a new OptionNode, and link it to the current node
            ConversationNode nuevoNodoOpcion = new OptionConversationNode(random, keepShowing, showUserOption, preListening, x, y);
            currentNode.addChild(nuevoNodoOpcion);

            // Change the actual node for the option node recently created
            currentNode = nuevoNodoOpcion;
        }
        foreach (XmlElement el in options)
        {
            currentNode = pastOptionNodes[pastOptionNodes.Count - 1];
            pastOptionNodes.RemoveAt(pastOptionNodes.Count - 1);
        }
        foreach (XmlElement el in effects)
        {
            currentEffects = new Effects();
            new EffectSubParser_(currentEffects, chapter).ParseElement(el);
            currentNode.setEffects(currentEffects);
        }
        foreach (XmlElement el in gosback)
        {
            currentNode.addChild(pastOptionNodes[pastOptionNodes.Count - 1]);
        }

        chapter.addConversation(new GraphConversation((TreeConversation)conversation));
    }
 public override bool undoTool()
 {
     parent.addChild(linkIndex, linkDeleted);
     Controller.getInstance().updatePanel();
     return(true);
 }
Esempio n. 14
0
    /*
     * (non-Javadoc)
     *
     * @see conversationaleditor.xmlparser.ConversationParser#startElement(java.lang.string, java.lang.string,
     *      java.lang.string, org.xml.sax.Attributes)
     */
    public override void startElement(string namespaceURI, string sName, string qName, Dictionary <string, string> attrs)
    {
        // If no element is being subparsed
        if (subParsing == SUBPARSING_NONE)
        {
            // If it is a "conversation" we pick the name, so we can build the tree later
            if (qName.Equals("tree-conversation"))
            {
                // Store the name
                string conversationName = "";
                foreach (KeyValuePair <string, string> entry in attrs)
                {
                    if (entry.Key.Equals("id"))
                    {
                        conversationName = entry.Value.ToString();
                    }
                }

                // Create a dialogue node (which will be the root node) and add it to a new tree
                // The content of the tree will be built adding nodes directly to the root
                currentNode     = new DialogueConversationNode();
                conversation    = new TreeConversation(conversationName, currentNode);
                pastOptionNodes = new List <ConversationNode>();
            }

            // If it is a non-player character line, store the character name and audio path (if present)
            else if (qName.Equals("speak-char"))
            {
                // Set default name to "NPC"
                characterName = "NPC";
                audioPath     = "";

                foreach (KeyValuePair <string, string> entry in attrs)
                {
                    // If there is a "idTarget" attribute, store it
                    if (entry.Key.Equals("idTarget"))
                    {
                        characterName = entry.Value.ToString();
                    }

                    // If there is a "uri" attribute, store it as audio path
                    if (entry.Key.Equals("uri"))
                    {
                        audioPath = entry.Value.ToString();
                    }
                    // If there is a "synthesize" attribute, store its value
                    if (entry.Key.Equals("synthesize"))
                    {
                        string response = entry.Value.ToString();
                        if (response.Equals("yes"))
                        {
                            synthesizerVoice = true;
                        }
                        else
                        {
                            synthesizerVoice = false;
                        }
                    }
                }
            }

            // If it is a player character line, store the audio path (if present)
            else if (qName.Equals("speak-player"))
            {
                audioPath = "";

                foreach (KeyValuePair <string, string> entry in attrs)
                {
                    // If there is a "uri" attribute, store it as audio path
                    if (entry.Key.Equals("uri"))
                    {
                        audioPath = entry.Value.ToString();
                    }

                    // If there is a "synthesize" attribute, store its value
                    if (entry.Key.Equals("synthesize"))
                    {
                        string response = entry.Value.ToString();
                        if (response.Equals("yes"))
                        {
                            synthesizerVoice = true;
                        }
                        else
                        {
                            synthesizerVoice = false;
                        }
                    }
                }
            }

            // If it is a point with a set of possible responses, create a new OptionNode
            else if (qName.Equals("response"))
            {
                foreach (KeyValuePair <string, string> entry in attrs)
                {
                    //If there is a "random" attribute, store is the options will be random
                    if (entry.Key.Equals("random"))
                    {
                        if (entry.Value.ToString().Equals("yes"))
                        {
                            random = true;
                        }
                        else
                        {
                            random = false;
                        }
                    }
                    //If there is a "keepShowing" attribute, keep the previous conversation line showing
                    if (entry.Key.Equals("keepShowing"))
                    {
                        if (entry.Value.ToString().Equals("yes"))
                        {
                            keepShowing = true;
                        }
                        else
                        {
                            keepShowing = false;
                        }
                    }
                    //If there is a "showUserOption" attribute, identify if show the user response at option node
                    if (entry.Key.Equals("showUserOption"))
                    {
                        if (entry.Value.ToString().Equals("yes"))
                        {
                            showUserOption = true;
                        }
                        else
                        {
                            showUserOption = false;
                        }
                    }

                    //If there is a "showUserOption" attribute, identify if show the user response at option node
                    if (entry.Key.Equals("preListening"))
                    {
                        if (entry.Value.ToString().Equals("yes"))
                        {
                            preListening = true;
                        }
                        else
                        {
                            preListening = false;
                        }
                    }

                    //If there is a "x" and "y" attributes with the position where the option node has to be painted,
                    if (entry.Key.Equals("x"))
                    {
                        x = int.Parse(entry.Value.ToString());
                    }

                    if (entry.Key.Equals("y"))
                    {
                        y = int.Parse(entry.Value.ToString());
                    }
                }
                // Create a new OptionNode, and link it to the current node
                ConversationNode nuevoNodoOpcion = new OptionConversationNode(random, keepShowing, showUserOption, preListening, x, y);
                currentNode.addChild(nuevoNodoOpcion);

                // Change the actual node for the option node recently created
                currentNode = nuevoNodoOpcion;
            }

            // If we are about to read an option, change the state of the recognizer, so we can read the line of the
            // option
            else if (qName.Equals("option"))
            {
                state = STATE_WAITING_OPTION;
            }

            // If it is an effect tag, create new effect, new subparser and switch state
            else if (qName.Equals("effect"))
            {
                currentEffects  = new Effects();
                effectSubParser = new EffectSubParser(currentEffects, chapter);
                subParsing      = SUBPARSING_EFFECT;
            }

            // If there is a go back, link the current node (which will be a DialogueNode) with the last OptionNode
            // stored
            else if (qName.Equals("go-back"))
            {
                currentNode.addChild(pastOptionNodes[pastOptionNodes.Count - 1]);
            }
        }

        // If an effect element is being subparsed, spread the call
        if (subParsing == SUBPARSING_EFFECT)
        {
            effectSubParser.startElement(namespaceURI, sName, qName, attrs);
        }
    }