//--------------------------------------
        // Construct User-Facing Conversation Object and Nodes
        //--------------------------------------

        private Conversation ConstructConversationObject(EditableConversation ec)
        {
            // Create a conversation object
            Conversation conversation = new Conversation();

            // Construct the parameters
            CreateParameters(ec, conversation);

            // Create a dictionary to store our created nodes by UID
            Dictionary <int, SpeechNode> speechByID  = new Dictionary <int, SpeechNode>();
            Dictionary <int, OptionNode> optionsByID = new Dictionary <int, OptionNode>();

            // Create a Dialogue and Option node for each in the conversation
            // Put them in the dictionary
            for (int i = 0; i < ec.SpeechNodes.Count; i++)
            {
                SpeechNode node = CreateSpeechNode(ec.SpeechNodes[i]);
                speechByID.Add(ec.SpeechNodes[i].ID, node);
            }

            for (int i = 0; i < ec.Options.Count; i++)
            {
                OptionNode node = CreateOptionNode(ec.Options[i]);
                optionsByID.Add(ec.Options[i].ID, node);
            }

            // Now that we have every node in the dictionary, reconstruct the tree
            // And also look for the root
            ReconstructTree(ec, conversation, speechByID, optionsByID);

            return(conversation);
        }
Esempio n. 2
0
        //--------------------------------------
        // Serialize and Deserialize
        //--------------------------------------

        public void Serialize(EditableConversation conversation)
        {
            saveVersion = CurrentVersion;

            conversation.Parameters = this.ParameterList;
            json = Jsonify(conversation);
        }
Esempio n. 3
0
        public EditableConversation DeserializeForEditor()
        {
            // Dejsonify
            EditableConversation conversation = Dejsonify();

            if (conversation != null)
            {
                // Deserialize the indivudual nodes
                {
                    if (conversation.SpeechNodes != null)
                    {
                        for (int i = 0; i < conversation.SpeechNodes.Count; i++)
                        {
                            conversation.SpeechNodes[i].Deserialize(this);
                        }
                    }

                    if (conversation.Options != null)
                    {
                        for (int i = 0; i < conversation.Options.Count; i++)
                        {
                            conversation.Options[i].Deserialize(this);
                        }
                    }
                }
            }

            // Clear our dummy event
            Event = new UnityEngine.Events.UnityEvent();

            return(conversation);
        }
Esempio n. 4
0
        public Conversation Deserialize()
        {
            // Deserialize an editor-version (containing all info) that
            // we will use to construct the user-facing Conversation data structure.
            EditableConversation ec = this.DeserializeForEditor();

            return(ConstructConversationObject(ec));
        }
    // Start is called before the first frame update

    // Testing out possibility of automatically parsing dialogue
    // TODO define structure for dialogue and parse into this script
    private void OnValidate()
    {
        DialogueEditor.EditableConversation ec = nPCConversation.DeserializeForEditor();
        for (int i = 0; i < ec.SpeechNodes.Count; i++)
        {
            ec.SpeechNodes[i].Text = i + " success!";
        }
        nPCConversation.Serialize(ec);
    }
        private void Save(bool manual = false)
        {
            if (CurrentAsset != null)
            {
                EditableConversation conversation = new EditableConversation();

                // Prepare each node for serialization
                for (int i = 0; i < uiNodes.Count; i++)
                {
                    uiNodes[i].Info.PrepareForSerialization(CurrentAsset);
                }

                // Now that each node has been prepared for serialization:
                // - Register the UIDs of their parents/children
                // - Add it to the conversation
                for (int i = 0; i < uiNodes.Count; i++)
                {
                    uiNodes[i].Info.RegisterUIDs();

                    if (uiNodes[i] is UISpeechNode)
                    {
                        conversation.SpeechNodes.Add((uiNodes[i] as UISpeechNode).SpeechNode);
                    }
                    else if (uiNodes[i] is UIOptionNode)
                    {
                        conversation.Options.Add((uiNodes[i] as UIOptionNode).OptionNode);
                    }
                }

                // Serialize
                CurrentAsset.Serialize(conversation);

                // Null / clear everything. We aren't pointing to it anymore.
                if (!manual)
                {
                    CurrentAsset = null;
                    while (uiNodes.Count != 0)
                    {
                        uiNodes.RemoveAt(0);
                    }
                    CurrentlySelectedNode = null;
                }

#if UNITY_EDITOR
                if (!Application.isPlaying)
                {
                    UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene());
                }
#endif
            }
        }
