Exemple #1
0
        public void FinalStage(ref int moduleId, ref int maxStage, ref List <int> calculatedValues, ref float sum, ref TextMesh[] NixieTexts, out bool canSolve, out sbyte solution)
        {
            Debug.LogFormat("[Forget The Colors #{0}]: FINAL STAGE", moduleId);
            Debug.LogFormat("[Forget The Colors #{0}]: <-------=-------> FINALE ~ ARCCOSINE <-------=------->", moduleId);

            //prevents out of array exceptions in editor
            if (Application.isEditor)
            {
                maxStage = calculatedValues.Count;
            }

            //adds all of the values
            for (byte i = 0; i < calculatedValues.Count; i++)
            {
                sum += calculatedValues[i];
                Debug.LogFormat("[Forget The Colors #{0}]: Adding stage {1}'s {2}, the total is now {3}.", moduleId, i, calculatedValues[i], sum);
            }

            //allow inputs in the module
            NixieTexts[0].text = "0";
            NixieTexts[1].text = "0";

            //turns into decimal number
            Debug.LogFormat("[Forget The Colors #{0}]: First five digits of cos-1({1}) is {2}.", moduleId, Ease.Modulo(Mathf.Abs(sum) / 100000, 1), Math.Truncate(Mathf.Acos((float)Ease.Modulo(Mathf.Abs(sum) / 100000, 1)) * Mathf.Rad2Deg));
            solution = (sbyte)(Mathf.Acos((float)Ease.Modulo(Mathf.Abs(sum) / 100000, 1)) * Mathf.Rad2Deg);

            Debug.LogFormat("[Forget The Colors #{0}]: The expected answer is {1}.", moduleId, solution);
            Debug.LogFormat("[Forget The Colors #{0}]: USER INPUT", moduleId);
            Debug.LogFormat("[Forget The Colors #{0}]: <-------=-------> LET'S SEE HOW THE USER DOES <-------=------->", moduleId);

            canSolve = true;
        }
Exemple #2
0
        public void UpdateCycleStage(ref TextMesh[] DisplayTexts, ref List <short> largeDisplay, ref int stage, ref TextMesh[] NixieTexts, ref List <byte> nixies, ref TextMesh GearText, ref List <byte> gear, ref bool colorblind, ref int maxStage, ref List <string> gearColor, ref Renderer[] ColoredObjects, ref Texture[] ColorTextures, ref List <byte> cylinder, ref Transform[] CylinderDisks)
        {
            //render initial displays
            DisplayTexts[0].text = largeDisplay[stage].ToString();
            DisplayTexts[1].text = Ease.Modulo(stage, 100).ToString();

            //if the large display lacks 3 characters, add 0's
            for (byte i = 0; i < DisplayTexts.Length; i++)
            {
                while (DisplayTexts[i].text.Length < 3 - i)
                {
                    DisplayTexts[i].text = "0" + DisplayTexts[i].text;
                }
            }

            //set nixies
            for (byte i = 0; i < NixieTexts.Length; i++)
            {
                NixieTexts[i].text = nixies[i + (stage * 2)].ToString();
            }

            //set gear number and size
            GearText.text = gear[stage].ToString();

            //render letter for colorblind
            if (colorblind)
            {
                //checks for pink, since pink and purple start with the same letter
                if (gearColor[stage] != "Pink")
                {
                    GearText.text = gearColor[stage].First() + GearText.text.Last().ToString();
                }
                else
                {
                    GearText.text = 'I' + GearText.text.Last().ToString();
                }
            }

            //set colors
            for (byte i = 0; i < ColoredObjects.Length; i++)
            {
                ColoredObjects[i].material.mainTexture = ColorTextures[cylinder[i + (stage * 4)]];
                ColoredObjects[i].material.SetTextureOffset("_MainTex", new Vector2(0.5f * Convert.ToByte(colorblind) * Convert.ToByte(maxStage != stage), -0.04f));
            }
            ColoredObjects[3].material.SetTextureScale("_MainTex", new Vector2(0, 0));

            //deletes cylinders if needed
            for (byte i = 0; i < CylinderDisks.Length; i++)
            {
                CylinderDisks[i].localRotation = new Quaternion(90 * Convert.ToByte(colorblind) * Convert.ToByte(maxStage != stage), -90, 0, 0);
            }
        }
