private IEnumerator DelayKeyTurn(bool restoreBombTimer, bool causeStrikeIfWrongTime = true, bool bypassSettings = false)
    {
        Animator keyAnimator = (Animator)KeyAnimatorField.GetValue(Module.BombComponent.GetComponent(ComponentType));
        KMAudio  keyAudio    = (KMAudio)KeyAudioField.GetValue(Module.BombComponent.GetComponent(ComponentType));
        int      time        = (int)TargetTimeField.GetValue(Module.BombComponent.GetComponent(ComponentType));

        if (!restoreBombTimer)
        {
            Module.Bomb.CurrentTimer = time + 0.5f + Time.deltaTime;
            yield return(null);
        }
        else if (causeStrikeIfWrongTime && time != (int)Mathf.Floor(Module.Bomb.CurrentTimer))
        {
            Module.BombComponent.GetComponent <KMBombModule>().HandleStrike();
            keyAnimator.SetTrigger("WrongTurn");
            keyAudio.PlaySoundAtTransform("WrongKeyTurnFK", Module.transform);
            yield return(null);

            if (!(TwitchPlaySettings.data.AllowTurnTheKeyEarlyLate || bypassSettings) || (bool)SolvedField.GetValue(Module.BombComponent.GetComponent(ComponentType)))
            {
                yield break;
            }
        }

        Module.BombComponent.GetComponent <KMBombModule>().HandlePass();
        KeyUnlockedField.SetValue(Module.BombComponent.GetComponent(ComponentType), true);
        SolvedField.SetValue(Module.BombComponent.GetComponent(ComponentType), true);
        keyAnimator.SetBool("IsUnlocked", true);
        keyAudio.PlaySoundAtTransform("TurnTheKeyFX", Module.transform);
        yield return(null);
    }
    private IEnumerator ReWriteTurnTheKey()
    {
        yield return(new WaitUntil(() => (bool)ActivatedField.GetValue(Module.BombComponent.GetComponent(ComponentType))));

        yield return(new WaitForSeconds(0.1f));

        StopAllCorotinesMethod.Invoke(Module.BombComponent.GetComponent(ComponentType), null);

        ((KMSelectable)_lock).OnInteract = () => OnKeyTurn();
        int expectedTime = (int)TargetTimeField.GetValue(Module.BombComponent.GetComponent(ComponentType));

        if (Math.Abs(expectedTime - Module.Bomb.CurrentTimer) < 30)
        {
            yield return(new WaitForSeconds(0.1f));

            AttemptedForcedSolve = true;
            HandleForcedSolve();
            yield break;
        }

        while (!Module.Solved)
        {
            int time = Mathf.FloorToInt(Module.Bomb.CurrentTimer);
            if ((!OtherModes.Unexplodable && time < expectedTime || OtherModes.Unexplodable && time > expectedTime) &&
                !(bool)SolvedField.GetValue(Module.BombComponent.GetComponent(ComponentType)) &&
                !TwitchPlaySettings.data.AllowTurnTheKeyEarlyLate)
            {
                Module.BombComponent.GetComponent <KMBombModule>().HandleStrike();
            }
            yield return(new WaitForSeconds(2.0f));
        }
    }
    private bool CanTurnEarlyWithoutStrike(int turnTime)
    {
        int time          = (int)TargetTimeField.GetValue(Module.BombComponent.GetComponent(ComponentType));
        int timeRemaining = (int)Module.Bomb.CurrentTimer;

        if ((!OtherModes.Unexplodable && timeRemaining < time) || (OtherModes.Unexplodable && timeRemaining > time) || !IsTargetTurnTimeCorrect(turnTime))
        {
            return(false);
        }
        return(TwitchGame.Instance.Modules.Where(x => x.BombID == Module.BombID && x.BombComponent.IsSolvable && !x.BombComponent.IsSolved).All(x => x.Solver.SkipTimeAllowed));
    }
 private bool IsTargetTurnTimeCorrect(int turnTime) => turnTime < 0 || turnTime == (int)TargetTimeField.GetValue(Module.BombComponent.GetComponent(ComponentType));