Example #1
0
        private double CalculateManiaPP(double combo, double c50, double c100, double c300, double cMiss, double cKatu = 0, double cGeki = 0)
        {
            if ((Play.Mods & OsuMods.Relax) != 0 || (Play.Mods & OsuMods.Relax2) != 0 ||
                (Play.Mods & OsuMods.Autoplay) != 0)
            {
                return(0f);
            }

            double cTotalHits = c50 + c100 + c300 + cMiss + cGeki + cKatu;

            double real_acc = OsuApi.CalculateAccuracy(Play.Mode, cMiss, c50, c100, c300, cKatu, cGeki);

            double strainbase = System.Math.Pow(5.0 * System.Math.Max(1, (double)Beatmap.Starrating / 0.2) - 4, 2.2) / 135.0;

            strainbase *= 1 + 0.1 * System.Math.Min(1, cTotalHits / 1500);

            double strain          = strainbase;
            double scoreMultiplier = 0;

            if (Play.Score < 500000)
            {
                scoreMultiplier = Play.Score / 500000 * 0.1;
            }
            else if (Play.Score < 600000)
            {
                scoreMultiplier = (Play.Score - 500000) / 100000 * 0.3;
            }
            else if (Play.Score < 700000)
            {
                scoreMultiplier = (Play.Score - 600000) / 100000 * 0.25 + 0.3;
            }
            else if (Play.Score < 800000)
            {
                scoreMultiplier = (Play.Score - 700000) / 100000 * 0.2 + 0.55;
            }
            else if (Play.Score < 900000)
            {
                scoreMultiplier = (Play.Score - 800000) / 100000 * 0.15 + 0.75;
            }
            else
            {
                scoreMultiplier = (Play.Score - 900000) / 100000 * 0.1 + 0.9;
            }


            // float[][] odconvertwindow = new float[2][]
            // {
            //     new float[2] {47, 34},
            //     new float[2] {65, 47}
            // };
            //
            // float odwindow = ((Beatmap.OriginalMode == OsuMode.Standard)) ? odconvertwindow[((Play.Mods&OsuMods.Easy)!=0)?1:0][(Beatmap.MapStats.OD>=5)?1:0]:((64f-3f*Beatmap.MapStats.OD)* (((Play.Mods & OsuMods.Easy) != 0) ? 1.4f : 1f));
            //
            // float acc = Mathf.Max(0.0f, 0.2f - ((odwindow - 34f) * 0.006667f)) * strain;
            // acc *= Mathf.Pow(Mathf.Max(0.0f, (Play.Score - 960000f)) / 40000.0f, 1.1f);

            double acc    = 1.0;
            double nerfod = ((Play.Mods & OsuMods.Easy) != 0) ? 0.5 : 1.0;

            if (Play.Score >= 960000)
            {
                acc = Beatmap.MapStats.OD * nerfod * 0.02 * strainbase *
                      System.Math.Pow((Play.Score - 960000) / 40000, 1.1);
            }
            else
            {
                acc = 0;
            }

            double total = 0.8;

            if ((Play.Mods & OsuMods.NoFail) != 0)
            {
                total *= 0.9;
            }

            if ((Play.Mods & OsuMods.SpunOut) != 0)
            {
                total *= 0.95;
            }

            if ((Play.Mods & OsuMods.Easy) != 0)
            {
                total *= 0.5;
            }

            return(total * System.Math.Pow(
                       System.Math.Pow(strain * scoreMultiplier, 1.1) +
                       System.Math.Pow(acc, 1.1),
                       1.0 / 1.1
                       ));
        }
