Exemple #1
0
        public void OnChoiceButtonClick(int idx)
        {
            AbortWaitAndAdvance();

            TryCallScript(CurrentFrameObject?.Scripts?.OnChoice);

            string choice = null;

            if (CurrentFrameObject is ChoiceFrame)
            {
                var cf = (ChoiceFrame)CurrentFrameObject;

                ChoiceNode choiceNode = cf.Choices[idx];
                if (choiceNode.SkillCheck != null)
                {
                    choice = choiceNode.SkillCheck.EvaluateSkillCheck();
                }
                else if (choiceNode.NextConditional != null)
                {
                    choice = choiceNode.EvaluateConditional();

                    if (choice == null)
                    {
                        choice = choiceNode.Next;
                    }
                }
                else
                {
                    choice = choiceNode.Next;
                }

                //exec microscripts
                if (choiceNode.NextMicroscript != null)
                {
                    choiceNode.EvaluateMicroscript();
                }
                if (GameParams.DialogueAlwaysExecuteFrameMicroscript && cf.NextMicroscript != null)
                {
                    cf.EvaluateMicroscript();
                }

                //handle trace
                Trace.Nodes.Add(new DialogueTraceNode()
                {
                    Choice  = idx,
                    Ignored = CurrentFrameObject.Options.TraceIncludeChoices ? choiceNode.TraceIgnore : !choiceNode.TraceShow,
                    Path    = $"{CurrentSceneName}.{CurrentFrameName}",
                    Speaker = choiceNode.TraceSpeaker == null ? GetDefaultTraceSpeaker(CurrentFrameObject) : Sub.Macro(choiceNode.TraceSpeaker),
                    Text    = choiceNode.TraceText == null ? choiceNode.Text : Sub.Macro(choiceNode.TraceText)
                });
            }
            else
            {
                if (CurrentFrameObject.NextConditional != null && CurrentFrameObject.NextConditional.Length > 0)
                {
                    choice = CurrentFrameObject.EvaluateConditional();
                }
                else
                {
                    choice = CurrentFrameObject.Next;
                }

                if (CurrentFrameObject.NextMicroscript != null)
                {
                    CurrentFrameObject.EvaluateMicroscript();
                }

                //handle trace
                Trace.Nodes.Add(new DialogueTraceNode()
                {
                    Choice  = -1,
                    Ignored = !CurrentFrameObject.Options.TraceIncludeNextText,
                    Path    = $"{CurrentSceneName}.{CurrentFrameName}",
                    Speaker = CurrentFrameObject.Options.TraceNextTextSpeaker == null ?  GetDefaultTraceSpeaker(CurrentFrameObject) : Sub.Macro(CurrentFrameObject.Options.TraceNextTextSpeaker),
                    Text    = CurrentFrameObject.Options.TraceNextTextText == null ? CurrentFrameObject.NextText : Sub.Macro(CurrentFrameObject.Options.TraceNextTextText)
                });
            }



            //Debug.Log(choice);

            GotoNext(choice);
        }