Esempio n. 7
0
        private EditableConversation Dejsonify()
        {
            if (json == null || json == "")
            {
                return(null);
            }

            EditableConversation conversation = new EditableConversation();

            System.IO.MemoryStream     ms  = new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(json));
            DataContractJsonSerializer ser = new DataContractJsonSerializer(conversation.GetType());

            conversation = ser.ReadObject(ms) as EditableConversation;
            ms.Close();

            return(conversation);
        }
Esempio n. 8
0
 private void CreateParameters(EditableConversation ec, Conversation conversation)
 {
     for (int i = 0; i < ec.Parameters.Count; i++)
     {
         if (ec.Parameters[i].ParameterType == EditableParameter.eParamType.Bool)
         {
             EditableBoolParameter editableParam = ec.Parameters[i] as EditableBoolParameter;
             BoolParameter         boolParam     = new BoolParameter(editableParam.ParameterName, editableParam.BoolValue);
             conversation.Parameters.Add(boolParam);
         }
         else if (ec.Parameters[i].ParameterType == EditableParameter.eParamType.Int)
         {
             EditableIntParameter editableParam = ec.Parameters[i] as EditableIntParameter;
             IntParameter         intParam      = new IntParameter(editableParam.ParameterName, editableParam.IntValue);
             conversation.Parameters.Add(intParam);
         }
     }
 }
Esempio n. 9
0
        private string Jsonify(EditableConversation conversation)
        {
            if (conversation == null || conversation.Options == null)
            {
                return("");
            }

            System.IO.MemoryStream ms = new System.IO.MemoryStream();

            DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(EditableConversation));

            ser.WriteObject(ms, conversation);
            byte[] jsonData = ms.ToArray();
            ms.Close();
            string toJson = System.Text.Encoding.UTF8.GetString(jsonData, 0, jsonData.Length);

            return(toJson);
        }
Esempio n. 10
0
        public EditableConversation DeserializeForEditor()
        {
            // Dejsonify
            EditableConversation conversation = Dejsonify();

            if (conversation != null)
            {
                // Copy the param list
                this.ParameterList = conversation.Parameters;

                // Deserialize the indivudual nodes
                {
                    if (conversation.SpeechNodes != null)
                    {
                        for (int i = 0; i < conversation.SpeechNodes.Count; i++)
                        {
                            conversation.SpeechNodes[i].DeserializeAssetData(this);
                        }
                    }

                    if (conversation.Options != null)
                    {
                        for (int i = 0; i < conversation.Options.Count; i++)
                        {
                            conversation.Options[i].DeserializeAssetData(this);
                        }
                    }
                }
            }
            else
            {
                conversation = new EditableConversation();
            }

            conversation.SaveVersion = this.saveVersion;

            // Clear our dummy event
            Event = new UnityEngine.Events.UnityEvent();

            // Reconstruct
            ReconstructEditableConversation(conversation);

            return(conversation);
        }
Esempio n. 11
0
        private void ReconstructTree(EditableConversation ec, Conversation conversation, Dictionary <int, SpeechNode> dialogues, Dictionary <int, OptionNode> options)
        {
            // Speech nodes
            List <EditableSpeechNode> editableSpeechNodes = ec.SpeechNodes;

            for (int i = 0; i < editableSpeechNodes.Count; i++)
            {
                EditableSpeechNode editableNode = editableSpeechNodes[i];
                SpeechNode         speechNode   = dialogues[editableNode.ID];

                // Connections
                List <EditableConnection> editableConnections = editableNode.Connections;
                for (int j = 0; j < editableConnections.Count; j++)
                {
                    int childID = editableConnections[j].NodeUID;

                    // Construct node->Speech
                    if (editableConnections[j].ConnectionType == EditableConnection.eConnectiontype.Speech)
                    {
                        SpeechConnection connection = new SpeechConnection(dialogues[childID]);
                        CopyConnectionConditions(editableConnections[j], connection);
                        speechNode.Connections.Add(connection);
                    }
                    // Construct node->Option
                    else if (editableConnections[j].ConnectionType == EditableConnection.eConnectiontype.Option)
                    {
                        OptionConnection connection = new OptionConnection(options[childID]);
                        CopyConnectionConditions(editableConnections[j], connection);
                        speechNode.Connections.Add(connection);
                    }
                }

                // Root?
                if (editableNode.EditorInfo.isRoot)
                {
                    conversation.Root = dialogues[editableNode.ID];
                }
            }


            // Option nodes
            List <EditableOptionNode> editableOptionNodes = ec.Options;

            for (int i = 0; i < editableOptionNodes.Count; i++)
            {
                EditableOptionNode editableNode = editableOptionNodes[i];
                OptionNode         optionNode   = options[editableNode.ID];

                // Connections
                List <EditableConnection> editableConnections = editableNode.Connections;
                for (int j = 0; j < editableConnections.Count; j++)
                {
                    int childID = editableConnections[j].NodeUID;

                    // Construct node->Speech
                    if (editableConnections[j].ConnectionType == EditableConnection.eConnectiontype.Speech)
                    {
                        SpeechConnection connection = new SpeechConnection(dialogues[childID]);
                        CopyConnectionConditions(editableConnections[j], connection);
                        optionNode.Connections.Add(connection);
                    }
                }
            }
        }
