Beispiel #1
0
    public void NextNode(int i)
    {
        if (tree == null)
        {
            return;
        }

        OCRootNode rootNode = tree.rootNodes[tree.currentRoot];
        OCNode     node     = rootNode.GetNode(currentNode);

        // Force output 0 on smalltalk nodes, just in case
        if (node.speak != null && node.speak.smalltalk)
        {
            i = 0;
        }

        // Check for range
        if (i < node.connectedTo.Length)
        {
            currentNode = node.connectedTo[i];
            DisplayNode();
        }
        else
        {
            Debug.LogError("OCManager | Node index '" + i + "' out of range (0-" + (node.connectedTo.Length - 1) + ")");
            EndConversation();
        }
    }
Beispiel #2
0
    public void SelectOption(int i)
    {
        eventHandler.OnSelectOption(i);

        OCNode node = tree.rootNodes[tree.currentRoot].GetNode(currentNode);

        node.speak.index = i;

        StartCoroutine(PlayLineAudio(node));
    }
Beispiel #3
0
    public OCNode AddNode()
    {
        List <OCNode> tmpNodes = new List <OCNode> (nodes);
        OCNode        newNode  = new OCNode();

        newNode.SetType(OCNodeType.Speak, true);

        tmpNodes.Add(newNode);

        nodes = tmpNodes.ToArray();

        return(newNode);
    }
Beispiel #4
0
    public void NextNode()
    {
        OCRootNode rootNode = tree.rootNodes[tree.currentRoot];
        OCNode     node     = rootNode.GetNode(currentNode);

        if (node.speak != null && node.speak.choice)
        {
            NextNode(node.speak.index);
        }
        else
        {
            NextNode(0);
        }
    }
Beispiel #5
0
    private IEnumerator PlayLineAudio(OCNode node)
    {
        // Make sure no other conversation audio is playing
        if (currentAudioSource)
        {
            currentAudioSource.Stop();
            currentAudioSource = null;
        }

        // With audio
        if (speaker.gameObject.audio && node.speak.lines[node.speak.index].audio)
        {
            speaker.gameObject.audio.clip = node.speak.lines[node.speak.index].audio;
            speaker.gameObject.audio.loop = false;
            speaker.gameObject.audio.Play();
            currentAudioSource = speaker.gameObject.audio;

            // Wait for speech duration
            float duration = speaker.gameObject.audio.clip.length;
            yield return(new WaitForSeconds(duration));

            // If we already continued manually, or the conversation has ended, abort
            if (node.id == currentNode && tree != null)
            {
                yield return(new WaitForSeconds(0.5f));

                NextNode(node.speak.index);
            }

            // Without audio
        }
        else
        {
            // For smalltalk, estimate the duration of the sentence
            if (node.speak.smalltalk)
            {
                float words          = node.speak.lines[node.speak.index].text.Split(" "[0]).Length;
                float wordsPerMinute = 130;
                yield return(new WaitForSeconds((words / wordsPerMinute) * 60f));

                NextNode();
            }
            else
            {
                yield return(null);
            }
        }
    }
