Beispiel #1
0
 /**
  * func: changes the currentNode state to the next node based on the chosen response with id 'id'
  * @id: a valid index for the available responses of the current node
  * @return: special signals like conversation exits
  */
 public EConOptionType chose(int id)
 {
     BasicDialResponse resp = _currentNode.GetResponse(id);
     switch(resp.optionType)
     {
         case EConOptionType.UNSET:
         case EConOptionType.NORMAL:
             if (resp.nextNode.HasOptions())
             {
                 _currentNode = resp.nextNode;
                 return EConOptionType.NORMAL;
             }
             else
             {
                 _currentNode = resp.nextNode;
                 return EConOptionType.EXIT;
             }
         default:
             return resp.optionType;
     }
 }
Beispiel #2
0
        public static Conversation[] loadFromGephiGraphML(TextAsset f)
        {
            if (f == null)
                throw new NullReferenceException("Cannot load graph from NULL reference!");

            /* load and prepare data */
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(f.text);

            XmlNodeList conKeyList = xmlDoc.GetElementsByTagName("key");
            XmlNodeList conNodeList = xmlDoc.GetElementsByTagName("node");
            XmlNodeList conEdgeList = xmlDoc.GetElementsByTagName("edge");
            Dictionary<string, BasicDialNode> dialNodes = new Dictionary<string, BasicDialNode>();
            List<BasicDialNode> conStartNodes = new List<BasicDialNode>(); // store conversation starts

            /* get data keys */
            string PlayerEventNodeId = null;
            string ActivationEventNodeId = null;
            string PlayerEventEdgeId = null;
            string ActivationEventEdgeId = null;
            string RequirementEdgeId = null;

            foreach (XmlNode key in conKeyList)
            {
                switch(key.Attributes["attr.name"].Value)
                {
                    case "PlayerEvent":
                        if (key.Attributes["for"].Value.Equals("node"))
                            PlayerEventNodeId = key.Attributes["id"].Value;
                        else
                            PlayerEventEdgeId = key.Attributes["id"].Value;
                        break;
                    case "ActivationEvent":
                        if (key.Attributes["for"].Value.Equals("node"))
                            ActivationEventNodeId = key.Attributes["id"].Value;
                        else
                            ActivationEventEdgeId = key.Attributes["id"].Value;
                        break;
                    case "Requirement":
                        RequirementEdgeId = key.Attributes["id"].Value;
                        break;
                }
            }

            /* load nodes aka dialogue */
            BasicDialNode latestNode;
            foreach (XmlNode node in conNodeList)
            {
                latestNode = new BasicDialNode();
                latestNode.XmlID = node.Attributes["id"].Value;
                Debug.Assert(!dialNodes.ContainsKey(latestNode.XmlID), "Duplicated nodes entries found in XML!");
                dialNodes[latestNode.XmlID] = latestNode;

                // get important ATTRIBUTES for this node
                Dictionary<string, string> nodeDic = XmlNodesToDic(node.ChildNodes, "key");
                Debug.Assert(nodeDic["label"] != null, "A node should contain a label!");
                latestNode.dialogueText = nodeDic["label"];
                if (nodeDic.ContainsKey("notetype"))
                {
                    string nodetype = nodeDic["notetype"];
                    switch (nodetype)
                    {
                        case "Start":
                            conStartNodes.Add(latestNode);
                            break;
                        case "OpenUI": // doesn't do much here
                            break;
                        case "Exit":   // doesn't do much here
                            break;
                        default:
                            Debug.LogError("Unknown Node Type detected: " + nodetype + " for node: " + latestNode.XmlID);
                            break;
                    }
                }

                if (nodeDic.ContainsKey(PlayerEventNodeId))
                {
                    Debug.Log(nodeDic[PlayerEventNodeId] + ": Node Activation Event found!");
                }

                if (nodeDic.ContainsKey(ActivationEventNodeId))
                {
                    Debug.Log(nodeDic[ActivationEventNodeId] + ": Node Player Event found!");
                }
            }

            /* load edges aka responses */
            foreach (XmlNode edge in conEdgeList)
            {
                BasicDialResponse response = new BasicDialResponse();
                response.nextNode = dialNodes[edge.Attributes["target"].Value];     // set target node link
                dialNodes[edge.Attributes["source"].Value].AddResponse(response);   // set source node link

                // get important ATTRIBUTES for this edge
                Dictionary<string, string> edgeDic = XmlNodesToDic(edge.ChildNodes, "key");
                Debug.Assert(edgeDic["edgelabel"] != null, "An edge should contain a label!");
                response.responseText = edgeDic["edgelabel"];

                if (edgeDic.ContainsKey("edgetype"))
                {
                    switch (edgeDic["edgetype"])
                    {
                        case "OpenShop":
                            response.optionType = EConOptionType.OPEN_SHOP;
                            break;
                        case "Exit":
                            response.optionType = EConOptionType.EXIT;
                            break;
                        case "Quest":  // EConOptionType.OFFER_QUEST
                            response.optionType = EConOptionType.OFFER_QUEST;
                            // TODO: load quest name
                            break;
                        default:
                            Debug.LogError("Unknown edge type: " + edgeDic["edgetype"]);
                            break;
                    }
                }
                else
                    response.optionType = EConOptionType.NORMAL;

                if (edgeDic.ContainsKey(PlayerEventEdgeId))
                {
                    Debug.Log(edgeDic[PlayerEventEdgeId] + ": Requirement found!");
                }

                if (edgeDic.ContainsKey(ActivationEventEdgeId))
                {
                    Debug.Log(edgeDic[ActivationEventEdgeId] + ": Requirement found!");
                }

                if (edgeDic.ContainsKey(RequirementEdgeId))
                {
                    Debug.Log(edgeDic[RequirementEdgeId] + ": Requirement found!");
                }
            }

            // separate nodes into multiple conversations, if necessary
            Conversation[] newConArr = new Conversation[(conStartNodes.Count > 0) ? conStartNodes.Count : 1];
            BasicDialNode[] dialNodesArr = new BasicDialNode[dialNodes.Count];
            dialNodes.Values.CopyTo(dialNodesArr, 0);

            if (conStartNodes.Count == 0)
            {
                Debug.LogError("A valid conversion file should ALWAYS have at least 1 conversation start!");
            }
            else
            {
                for (int i = 0; i < conStartNodes.Count; ++i)
                {
                    Conversation newCon = new Conversation();
                    newCon.conNodes = dialNodesArr;
                    newCon.startNode = conStartNodes[i];
                    newCon._currentNode = conStartNodes[i];
                    newConArr[i] = newCon;
                }
            }

            return newConArr;
        }
