Пример #1
0
    private IEnumerator oneLine(string c_name, string content, string sprite_state, string display_spd, string not_found_param,
                                string special_index, string param_1, string param_2, string param_3)
    {
        if (c_name == "")
        {
            c_name = prevChaName;                       //inherit prev char name (assumes it's the same character) if c_name is not provided
        }
        //sprite fixes size of background square
        AudioClip cVoiceClip = null;

        lineDone = false;         //dialogue is shown one char at a time
        if (NAME)
        {
            NAME.text = c_name;
        }


        if (!prevChaName.Equals(c_name)) //if equal, no need to change animator
        {
            cIndex = -1;                 //cCode of the upcoming character
            cIndex = characterLoader.getIndex(c_name);
            //print("cIndex got from loader for " + c_name + ": " + cIndex);

            if (cIndex == -1)             //not found, check for special param instructing which Animator to use
            {
                if (Invasion2000 != null && NAME)
                {
                    NAME.font = Invasion2000;
                }
                int.TryParse(not_found_param, out cIndex);                 //if success, assign animator accordingly
            }
            else
            {
                if (ArcadeClassic != null && NAME)
                {
                    NAME.font = ArcadeClassic;
                }
            }

            if (cIndex == -1)                     //not assigned, no animator
            {
                bgBox.color = new Color(0, 0, 0); //black
            }
            else
            {
                // assign animator
                character.GetComponent <Animator>().runtimeAnimatorController =
                    characterLoader.getAnimatorByIndex(cIndex);
                cVoiceClip        = characterLoader.getVoiceByIndex(cIndex);
                cVoiceSource.clip = cVoiceClip;
                Color c = bgBox.color;
                c           = characterLoader.getColorByIndex(cIndex);
                bgBox.color = new Color(c.r, c.g, c.b);
            }

            prevChaName = c_name;
        }

        int SpriteStateNum;

        if (!int.TryParse(sprite_state, out SpriteStateNum))
        {
            SpriteStateNum = 0;
        }

        //display speed
        float disp_spd;

        if (!float.TryParse(display_spd, out disp_spd))
        {
            disp_spd = 1;                                                    //converts string to int
        }
        //format sentence
        string[]  store;
        ArrayList result = new ArrayList();

        List <(int[], string, string)> tags = GetFormattedText(DIALOGUE, content, result);

        store = result.ToArray(typeof(string)) as string[];
        Canvas.ForceUpdateCanvases();
        DIALOGUE.text = "";

        //character start talking (default talking anim state); assumes part1 is always mouth
        setPartLayerParam(cIndex, character, 1, 2);

        //sets default base state
        setAnimBaseState(cIndex, character, SpriteStateNum);

        int special;

        int.TryParse(special_index, out special);

        /*
         * the params for special events could be int, could be int arrays, so to cover all
         * cases we create variables for all possibilities
         */
        ArrayList PARAM1, PARAM2, PARAM3;

        PARAM1 = new ArrayList(); PARAM2 = new ArrayList(); PARAM3 = new ArrayList();
        if (special != 0)         //if there is special, parse params
        {
            parseDLGspecialParams(PARAM1, PARAM2, PARAM3, param_1, param_2, param_3);
        }
        //end parsing special param, start adding chars

        int wordCount = 1; int[] paramPointer = new int[4]; //paramPointer[2] would be pointer for special #2, pointer tracks curr position in string

        if (special == 3)                                   //SPECIAL 3 disables users from clicking to proceed; will auto proceed after certain seconds
        {
            gameFlow.canMovePointer = false;
            //chains a WaitForSecond with <what should be done afterwards>
            StartCoroutine(Global.Chain(this, Global.WaitForSeconds((int)PARAM1[0]), Global.Do(() =>
            {
                gameFlow.canMovePointer = true;
                gameFlow.incrementPointer();
            })));
        }
        else if (special == 6)
        {
            //SPECIAL 6: incrementPointer() will go to PARAM1[0] instead of the next line
            gameFlow.setSpecialGoToLine((int)PARAM1[0]);
        }


        int    endSentencePartIDefaultBack = 0;
        int    currOpenTagIndex = -1, currEndTagIndex = -1;
        string currOpenTag = "", currEndTag = "";

        int currTagIndex = 0;              //which tag are we adding in the tagsList

        if (tags.Count > currTagIndex + 1) //if has tags at all
        {
            currOpenTagIndex = tags[currTagIndex].Item1[0]; currEndTagIndex = tags[currTagIndex].Item1[2];
            currOpenTag      = tags[currTagIndex].Item2; currEndTag = tags[currTagIndex].Item3;
        }

        //loop through lines of this sentence
        for (int s = 0; s < store.Length; s++)
        {
            for (int n = 0; n < store[s].Length; n++)             //loop through characters of each line
            {
                //tagging is for tags in rich text, not a part of the special effects system
                if (n == currOpenTagIndex)                 //we're at the first letter that needs to be tagged
                {
                    DIALOGUE.text += currOpenTag;
                }
                else if (currOpenTagIndex != -1 && n > currOpenTagIndex && n <= currEndTagIndex)
                //remove previously added temp end tag, the last one won't be removed
                {
                    DIALOGUE.text = DIALOGUE.text.Remove
                                        (DIALOGUE.text.Length - (currEndTag.Length));
                }

                DIALOGUE.text += store[s][n];                 //the actual adding of the char

                //Sound effect play
                if (cVoiceSource.clip && (n % 2 == 0))
                {
                    cVoiceSource.Play();
                }

                if (store[s][n] == ' ')                 //if new word
                {
                    wordCount++;
                }

                if (currOpenTagIndex != -1 && n >= currOpenTagIndex && n <= currEndTagIndex)
                {
                    DIALOGUE.text += currEndTag;                     //add temp ending tag
                }

                if (n == currEndTagIndex)
                {
                    currTagIndex++;                     //move on to next tag
                    if (tags.Count > currTagIndex + 1)  //see if next tag even exists
                    {
                        currOpenTagIndex = tags[currTagIndex].Item1[0]; currEndTagIndex = tags[currTagIndex].Item1[2];
                        currOpenTag      = tags[currTagIndex].Item2; currEndTag = tags[currTagIndex].Item3;
                    }
                    else
                    {
                        currOpenTagIndex = -1; currEndTagIndex = -1;
                        currOpenTag      = ""; currEndTag = "";
                    }
                }

                switch (special)
                {
                /*
                 * SPECIAL mode 1, changing of sprite of the speaking character
                 *  -param 1: indices of char count to change sprite
                 *  -param 2: number for State variable of the character (will assign sprite accordingly)
                 */
                case 1:
                    if (paramPointer[1] < PARAM1.Count &&
                        n == (int)PARAM1[paramPointer[1]])                                 //if current char is char at which a switch should happen
                    {
                        setAnimBaseState(cIndex, character, (int)PARAM2[paramPointer[1]]);
                        if (paramPointer[1] <= PARAM1.Count - 1)
                        {
                            paramPointer[1]++;
                        }
                    }
                    break;

                /*
                 * SPECIAL mode 2, the changing of motion states of the character's body parts (Part1, Part2, etc.)
                 * -param 1: "which" state(s) to be set
                 *		- 1: part I layer
                 *		- 2: part II layer
                 * the same state can appear for multiple times (e.g. 1, 2, 1 will set, for example, part1 twice and part2 once);
                 * NOTE: this needs to match the number of items in param2/3; in other words, even "[1];[1]" is necessary
                 * -param 2: value(s) to set those state(s), integer
                 * -param 3: word count indices at which the state(s) are to be set, at least 1
                 *
                 * e.g. [1,2];[3,5];[2,3] sets part 1 to "3" at word 2, sets part 2 to "5" at word 3
                 *
                 * if part I state change happens at word -1 (should take place last), will change to provided state instead of recovering to default
                 * part I layer state (only valid for this sentence). e.g. [1,1];[3,5];[2,-1] sets part 1 to "3" at word 2, sets part 1 to "5" after
                 * sentence ends
                 */
                case 2:
                    if (paramPointer[2] < PARAM3.Count && (int)PARAM3[paramPointer[2]] == -1)
                    {
                        endSentencePartIDefaultBack = (int)PARAM2[paramPointer[2]];

                        if (paramPointer[2] <= PARAM3.Count - 1)
                        {
                            paramPointer[2]++;
                        }
                    }

                    while (paramPointer[2] < PARAM3.Count &&
                           wordCount == (int)PARAM3[paramPointer[2]])                              //is at the right word and the first char
                    {
                        setPartLayerParam(cIndex, character, (int)PARAM1[paramPointer[2]],
                                          (int)PARAM2[paramPointer[2]]);

                        if (paramPointer[2] <= PARAM3.Count - 1)
                        {
                            paramPointer[2]++;
                        }
                    }
                    break;

                //SPECIAL mode 3 disables users from clicking to proceed, will auto proceed after certain seconds
                //-param 1: seconds to wait
                case 3:
                    //called once above previous to the double for loop
                    break;

                /*
                 * SPECIAL mode 4, character speaking speed change in dialogue
                 * -param 1: indices of char count to change dialogue speed
                 * -param 2: spd(s) to change into
                 */
                case 4:
                    if (paramPointer[4] < PARAM1.Count &&
                        n == (int)PARAM1[paramPointer[4]])
                    {
                        disp_spd = (float)PARAM2[paramPointer[4]];
                        if (paramPointer[4] <= PARAM1.Count - 1)
                        {
                            paramPointer[4]++;
                        }
                    }
                    break;

                /*
                 * SPECIAL mode 5, opens up option prompt for user to choose after character finishes talking
                 * -param 1: texts of choices, separated by comma
                 * -param 2: lines to point to after selecting those choices
                 */
                case 5:
                    //happens after the entire dialogue is displayed, so isn't called repetitively here
                    break;

                /*
                 * SPECIAL mode 6, directs pointer to provided line other than increment by 1
                 * -param 1: line to point to
                 */
                case 6:
                    //needs only happen once, is invoked up above
                    break;

                default:
                    break;
                }

                if (!skipping)
                {
                    if (store[s][n].Equals(','))
                    {
                        //for break in between (half) sentences, give a longer wait time
                        yield return(new WaitForSeconds(0.2f));
                    }
                    else if (store[s][n].Equals('.'))
                    {
                        yield return(new WaitForSeconds(0.4f));
                    }
                    else
                    {
                        yield return(new WaitForSeconds(-1.0333f * disp_spd + 1.07f));
                    }
                }
            }
            if (!(s == (store.Length - 1)))
            {
                DIALOGUE.text = "";                 //reset and print the second section
            }
        }

        if (special == 5)
        {        //only happens after entirety of text is up
            gameFlow.canMovePointer = false;
            int[]    lines    = new int[PARAM2.Count];
            string[] messages = new string[PARAM1.Count];
            for (int i = 0; i < PARAM2.Count; i++)
            {
                lines[i]    = (int)PARAM2[i];
                messages[i] = (string)PARAM1[i];
            }

            dlgOptions.showOptions(PARAM1.Count, messages, lines);
        }

        //character stop talking (default talking anim state)
        setPartLayerParam(cIndex, character, 1, endSentencePartIDefaultBack);

        lineDone = true;
        skipping = false;
    }