Esempio n. 12
0
        private void ReconstructEditableConversation(EditableConversation conversation)
        {
            if (conversation == null)
            {
                conversation = new EditableConversation();
            }

            // Get a list of every node in the conversation
            List <EditableConversationNode> allNodes = new List <EditableConversationNode>();

            for (int i = 0; i < conversation.SpeechNodes.Count; i++)
            {
                allNodes.Add(conversation.SpeechNodes[i]);
            }
            for (int i = 0; i < conversation.Options.Count; i++)
            {
                allNodes.Add(conversation.Options[i]);
            }

            // For every node:
            // Find the children and parents by UID
            for (int i = 0; i < allNodes.Count; i++)
            {
                // New parents list
                allNodes[i].parents = new List <EditableConversationNode>();

                // Get parents by UIDs
                //-----------------------------------------------------------------------------
                // UPDATE:  This behaviour has now been removed. Later in this function,
                //          the child->parent connections are constructed by using the
                //          parent->child connections. Having both of these behaviours run
                //          results in each parent being in the "parents" list twice.
                //
                // for (int j = 0; j < allNodes[i].parentUIDs.Count; j++)
                // {
                //     allNodes[i].parents.Add(conversation.GetNodeByUID(allNodes[i].parentUIDs[j]));
                // }
                //-----------------------------------------------------------------------------

                // Construct the parent->child connections
                //
                // V1.03
                if (conversation.SaveVersion <= (int)eSaveVersion.V1_03)
                {
                    // Construct Connections from the OptionUIDs and SpeechUIDs (which are now deprecated)
                    // This supports upgrading from V1.03 +

                    allNodes[i].Connections  = new List <EditableConnection>();
                    allNodes[i].ParamActions = new List <EditableSetParamAction>();

                    if (allNodes[i].NodeType == EditableConversationNode.eNodeType.Speech)
                    {
                        EditableSpeechNode thisSpeech = allNodes[i] as EditableSpeechNode;

                        // Speech options
                        int count = thisSpeech.OptionUIDs.Count;
                        for (int j = 0; j < count; j++)
                        {
                            int optionUID             = thisSpeech.OptionUIDs[j];
                            EditableOptionNode option = conversation.GetOptionByUID(optionUID);

                            thisSpeech.Connections.Add(new EditableOptionConnection(option));
                        }

                        // Speech following speech
                        {
                            int speechUID             = thisSpeech.SpeechUID;
                            EditableSpeechNode speech = conversation.GetSpeechByUID(speechUID);

                            if (speech != null)
                            {
                                thisSpeech.Connections.Add(new EditableSpeechConnection(speech));
                            }
                        }
                    }
                    else if (allNodes[i] is EditableOptionNode)
                    {
                        int speechUID             = (allNodes[i] as EditableOptionNode).SpeechUID;
                        EditableSpeechNode speech = conversation.GetSpeechByUID(speechUID);

                        if (speech != null)
                        {
                            allNodes[i].Connections.Add(new EditableSpeechConnection(speech));
                        }
                    }
                }
                //
                // V1.10 +
                else
                {
                    // For each node..  Reconstruct the connections
                    for (int j = 0; j < allNodes[i].Connections.Count; j++)
                    {
                        if (allNodes[i].Connections[j] is EditableSpeechConnection)
                        {
                            EditableSpeechNode speech = conversation.GetSpeechByUID(allNodes[i].Connections[j].NodeUID);
                            (allNodes[i].Connections[j] as EditableSpeechConnection).Speech = speech;
                        }
                        else if (allNodes[i].Connections[j] is EditableOptionConnection)
                        {
                            EditableOptionNode option = conversation.GetOptionByUID(allNodes[i].Connections[j].NodeUID);
                            (allNodes[i].Connections[j] as EditableOptionConnection).Option = option;
                        }
                    }
                }
            }

            // For every node:
            // Tell any of the nodes children that the node is the childs parent
            for (int i = 0; i < allNodes.Count; i++)
            {
                EditableConversationNode thisNode = allNodes[i];

                for (int j = 0; j < thisNode.Connections.Count; j++)
                {
                    if (thisNode.Connections[j].ConnectionType == EditableConnection.eConnectiontype.Speech)
                    {
                        (thisNode.Connections[j] as EditableSpeechConnection).Speech.parents.Add(thisNode);
                    }
                    else if (thisNode.Connections[j].ConnectionType == EditableConnection.eConnectiontype.Option)
                    {
                        (thisNode.Connections[j] as EditableOptionConnection).Option.parents.Add(thisNode);
                    }
                }
            }
        }
        //--------------------------------------
        // Load New Asset
        //--------------------------------------

        public void LoadNewAsset(NPCConversation asset)
        {
            CurrentAsset = asset;
            Log("Loading new asset: " + CurrentAsset.name);

            // Clear all current UI Nodes
            uiNodes.Clear();

            // Deseralize the asset and get the conversation root
            EditableConversation conversation = CurrentAsset.DeserializeForEditor();

            if (conversation == null)
            {
                conversation = new EditableConversation();
            }
            ConversationRoot = conversation.GetRootNode();

            // If it's null, create a root
            if (ConversationRoot == null)
            {
                ConversationRoot = new EditableSpeechNode();
                ConversationRoot.EditorInfo.xPos   = (Screen.width / 2) - (UISpeechNode.Width / 2);
                ConversationRoot.EditorInfo.yPos   = 0;
                ConversationRoot.EditorInfo.isRoot = true;
                conversation.SpeechNodes.Add(ConversationRoot);
            }

            // Get a list of every node in the conversation
            List <EditableConversationNode> allNodes = new List <EditableConversationNode>();

            for (int i = 0; i < conversation.SpeechNodes.Count; i++)
            {
                allNodes.Add(conversation.SpeechNodes[i]);
            }
            for (int i = 0; i < conversation.Options.Count; i++)
            {
                allNodes.Add(conversation.Options[i]);
            }

            // For every node:
            // Find the children and parents by UID
            for (int i = 0; i < allNodes.Count; i++)
            {
                // Remove duplicate parent UIDs
                HashSet <int> noDupes = new HashSet <int>(allNodes[i].parentUIDs);
                allNodes[i].parentUIDs.Clear();
                foreach (int j in noDupes)
                {
                    allNodes[i].parentUIDs.Add(j);
                }

                allNodes[i].parents = new List <EditableConversationNode>();
                for (int j = 0; j < allNodes[i].parentUIDs.Count; j++)
                {
                    allNodes[i].parents.Add(conversation.GetNodeByUID(allNodes[i].parentUIDs[j]));
                }

                if (allNodes[i] is EditableSpeechNode)
                {
                    // Speech options
                    int count = (allNodes[i] as EditableSpeechNode).OptionUIDs.Count;
                    (allNodes[i] as EditableSpeechNode).Options = new List <EditableOptionNode>();
                    for (int j = 0; j < count; j++)
                    {
                        (allNodes[i] as EditableSpeechNode).Options.Add(
                            conversation.GetOptionByUID((allNodes[i] as EditableSpeechNode).OptionUIDs[j]));
                    }

                    // Speech following speech
                    (allNodes[i] as EditableSpeechNode).Speech = conversation.
                                                                 GetSpeechByUID((allNodes[i] as EditableSpeechNode).SpeechUID);
                }
                else if (allNodes[i] is EditableOptionNode)
                {
                    (allNodes[i] as EditableOptionNode).Speech =
                        conversation.GetSpeechByUID((allNodes[i] as EditableOptionNode).SpeechUID);
                }
            }

            // For every node:
            // 1: Create a corresponding UI Node to represent it, and add it to the list
            // 2: Tell any of the nodes children that the node is the childs parent
            for (int i = 0; i < allNodes.Count; i++)
            {
                EditableConversationNode node = allNodes[i];

                if (node is EditableSpeechNode)
                {
                    // 1
                    UISpeechNode uiNode = new UISpeechNode(node,
                                                           new Vector2(node.EditorInfo.xPos, node.EditorInfo.yPos));

                    uiNodes.Add(uiNode);

                    // 2
                    EditableSpeechNode speech = node as EditableSpeechNode;
                    if (speech.Options != null)
                    {
                        for (int j = 0; j < speech.Options.Count; j++)
                        {
                            speech.Options[j].parents.Add(speech);
                        }
                    }

                    if (speech.Speech != null)
                    {
                        speech.Speech.parents.Add(speech);
                    }
                }
                else
                {
                    // 1
                    UIOptionNode uiNode = new UIOptionNode(node,
                                                           new Vector2(node.EditorInfo.xPos, node.EditorInfo.yPos));

                    uiNodes.Add(uiNode);

                    // 2
                    EditableOptionNode option = node as EditableOptionNode;
                    if (option.Speech != null)
                    {
                        option.Speech.parents.Add(option);
                    }
                }
            }

            Recenter();
            Repaint();
#if UNITY_EDITOR
            UnityEditor.SceneManagement.EditorSceneManager.MarkSceneDirty(UnityEditor.SceneManagement.EditorSceneManager.GetActiveScene());
#endif
        }