Beispiel #6
0
    public void OnGUI()
    {
        placedInputs.Clear();

        title = "Tree Editor";

        distance.x = 220;
        distance.y = 100;

        List <string>     tmpStr   = new List <string> ();
        List <OCRootNode> tmpRoot  = new List <OCRootNode> ();
        OCRootNode        thisRoot = null;
        OCRootNode        thatRoot = null;

        if (!target)
        {
            EditorGUI.LabelField(new Rect(position.width / 2 - 42, position.height / 2 - 10, 84, 20), "No target tree!", EditorStyles.boldLabel);
            return;
        }

        if (target.rootNodes.Length < 1)
        {
            target.AddRootNode();
        }

        if (currentRoot > target.rootNodes.Length - 1)
        {
            currentRoot = target.rootNodes.Length - 1;
        }

        // Inspector
        Rect inspectorRect      = new Rect(position.width - 300, 0, 300, position.height);
        Rect innerInspectorRect = new Rect(inspectorRect.x + 10, inspectorRect.y + 10, inspectorRect.width - 20, inspectorRect.height - 20);

        GUILayout.BeginArea(innerInspectorRect);

        int i;

        GUILayout.Label("Tree (" + target.gameObject.name + ")", EditorStyles.largeLabel);
        GUILayout.Box("", GUILayout.Height(1), GUILayout.Width(270));

        // ^ Speaker names
        if (target.speakers.Length < 1)
        {
            tmpStr = new List <string> (target.speakers);
            tmpStr.Add("Speaker");
            target.speakers = tmpStr.ToArray();
        }

        GUILayout.Label("Speaker names", EditorStyles.boldLabel);
        for (i = 0; i < target.speakers.Length; i++)
        {
            GUILayout.BeginHorizontal();

            GUI.backgroundColor = speakerColors[i];
            target.speakers[i]  = GUILayout.TextField(target.speakers[i]);
            GUI.backgroundColor = Color.white;

            GUI.color = Color.red;
            if (target.speakers.Length > 1 && GUILayout.Button("x", GUILayout.Height(16), GUILayout.Width(32)))
            {
                tmpStr = new List <string> (target.speakers);
                tmpStr.RemoveAt(i);
                target.speakers = tmpStr.ToArray();
                return;
            }
            GUI.color = Color.white;

            GUILayout.EndHorizontal();
        }

        GUI.color = Color.green;
        if (target.speakers.Length < 10 && GUILayout.Button("+", GUILayout.Height(16), GUILayout.Width(32)))
        {
            tmpStr = new List <string> (target.speakers);
            tmpStr.Add("Speaker");
            target.speakers = tmpStr.ToArray();
        }
        GUI.color = Color.white;

        GUILayout.Space(20);

        GUILayout.Label("Root", EditorStyles.largeLabel);
        GUILayout.Box("", GUILayout.Height(1), GUILayout.Width(270));

        // ^ Tags
        string[] tags      = target.rootNodes[currentRoot].tags;
        string   tagString = "";

        for (i = 0; i < tags.Length; i++)
        {
            tagString += tags[i];

            if (i < tags.Length - 1)
            {
                tagString += ",";
            }
        }

        GUILayout.Label("Tags", EditorStyles.boldLabel);
        tagString = GUILayout.TextField(tagString);

        target.rootNodes[currentRoot].tags = tagString.Split(","[0]);

        GUILayout.Space(20);

        // ^ Node
        GUILayout.Label("Node", EditorStyles.largeLabel);
        GUILayout.Box("", GUILayout.Height(1), GUILayout.Width(270));

        inspectorScrollPosition = GUILayout.BeginScrollView(inspectorScrollPosition);

        if (node != null)
        {
            DrawInspector();
        }

        GUILayout.EndScrollView();

        GUILayout.EndArea();

        scrollRect = new Rect(0, 0, position.width - inspectorRect.width, position.height);

        GUI.Box(scrollRect, "");

        // Tree editor
        scrollPosition = GUI.BeginScrollView(scrollRect, scrollPosition, innerScrollRect);

        Vector2 center = scrollRect.center;
        float   right  = center.x - ((target.rootNodes.Length * 1.0f) / 2f) * 32f;

        // ^ Root navigation
        if (currentRoot > 0 && GUI.Button(new Rect(right + (currentRoot - 1) * 32 - 16, 8, 32, 16), "<"))
        {
            tmpRoot  = new List <OCRootNode> (target.rootNodes);
            thisRoot = tmpRoot [currentRoot];
            thatRoot = tmpRoot [currentRoot - 1];
            tmpRoot [currentRoot]     = thatRoot;
            tmpRoot [currentRoot - 1] = thisRoot;
            target.rootNodes          = tmpRoot.ToArray();
            currentRoot--;
        }

        GUI.color = Color.red;
        if (GUI.Button(new Rect(right + currentRoot * 32 - 16, 8, 32, 16), "x"))
        {
            target.RemoveRootNode(currentRoot);
            return;
        }
        GUI.color = Color.white;

        if (currentRoot < target.rootNodes.Length - 1 && GUI.Button(new Rect(right + (currentRoot + 1) * 32 - 16, 8, 32, 16), ">"))
        {
            tmpRoot  = new List <OCRootNode> (target.rootNodes);
            thisRoot = tmpRoot [currentRoot];
            thatRoot = tmpRoot [currentRoot + 1];
            tmpRoot [currentRoot]     = thatRoot;
            tmpRoot [currentRoot + 1] = thisRoot;
            target.rootNodes          = tmpRoot.ToArray();
            currentRoot++;
        }

        // ^ Root display
        for (i = 0; i < target.rootNodes.Length; i++)
        {
            if (i == currentRoot)
            {
                GUI.color = Color.white;
            }
            else
            {
                GUI.color = Color.grey;
            }

            if (GUI.Button(new Rect(right + i * 32 - 16, 32, 32, 16), i.ToString()))
            {
                currentRoot            = i;
                innerScrollRect.width  = scrollRect.width;
                innerScrollRect.height = scrollRect.height;
                innerScrollRect.x      = 0;
                innerScrollRect.y      = 0;
            }

            GUI.color = Color.white;
        }

        // ^ Add root node
        GUI.color = Color.green;
        if (GUI.Button(new Rect(right + i * 32 - 16, 32, 32, 16), "+"))
        {
            target.AddRootNode();
        }
        GUI.color = Color.white;

        // ^ Node display
        GUI.color = Color.green;
        if (GUI.Button(new Rect(right + currentRoot * 32 - 12, 56, 24, 12), "+"))
        {
            OCNode newNode   = target.rootNodes [currentRoot].AddNode();
            OCNode firstNode = target.rootNodes [currentRoot].GetFirstNode();

            if (firstNode.connectedTo [i] > 0)
            {
                newNode.connectedTo [0] = firstNode.connectedTo [i];
            }

            firstNode.connectedTo [i] = newNode.id;

            node = newNode;
        }

        GUI.color = Color.white;
        if (target.rootNodes[currentRoot].nodes.Length < 1)
        {
            target.rootNodes[currentRoot].AddFirstNode();
        }

        DrawLine(new Vector2(right + currentRoot * 32, 48), new Vector2(center.x, 96));
        DrawNode(target.rootNodes[currentRoot].GetNode(target.rootNodes[currentRoot].firstNode), center.x, 96);

        GUI.EndScrollView();

        if (Event.current.type == EventType.MouseDown)
        {
            OCNode cNode = target.rootNodes [currentRoot].GetNode(connectingNode);

            if (cNode != null)
            {
                cNode.connectedTo[connectingOutput] = 0;
            }

            connectingNode   = 0;
            connectingOutput = 0;
        }

        if (connectingNode > 0)
        {
            Repaint();
        }

        if (innerScrollRect.width < scrollRect.width)
        {
            innerScrollRect.width = scrollRect.width;
        }

        if (innerScrollRect.height < scrollRect.height)
        {
            innerScrollRect.height = scrollRect.height;
        }

        if (GUI.changed)
        {
            target.CleanUp();
        }
    }
