Пример #1
0
    //Next command
    public void Next()
    {
        for (;;)
        {
            if (programCounter >= commands.Count)
            {
                Debug.LogWarning("programCounter >= commands.Count");
                Debug.LogWarning(programCounter);
                return;
            }
            Debug.Log(programCounter);
            if (commands[programCounter].GetType() == typeof(DialogueAndNarration))
            {
                DialogueAndNarration dialogueAndNarrationCommand = (DialogueAndNarration)commands[programCounter];
                //Debug.Log(dialogueAndNarrationCommand);
                dialogueManager.SetText(((dialogueAndNarrationCommand.Character != null) ? dialogueAndNarrationCommand.Character.Name : "") + "\n\n" + dialogueAndNarrationCommand.Text);
                programCounter++;
                return;
            }
            else if (commands[programCounter].GetType() == typeof(string[]))
            {
                string[] arrayCommand = (string[])commands[programCounter];
                Debug.Log(string.Join(", ", arrayCommand));
                switch (arrayCommand[0])
                {
                case "hide":
                    if (arrayCommand.Length == 2)
                    {
                        characterManager.RemoveCharacter(arrayCommand[1]);
                    }
                    else if (arrayCommand.Length == 3)
                    {
                        if (arrayCommand[2].ToUpper().Equals("FADEOUT"))
                        {
                            characterManager.GetCharacter(arrayCommand[1]).GetComponent <CharacterModel>().FadeOutInit(1f);
                        }
                    }
                    else
                    {
                        if (arrayCommand[2].ToUpper().Equals("FADEOUT"))
                        {
                            characterManager.GetCharacter(arrayCommand[1]).GetComponent <CharacterModel>().FadeOutInit(int.Parse(arrayCommand[3]));
                        }
                    }
                    programCounter++;
                    continue;

                case "jump":
                    if (labels.ContainsKey(arrayCommand[1]))
                    {
                        programCounter = labels[arrayCommand[1]];
                        continue;
                    }
                    else
                    {
                        Debug.LogWarning(string.Format("Unknown label `{0}`", arrayCommand[1]));
                        programCounter++;
                        return;
                    }

                case "play":
                    if (arrayCommand[1].ToUpper().Equals("MUSIC"))
                    {
                        audioManager.ChangeMusic(arrayCommand[2], true);
                    }
                    else if (arrayCommand[1].ToUpper().Equals("SOUND"))
                    {
                        audioManager.PlaySound(arrayCommand[2]);
                    }
                    programCounter++;
                    continue;

                case "scene":
                    if (arrayCommand[2] == null)
                    {
                        backgroundManager.ChangeBackground(arrayCommand[1]);
                    }
                    else
                    {
                        string[] trans = arrayCommand[2].Split(' ');
                        if (trans.Length == 1)
                        {
                            backgroundManager.ChangeBackground(arrayCommand[1], transitions[trans[0]]);
                        }
                        else if (trans.Length == 2)
                        {
                            backgroundManager.ChangeBackground(arrayCommand[1], transitions[trans[0]], int.Parse(trans[1]));
                        }
                        else
                        {
                            Debug.Log(string.Format("Excessive Transition modifiers at line '{0}'."));
                        }
                    }
                    programCounter++;
                    continue;

                case "lighting":
                    float[] newLight;
                    lightingColors.TryGetValue(arrayCommand[1], out newLight);
                    if (newLight != null)
                    {
                        backgroundManager.AmbientLight.GetComponent <Light>().color     = new Color(newLight[0], newLight[1], newLight[2]);
                        backgroundManager.AmbientLight.GetComponent <Light>().intensity = newLight[3];
                    }
                    else
                    {
                        Debug.Log(string.Format("Unknown lighting parameter '{0}'.", arrayCommand[1]));
                    }
                    programCounter++;
                    continue;

                case "show":
                    string[] anims = arrayCommand[1].Split(' ');
                    if (!characterManager.GetCharacter(anims[0]))
                    {
                        characterManager.AddCharacter(anims[0]);
                    }
                    if (anims.Length > 1)
                    {
                        for (int i = 1; i < anims.Length; i++)
                        {
                            characterManager.StartAnimation(anims[i], anims[0]);
                        }
                    }
                    else
                    {
                        characterManager.StartAnimation(anims[1], anims[0]);
                    }
                    programCounter++;
                    continue;

                case "choices":
                    if (!dialogueManager.choiceState && !dialogueManager.choiceBuffer)
                    {
                        int      numChoices  = int.Parse(arrayCommand[1]);
                        string[] choiceTexts = new string[numChoices];
                        string   choiceName  = arrayCommand[2];
                        //Debug.LogError(choiceName);
                        for (int l = 1; l <= numChoices; l++)
                        {
                            //Debug.LogError(2 + l * 3);
                            choiceTexts[l - 1] = arrayCommand[2 + l * 3];
                        }
                        dialogueManager.ChoiceInit(choiceTexts, choiceName);
                        return;
                    }
                    else if (dialogueManager.choiceBuffer)
                    {
                        if (dialogueManager.GetSelectedChoice() < 1 || dialogueManager.GetSelectedChoice() > 5)
                        {
                            Debug.LogError("Invalid choice index returned: " + dialogueManager.GetSelectedChoice() + " Choice aborted");
                            programCounter++;
                            dialogueManager.ResetChoice();
                            return;
                        }
                        else
                        {
                            int choiceIndex = dialogueManager.GetSelectedChoice() * 3;
                            //choiceData.Add("" + choiceIndex/3);
                            if (labels.ContainsKey(arrayCommand[choiceIndex + 1]))
                            {
                                programCounter = labels[arrayCommand[choiceIndex + 1]];
                                dialogueManager.ResetChoice();
                                continue;
                            }
                            else
                            {
                                Debug.LogWarning(string.Format("Unknown label assigned to choice `{0}`", arrayCommand[choiceIndex]));
                                programCounter++;
                                dialogueManager.ResetChoice();
                                return;
                            }
                        }
                    }
                    else
                    {
                        return;
                    }

                case "return":
                    //UnityEditor.EditorApplication.isPlaying = false;
                    programCounter++;
                    return;

                default:
                    Debug.LogWarning(string.Format("Unknown command `{0}`", arrayCommand[0]));
                    programCounter++;
                    continue;
                }
            }
            else
            {
                Debug.LogWarning(string.Format("Unknown command `{0}`", commands[programCounter]));
                programCounter++;
                continue;
            }
        }
    }