Beispiel #3
0
        /**
         * func: loads a conversion saved as a graphml file
         * the expected graphml syntax is as follows:
         *
         * - allows 1 dimensional grouping inside the graph. Stacked grouping may cause unexpected behaviour
         * - a group is considered a separate conversation, but edge can connect them
         * @graphmlFile: Asset reference to a valid graphml file
         */
        public static Conversation[] loadFromYedGraphml(TextAsset graphmlFile)
        {
            if (!graphmlFile)
                throw new NullReferenceException("no xmlFile given!");

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(graphmlFile.text);

            XmlNodeList conNodeList = xmlDoc.GetElementsByTagName("node");
            XmlNodeList conEdgeList = xmlDoc.GetElementsByTagName("edge");
            Dictionary<string, BasicDialNode> dialNodes = new Dictionary<string, BasicDialNode>();
            List<string> groupNodes = new List<string>(); // may have some use later on
            List<string> groupLabel = new List<string>();
            List<BasicDialNode> conStartNodes = new List<BasicDialNode>(); // store conversation starts

             // LOAD NODES ~> ANSWERES/QUESTIONS
            BasicDialNode lastNode;
            foreach (XmlNode node in conNodeList)
            {
                // grouping nodes only indicate
                string grpLabel = GetGroupNodeLabel(node);
                if (grpLabel != null)
                {
                    Debug.Log("Group node found!");
                    groupNodes.Add(node.Attributes["id"].Value);
                    groupLabel.Add(grpLabel);
                    continue; // TODO: we may grab the group label later on. Do this in here!
                }

                // normal dialogue node
                lastNode = new BasicDialNode();
                lastNode.XmlID = node.Attributes["id"].Value;
                Debug.Assert(!dialNodes.ContainsKey(lastNode.XmlID), "Duplicated nodes entries found in XML!");
                dialNodes[lastNode.XmlID] = lastNode;

                // get important ATTRIBUTES for this node
                foreach (XmlNode i in node.ChildNodes)
                {
                    if (i.Attributes["key"] != null)
                    {
                        if (i.Attributes["key"].Value.Equals(NODE_GRAPHICS_KEY))
                        {
                            if (i.HasChildNodes && i.ChildNodes[0].Name.Equals("y:ShapeNode"))
                            {
                                bool labelFound = false;
                                foreach (XmlNode n in i.ChildNodes[0].ChildNodes)
                                {
                                    if (n.Name.Equals("y:NodeLabel"))
                                    {
                                        labelFound = true;
                                        lastNode.dialogueText = n.InnerText;
                                        // TODE: set up multi dialogue texts HERE!
                                    }
                                    else if (n.Name.Equals("y:Fill"))
                                    {
                                        if (n.Attributes["color"].Value.Equals(START_NODE_COLOR))
                                            conStartNodes.Add(lastNode); // found a conversation start node
                                    }
                                }
                                Debug.Assert(labelFound, "Found a response edge, but no response message??");
                            }
                        }

                        if (i.Attributes["key"].Value.Equals(NODE_ACTIVATION_EVENT_KEY))
                        {
                            Debug.Log(node.Attributes["id"].Value + ": Node Activation Event found!");
                        }

                        if (i.Attributes["key"].Value.Equals(NODE_PLAYER_EVENT_KEY))
                        {
                            Debug.Log(node.Attributes["id"].Value + ": Node Player Event found!");
                        }
                    }
                }
            }

            // LOAD EDGE ~> RESPONSES
            foreach (XmlNode edge in conEdgeList)
            {
                BasicDialResponse response = new BasicDialResponse();
                response.nextNode = dialNodes[edge.Attributes["target"].Value];     // set target node link
                dialNodes[edge.Attributes["source"].Value].AddResponse(response);   // set source node link

                foreach (XmlNode i in edge.ChildNodes)
                {
                    // get the label -> response string
                    if (i.Attributes["key"].Value.Equals(EDGE_GRAPHICS_KEY))
                    {
                        XmlNode PolyLineEdge = i.ChildNodes[0];
                        Debug.Assert(PolyLineEdge.Name.Equals("y:PolyLineEdge"), "Unexpected edge structure!");
                        bool labelFound = false;
                        foreach (XmlNode n in PolyLineEdge.ChildNodes)
                            if (n.Name.Equals("y:LineStyle"))
                            {
                                if (n.Attributes["color"].Value.Equals(OPENSHOP_EDGE_COLOR))
                                    response.optionType = EConOptionType.OPEN_SHOP;
                            }
                            else if (n.Name.Equals("y:EdgeLabel"))
                            {
                                labelFound = true;
                                response.responseText = n.InnerText;
                                // TODO: set up multi response texts HERE
                            }

                        Debug.Assert(labelFound, "Found a response edge, but no response message??");
                    }

                    if (i.Attributes["key"].Value.Equals(EDGE_REQUIREMENT_KEY))
                    {
                        Debug.Log(edge.Attributes["id"].Value + ": Requirement found!");
                    }

                    if (i.Attributes["key"].Value.Equals(EDGE_ACTIVATION_EVENT))
                    {
                        Debug.Log(edge.Attributes["id"].Value + ": Requirement found!");
                    }

                    if (i.Attributes["key"].Value.Equals(EDGE_PLAYER_EVENT))
                    {
                        Debug.Log(edge.Attributes["id"].Value + ": Requirement found!");
                    }
                }
            }

            // separate nodes into multiple conversations, if necessary
            Conversation[] newConArr = new Conversation[(conStartNodes.Count > 0) ? conStartNodes.Count : 1];
            BasicDialNode[] dialNodesArr = new BasicDialNode[dialNodes.Values.Count];
            dialNodes.Values.CopyTo(dialNodesArr, 0); // TODO: may split it up later on

            if (conStartNodes.Count == 0)
            {
                Debug.LogError("A valid conversion file should ALWAYS have at least 1 conversation start!");
            }
            else
            {
                for (int i=0; i<conStartNodes.Count; ++i)
                {
                    Conversation newCon = new Conversation();
                    newCon.conNodes = dialNodesArr;
                    newCon.startNode = conStartNodes[i];
                    newCon._currentNode = conStartNodes[i];
                    newConArr[i] = newCon;
                }
            }

            return newConArr;
        }