Exemple #3
0
        public void Press(byte btn, ref KMAudio Audio, ref KMSelectable[] Selectables, ref bool solved, ref bool canSolve, ref bool allowCycleStage, ref int stage, ref int maxStage, ref TextMesh[] DisplayTexts, ref List <short> largeDisplay, ref TextMesh[] NixieTexts, ref List <byte> nixies, ref TextMesh GearText, ref List <byte> gear, ref bool colorblind, ref List <string> gearColor, ref Renderer[] ColoredObjects, ref Texture[] ColorTextures, ref List <byte> cylinder, ref Transform[] CylinderDisks, ref int[] colorValues, ref sbyte debugPointer, ref int moduleId, ref Rule[][] rules, ref KMBombInfo BombInfo, ref List <string> ruleColor, ref List <int> calculatedValues, ref List <int> sineNumber, ref float sum, ref sbyte solution, ref bool isRotatingGear, ref int currentAngle, int angleIncreasePerSolve, ref float ease, ref KMBombModule Module, ref bool isRotatingKey)
        {
            //adds interaction punch
            if (btn != 2)
            {
                Audio.PlayGameSoundAtTransform(KMSoundOverride.SoundEffect.ButtonPress, Selectables[btn].transform);
                Selectables[btn].AddInteractionPunch();
            }

            //if solved, buttons and key should do nothing
            if (solved || (!canSolve && !FTCScript.isEditor))
            {
                return;
            }

            //strike mode
            if (allowCycleStage)
            {
                switch (btn)
                {
                case 0: stage = (int)Ease.Modulo(stage - 1, maxStage); moduleRender.UpdateCycleStage(ref DisplayTexts, ref largeDisplay, ref stage, ref NixieTexts, ref nixies, ref GearText, ref gear, ref colorblind, ref maxStage, ref gearColor, ref ColoredObjects, ref ColorTextures, ref cylinder, ref CylinderDisks); break;

                case 1: stage = (int)Ease.Modulo(stage + 1, maxStage); moduleRender.UpdateCycleStage(ref DisplayTexts, ref largeDisplay, ref stage, ref NixieTexts, ref nixies, ref GearText, ref gear, ref colorblind, ref maxStage, ref gearColor, ref ColoredObjects, ref ColorTextures, ref cylinder, ref CylinderDisks); break;

                case 2: allowCycleStage = false; stage = maxStage; moduleRender.Update(ref canSolve, ref DisplayTexts, ref GearText, ref ColoredObjects, ref ColorTextures, ref CylinderDisks, ref colorValues, ref colorblind, ref maxStage, ref stage); break;
                }
                return;
            }

            //NOT the key
            else if (btn != 2)
            {
                //increments respective nixie by 1
                if (!FTCScript.isEditor)
                {
                    NixieTexts[btn].text = Ease.Modulo(int.Parse(NixieTexts[btn].text) + 1, 10).ToString();
                }

                //complete debugging
                else
                {
#pragma warning disable CS0162 // Unreachable code detected
                    //right nixie changes value selected by one
                    if (btn == 1)
                    {
                        switch (debugPointer)
                        {
                        case 0: DisplayTexts[0].text = Ease.Modulo(int.Parse(DisplayTexts[0].text) + 100, 1000).ToString(); break;

                        case 1: DisplayTexts[0].text = Ease.Modulo(int.Parse(DisplayTexts[0].text) + 10, 1000).ToString(); break;

                        case 2: DisplayTexts[0].text = Ease.Modulo(int.Parse(DisplayTexts[0].text) + 1, 1000).ToString(); break;

                        case 3: colorValues[0] = (int)Ease.Modulo(colorValues[0] + 1, 10); break;

                        case 4: colorValues[1] = (int)Ease.Modulo(colorValues[1] + 1, 10); break;

                        case 5: colorValues[2] = (int)Ease.Modulo(colorValues[2] + 1, 10); break;

                        case 6: GearText.text = Ease.Modulo(int.Parse(GearText.text[Convert.ToByte(colorblind)].ToString()) + 1, 10).ToString(); break;

                        case 7: colorValues[3] = (int)Ease.Modulo(colorValues[3] + 1, 10); break;

                        case 8: NixieTexts[0].text = Ease.Modulo(int.Parse(NixieTexts[0].text) + 1, 10).ToString(); break;

                        case 9: NixieTexts[1].text = Ease.Modulo(int.Parse(NixieTexts[1].text) + 1, 10).ToString(); break;

                        case 10: stage++; break;

                        case 11:
                            //souvenir
                            gear[stage]         = byte.Parse(GearText.text.Last().ToString());
                            gearColor[stage]    = Strings.ColorLog[colorValues[3]];
                            largeDisplay[stage] = short.Parse(DisplayTexts[0].text);

                            for (byte i = 0; i < 2; i++)
                            {
                                nixies[(stage * 2) + i] = byte.Parse(NixieTexts[i].text);
                            }
                            for (byte i = 0; i < 4; i++)
                            {
                                cylinder[(stage * 4) + i] = (byte)colorValues[i];
                            }

                            calculate.NextStage(ref moduleId, ref stage, ref DisplayTexts, ref NixieTexts, ref GearText, ref colorblind, ref rules, ref colorValues, ref BombInfo, ref maxStage, ref ruleColor, ref calculatedValues, ref sineNumber);
                            calculate.FinalStage(ref moduleId, ref maxStage, ref calculatedValues, ref sum, ref NixieTexts, out canSolve, out solution);
                            break;
                        }
                    }

                    //left nixie changes which value is selected
                    else
                    {
                        debugPointer = (sbyte)Ease.Modulo(++debugPointer, 12);
                    }

                    DisplayTexts[1].text = Strings.DebugText[debugPointer];

                    moduleRender.Update(ref canSolve, ref DisplayTexts, ref GearText, ref ColoredObjects, ref ColorTextures, ref CylinderDisks, ref colorValues, ref colorblind, ref maxStage, ref stage);
#pragma warning restore CS0162 // Unreachable code detected
                }
            }

            //key
            else
            {
                //debugging
                if (FTCScript.isEditor)
                {
#pragma warning disable CS0162 // Unreachable code detected
                    //souvenir
                    gear[stage]         = byte.Parse(GearText.text[Convert.ToByte(colorblind)].ToString());
                    gearColor[stage]    = Strings.ColorLog[colorValues[3]];
                    largeDisplay[stage] = short.Parse(DisplayTexts[0].text);

                    //in case of strikes
                    for (byte i = 0; i < 2; i++)
                    {
                        nixies[(stage * 2) + i] = byte.Parse(NixieTexts[i].text);
                    }
                    for (byte i = 0; i < 4; i++)
                    {
                        cylinder[(stage * 4) + i] = (byte)colorValues[i];
                    }

                    calculate.NextStage(ref moduleId, ref stage, ref DisplayTexts, ref NixieTexts, ref GearText, ref colorblind, ref rules, ref colorValues, ref BombInfo, ref maxStage, ref ruleColor, ref calculatedValues, ref sineNumber);

                    if (!isRotatingGear)
                    {
                        currentAngle += angleIncreasePerSolve;
                        ease          = 0;
                    }
#pragma warning restore CS0162 // Unreachable code detected
                }

                //if both correct
                else if (int.Parse(string.Concat(NixieTexts[0].text, NixieTexts[1].text)) == solution)
                {
                    solved = true;
                    ease   = 0;

                    Audio.PlaySoundAtTransform(Sounds.Ftc.KeySuccess, Selectables[2].transform);
                    Audio.PlaySoundAtTransform(Sounds.Ftc.Solve, Module.transform);

                    Debug.LogFormat("[Forget The Colors #{0}]: {1}; module solved!", moduleId, Strings.WinPhrases[Rnd.Range(0, Strings.WinPhrases.Length)]);
                    Module.HandlePass();
                }

                //if either incorrect
                else
                {
                    allowCycleStage = true;
                    isRotatingKey   = true;
                    ease            = 0;

                    Audio.PlaySoundAtTransform(Sounds.Ftc.Key, Selectables[2].transform);

                    //if submitting a possible answer
                    if (int.Parse(string.Concat(NixieTexts[0].text, NixieTexts[1].text)) <= 90)
                    {
                        Debug.LogFormat("[Forget The Colors #{0}]: {1}; you submitted {2} when I expected {3}.", moduleId, Strings.FailPhrases[Rnd.Range(0, Strings.FailPhrases.Length)], NixieTexts[0].text + NixieTexts[1].text, solution);
                    }

                    //if submitting an impossible answer
                    else
                    {
                        Audio.PlaySoundAtTransform(Sounds.Fac.Strike, Selectables[2].transform);
                        Debug.LogFormat("[Forget The Colors #{0}]: Wh- why would you submit {1}? Why would you submit {1}?! Do you even know how I work?! That answer isn't even possible... You submitted {1} when I expected {2}.", moduleId, NixieTexts[0].text + NixieTexts[1].text, solution);
                    }

                    Module.HandleStrike();
                }
            }

            moduleRender.Update(ref canSolve, ref DisplayTexts, ref GearText, ref ColoredObjects, ref ColorTextures, ref CylinderDisks, ref colorValues, ref colorblind, ref maxStage, ref stage);
        }