Esempio n. 14
0
        public Conversation Deserialize()
        {
            // Deserialize an editor-version (containing all info) that
            // we will use to construct the user-facing Conversation data structure.
            EditableConversation ec = this.DeserializeForEditor();

            // Create a conversation.
            Conversation conversation = new Conversation();
            // Create a dictionary to store our created nodes by UID
            Dictionary <int, SpeechNode> dialogues = new Dictionary <int, SpeechNode>();
            Dictionary <int, OptionNode> options   = new Dictionary <int, OptionNode>();

            // Create a Dialogue and Option node for each in the conversation
            // Put them in the dictionary
            for (int i = 0; i < ec.SpeechNodes.Count; i++)
            {
                SpeechNode node = new SpeechNode();
                node.Name = ec.SpeechNodes[i].Name;
                node.Text = ec.SpeechNodes[i].Text;
                node.AutomaticallyAdvance           = ec.SpeechNodes[i].AdvanceDialogueAutomatically;
                node.AutoAdvanceShouldDisplayOption = ec.SpeechNodes[i].AutoAdvanceShouldDisplayOption;
                node.TimeUntilAdvance = ec.SpeechNodes[i].TimeUntilAdvance;
                node.TMPFont          = ec.SpeechNodes[i].TMPFont;
                node.Icon             = ec.SpeechNodes[i].Icon;
                node.Audio            = ec.SpeechNodes[i].Audio;
                node.Volume           = ec.SpeechNodes[i].Volume;
                node.Options          = new List <OptionNode>();
                if (this.GetNodeData(ec.SpeechNodes[i].ID) != null)
                {
                    node.Event = this.GetNodeData(ec.SpeechNodes[i].ID).Event;
                }

                dialogues.Add(ec.SpeechNodes[i].ID, node);
            }
            for (int i = 0; i < ec.Options.Count; i++)
            {
                OptionNode node = new OptionNode();
                node.Text    = ec.Options[i].Text;
                node.TMPFont = ec.Options[i].TMPFont;

                options.Add(ec.Options[i].ID, node);
            }

            // Now that we have every node in the dictionary, reconstruct the tree
            // And also look for the root
            for (int i = 0; i < ec.SpeechNodes.Count; i++)
            {
                // Connect dialogue to options
                for (int j = 0; j < ec.SpeechNodes[i].OptionUIDs.Count; j++)
                {
                    dialogues[ec.SpeechNodes[i].ID].Options.Add(options[ec.SpeechNodes[i].OptionUIDs[j]]);
                }

                // Connect dialogue to following dialogue
                if (ec.SpeechNodes[i].SpeechUID != EditableConversation.INVALID_UID)
                {
                    dialogues[ec.SpeechNodes[i].ID].Dialogue = dialogues[ec.SpeechNodes[i].SpeechUID];
                }

                // Check if root
                if (ec.SpeechNodes[i].EditorInfo.isRoot)
                {
                    conversation.Root = dialogues[ec.SpeechNodes[i].ID];
                }
            }

            for (int i = 0; i < ec.Options.Count; i++)
            {
                // Connect option to following dialogue
                if (dialogues.ContainsKey(ec.Options[i].SpeechUID))
                {
                    options[ec.Options[i].ID].Dialogue = dialogues[ec.Options[i].SpeechUID];
                }
            }

            return(conversation);
        }
Esempio n. 15
0
        //--------------------------------------
        // Serialize and Deserialize
        //--------------------------------------

        public void Serialize(EditableConversation conversation)
        {
            json        = Jsonify(conversation);
            saveVersion = CurrentVersion;
        }
Esempio n. 16
0
        //--------------------------------------
        // Serialize and Deserialize
        //--------------------------------------

        /// <summary>
        /// Save a editable conversation to an NPCConversation during runtime.
        /// </summary>
        /// <param name="conversation">The conversation to save.</param>
        public void RuntimeSave(EditableConversation conversation)
        {
            this.RuntimeEC = conversation;
        }