/** * 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 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 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); } 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); } 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); nuevoNodoOpcion.setEditorX(x); nuevoNodoOpcion.setEditorY(y); currentNode.addChild(nuevoNodoOpcion); // Change the actual node for the option node recently created currentNode = nuevoNodoOpcion; } { var iterator = options.GetEnumerator(); while (iterator.MoveNext()) { 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); } { var i = gosback.GetEnumerator(); while (i.MoveNext()) { currentNode.addChild(pastOptionNodes[pastOptionNodes.Count - 1]); } } chapter.addConversation(new GraphConversation((TreeConversation)conversation)); }