Example #1
0
        public async Task SayAsync(string text, PointF?textPosition = null, PointF?portraitPosition = null)
        {
            if (_state.Cutscene.IsSkipping)
            {
                if (_outfit != null)
                {
                    await setAnimation(_outfit.Outfit[AGSOutfit.Idle]);
                }
                return;
            }
            if (_outfit != null)
            {
                await setAnimation(_outfit.Outfit[AGSOutfit.Speak]);
            }
            await Task.Delay(1);

            var speech = await _speechCache.GetSpeechLineAsync(_characterName, text);

            text = speech.Text;

            ISayLocation location     = getLocation(text);
            var          textLocation = textPosition ?? location.TextLocation;

            portraitPosition = portraitPosition ?? location.PortraitLocation;
            IObject portrait = showPortrait(portraitPosition);
            ILabel  label    = _factory.UI.GetLabel($"Say: {text}", text, SpeechConfig.LabelSize.Width,
                                                    SpeechConfig.LabelSize.Height, textLocation.X, textLocation.Y,
                                                    config: SpeechConfig.TextConfig, addToUi: false);

            label.RenderLayer = AGSLayers.Speech;
            label.Border      = SpeechConfig.Border;
            label.Tint        = SpeechConfig.BackgroundColor;
            TaskCompletionSource <object> externalSkipToken = new TaskCompletionSource <object> (null);
            BeforeSayEventArgs            args = new BeforeSayEventArgs(label, () => externalSkipToken.TrySetResult(null));

            OnBeforeSay.Invoke(args);
            label = args.Label;
            _state.UI.Add(label);
            ISound sound = null;

            if (speech.AudioClip != null)
            {
                _emitter.AudioClip = speech.AudioClip;
                sound = _emitter.Play();
            }

            await waitForText(text, externalSkipToken.Task, sound);

            _state.UI.Remove(label);
            label.Dispose();
            if (portrait != null)
            {
                portrait.Visible = false;
            }

            if (_outfit != null)
            {
                await setAnimation(_outfit.Outfit[AGSOutfit.Idle]);
            }
        }
Example #2
0
        public async Task SayAsync(string text, PointF?textPosition = null, PointF?portraitPosition = null)
        {
            var  outfit            = _outfit;
            var  walkComponent     = _walkComponent;
            var  previousAnimation = _faceDirection.CurrentDirectionalAnimation;
            var  speakAnimation    = outfit == null ? null : outfit.Outfit[AGSOutfit.Speak];
            bool wasWalking        = false;

            if (walkComponent?.IsWalking ?? false)
            {
                if (outfit?.Outfit[AGSOutfit.SpeakAndWalk] == null)
                {
                    await walkComponent.StopWalkingAsync();

                    previousAnimation = _outfit.Outfit[AGSOutfit.Idle];
                }
                else
                {
                    wasWalking     = true;
                    speakAnimation = outfit.Outfit[AGSOutfit.SpeakAndWalk];
                }
            }
            if (_state.Cutscene.IsSkipping)
            {
                if (outfit != null)
                {
                    await setAnimation(previousAnimation);
                }
                return;
            }

            if (speakAnimation != null)
            {
                await setAnimation(speakAnimation);
            }
            await Task.Delay(1);

            var speech = await _speechCache.GetSpeechLineAsync(_characterName, text);

            text = speech.Text;

            ISayLocation location     = getLocation(text);
            var          textLocation = textPosition ?? location.TextLocation;

            portraitPosition = portraitPosition ?? location.PortraitLocation;
            IObject portrait = showPortrait(portraitPosition);
            ILabel  label    = _factory.UI.GetLabel($"Say: {text} {Guid.NewGuid().ToString()}", text, SpeechConfig.LabelSize.Width,
                                                    SpeechConfig.LabelSize.Height, textLocation.X, textLocation.Y,
                                                    config: SpeechConfig.TextConfig, addToUi: false);

            label.RenderLayer = AGSLayers.Speech;
            label.Border      = SpeechConfig.Border;
            label.Tint        = SpeechConfig.BackgroundColor;
            TaskCompletionSource <object> externalSkipToken = new TaskCompletionSource <object> (null);
            BeforeSayEventArgs            args = new BeforeSayEventArgs(label, () => externalSkipToken.TrySetResult(null));

            OnBeforeSay.Invoke(args);
            label = args.Label;
            _state.UI.Add(label);
            ISound sound = null;

            if (speech.AudioClip != null)
            {
                _emitter.AudioClip = speech.AudioClip;
                sound = _emitter.Play();
            }

            await waitForText(text, externalSkipToken.Task, sound);

            _state.UI.Remove(label);
            label.Dispose();
            if (portrait != null)
            {
                portrait.Visible = false;
            }

            if (outfit != null)
            {
                if (wasWalking && !walkComponent.IsWalking)
                {
                    previousAnimation = outfit.Outfit[AGSOutfit.Idle];                                         //If we were in the middle of a walk but walk was completed before speech, then instead of revert to the previous animation (walk) we need to go to idle.
                }
                await setAnimation(previousAnimation);
            }
        }