Beispiel #7
0
    private void DrawNode(OCNode n, float x, float y)
    {
        string nodeText  = "";
        Color  nodeColor = Color.white;

        if (x - 70 < 0)
        {
            innerScrollRect.xMin = x - 70;
        }
        else if (x + 70 > innerScrollRect.xMax)
        {
            innerScrollRect.xMax = x + 70;
        }

        if (y + 60 > innerScrollRect.yMax)
        {
            innerScrollRect.yMax = y + 60;
        }

        switch (n.type)
        {
        case OCNodeType.Speak:
            nodeColor = speakerColors [n.speak.speaker];

            if (n.speak.lines.Length == 1)
            {
                nodeText = n.speak.lines[0].text;

                if (nodeText.Length < 1)
                {
                    nodeText = "...";
                }
                else if (nodeText.Length > 16)
                {
                    nodeText = nodeText.Substring(0, 13) + "...";
                }
            }
            else
            {
                if (n.speak.smalltalk)
                {
                    nodeText = "(smalltalk)";
                }
                else
                {
                    nodeText = "(choice)";
                }
            }

            break;

        case OCNodeType.Event:
            nodeText = "(event)";

            break;

        case OCNodeType.End:
            nodeText = "(end)";

            break;

        case OCNodeType.Jump:
            nodeText = "(jump)";

            break;

        case OCNodeType.SetQuest:
            nodeText = "(set quest)";

            break;

        case OCNodeType.GetQuest:
            nodeText = "(get quest)";

            break;

        case OCNodeType.SetFlag:
            nodeText = "(set flag)";

            break;

        case OCNodeType.GetFlag:
            nodeText = "(get flag)";

            break;
        }

        GUI.backgroundColor = nodeColor;
        if (GUI.Button(new Rect(x - 50, y, 100, 40), nodeText))
        {
            if (connectingNode > 0)
            {
                OCNode fromNode = target.rootNodes [currentRoot].GetNode(connectingNode);

                if (fromNode != null)
                {
                    fromNode.connectedTo[connectingOutput] = n.id;
                    connectingNode   = 0;
                    connectingOutput = 0;
                    return;
                }
            }

            node = n;
        }
        GUI.backgroundColor = Color.white;

        GUI.color = Color.red;
        if (GUI.Button(new Rect(x + 30, y - 6, 24, 12), "x"))
        {
            n.id = 0;
            return;
        }
        GUI.color = Color.white;

        // Input
        Rect inputRect = new Rect(x - 6, y - 6, 12, 12);

        placedInputs.Add(n.id, inputRect);

        if (GUI.Button(inputRect, ""))
        {
        }

        for (int i = 0; i < n.connectedTo.Length; i++)
        {
            int   nextId   = n.connectedTo[i];
            float xPos     = x;
            float nodeXPos = xPos;

            if (n.connectedTo.Length > 1)
            {
                float span    = distance.x;
                float segment = span / (n.connectedTo.Length - 1);
                xPos     = x - span / 2 + i * segment;
                nodeXPos = x - 100 / 2 + i * (100 / (n.connectedTo.Length - 1));
            }

            GUI.color = Color.green;
            if (GUI.Button(new Rect(nodeXPos - 12, y + 50, 24, 12), "+"))
            {
                OCNode newNode = target.rootNodes [currentRoot].AddNode();

                if (n.connectedTo [i] > 0)
                {
                    newNode.connectedTo [0] = n.connectedTo [i];
                }

                n.connectedTo [i] = newNode.id;

                node = newNode;
            }
            GUI.color = Color.white;

            Rect outputRect;

            if (n.type == OCNodeType.GetFlag || n.type == OCNodeType.GetQuest)
            {
                string bString = i == 0 ? "false" : "true";
                outputRect = new Rect(nodeXPos - 24, y + 32, 48, 14);

                if (GUI.Button(outputRect, bString))
                {
                    connectingNode   = n.id;
                    connectingOutput = i;
                }
            }
            else
            {
                outputRect = new Rect(nodeXPos - 6, y + 34, 12, 12);

                if (GUI.Button(outputRect, ""))
                {
                    connectingNode   = n.id;
                    connectingOutput = i;
                }
            }

            if (nextId > 0)
            {
                OCNode nextNode = target.rootNodes[currentRoot].GetNode(nextId);

                if (nextNode == null)
                {
                    n.connectedTo[i] = 0;
                    return;
                }

                if (placedInputs.ContainsKey(nextId))
                {
                    DrawLine(new Vector2(nodeXPos, y + 40), placedInputs[nextId].center);
                }
                else
                {
                    DrawLine(new Vector2(nodeXPos, y + 40), new Vector2(xPos, y + distance.y));
                    DrawNode(nextNode, xPos, y + distance.y);
                }
            }

            if (connectingNode == n.id && connectingOutput == i)
            {
                DrawLine(outputRect.center, Event.current.mousePosition);
            }
        }
    }