Exemple #2
0
        private void PresentNewFrame(Frame f)
        {
            //special handling for blank frames
            if (f is BlankFrame)
            {
                CurrentFrameObject = f;
                OnChoiceButtonClick(0);
                return;
            }

            //present music
            if (!string.IsNullOrEmpty(f.Music))
            {
                if (!(AudioPlayer.Instance.IsMusicSetToPlay(MusicSlot.Cinematic) && AudioPlayer.Instance.GetMusicName(MusicSlot.Cinematic) == f.Music))
                {
                    AudioPlayer.Instance.SetMusic(f.Music, MusicSlot.Cinematic, 1.0f, true, false);
                    AudioPlayer.Instance.StartMusic(MusicSlot.Cinematic);
                }
            }
            else
            {
                AudioPlayer.Instance.ClearMusic(MusicSlot.Cinematic);
            }

            //present audio
            if (VoiceAudioSource.isPlaying)
            {
                VoiceAudioSource.Stop();
            }
            var voiceClip = CCBase.GetModule <AudioModule>().GetSound($"{CurrentSceneName}/{CurrentFrameName}", SoundType.Voice); //GetModule<T> is now preferred

            if (voiceClip != null)
            {
                VoiceAudioSource.clip = voiceClip;
                VoiceAudioSource.Play();
            }

            //present background
            BackgroundImage.sprite = null;
            BackgroundImage.gameObject.SetActive(false);
            if (!string.IsNullOrEmpty(f.Background))
            {
                var sprite = CoreUtils.LoadResource <Sprite>("Dialogue/bg/" + f.Background);
                if (sprite != null)
                {
                    BackgroundImage.sprite = sprite;
                    BackgroundImage.gameObject.SetActive(true);
                }
                else
                {
                    CDebug.LogEx($"Couldn't find face sprite Dialogue/bg/{f.Background}", LogLevel.Verbose, this);
                }
            }

            //present image
            FaceImage.sprite = null;
            FaceImage.gameObject.SetActive(false);
            if (!string.IsNullOrEmpty(f.Image))
            {
                //attempt to present image
                var sprite = CoreUtils.LoadResource <Sprite>("Dialogue/char/" + f.Image);
                if (sprite != null)
                {
                    //Debug.Log(sprite.name);

                    float spriteX = sprite.texture.width * (100f / sprite.pixelsPerUnit);
                    float spriteY = sprite.texture.height * (100f / sprite.pixelsPerUnit);

                    switch (f.ImagePosition)
                    {
                    case FrameImagePosition.Fill:
                        FaceImage.rectTransform.localPosition = Vector3.zero;
                        FaceImage.rectTransform.sizeDelta     = FaceImage.canvas.pixelRect.size;
                        break;

                    case FrameImagePosition.Character:
                        FaceImage.rectTransform.localPosition = new Vector3(0, 100, 0);
                        FaceImage.rectTransform.sizeDelta     = new Vector2(spriteX, spriteY);
                        break;

                    default:
                        //center, no scale
                        FaceImage.rectTransform.localPosition = Vector3.zero;
                        FaceImage.rectTransform.sizeDelta     = new Vector2(spriteX, spriteY);
                        break;
                    }

                    FaceImage.sprite = sprite;
                    FaceImage.gameObject.SetActive(true);
                }
                else
                {
                    CDebug.LogEx($"Couldn't find face sprite Dialogue/char/{f.Image}", LogLevel.Verbose, this);
                }
            }

            //present camera
            try
            {
                if (!string.IsNullOrEmpty(f.CameraDirection) && !f.CameraDirection.StartsWith("Default", StringComparison.OrdinalIgnoreCase))
                {
                    if (CameraController == null)
                    {
                        var cameraGo = Instantiate(CameraPrefab, CoreUtils.GetWorldRoot());
                        CameraController = cameraGo.GetComponent <DialogueCameraController>();
                    }

                    CameraController.Activate(f.CameraDirection);
                }
                else
                {
                    CameraController.Ref()?.Deactivate();
                }
            }
            catch (Exception e)
            {
                Debug.LogError($"Failed to point camera ({f.CameraDirection})");
                Debug.LogException(e);
            }

            //present text
            TextTitle.text = Sub.Macro(f.NameText);
            TextMain.text  = Sub.Macro(f.Text);

            //clear buttons
            foreach (Transform t in ScrollChoiceContent)
            {
                Destroy(t.gameObject);
            }
            ScrollChoiceContent.DetachChildren();

            //present buttons
            if (f is ChoiceFrame)
            {
                ScrollChoice.gameObject.SetActive(true);
                ButtonContinue.gameObject.SetActive(false);

                ChoiceFrame cf = (ChoiceFrame)f;
                for (int i = 0; i < cf.Choices.Length; i++)
                {
                    ChoiceNode cn = cf.Choices[i];

                    string prependText = string.Empty;
                    bool   showChoice  = true;
                    bool   lockChoice  = false;

                    if (cn.ShowCondition != null)
                    {
                        showChoice = cn.ShowCondition.Evaluate();
                    }
                    if (cn.HideCondition != null && showChoice)
                    {
                        showChoice = !cn.HideCondition.Evaluate();
                    }

                    //skill checks
                    if (cn.SkillCheck != null)
                    {
                        bool isPossible = cn.SkillCheck.CheckIfPossible();

                        if (!GameParams.ShowImpossibleSkillChecks && !isPossible)
                        {
                            showChoice = false;
                        }

                        if (!GameParams.AttemptImpossibleSkillChecks && !isPossible)
                        {
                            lockChoice = true;
                        }

                        string passValue = cn.SkillCheck.CheckType == SkillCheckType.Soft ? $"{(int)(cn.SkillCheck.GetApproximatePassChance() * 100)}%" : cn.SkillCheck.Value.ToString();

                        prependText = $"[{Sub.Replace(cn.SkillCheck.Target, "IGUI_AV")} {passValue}] ";
                    }

                    if (showChoice)
                    {
                        GameObject choiceGO = Instantiate <GameObject>(ButtonPrefab, ScrollChoiceContent);
                        Button     b        = choiceGO.GetComponent <Button>();
                        b.interactable = !lockChoice;
                        b.gameObject.SetActive(true);
                        b.transform.Find("Text").GetComponent <Text>().text = prependText + Sub.Macro(cn.Text);
                        int idx = i;
                        b.onClick.AddListener(delegate { OnChoiceButtonClick(idx); });
                    }
                }
            }
            else // if(f is TextFrame)
            {
                ScrollChoice.gameObject.SetActive(false);

                string nextText = string.IsNullOrEmpty(f.NextText) ? Sub.Replace("DefaultNextText", "IGUI_DIALOGUE", false) : f.NextText;

                Button b = ButtonContinue;
                b.gameObject.SetActive(true);
                b.transform.Find("Text").GetComponent <Text>().text = nextText;
            }

            CurrentFrameObject = f;
        }