Exemple #4
0
        public void NextStage(ref int moduleId, ref int currentStage, ref TextMesh[] DisplayTexts, ref TextMesh[] NixieTexts, ref TextMesh GearText, ref bool colorblind, ref Rule[][] rules, ref int[] colorValues, ref KMBombInfo BombInfo, ref int maxStage, ref List <string> ruleColor, ref List <int> calculatedValues, ref List <int> sineNumber)
        {
            Debug.LogFormat("[Forget The Colors #{0}]: STAGE {1}", moduleId, currentStage);
            Debug.LogFormat("[Forget The Colors #{0}]: <-------=-------> MODULE APPEARANCE <-------=------->", moduleId);
            Debug.LogFormat("[Forget The Colors #{0}]: Large Display: {1}. Cylinders (left-to-right): {2}, {3}, and {4}. Nixies: {5} and {6}. Gear: {7} and {8}.", moduleId, DisplayTexts[0].text, Strings.ColorLog[colorValues[0]], Strings.ColorLog[colorValues[1]], Strings.ColorLog[colorValues[2]], NixieTexts[0].text, NixieTexts[1].text, GearText.text[Convert.ToByte(colorblind)], Strings.ColorLog[colorValues[3]]);
            Debug.LogFormat("[Forget The Colors #{0}]: <-------=-------> NIXIES ~ FIRST TABLE <-------=------->", moduleId);
            short nixie1 = sbyte.Parse(NixieTexts[0].text), nixie2 = sbyte.Parse(NixieTexts[1].text);

            if (rules == null)
            {
                //this will run through the changes applied to both nixie tubes during step 1 of second page on manual
                for (byte i = 0; i < colorValues.Length - 1; i++)
                {
                    //each digit rule
                    switch (colorValues[i])
                    {
                    case 0: nixie1 += 5; nixie2 -= 1; break;

                    case 1: nixie1 -= 1; nixie2 -= 6; break;

                    case 2: nixie1 += 3; break;

                    case 3: nixie1 += 7; nixie2 -= 4; break;

                    case 4: nixie1 -= 7; nixie2 -= 5; break;

                    case 5: nixie1 += 8; nixie2 += 9; break;

                    case 6: nixie1 += 5; nixie2 -= 9; break;

                    case 7: nixie1 -= 9; nixie2 += 4; break;

                    case 8: nixie2 += 7; break;

                    case 9: nixie1 -= 3; nixie2 += 5; break;
                    }
                    Debug.LogFormat("[Forget The Colors #{0}]: Applying the {1}-colored cylinder on the first table, the nixies are now {2} and {3}.", moduleId, Strings.ColorLog[colorValues[i]], nixie1, nixie2);
                }
            }

            else
            {
                for (byte i = 0; i < colorValues.Length - 1; i++)
                {
                    Rule rule = rules[0][colorValues[i]];

                    switch (rule.Operator)
                    {
                    case 0: nixie1 += (sbyte)rule.Cylinder; break;

                    case 1: nixie1 -= (sbyte)rule.Cylinder; break;

                    case 2: nixie1 *= (sbyte)rule.Cylinder; break;

                    case 3: if (nixie1 != 0)
                        {
                            nixie1 = (sbyte)(nixie1 / rule.Cylinder);
                        }
                        break;

                    case 4: if (rule.Cylinder != 0)
                        {
                            nixie1 = (sbyte)Ease.Modulo(nixie1, rule.Cylinder);
                        }
                        break;
                    }

                    rule = rules[0][colorValues[i] + 10];

                    switch (rule.Operator)
                    {
                    case 0: nixie2 += (sbyte)rule.Cylinder; break;

                    case 1: nixie2 -= (sbyte)rule.Cylinder; break;

                    case 2: nixie2 *= (sbyte)rule.Cylinder; break;

                    case 3: if (nixie2 != 0)
                        {
                            nixie2 = (sbyte)(nixie2 / rule.Cylinder);
                        }
                        break;

                    case 4: if (rule.Cylinder != 0)
                        {
                            nixie2 = (sbyte)Ease.Modulo(nixie2, rule.Cylinder);
                        }
                        break;
                    }

                    Debug.LogFormat("[Forget The Colors #{0}]: Applying the {1}-colored cylinder on the first table, the nixies are now {2} and {3}.", moduleId, Strings.ColorLog[colorValues[i]], nixie1, nixie2);
                }
            }

            //modulo
            nixie1 = (sbyte)Ease.Modulo(nixie1, 10);
            nixie2 = (sbyte)Ease.Modulo(nixie2, 10);
            Debug.LogFormat("[Forget The Colors #{0}]: Modulo 10, their values are now {1} and {2}.", moduleId, nixie1, nixie2);

            Debug.LogFormat("[Forget The Colors #{0}]: <-------=-------> GEAR NUMBER ~ SECOND TABLE <-------=------->", moduleId);

            //new gear = calculated nixies + gear
            int lsd = (byte)Ease.Modulo(nixie1 + nixie2 + int.Parse(GearText.text[Convert.ToByte(colorblind)].ToString()), 10);

            Debug.LogFormat("[Forget The Colors #{0}]: Combine both nixies ({1}&{2}) and the gear number {3}. The sum is {4}. Modulo 10, its value is {5}.", moduleId, nixie1, nixie2, GearText.text[Convert.ToByte(colorblind)], nixie1 + nixie2 + int.Parse(GearText.text[Convert.ToByte(colorblind)].ToString()), lsd);

            //move the index up and down according to calculated nixies
            Debug.LogFormat("[Forget The Colors #{0}]: Start on gear color ({1}), move up left nixie ({2}) which lands on {3}, then move down right nixie ({4}) which lands us on {5}.", moduleId, Strings.ColorLog[colorValues[3]], nixie1, Strings.ColorLog[(int)Ease.Modulo(colorValues[3] - nixie1, 10)], nixie2, Strings.ColorLog[(int)Ease.Modulo(colorValues[3] - nixie1 + nixie2, 10)]);

            if (rules == null)
            {
                //this will run through the changes applied to the gear during step 2 of second page on manual
                switch ((int)Ease.Modulo(colorValues[3] - nixie1 + nixie2, 10))
                {
                case 0: lsd += BombInfo.GetBatteryCount(); break;

                case 1: lsd -= BombInfo.GetPortCount(); break;

                case 2: lsd += BombInfo.GetSerialNumberNumbers().Last(); break;

                case 3: lsd -= BombInfo.GetSolvedModuleNames().Count(); break;

                case 4: lsd += BombInfo.GetPortPlateCount(); break;

                case 5: lsd -= BombInfo.GetModuleNames().Count(); break;

                case 6: lsd += BombInfo.GetBatteryHolderCount(); break;

                case 7: lsd -= BombInfo.GetOnIndicators().Count(); break;

                case 8: lsd += BombInfo.GetIndicators().Count(); break;

                case 9: lsd -= BombInfo.GetOffIndicators().Count(); break;
                }
            }

            else
            {
                string[] ports = new string[BombInfo.GetPorts().Count()];
                for (ushort i = 0; i < BombInfo.GetPorts().Count(); i++)
                {
                    ports[i] = BombInfo.GetPorts().ElementAt(i);
                }

                int ignoredCount = 0;
                foreach (string module in BombInfo.GetModuleNames())
                {
                    if (Strings.Ignore.Contains(module))
                    {
                        ignoredCount++;
                    }
                }

                Rule rule = rules[1][(int)Ease.Modulo(colorValues[3] - nixie1 + nixie2, 10)];

                //the smaller display is used as a debug displayer in the editor, which cannot be parsed
                int[] edgework = new int[22] {
                    BombInfo.GetBatteryCount(), BombInfo.GetBatteryCount(Battery.AA) + BombInfo.GetBatteryCount(Battery.AAx3) + BombInfo.GetBatteryCount(Battery.AAx4), BombInfo.GetBatteryCount(Battery.D), BombInfo.GetBatteryHolderCount(), BombInfo.GetIndicators().Count(), BombInfo.GetOnIndicators().Count(), BombInfo.GetOffIndicators().Count(), BombInfo.GetPortPlateCount(), BombInfo.GetPorts().Distinct().Count(), BombInfo.GetPorts().Count() - BombInfo.GetPorts().Distinct().Count(), BombInfo.GetPortCount(), BombInfo.GetSerialNumberNumbers().First(), BombInfo.GetSerialNumberNumbers().Last(), BombInfo.GetSerialNumberNumbers().Count(), BombInfo.GetSerialNumberLetters().Count(), BombInfo.GetSolvedModuleNames().Count(), maxStage, BombInfo.GetModuleNames().Count(), BombInfo.GetSolvableModuleNames().Count() - BombInfo.GetSolvedModuleNames().Count(), ignoredCount, Application.isEditor ? 0 : int.Parse(DisplayTexts[1].text), int.Parse(DisplayTexts[0].text)
                };

                switch (rule.Operator)
                {
                case 0: lsd += edgework[rule.Edgework]; break;

                case 1: lsd -= edgework[rule.Edgework]; break;

                case 2: lsd *= edgework[rule.Edgework]; break;

                case 3: if (edgework[rule.Edgework] != 0)
                    {
                        lsd = nixie2 / edgework[rule.Edgework];
                    }
                    break;

                case 4: if (edgework[rule.Edgework] != 0)
                    {
                        lsd = (int)Ease.Modulo(nixie2, edgework[rule.Edgework]);
                    }
                    break;
                }
            }

            ruleColor[currentStage] = Strings.ColorLog[(int)Ease.Modulo(colorValues[3] - nixie1 + nixie2, 10)];
            Debug.LogFormat("[Forget The Colors #{0}]: Apply the color rule {1} to the sum of the first nixie ({2}) + the second nixie ({3}) + the gear number ({4}). This gives us {5}. Modulo 10, its value is {6}.", moduleId, Strings.ColorLog[(int)Ease.Modulo(colorValues[3] - nixie1 + nixie2, 10)], nixie1, nixie2, GearText.text, nixie1 + nixie2 + int.Parse(GearText.text.Last().ToString()), Ease.Modulo(lsd, 10));

            //modulo
            lsd = (int)Ease.Modulo(lsd, 10);

            Debug.LogFormat("[Forget The Colors #{0}]: <-------=-------> STAGE VALUE ~ SINE/COSINE) <-------=------->", moduleId);

            //get the sine degrees
            Debug.LogFormat("[Forget The Colors #{0}]: The nixies are {1} and {2}, and the number obtained before is {3}, combining all of them gives us {4}.", moduleId, nixie1, nixie2, lsd, string.Concat(nixie1, nixie2, lsd));
            int sin = (int)(Math.Sin(int.Parse(string.Concat(nixie1, nixie2, lsd)) * Mathf.Deg2Rad) * 100000 % 100000);

            //floating point rounding fix, ensuring that it adds/subtracts 1 depending if it's a positive or negative number
            if (Ease.Modulo(Math.Abs(sin), 1000) == 999)
            {
                if (sin > 0)
                {
                    sin = (sin + 1) % 100000;
                }
                else
                {
                    sin = (sin - 1) % 100000;
                }
            }

            //get stage number
            int cos = (int)(Math.Abs(Math.Cos(int.Parse(DisplayTexts[0].text) * Mathf.Deg2Rad) * 100000) % 100000);

            //floating point rounding fix
            if (Ease.Modulo(cos, 1000) == 999)
            {
                cos = (int)Ease.Modulo(cos + 1, 100000);
            }

            Debug.LogFormat("[Forget The Colors #{0}]: The first five decimals of sin({1}) is {2}. The absolute of the first five decimals of cos({3}) is {4}.", moduleId, string.Concat(nixie1, nixie2, lsd), sin, DisplayTexts[0].text, cos);

            //get final value for the stage
            calculatedValues[currentStage] = cos + sin;
            Debug.LogFormat("[Forget The Colors #{0}]: Stage {1}'s value is sine's {2} + cosine's {3} which is {4}.", moduleId, currentStage, sin, cos, (cos + sin).ToString("F0"));

            sineNumber[currentStage] = sin;
        }