Example #2
0
        private double CalculateStandardPP(double combo, double c50, double c100, double c300, double cMiss, double cKatu = 0, double cGeki = 0)
        {
            if ((Play.Mods & OsuMods.Relax) != 0 || (Play.Mods & OsuMods.Relax2) != 0 ||
                (Play.Mods & OsuMods.Autoplay) != 0)
            {
                return(0d);
            }

            double Accuracy = OsuApi.CalculateAccuracy(Play.Mode, cMiss, c50, c100, c300, cKatu, cGeki) * 0.01;

            double totalHits = Play.C300 + Play.C100 + Play.C50 + Play.CMiss;

            #region Standard MUL
            double cTotalHits = c50 + c100 + c300 + cMiss;

            double BonusLength = 0.95 + 0.4 * System.Math.Min(1.0, cTotalHits / 2000.0) +
                                 (cTotalHits > 2000.0 ? System.Math.Log10(cTotalHits / 2000.0) * 0.5 : 0.0);

            double BonusApproachRateAim   = 0.0d;
            double BonusApproachRateSpeed = 0.0d;
            if (Beatmap.MapStats.AR > 10.33)
            {
                BonusApproachRateAim = BonusApproachRateSpeed = 0.3d * (Beatmap.MapStats.AR - 10.33d);
            }
            else if (Beatmap.MapStats.AR < 8.0)
            {
                BonusApproachRateAim = 0.1d * (8.0d - Beatmap.MapStats.AR);
            }
            //float BonusApproachRate =
            //    1.0f + Mathf.Min(BonusApproachRateFactor, BonusApproachRateFactor * (cTotalHits / 1000.0f));
            //double BonusApproachRateHitFactor = 1.0d / (1.0d+System.Math.Exp(-(0.007d*(cTotalHits-400d))));
            //double BonusApproachRate = 1.0d+(0.03d + 0.37d * BonusApproachRateHitFactor) * BonusApproachRateFactor;


            double BonusHidden = ((Play.Mods & OsuMods.Hidden) != 0) ? 1.0d + 0.04d * (12.0 - Beatmap.MapStats.AR) : 1.0d;

            double BonusFlashlight = ((Play.Mods & OsuMods.Flashlight) != 0)
                    ? 1.0d + 0.35d * System.Math.Min(1.0d, cTotalHits / 200.0d) + (cTotalHits > 200d ? 0.3d * System.Math.Min(1.0d, (cTotalHits - 200d) / 300d) + (cTotalHits > 500d ? (
                                                                                                                                                                       cTotalHits - 500d) / 1200.0d : 0.0d) : 0.0d) : 1.0d;

            #endregion

            #region Standard EFFMISS

            double comboBasesMissCount = 0.0;
            double beatmapMaxCombo     = Beatmap.TryMaxCombo;
            if (Beatmap.SliderCount > 0)
            {
                double fullComboThreshold = beatmapMaxCombo - 0.1 * (double)Beatmap.SliderCount;
                if (Play.MaxCombo < fullComboThreshold)
                {
                    comboBasesMissCount = fullComboThreshold / System.Math.Max(1, Play.MaxCombo);
                }
            }

            comboBasesMissCount = System.Math.Min(comboBasesMissCount, (double)totalHits);
            double effectiveMissCount = System.Math.Max(Play.CMiss, System.Math.Floor(comboBasesMissCount));

            #endregion

            #region Standard AIM
            double AimValue = GetPPBase((double)Beatmap.StarratingAim);

            //AimValue *= BonusLength;
            AimValue *= BonusLength;

            if (effectiveMissCount > 0)
            {
                AimValue *= 0.97f * System.Math.Pow(1.0 - System.Math.Pow(effectiveMissCount / totalHits, 0.775), effectiveMissCount);
            }
            AimValue *= GetComboScalingFactor(Beatmap);

            //AimValue *= BonusMiss;
            //AimValue *= BonusCombo;
            AimValue *= BonusHidden;

            double estimateDifficultSliders = (double)Beatmap.SliderCount * 0.15;

            if (Beatmap.SliderCount > 0)
            {
                double estimateSliderEndsDropped = System.Math.Min(System.Math.Max(System.Math.Min((double)(Play.C100 + Play.C50 + Play.CMiss), beatmapMaxCombo - Play.MaxCombo), 0.0), estimateDifficultSliders);
                double sliderFactor     = 18; // TEMP, REQUIRES FIX!!!!!
                double sliderNerfFactor = (1.0 - sliderFactor) * System.Math.Pow(1.0 - estimateSliderEndsDropped / estimateDifficultSliders, 3.0) + sliderFactor;
                AimValue *= sliderNerfFactor;
            }

            AimValue *= 1.0d + BonusApproachRateAim * BonusLength;
            AimValue *= BonusFlashlight;

            //AimValue *= (0.5d + Accuracy / 2.0d);
            AimValue *= Accuracy;

            AimValue *= (0.98 + (System.Math.Pow(Beatmap.MapStats.OD, 2.0) / 2500.0));
            #endregion

            #region Standard SPEED
            double SpeedValue = GetPPBase((double)Beatmap.StarratingSpeed);

            SpeedValue *= BonusLength;
            //SpeedValue *= BonusMiss;
            if (effectiveMissCount > 0)
            {
                SpeedValue *= 0.97f * System.Math.Pow(1.0 - System.Math.Pow(effectiveMissCount / totalHits, 0.775), System.Math.Pow(effectiveMissCount, 0.875));
            }
            SpeedValue *= GetComboScalingFactor(Beatmap);
            //SpeedValue *= BonusCombo;
            SpeedValue *= 1.0d + BonusApproachRateSpeed * BonusLength;
            SpeedValue *= BonusHidden;

            SpeedValue *= (0.95 + System.Math.Pow(Beatmap.MapStats.OD, 2.0) / 750.0) *
                          System.Math.Pow(Accuracy, (14.5 - System.Math.Max(Beatmap.MapStats.OD, 8.0)) / 2.0);
            SpeedValue *= System.Math.Pow(0.98d, (c50 < cTotalHits / 500.0) ? (0.0) : (c50 - cTotalHits / 500.0));
            #endregion

            #region Standard ACC

            double BetterAccuracyPercentage = 0d;
            double cHitObjectsWithAccuracy  = (double)Beatmap.CircleCount;
            if (cHitObjectsWithAccuracy > 0)
            {
                BetterAccuracyPercentage = ((c300 - (cTotalHits - cHitObjectsWithAccuracy)) * 6d + c100 * 2d + c50) / (cHitObjectsWithAccuracy * 6d);
            }

            if (BetterAccuracyPercentage < 0)
            {
                BetterAccuracyPercentage = 0d;
            }

            double AccValue = System.Math.Pow(1.52163d, Beatmap.MapStats.OD) * System.Math.Pow(BetterAccuracyPercentage, 24d) * 2.83d;

            AccValue *= System.Math.Min(1.15d, System.Math.Pow(cHitObjectsWithAccuracy / 1000d, 0.3d));

            if ((Play.Mods & OsuMods.Hidden) != 0)
            {
                AccValue *= 1.08d;
            }

            if ((Play.Mods & OsuMods.Flashlight) != 0)
            {
                AccValue *= 1.02d;
            }
            #endregion

            double TotalMultiplier = 1.12d;

            if ((Play.Mods & OsuMods.NoFail) != 0)
            {
                TotalMultiplier *= System.Math.Max(0.9d, 1.0d - 0.02d * effectiveMissCount);
            }

            if ((Play.Mods & OsuMods.SpunOut) != 0)
            {
                TotalMultiplier *= 1.0d - System.Math.Pow((double)Beatmap.SpinnerCount / cTotalHits, 0.85d);
            }

            double TotalValue = System.Math.Pow(
                System.Math.Pow(AimValue, 1.1d) +
                System.Math.Pow(SpeedValue, 1.1d) +
                System.Math.Pow(AccValue, 1.1d),
                1.0d / 1.1d
                ) * TotalMultiplier;

            return(TotalValue);
        }
