private IEnumerator RotatingToPreSolve()
    {
        this._transitioning = true;

        yield return(new WaitUntil(() => this._rotationCoroutine == null));

        PlayRandomSound();

        this.chosenColors = colorNames.ToList().Shuffle().Take(this.vertexCount)
                            .OrderBy(x => Array.IndexOf(colorNames, x)).ToArray();

        var verts     = this.geoObject.GetVertexObjects().ToList();
        var centerLoc = verts.Select(x => x.ProjectTo3D()).Aggregate((a, b) => a + b) / verts.Count;
        var vo        = verts.OrderByDescending(x => Vector3.Distance(x.ProjectTo3D(), centerLoc)).ToArray().Shuffle();

        for (int i = 0; i < vo.Length; i++)
        {
            var c = i < this.chosenColors.Length ? this.chosenColors[i] : this.chosenColors.PickRandom();
            vo[i].vertexTransform.GetComponent <MeshRenderer>().material.color = GetColorFromName(c);
            //Log("Assigned color " + c + " with a value of " + GetColorFromName(c).ToString());
        }

        this.calculatedSolveNumbers = GetSolveNumbers();

        Log("The numbers that need to be entered are: " + this.calculatedSolveNumbers.Select(x => SolveNumberToSequence(x).Join("-")).Join(", "));
        Log("The colors that need to be entered are: " + this.calculatedSolveNumbers.Select(x => SolveNumberToSequence(x).Select(y => this.chosenColors[y]).Join("-")).Join(", "));

        this.moduleState = ModuleSolveState.Solving;
    }
    private void StrikeAndReset()
    {
        this.Module.HandleStrike();
        this.solveProgress  = 0;
        this._transitioning = false;
        this.enteredNumbers.Clear();
        this.chosenColors = null;
        this.moduleState  = ModuleSolveState.Rotating;

        var vo = this.geoObject.GetVertexObjects();

        for (int i = 0; i < vo.Count; i++)
        {
            vo[i].vertexTransform.GetComponent <MeshRenderer>().material.color = this.originalVertexColor;
        }

        this._rotationCoroutine = StartCoroutine(RotateDimKing());
    }
    private void GeoObject_OnVertexClicked(object sender, VertexPressedEventArgs e)
    {
        if (this.moduleState == ModuleSolveState.Solved)
        {
            return;
        }

        Log("Clicked vertex " + e.i);

        this.Audio.PlaySoundAtTransform("Bleep" + new[] { 3, 4, 6 }.PickRandom(), this.transform);
        e.VertexObject.GetKMSelectable().AddInteractionPunch(0.2f);

        //Vertices[v].AddInteractionPunch(.2f);
        //if (_transitioning)
        //    return false;


        if (this.moduleState == ModuleSolveState.Rotating)
        {
            this.moduleState = ModuleSolveState.PreSolving;
            StartCoroutine(RotatingToPreSolve());
            this.enteredNumbers = new List <int>();
        }
        else if (this.moduleState == ModuleSolveState.Solving)
        {
            var c            = e.VertexObject.vertexTransform.GetComponent <MeshRenderer>().material.color;
            var pressedColor = colorNames[Array.IndexOf(colorValues, c)];
            Log("Color " + pressedColor + " was pressed.");
            var val = Array.IndexOf(this.chosenColors, pressedColor);
            this.enteredNumbers.Add(val);
            var nums             = this.enteredNumbers[0];
            var currentNumberSum = this.enteredNumbers.Skip(1).Sum();

            Log("The following number was entered: " + val + ". There are/is " + (this.enteredNumbers[0] - (this.enteredNumbers.Count - 1)) + " number(s) left to be entered.");
            Log(currentNumberSum + (this.enteredNumbers[0] - (this.enteredNumbers.Count - 1)) * (this.chosenColors.Length - 1) + " >= " + this.calculatedSolveNumbers[this.solveProgress]);

            if (this.enteredNumbers.Count == nums + 1) // all numbers have been entered.
            {
                if (currentNumberSum == this.calculatedSolveNumbers[this.solveProgress])
                {
                    Log("Sequence correct.");
                    this.solveProgress++;
                    if (this.solveProgress == this.calculatedSolveNumbers.Length)
                    {
                        this.moduleState = ModuleSolveState.Solved;
                        StartCoroutine(SolvedAnimation());
                    }
                    this.enteredNumbers.Clear();
                }
                else
                {
                    Log("Invalid number entered!");
                    StrikeAndReset();
                }
            }
            else if (currentNumberSum > this.calculatedSolveNumbers[this.solveProgress])
            {
                Log("The sum of the entered numbers " + this.enteredNumbers[0] + ", [" + this.enteredNumbers.Skip(1).Join(" ") + "] is " +
                    currentNumberSum + " which is bigger than the correct number " + this.calculatedSolveNumbers[this.solveProgress] + " already, meaning that it cannot be solved anymore.\n");
                StrikeAndReset();
            }
            else if (currentNumberSum                                   // if currently entered number sum + (numbers left to enter)*maxNumberValue, so the currently maximum enterable number ...
                     + (this.enteredNumbers[0] - (this.enteredNumbers.Count - 1)) * (this.chosenColors.Length - 1)
                     < this.calculatedSolveNumbers[this.solveProgress]) // ... is less than the required, then strike
            {
                Log("The sum of the entered numbers " + this.enteredNumbers[0] + ", [" + this.enteredNumbers.Skip(1).Join(" ") + "] is " + currentNumberSum + ". " +
                    "If you add " + ((this.enteredNumbers[0] - (this.enteredNumbers.Count - 1)) * (this.chosenColors.Length - 1)) + ", which is what you could enter at most, " +
                    "then the resulting value is smaller than " + this.calculatedSolveNumbers[this.solveProgress] + ", meaning that it cannot be solved anymore.\n");
                StrikeAndReset();
            }
        }

        //if (this._rotationCoroutine != null)
        //{
        //    _progress = 0;
        //    StartCoroutine(ColorChange(setVertexColors: true));
        //}
        //else if (v == _correctVertex)
        //{
        //    _progress++;
        //    if (_progress == 4)
        //    {
        //        Debug.LogFormat(@"[The Hypercube #{0}] Module solved.", this._moduleId);
        //        this.Module.HandlePass();
        //        StartCoroutine(ColorChange(keepGrey: true));
        //        this.Audio.PlayGameSoundAtTransform(KMSoundOverride.SoundEffect.CorrectChime, this.transform);
        //    }
        //    else
        //    {
        //        StartCoroutine(ColorChange(setVertexColors: true));
        //    }
        //}
        //else
        //{
        //    Debug.LogFormat(@"[The Hypercube #{0}] Incorrect vertex {1} pressed; resuming rotations.", this._moduleId, StringifyShape(v));
        //    this.Module.HandleStrike();
        //    this._rotationCoroutine = StartCoroutine(RotateHypercube(delay: true));
        //}
    }