Пример #2
0
    //Start is called multiple times: one during initializing the scripts, and one in DialogueManager. Move initialization to a different method.
    //Call New before using this script.
    public bool New()
    {
        audioManager      = GameObject.Find("AudioManager").GetComponent <AudioManager>();
        backgroundManager = GameObject.Find("BackgroundManager").GetComponent <BackgroundManager>();
        characterManager  = GameObject.Find("CharacterManager").GetComponent <CharacterManager>();
        dialogueManager   = GameObject.Find("DialogueManager").GetComponent <DialogueManager>();

        InitTransitions();
        InitLighting();

        Debug.Log("----------Read----------");
        Debug.Log(System.IO.Directory.GetCurrentDirectory());
        //try {
        string[] streamReader = (Resources.Load("Script") as TextAsset).text.Split('\n');
        string   line         = "";

        for (int i = 0; i < streamReader.Length; i++)                //Multi-line logical lines are unsupported; logical lines must begin and end on same line. See: https://www.renpy.org/doc/html/language_basics.html#logical-lines
        {
            line = streamReader[i];
            line = line.Trim();
            Debug.Log("\"" + line + "\"");
            if (String.IsNullOrEmpty(line))
            {
                continue;
            }
            if (line[0] == '#')
            {
                Debug.Log("Comment");
                continue;
            }
            int      index      = IndexOfWhiteSpace(line);
            string   first      = line.Substring(0, index);
            int      startIndex = index = IndexOfNonWhiteSpace(line, index + 1);
            string[] arrayCommand;
            switch (first)
            {
            case "define":
                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                index = IndexOfWhiteSpace(line, index);
                string identifier = line.Substring(startIndex, index - startIndex);
                if (identifier[0] == '"')
                {
                    Debug.LogError(string.Format("Line `{0}` contains identifier `{1}` beginning with quote", line, identifier));
                    return(false);
                }

                startIndex = index = IndexOfNonWhiteSpace(line, index + 1);
                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                index = IndexOfWhiteSpace(line, index);
                string equalsSign = line.Substring(startIndex, index - startIndex);
                if ((equalsSign.Length > 1) || !(equalsSign.Equals("=")))
                {
                    Debug.LogError(string.Format("Line `{0}` does not contain equals sign", line));
                    return(false);
                }

                index = IndexOfNonWhiteSpace(line, index + 1);
                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                if (!line.Substring(index, Math.Min(9, line.Length - index)).Equals("Character"))
                {
                    Debug.LogError(string.Format("Line `{0}` does not contain `Character`", line));
                    return(false);
                }

                index = index + 9;                 //9 is length of "Character"
                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                index = IndexOfNonWhiteSpace(line, index);
                if (line[index] != '(')
                {
                    Debug.LogError(string.Format("Line `{0}` does not contain left parenthesis after Character", line));
                    return(false);
                }

                index++;
                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                index = IndexOfNonWhiteSpace(line, index);
                if (line[index] != '"')
                {
                    Debug.LogError(string.Format("Line `{0}` does not contain quote after left parenthesis", line));
                    return(false);
                }

                string characterName = QuotedSubstring(line, index);
                if (characterName == null)
                {
                    Debug.LogError(string.Format("Line `{0}` does not contain quoted string", line));
                    return(false);
                }

                index += characterName.Length + 2;
                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                index = IndexOfNonWhiteSpace(line, index);
                if (line[index] != ')')
                {
                    Debug.LogError(string.Format("Line `{0}` does not contain right parenthesis after closing quote", line));
                    return(false);
                }

                identifiers.Add(identifier, new Character {
                    Name = characterName
                });
                break;

            case "if":
                startIndex = index = IndexOfNonWhiteSpace(line, index + 1);
                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                index = IndexOfWhiteSpace(line, index);
                if (line[index] != '(')
                {
                    Debug.LogError(string.Format("Line `{0}` does not contain left parenthesis after Character", line));
                    return(false);
                }
                index++;

                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                index = IndexOfNonWhiteSpace(line, index);
                if (line[index] != ')')
                {
                    Debug.LogError(string.Format("Line `{0}` does not contain right parenthesis after conditional", line));
                    return(false);
                }
                //string conditional = QuotedSubstring(line, index);
                Debug.LogError("If statement not supported.");
                break;

            case "hide":
                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                string[] temp = line.Substring(startIndex, line.Length - startIndex).Split(' ');

                if (temp.Length == 1)
                {
                    commands.Add(new string[] { first, temp[0] });
                }
                else if (temp.Length == 3)
                {
                    if (temp[1] == "with")
                    {
                        if (!transitions.ContainsKey(temp[2]))
                        {
                            Debug.LogError(string.Format("Line `{0}` contains unknown transition `{1}`", line, temp[2]));
                            return(false);
                        }
                        commands.Add(new string[] { first, temp[0], temp[2] });
                    }
                    else
                    {
                        Debug.LogError(string.Format("Line `{0}` does not contain `with`", line));
                        return(false);
                    }
                }
                else if (temp.Length == 4)
                {
                    if (temp[1] == "with")
                    {
                        if (!transitions.ContainsKey(temp[2]))
                        {
                            Debug.LogError(string.Format("Line `{0}` contains unknown transition `{1}`", line, temp[2]));
                            return(false);
                        }
                        int parsedInt;
                        int.TryParse(temp[3], out parsedInt);
                        if (parsedInt != 0)
                        {
                            commands.Add(new string[] { first, temp[0], temp[2], temp[3] });
                        }
                        else
                        {
                            Debug.LogError(string.Format("Line `{0}` contains invalid transition time", line));
                        }
                    }
                    else
                    {
                        Debug.LogError(string.Format("Line `{0}` does not contain `with`", line));
                        return(false);
                    }
                }
                else
                {
                    goto InsufficientTokens;
                }
                break;

            case "jump":
                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                commands.Add(new string[] { first, line.Substring(startIndex, line.Length - startIndex) });
                break;

            case "label":
                index = line.IndexOf(':');
                if (index == -1)
                {
                    Debug.LogError(string.Format("Line `{0}` does not contain colon for label", line));
                    return(false);
                }
                else if (index == startIndex)
                {
                    Debug.LogError(string.Format("Line `{0}` contains empty label name", line));
                    return(false);
                }

                labels.Add(line.Substring(startIndex, index - startIndex), commands.Count);
                break;

            case "lighting":
                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                string[] newCommand = new string[] { first, line.Substring(startIndex, line.Length - startIndex) };
                commands.Add(newCommand);
                break;

            case "play":
                //Unlike Ren'Py, no file extension required
                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                index = IndexOfWhiteSpace(line, index);
                string play = line.Substring(startIndex, index - startIndex);
                if ((!play.Equals("music")) && (!play.Equals("sound")))
                {
                    Debug.LogError(string.Format("Line `{0}` does not contain play `music` or `sound`", line));
                    return(false);
                }
                arrayCommand = new string[] { "play", play, "" };

                startIndex = index = IndexOfNonWhiteSpace(line, index + 1);
                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                if (line[index] != '"')
                {
                    Debug.LogError(string.Format("Line `{0}` does not contain quote", line));
                    return(false);
                }
                arrayCommand[2] = QuotedSubstring(line, index);
                if (String.IsNullOrEmpty(arrayCommand[2]))
                {
                    Debug.LogError(string.Format("Line `{0}` does not contain quoted string", line));
                    return(false);
                }
                commands.Add(arrayCommand);
                break;

            case "return":
                commands.Add(new string[] { first });
                break;

            case "scene":
                //Unlike Ren'Py, no image definition required
                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                //commands.Add(new string[] {"scene", line.Substring(startIndex, line.Length - startIndex).Trim()});
                //string sceneName = line.Substring(startIndex, line.Length - startIndex).Trim();
                index = IndexOfWhiteSpace(line, index + 1);
                string sceneName = line.Substring(startIndex, index - startIndex);
                startIndex = index = IndexOfNonWhiteSpace(line, index);
                string transition = null;
                if (index < line.Length)                   //Optional "with"
                {
                    index = IndexOfWhiteSpace(line, index);
                    string with = line.Substring(startIndex, index - startIndex);
                    if (!with.Equals("with"))
                    {
                        Debug.LogError(string.Format("Line `{0}` does not contain `with`", line));
                        return(false);
                    }
                    startIndex = index = IndexOfNonWhiteSpace(line, index);
                    if (index >= line.Length)
                    {
                        goto InsufficientTokens;
                    }
                    transition = line.Substring(startIndex, line.Length - startIndex).Trim();
                    if (!transitions.ContainsKey(transition.Split(' ')[0]))
                    {
                        Debug.LogError(string.Format("Line `{0}` contains unknown transition `{1}`", line, transition));
                        return(false);
                    }
                }
                commands.Add(new string[] { first, sceneName, transition });
                break;

            case "choices":
                List <string> finalCommand = new List <string>();
                //split by choice text quotes
                List <string> splitLine = new List <string>(line.Split('"'));
                //clean up and remove empty strings
                for (int j = 0; j < splitLine.Count; j++)
                {
                    splitLine[j].Trim();
                    if (string.IsNullOrEmpty(splitLine[j]))
                    {
                        splitLine.RemoveAt(j);
                        j--;
                    }
                }
                //Debug.LogError(splitLine[1]);
                //finalCommand.Add(splitLine[1]);
                //split into groups of two elements: target label and choice text
                for (int k = 0; k < splitLine.Count; k += 2)
                {
                    List <string> tempLine = new List <string>(splitLine[k].Split(' '));
                    for (int s = 0; s < tempLine.Count; s++)
                    {
                        tempLine[s].Trim();
                        if (string.IsNullOrEmpty(tempLine[s]))
                        {
                            tempLine.RemoveAt(s);
                            s--;
                        }
                    }
                    finalCommand.AddRange(tempLine);
                    finalCommand.Add(splitLine[k + 1]);
                }
                commands.Add(finalCommand.ToArray());
                break;

            case "show":
                //Unlike Ren'Py, no image definition required
                if (index >= line.Length)
                {
                    goto InsufficientTokens;
                }
                commands.Add(new string[] { first, line.Substring(startIndex, line.Length - startIndex) });
                //Debug.Log(first + line.Substring(startIndex, line.Length - startIndex));
                break;

            case "stop":
                Debug.LogWarning(first + " not supported");
                break;

            default:
                if (!identifiers.ContainsKey(first) && (line[0] != '"'))
                {
                    Debug.LogError(string.Format("Line `{0}` contains unknown identifier `{1}`", line, first));
                    return(false);
                }
                Stack <string> dialogueAndNarration = new Stack <string>(2);
                startIndex = index = (line[0] == '"') ? 0 : index;
                string quotedString = QuotedSubstring(line, index);
                if (quotedString == null)
                {
                    Debug.LogError(string.Format("Line `{0}` does not contain quoted string", line));
                    return(false);
                }
                dialogueAndNarration.Push(quotedString.Replace("\\n", "\n"));
                index += quotedString.Length + 2;
                index  = IndexOfNonWhiteSpace(line, index);
                if (index < line.Length)
                {
                    if (line[index] != '"')
                    {
                        Debug.LogError(string.Format("Line `{0}` contains illegal characters between quoted strings", line));
                        return(false);
                    }
                    quotedString = QuotedSubstring(line, index);
                    if (quotedString == null)
                    {
                        Debug.LogError(string.Format("Line `{0}` does not contain quoted string", line));
                        return(false);
                    }
                    dialogueAndNarration.Push(quotedString.Replace("\\n", "\n"));
                }

                /*for (bool escape = false; index < line.Length; index++) {
                 *  if ((line[index] == '\\') && (line[index + 1] == '"')) { //Escaped quote
                 *      escape = true;
                 *      index += 2;
                 *  }
                 *  if (line[index] == '"') {
                 *      dialogueAndNarration.Push(escape ? line.Substring(startIndex, index - startIndex).Replace("\\\"", "\"") : line.Substring(startIndex, index - startIndex));
                 *      index = line.IndexOf('"', index + 1); //Characters between quoted strings permitted!
                 *      if (index == -1) {
                 *          break;
                 *      }
                 *      startIndex = index = index + 1;
                 *  }
                 * }*/
                if (dialogueAndNarration.Count < 1)
                {
                    goto InsufficientTokens;
                }
                DialogueAndNarration dialogueAndNarrationCommand = new DialogueAndNarration {
                    Text = dialogueAndNarration.Pop()
                };
                if (identifiers.ContainsKey(first))
                {
                    dialogueAndNarrationCommand.Character = identifiers[first];
                }
                else if (dialogueAndNarration.Count >= 1)
                {
                    dialogueAndNarrationCommand.Character = new Character {
                        Name = dialogueAndNarration.Pop()
                    };
                }
                commands.Add(dialogueAndNarrationCommand);
                break;
            }
            continue;
InsufficientTokens:
            Debug.LogError(string.Format("Line `{0}` contains insufficient tokens", line, first));
            return(false);
        }

        /*} catch (Exception exception) {
         *          Debug.Log(exception);
         *  }*/
        Debug.Log("----------Commands----------");
        for (int i = 0; i < commands.Count; i++)
        {
            string commandString = "" + i + ": ";
            if (commands[i].GetType() == typeof(string[]))
            {
                string[] arrayCommand = (string[])commands[i];
                Debug.Log(commandString + string.Join(", ", arrayCommand));
            }
            else
            {
                Debug.Log(commandString + commands[i]);
            }
        }

        /*Debug.Log("----------Images----------");
         * foreach (string key in images.Keys) {
         *      Debug.Log(key + " = " + images[key]);
         * }*/
        Debug.Log("----------Labels----------");
        foreach (string key in labels.Keys)
        {
            Debug.Log(key + " = " + labels[key] + ": " + commands[labels[key]]);
        }
        Debug.Log("----------New completed----------");
        return(true);
    }