Exemple #3
0
        private void PresentNewFrame(Frame f)
        {
            TryCallScript(f?.Scripts?.BeforePresent, f);

            //special handling for blank frames
            if (f is BlankFrame)
            {
                CurrentFrameObject = f;
                ScriptingModule.CallNamedHooked("DialogueOnPresent", this, CurrentFrameObject);
                TryCallScript(f?.Scripts?.OnPresent, f);
                OnChoiceButtonClick(0);
                return;
            }

            //create trace node
            var traceNode = new DialogueTraceNode();

            traceNode.Path = $"{CurrentSceneName}.{CurrentFrameName}";

            //present music
            if (!string.IsNullOrEmpty(f.Music))
            {
                if (!(AudioPlayer.Instance.IsMusicSetToPlay(MusicSlot.Cinematic) && AudioPlayer.Instance.GetMusicName(MusicSlot.Cinematic) == f.Music))
                {
                    AudioPlayer.Instance.SetMusic(f.Music, MusicSlot.Cinematic, 1.0f, true, false);
                    AudioPlayer.Instance.StartMusic(MusicSlot.Cinematic);
                }
            }
            else if (f.Music != null) //null = no change, empty = no music
            {
                AudioPlayer.Instance.ClearMusic(MusicSlot.Cinematic);
            }

            //present audio
            string voiceClipName         = $"{CurrentSceneName}/{CurrentFrameName}";
            string voiceClipNameOverride = f.Options.VoiceOverride;

            if (!string.IsNullOrEmpty(voiceClipNameOverride))
            {
                if (voiceClipNameOverride.StartsWith("/"))
                {
                    voiceClipName = voiceClipNameOverride.TrimStart('/');
                }
                else
                {
                    voiceClipName = $"{CurrentSceneName}/{voiceClipNameOverride}";
                }
            }
            if (VoiceAudioSource.isPlaying)
            {
                VoiceAudioSource.Stop();
            }
            var voiceClip = CCBase.GetModule <AudioModule>().GetSound(voiceClipName, SoundType.Voice, !GameParams.DialogueVerboseLogging); //GetModule<T> is now preferred

            if (voiceClip != null)
            {
                VoiceAudioSource.clip   = voiceClip;
                VoiceAudioSource.volume = f.Options.VoiceVolume ?? 1f;
                VoiceAudioSource.Play();
            }

            //present background
            BackgroundImage.sprite = null;
            BackgroundImage.gameObject.SetActive(false);
            if (!string.IsNullOrEmpty(f.Background))
            {
                var sprite = CoreUtils.LoadResource <Sprite>("Dialogue/bg/" + f.Background);
                if (sprite != null)
                {
                    BackgroundImage.sprite = sprite;
                    BackgroundImage.gameObject.SetActive(true);
                }
                else
                {
                    if (GameParams.DialogueVerboseLogging)
                    {
                        CDebug.LogEx($"Couldn't find face sprite Dialogue/bg/{f.Background}", LogLevel.Verbose, this);
                    }
                }
            }

            //size panel
            float faceYOffset      = 0;
            var   framePanelHeight = f.Options.PanelHeight;
            var   panelHeight      = framePanelHeight == ChoicePanelHeight.Default ? GameParams.DialoguePanelHeight : framePanelHeight;

            switch (panelHeight)
            {
            case ChoicePanelHeight.Half:
                if (!Mathf.Approximately(ChoicePanel.rect.height, DefaultPanelHeight / 2f))
                {
                    ChoicePanel.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, DefaultPanelHeight / 2f);
                }
                faceYOffset = -(DefaultPanelHeight / 2f);
                break;

            case ChoicePanelHeight.Variable:
                CDebug.LogEx($"{nameof(ChoicePanelHeight)} {ChoicePanelHeight.Variable} is not supported!", LogLevel.Warning, this);
                break;

            case ChoicePanelHeight.Fixed:
                ChoicePanel.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, f.Options.PanelHeightPixels);
                faceYOffset = -(DefaultPanelHeight - f.Options.PanelHeightPixels);
                break;

            default:
                if (!Mathf.Approximately(ChoicePanel.rect.height, DefaultPanelHeight))
                {
                    ChoicePanel.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, DefaultPanelHeight);     //correct?
                }
                break;
            }

            //show/hide name text
            if (f.Options.HideNameText)
            {
                NameTextPanel.gameObject.SetActive(false);
            }
            else
            {
                NameTextPanel.gameObject.SetActive(true);
            }

            //present image
            FaceImage.sprite = null;
            FaceImage.gameObject.SetActive(false);
            if (!string.IsNullOrEmpty(f.Image))
            {
                //attempt to present image
                var sprite = CoreUtils.LoadResource <Sprite>("Dialogue/char/" + f.Image);
                if (sprite != null)
                {
                    //Debug.Log(sprite.name);

                    Vector2 canvasSize = ((RectTransform)FaceImage.canvas.transform).rect.size;

                    float spriteX = sprite.texture.width * (100f / sprite.pixelsPerUnit);
                    float spriteY = sprite.texture.height * (100f / sprite.pixelsPerUnit);

                    switch (f.ImagePosition)
                    {
                    case FrameImagePosition.Fill:     //works
                        FaceImage.rectTransform.localPosition = Vector3.zero;
                        FaceImage.rectTransform.sizeDelta     = canvasSize;
                        break;

                    case FrameImagePosition.Contain:     //works
                    {
                        FaceImage.rectTransform.localPosition = Vector3.zero;

                        float imageRatio = (float)sprite.texture.width / (float)sprite.texture.height;         //force float division!
                        float rectRatio  = canvasSize.x / canvasSize.y;

                        if (imageRatio > rectRatio)         //image is wider than rect
                        {
                            FaceImage.rectTransform.sizeDelta = new Vector2(canvasSize.x, canvasSize.x / imageRatio);
                        }
                        else         //image is narrower than rect
                        {
                            FaceImage.rectTransform.sizeDelta = new Vector2(canvasSize.y * imageRatio, canvasSize.y);
                        }
                    }
                    break;

                    case FrameImagePosition.Cover:     //works
                    {
                        FaceImage.rectTransform.localPosition = Vector3.zero;

                        float imageRatio = (float)sprite.texture.width / (float)sprite.texture.height;
                        float rectRatio  = canvasSize.x / canvasSize.y;

                        if (imageRatio > rectRatio)         //image is wider than rect
                        {
                            FaceImage.rectTransform.sizeDelta = new Vector2(canvasSize.y * imageRatio, canvasSize.y);
                        }
                        else         //image is narrower than rect
                        {
                            FaceImage.rectTransform.sizeDelta = new Vector2(canvasSize.x, canvasSize.x / imageRatio);
                        }
                    }
                    break;

                    case FrameImagePosition.Character:     //works
                        FaceImage.rectTransform.localPosition = new Vector3(0, faceYOffset + (GameParams.DialogueDrawPortraitHigh ? 140 : 100), 0);
                        FaceImage.rectTransform.sizeDelta     = new Vector2(spriteX, spriteY);
                        break;

                    case FrameImagePosition.CharacterBottom:                  //works
                    {
                        float yPos = (-(canvasSize.y / 2f)) + (spriteY / 2f); //I think we want SpriteY and not pixels directly

                        FaceImage.rectTransform.localPosition = new Vector3(0, yPos, 0);
                        FaceImage.rectTransform.sizeDelta     = new Vector2(spriteX, spriteY);
                    }
                    break;

                    case FrameImagePosition.Battler:     //deliberately broken
                        CDebug.LogEx($"FrameImagePosition {f.ImagePosition} is not supported!", LogLevel.Warning, this);
                        FaceImage.rectTransform.localPosition = Vector3.zero;
                        FaceImage.rectTransform.sizeDelta     = new Vector2(spriteX, spriteY);
                        break;

                    default:     //works
                        FaceImage.rectTransform.localPosition = Vector3.zero;
                        FaceImage.rectTransform.sizeDelta     = new Vector2(spriteX, spriteY);;
                        break;
                    }

                    FaceImage.sprite = sprite;
                    FaceImage.gameObject.SetActive(true);
                }
                else
                {
                    if (GameParams.DialogueVerboseLogging)
                    {
                        CDebug.LogEx($"Couldn't find face sprite Dialogue/char/{f.Image}", LogLevel.Verbose, this);
                    }
                }
            }

            //present camera
            try
            {
                if (!string.IsNullOrEmpty(f.CameraDirection) && !f.CameraDirection.StartsWith("Default", StringComparison.OrdinalIgnoreCase))
                {
                    if (CameraController == null)
                    {
                        var cameraGo = Instantiate(CameraPrefab, CoreUtils.GetWorldRoot());
                        CameraController = cameraGo.GetComponent <DialogueCameraController>();
                    }

                    CameraController.Activate(f.CameraDirection);
                }
                else
                {
                    CameraController.Ref()?.Deactivate();
                }
            }
            catch (Exception e)
            {
                Debug.LogError($"Failed to point camera ({f.CameraDirection})");
                Debug.LogException(e);
            }

            //present hidden objects
            var objectsToHide = f.Options.HideObjects;

            if (objectsToHide != null)
            {
                var hiddenObjectsToShow = HiddenObjects.Except(objectsToHide);
                UnhideObjects(hiddenObjectsToShow);

                var newObjectsToHide = objectsToHide.Except(HiddenObjects);
                HideObjects(newObjectsToHide);

                HiddenObjects.Clear();
                HiddenObjects.UnionWith(objectsToHide);
            }
            else
            {
                UnhideAllObjects();
            }

            //present text
            string nameText = Sub.Macro(f.NameText);

            TextTitle.text = nameText;
            string mainText = Sub.Macro(f.Text);

            TextMain.text = mainText;

            //save text to trace (note use of null instead of null-or-empty)
            traceNode.Speaker = (f.Options.TraceSpeaker == null) ? (string.IsNullOrEmpty(nameText) ? GetDefaultTraceSpeaker(f) : nameText) : Sub.Macro(f.Options.TraceSpeaker);
            traceNode.Text    = (f.Options.TraceText == null) ? mainText : Sub.Macro(f.Options.TraceText);

            //clear buttons
            Navigator.ClearButtons();
            foreach (Transform t in ScrollChoiceContent)
            {
                Destroy(t.gameObject);
            }
            ScrollChoiceContent.DetachChildren();
            ButtonAlternateContinue.gameObject.SetActive(false);

            //present buttons and frame
            if (f is ChoiceFrame choiceFrame)
            {
                ChoicePanel.gameObject.SetActive(true);

                ScrollChoice.gameObject.SetActive(true);
                ButtonContinue.gameObject.SetActive(false);

                //ChoiceFrame cf = (ChoiceFrame)f;
                var buttons = new List <Button>();
                for (int i = 0; i < choiceFrame.Choices.Length; i++)
                {
                    ChoiceNode cn = choiceFrame.Choices[i];

                    string prependText = string.Empty;
                    bool   showChoice  = true;
                    bool   lockChoice  = false;

                    if (cn.ShowCondition != null)
                    {
                        showChoice = cn.ShowCondition.Evaluate();
                    }
                    if (cn.HideCondition != null && showChoice)
                    {
                        showChoice = !cn.HideCondition.Evaluate();
                    }

                    //skill checks
                    if (cn.SkillCheck != null)
                    {
                        bool isPossible = cn.SkillCheck.CheckIfPossible();

                        if (!GameParams.ShowImpossibleSkillChecks && !isPossible)
                        {
                            showChoice = false;
                        }

                        if (!GameParams.AttemptImpossibleSkillChecks && !isPossible)
                        {
                            lockChoice = true;
                        }

                        string passValue = cn.SkillCheck.CheckType == SkillCheckType.Soft ? $"{(int)(cn.SkillCheck.GetApproximatePassChance() * 100)}%" : cn.SkillCheck.Value.ToString();

                        prependText = $"[{Sub.Replace(cn.SkillCheck.Target, "RPG_AV")} {passValue}] ";
                    }

                    if (showChoice)
                    {
                        GameObject choiceGO = Instantiate <GameObject>(ButtonPrefab, ScrollChoiceContent);
                        Button     b        = choiceGO.GetComponent <Button>();
                        b.interactable = !lockChoice;
                        b.gameObject.SetActive(true);
                        b.transform.Find("Text").GetComponent <Text>().text = prependText + Sub.Macro(cn.Text);
                        int idx = i;
                        b.onClick.AddListener(delegate { OnChoiceButtonClick(idx); });
                        buttons.Add(b);
                    }
                }

                Navigator.AttachButtons(buttons);
            }
            else if (f is ImageFrame imageFrame)
            {
                string nextText = string.IsNullOrEmpty(f.NextText) ? Sub.Replace("DefaultNextText", "IGUI_DIALOGUE", false) : f.NextText;

                if (imageFrame.AllowSkip)
                {
                    ChoicePanel.gameObject.SetActive(false);
                    ScrollChoice.gameObject.SetActive(false);

                    Button b = ButtonAlternateContinue;
                    b.gameObject.SetActive(true);
                    b.transform.Find("Text").GetComponent <Text>().text = nextText;
                    Navigator.AttachButtons(new Button[] { b });
                }
                else
                {
                    ChoicePanel.gameObject.SetActive(false);
                    ButtonAlternateContinue.gameObject.SetActive(false);
                }

                if (imageFrame.HideSkip)
                {
                    CDebug.LogEx("Image frame HideSkip is deprecated and not implemented (use AllowSkip=false instead)", LogLevel.Warning, this);
                }

                if (imageFrame.UseTimer)
                {
                    StartWaitAndAdvance(imageFrame.TimeToShow);
                }
            }
            else if (f is TextFrame textFrame)
            {
                ChoicePanel.gameObject.SetActive(true);
                ScrollChoice.gameObject.SetActive(false);

                string nextText = string.IsNullOrEmpty(f.NextText) ? Sub.Replace("DefaultNextText", "IGUI_DIALOGUE", false) : f.NextText;

                Button b = ButtonContinue;
                b.gameObject.SetActive(textFrame.AllowSkip);
                b.transform.Find("Text").GetComponent <Text>().text = nextText;
                Navigator.AttachButtons(new Button[] { b });

                if (textFrame.UseTimer)
                {
                    StartWaitAndAdvance(textFrame.TimeToShow);
                }
            }
            else
            {
                throw new NotImplementedException($"Frame type {f.GetType().Name} is not supported");
            }

            //apply theme
            ApplyThemeToPanel();

            CurrentFrameObject = f;

            ScriptingModule.CallNamedHooked("DialogueOnPresent", this, CurrentFrameObject);
            TryCallScript(f?.Scripts?.OnPresent, f);

            if (f.Options.TraceIgnore)
            {
                traceNode.Ignored = true;
            }
            Trace.Nodes.Add(traceNode);
        }