Beispiel #8
0
    public void DisplayNode()
    {
        OCNode node     = tree.rootNodes[tree.currentRoot].GetNode(currentNode);
        bool   wait     = false;
        bool   exit     = false;
        int    nextNode = 0;

        switch (node.type)
        {
        case OCNodeType.Jump:
            tree.currentRoot = node.jump.rootNode;
            nextNode         = tree.rootNodes[tree.currentRoot].firstNode;
            break;

        case OCNodeType.Speak:
            speaker = speakers [node.speak.speaker];
            wait    = true;
            break;

        case OCNodeType.Event:
            // Send the event message to the target object
            if (node.evt.obj != null && node.evt.eventToTarget)
            {
                if (!string.IsNullOrEmpty(node.evt.argument))
                {
                    node.evt.obj.SendMessage(node.evt.message, node.evt.argument, SendMessageOptions.DontRequireReceiver);
                }
                else
                {
                    node.evt.obj.SendMessage(node.evt.message, tree, SendMessageOptions.DontRequireReceiver);
                }

                // Send the message to the event handler
            }
            else if (eventHandler)
            {
                if (!string.IsNullOrEmpty(node.evt.argument))
                {
                    eventHandler.Event(node.evt.message, node.evt.argument);
                }
                else if (node.evt.obj != null)
                {
                    eventHandler.Event(node.evt.message, node.evt.obj);
                }
                else
                {
                    eventHandler.Event(node.evt.message, tree);
                }
            }

            nextNode = node.connectedTo[0];
            break;

        case OCNodeType.SetFlag:
            flags.Set(node.setFlag.flag, node.setFlag.b);

            nextNode = node.connectedTo[0];
            break;

        case OCNodeType.GetFlag:
            if (flags.Get(node.getFlag.flag))
            {
                nextNode = node.connectedTo[1];
            }
            else
            {
                nextNode = node.connectedTo[0];
            }
            break;

        case OCNodeType.SetQuest:
            OCQuests.Quest quest = quests.GetUserQuest(node.setQuest.quest);

            if (quest == null)
            {
                quest = quests.GetPotentialQuest(node.setQuest.quest);

                if (quest != null)
                {
                    quests.AddUserQuest(quest);
                }
            }

            if (quest != null)
            {
                OCQuests.Objective objective = quest.objectives [node.setQuest.objective];
                objective.completed = node.setQuest.completed;
            }
            else
            {
                Debug.LogWarning("OCManager | Quest is null!");
            }

            nextNode = node.connectedTo[0];
            break;

        case OCNodeType.GetQuest:
            quest = quests.GetUserQuest(node.getQuest.quest);

            if ((!node.getQuest.completed && quest != null) || (quest != null && node.getQuest.objective < quest.objectives.Length && quest.objectives[node.getQuest.objective].completed))
            {
                nextNode = node.connectedTo[1];
            }
            else
            {
                nextNode = node.connectedTo[0];
            }
            break;

        case OCNodeType.End:
            tree.currentRoot = node.end.rootNode;
            exit             = true;
            break;
        }

        // Meta nodes
        if (exit)
        {
            EndConversation();
        }
        else if (!wait)
        {
            currentNode = nextNode;
            DisplayNode();

            // OCSpeak nodes
        }
        else if (node != null && node.speak != null)
        {
            eventHandler.OnSetSpeaker(speaker, node.speak);

            if (!node.speak.choice)
            {
                StartCoroutine(PlayLineAudio(node));

                if (node.speak.smalltalk)
                {
                    if (node.speak.index < node.speak.lines.Length - 1)
                    {
                        node.speak.index++;
                    }
                }
            }
        }
    }
Beispiel #9
0
    public void AddFirstNode()
    {
        OCNode newNode = AddNode();

        firstNode = newNode.id;
    }