Example #3
0
        private double CalculateTaikoPP(double combo, double c50, double c100, double c300, double cMiss, double cKatu = 0, double cGeki = 0)
        {
            if ((Play.Mods & OsuMods.Relax) != 0 || (Play.Mods & OsuMods.Relax2) != 0 ||
                (Play.Mods & OsuMods.Autoplay) != 0)
            {
                return(0f);
            }

            double cTotalHits = combo;

            double real_acc = OsuApi.CalculateAccuracy(Play.Mode, cMiss, c50, c100, c300, cKatu, cGeki) * 0.01;
            //float real_acc = Mathf.Min(1.0f, Mathf.Max(0.0f, (c100 * 150 + c300 * 300)/(cTotalHits*300)));

            double strain = System.Math.Pow(5.0 * System.Math.Max(1.0, (double)Beatmap.Starrating / 0.0075) - 4.0, 2.0) / 100000.0;

            double bonusLength = 1 + 0.1 * System.Math.Min(1.0, cTotalHits / 1500);

            strain *= bonusLength;

            strain *= System.Math.Pow(0.985, cMiss);

            strain *= System.Math.Min(System.Math.Pow(Play.MaxCombo, 0.5) / System.Math.Pow(cTotalHits, 0.5), 1);

            if ((Play.Mods & OsuMods.Hidden) != 0)
            {
                strain *= 1.025;
            }

            if ((Play.Mods & OsuMods.Flashlight) != 0)
            {
                strain *= 1.05 * bonusLength;
            }

            strain *= real_acc;

            double hwMax = 20;
            double hwMin = 50;

            double hwResult = hwMin + (hwMax - hwMin) * Beatmap.MapStats.OD / 10;

            hwResult = System.Math.Floor(hwResult) - 0.5;

            if ((Play.Mods & OsuMods.HalfTime) != 0)
            {
                hwResult *= 1.5;
            }
            if ((Play.Mods & OsuMods.DoubleTime) != 0)
            {
                hwResult *= 0.75;
            }

            double OD300 = System.Math.Round(hwResult * 100) / 100;

            double acc = 0;

            if (OD300 > 0)
            {
                acc  = System.Math.Pow(150.0 / OD300, 1.1) * System.Math.Pow(real_acc, 15) * 22.0;
                acc *= System.Math.Min(1.15, System.Math.Pow(cTotalHits / 1500.0, 0.3));
            }

            double total = 1.1;

            if ((Play.Mods & OsuMods.NoFail) != 0)
            {
                total *= 0.9;
            }

            if ((Play.Mods & OsuMods.Hidden) != 0)
            {
                total *= 1.1;
            }

            return(System.Math.Pow(
                       System.Math.Pow(strain, 1.1) + System.Math.Pow(acc, 1.1),
                       1.0 / 1.1
                       ) * total);
        }