public void OnPuzzleComplete(string arg)
    {
        Script_PuzzlesEventsManager.PuzzleProgress();

        isDone = true;

        game.ChangeStateCutScene();
        game.DisableExits(false, 0);

        float defaultFastFadeTime = Script_AudioEffectsManager.GetFadeTime(FadeSpeeds.Fast);

        StartCoroutine(
            Script_AudioMixerFader.Fade(
                audioMixer,
                Const_AudioMixerParams.ExposedBGVolume,
                beforeShakeFadeOutMusicTime,
                0f,
                () => { game.StopBgMusic(); }
                )
            );

        // Bind Player & Player Ghost to the Retreat Timeline & play.
        Script_Player player = Script_Game.Game.GetPlayer();

        playerObjsToBind.Clear();

        // Player Transform Track
        playerObjsToBind.Add(player.gameObject);
        // Player Signal Receiver Track
        playerObjsToBind.Add(player.gameObject);

        playerPlayableDirector.BindTimelineTracks(playerRetreatTimeline, playerObjsToBind);

        StartCoroutine(WaitForExplosionCutScene());

        // Zoom camera back in.
        IEnumerator WaitForExplosionCutScene()
        {
            Script_VCamManager.VCamMain.SwitchToMainVCam(staticZoomOutVCam);

            yield return(new WaitForSeconds(zoomBackInTime));

            // play manually do to dynamic handling of Player timeline via Script_TimelineController
            GetComponent <Script_TimelineController>().PlayableDirectorPlayFromTimelines(0, 0);

            playerPlayableDirector.Play(playerRetreatTimeline);
        }
    }
    private void FadeOutDramaticMusic()
    {
        fadingOutMusicCoroutine = StartCoroutine(
            Script_AudioMixerFader.Fade(
                audioMixer,
                BGMParam,
                musicFadeOutSpeed,
                0f,
                () => {
            bgThemePlayer.SoftStop();
            bgThemePlayer.gameObject.SetActive(false);
            Script_BackgroundMusicManager.Control.SetVolume(1f, BGMParam);

            fadingOutMusicCoroutine = null;
        }
                )
            );
    }
    private void HandleDramaticThoughtsCutScene()
    {
        var isDramaticThoughts = isPauseSpikes &&
                                 attackController.Timer == 0 &&
                                 !isDramaCutSceneActivated;

        if (isDramaticThoughts)
        {
            isDramaCutSceneActivated = true;

            if (!didActivateDramaticThoughts)
            {
                FullCutScene();
            }
            else
            {
                RepeatCutScene();
            }
        }

        void FullCutScene()
        {
            didActivateDramaticThoughts = true;
            GetComponent <Script_TimelineController>().PlayableDirectorPlayFromTimelines(1, 1);

            StartCoroutine(
                Script_AudioMixerFader.Fade(
                    audioMixer,
                    BGMParam,
                    musicFadeOutSpeed,
                    0f,
                    () => game.StopBgMusic()
                    )
                );

            Script_TeletypeNotificationManager.Control.InitialState();
        }

        void RepeatCutScene()
        {
            Script_DialogueManager.DialogueManager.StartDialogueNode(dramaDoneRepeatDialogue);
        }
    }
    public void FadeInMusic()
    {
        // set master volume to 0 to prep fade in
        Script_AudioMixerVolume.SetVolume(
            audioMixer,
            Const_AudioMixerParams.ExposedBGVolume,
            0f
            );

        // fade in master volume
        StartCoroutine(
            Script_AudioMixerFader.Fade(
                audioMixer,
                Const_AudioMixerParams.ExposedBGVolume,
                bgMusicFadeInTime,
                1f,
                null
                )
            );
    }
    public void IntroDoneWrong()
    {
        if (game.state == Const_States_Game.CutScene)
        {
            StartCoroutine(
                Script_AudioMixerFader.Fade(
                    audioMixer,
                    Const_AudioMixerParams.ExposedMasterVolume,
                    bgMusicEndIntroFadeOutTime,
                    0f,
                    () => {
                Script_AudioMixerVolume.SetVolume(
                    audioMixer,
                    Const_AudioMixerParams.ExposedMasterVolume,
                    1f
                    );
                ElleniaBgThemePlayer.GetComponent <AudioSource>().volume = 0f;
                ElleniaBgThemePlayer.gameObject.SetActive(false);

                /// Need to wait for music to fade out before return facing easle
                /// otherwise, would use controller/NextNodeAction
                Ellenia.FaceDirection(Directions.Left);

                // need to change state in LateUpdate so NPC doesn't read the button event
                shouldChangeGameStateToInteract = true;
                game.UnPauseBgMusic();
            }
                    )
                );
        }
        else
        {
            Ellenia.FaceDirection(Directions.Left);
        }

        ElleniaIntroDoneDialogueNodes();
        spokenWithEllenia = true;
    }
    /// NextNodeAction START =====================================================================

    /// Node: "i'm part of the..."
    public void PlayOminousMusic()
    {
        game.ChangeStateCutScene();
        Ellenia.FaceDirection(Directions.Left);
        // fade out music and pause
        StartCoroutine(
            Script_AudioMixerFader.Fade(
                audioMixer,
                Const_AudioMixerParams.ExposedMasterVolume,
                bgMusicFadeOutTime,
                0f,
                () => {
            // after faded out, pause bg music and start theme music where Ellenia
            // should turn on beat
            game.PauseBgMusic();
            Script_AudioMixerVolume
            .SetVolume(audioMixer, Const_AudioMixerParams.ExposedMasterVolume, 1f);
            ElleniaBgThemePlayer.gameObject.SetActive(true);

            StartCoroutine(StartDialogueOnBeat());
        }
                )
            );

        IEnumerator StartDialogueOnBeat()
        {
            yield return(new WaitForSeconds(waitToTurnTime));

            Directions directionToPlayer = Script_Utils.GetDirectionToTarget(
                Ellenia.transform.position,
                Script_Game.Game.GetPlayer().transform.position
                );

            Ellenia.FaceDirection(directionToPlayer);
            // then play dialogueNode
            Script_DialogueManager.DialogueManager.StartDialogueNode(introContinuationNode, false);
        }
    }
    public void PreShakeRoom()
    {
        // fade out music
        StartCoroutine(
            Script_AudioMixerFader.Fade(
                audioMixer,
                Const_AudioMixerParams.ExposedBGVolume,
                beforeShakeFadeOutMusicTime,
                0f,
                () => { game.StopBgTheme(); }
                )
            );

        // wait a bit, then talk
        StartCoroutine(WaitToStartErasQuestion());

        IEnumerator WaitToStartErasQuestion()
        {
            yield return(new WaitForSeconds(preShakeRoomWaitTime));

            dialogueManager.StartDialogueNode(erasQuestionNode);
        }
    }
    /* ===========================================================================================
    *   CUTSCENE
    *  =========================================================================================== */

    /// <summary>
    /// when director is finished, start the next dialogue node
    /// </summary>
    public void OnElleniaPlayableDone(PlayableDirector aDirector)
    {
        // walked to first painting
        if (aDirector.playableAsset == GetComponent <Script_TimelineController>().timelines[0])
        {
            Script_DialogueManager.DialogueManager.StartDialogueNode(cutSceneNodes[0], false);
        }
        // walked to middle painting
        else if (aDirector.playableAsset == GetComponent <Script_TimelineController>().timelines[1])
        {
            Script_DialogueManager.DialogueManager.StartDialogueNode(cutSceneNodes[1], false);
        }
        // walked to last painting
        else if (aDirector.playableAsset == GetComponent <Script_TimelineController>().timelines[2])
        {
            Script_DialogueManager.DialogueManager.StartDialogueNode(cutSceneNodes[2], false);
        }
        // walked to room center
        else if (aDirector.playableAsset == GetComponent <Script_TimelineController>().timelines[3])
        {
            Script_DialogueManager.DialogueManager.StartDialogueNode(cutSceneNodes[3], false);
        }
        // return to easle
        else if (aDirector.playableAsset == GetComponent <Script_TimelineController>().timelines[4])
        {
            OnReturnedToEasle();
        }
        /// OnCorrect Timeline
        else if (aDirector.playableAsset == GetComponent <Script_TimelineController>().timelines[5])
        {
            Script_DialogueNode onSubmitCorrectNode = Ellenia.MyPastQuestState == Script_DemonNPC.PastQuestState.Done
                ? onCorrectDonePastQuestDoneNode
                : onCorrectDoneNode;

            // Start dialogue & fade out music.
            // If it's Weekend, use already done nodes.
            if (game.RunCycle == Script_RunsManager.Cycle.Weekend)
            {
                Script_DialogueManager.DialogueManager.StartDialogueNode(onCorrectWeekendNode, false);
            }
            else
            {
                Script_DialogueManager.DialogueManager.StartDialogueNode(onSubmitCorrectNode, false);
            }

            StartCoroutine(
                Script_AudioMixerFader.Fade(
                    audioMixer,
                    BGMParam,
                    bgMusicEndIntroFadeOutTime,
                    0f,
                    () => {
                AudioSource ElleniaAudio = ElleniaBgThemePlayer.GetComponent <AudioSource>();
                if (ElleniaAudio.isPlaying)
                {
                    ElleniaAudio.volume = 0f;
                    ElleniaAudio.Stop();
                    ElleniaAudio.gameObject.SetActive(false);
                }
                if (game.BGMManager.GetIsPlaying())
                {
                    game.PauseBgMusic();
                }
            }
                    )
                );
        }
        // Ellenia walked to the Exit and will brag to Player to look at her painting.
        else if (aDirector.playableAsset == GetComponent <Script_TimelineController>().timelines[6])
        {
            Script_DialogueManager.DialogueManager.StartDialogueNode(beforeExitNode, SFXOn: true);
        }
        // Ellenia actually exits.
        else if (aDirector.playableAsset == GetComponent <Script_TimelineController>().timelines[7])
        {
            OnElleniaExitsDone();
        }

        void OnReturnedToEasle()
        {
            var VCamManager = Script_VCamManager.VCamMain;

            VCamManager.SwitchToMainVCam(followElleniaVCam);
            VCamManager.SetDefaultCinemachineBlendUpdateMethod();

            Script_DialogueManager.DialogueManager.StartDialogueNode(cutSceneNodes[4], false);
        }
    }