コード例 #1
0
 public virtual PerformanceCalculator CreatePerformanceCalculator(DifficultyAttributes attributes, ScoreInfo score) => null;
コード例 #2
0
ファイル: CatchRuleset.cs プロジェクト: yurabolt/osu
 public override PerformanceCalculator CreatePerformanceCalculator(DifficultyAttributes attributes, ScoreInfo score) => new CatchPerformanceCalculator(this, attributes, score);
コード例 #3
0
        protected override PerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes)
        {
            var maniaAttributes = (ManiaDifficultyAttributes)attributes;

            scaledScore  = score.TotalScore;
            countPerfect = score.Statistics.GetValueOrDefault(HitResult.Perfect);
            countGreat   = score.Statistics.GetValueOrDefault(HitResult.Great);
            countGood    = score.Statistics.GetValueOrDefault(HitResult.Good);
            countOk      = score.Statistics.GetValueOrDefault(HitResult.Ok);
            countMeh     = score.Statistics.GetValueOrDefault(HitResult.Meh);
            countMiss    = score.Statistics.GetValueOrDefault(HitResult.Miss);

            if (maniaAttributes.ScoreMultiplier > 0)
            {
                // Scale score up, so it's comparable to other keymods
                scaledScore *= 1.0 / maniaAttributes.ScoreMultiplier;
            }

            // Arbitrary initial value for scaling pp in order to standardize distributions across game modes.
            // The specific number has no intrinsic meaning and can be adjusted as needed.
            double multiplier = 0.8;

            if (score.Mods.Any(m => m is ModNoFail))
            {
                multiplier *= 0.9;
            }
            if (score.Mods.Any(m => m is ModEasy))
            {
                multiplier *= 0.5;
            }

            double difficultyValue = computeDifficultyValue(maniaAttributes);
            double accValue        = computeAccuracyValue(difficultyValue, maniaAttributes);
            double totalValue      =
                Math.Pow(
                    Math.Pow(difficultyValue, 1.1) +
                    Math.Pow(accValue, 1.1), 1.0 / 1.1
                    ) * multiplier;

            return(new ManiaPerformanceAttributes
            {
                Difficulty = difficultyValue,
                Accuracy = accValue,
                ScaledScore = scaledScore,
                Total = totalValue
            });
        }
コード例 #4
0
 public OsuPerformanceCalculator(Ruleset ruleset, DifficultyAttributes attributes, ScoreInfo score)
     : base(ruleset, attributes, score)
 {
 }
コード例 #5
0
        protected override PerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes)
        {
            var taikoAttributes = (TaikoDifficultyAttributes)attributes;

            countGreat = score.Statistics.GetValueOrDefault(HitResult.Great);
            countOk    = score.Statistics.GetValueOrDefault(HitResult.Ok);
            countMeh   = score.Statistics.GetValueOrDefault(HitResult.Meh);
            countMiss  = score.Statistics.GetValueOrDefault(HitResult.Miss);

            double multiplier = 1.1; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things

            if (score.Mods.Any(m => m is ModNoFail))
            {
                multiplier *= 0.90;
            }

            if (score.Mods.Any(m => m is ModHidden))
            {
                multiplier *= 1.10;
            }

            double difficultyValue = computeDifficultyValue(score, taikoAttributes);
            double accuracyValue   = computeAccuracyValue(score, taikoAttributes);
            double totalValue      =
                Math.Pow(
                    Math.Pow(difficultyValue, 1.1) +
                    Math.Pow(accuracyValue, 1.1), 1.0 / 1.1
                    ) * multiplier;

            return(new TaikoPerformanceAttributes
            {
                Difficulty = difficultyValue,
                Accuracy = accuracyValue,
                Total = totalValue
            });
        }
コード例 #6
0
        protected override PerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes)
        {
            var catchAttributes = (CatchDifficultyAttributes)attributes;

            fruitsHit       = score.Statistics.GetValueOrDefault(HitResult.Great);
            ticksHit        = score.Statistics.GetValueOrDefault(HitResult.LargeTickHit);
            tinyTicksHit    = score.Statistics.GetValueOrDefault(HitResult.SmallTickHit);
            tinyTicksMissed = score.Statistics.GetValueOrDefault(HitResult.SmallTickMiss);
            misses          = score.Statistics.GetValueOrDefault(HitResult.Miss);

            // We are heavily relying on aim in catch the beat
            double value = Math.Pow(5.0 * Math.Max(1.0, catchAttributes.StarRating / 0.0049) - 4.0, 2.0) / 100000.0;

            // Longer maps are worth more. "Longer" means how many hits there are which can contribute to combo
            int numTotalHits = totalComboHits();

            double lengthBonus =
                0.95 + 0.3 * Math.Min(1.0, numTotalHits / 2500.0) +
                (numTotalHits > 2500 ? Math.Log10(numTotalHits / 2500.0) * 0.475 : 0.0);

            value *= lengthBonus;

            value *= Math.Pow(0.97, misses);

            // Combo scaling
            if (catchAttributes.MaxCombo > 0)
            {
                value *= Math.Min(Math.Pow(score.MaxCombo, 0.8) / Math.Pow(catchAttributes.MaxCombo, 0.8), 1.0);
            }

            double approachRate       = catchAttributes.ApproachRate;
            double approachRateFactor = 1.0;

            if (approachRate > 9.0)
            {
                approachRateFactor += 0.1 * (approachRate - 9.0); // 10% for each AR above 9
            }
            if (approachRate > 10.0)
            {
                approachRateFactor += 0.1 * (approachRate - 10.0); // Additional 10% at AR 11, 30% total
            }
            else if (approachRate < 8.0)
            {
                approachRateFactor += 0.025 * (8.0 - approachRate); // 2.5% for each AR below 8
            }
            value *= approachRateFactor;

            if (score.Mods.Any(m => m is ModHidden))
            {
                // Hiddens gives almost nothing on max approach rate, and more the lower it is
                if (approachRate <= 10.0)
                {
                    value *= 1.05 + 0.075 * (10.0 - approachRate); // 7.5% for each AR below 10
                }
                else if (approachRate > 10.0)
                {
                    value *= 1.01 + 0.04 * (11.0 - Math.Min(11.0, approachRate)); // 5% at AR 10, 1% at AR 11
                }
            }

            if (score.Mods.Any(m => m is ModFlashlight))
            {
                value *= 1.35 * lengthBonus;
            }

            value *= Math.Pow(accuracy(), 5.5);

            if (score.Mods.Any(m => m is ModNoFail))
            {
                value *= 0.90;
            }

            return(new CatchPerformanceAttributes
            {
                Total = value
            });
        }
コード例 #7
0
        protected override PerformanceAttributes CreatePerformanceAttributes(ScoreInfo score, DifficultyAttributes attributes)
        {
            var osuAttributes = (OsuDifficultyAttributes)attributes;

            accuracy           = score.Accuracy;
            scoreMaxCombo      = score.MaxCombo;
            countGreat         = score.Statistics.GetValueOrDefault(HitResult.Great);
            countOk            = score.Statistics.GetValueOrDefault(HitResult.Ok);
            countMeh           = score.Statistics.GetValueOrDefault(HitResult.Meh);
            countMiss          = score.Statistics.GetValueOrDefault(HitResult.Miss);
            effectiveMissCount = calculateEffectiveMissCount(osuAttributes);

            double multiplier = 1.12; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things.

            if (score.Mods.Any(m => m is OsuModNoFail))
            {
                multiplier *= Math.Max(0.90, 1.0 - 0.02 * effectiveMissCount);
            }

            if (score.Mods.Any(m => m is OsuModSpunOut) && totalHits > 0)
            {
                multiplier *= 1.0 - Math.Pow((double)osuAttributes.SpinnerCount / totalHits, 0.85);
            }

            if (score.Mods.Any(h => h is OsuModRelax))
            {
                // As we're adding Oks and Mehs to an approximated number of combo breaks the result can be higher than total hits in specific scenarios (which breaks some calculations) so we need to clamp it.
                effectiveMissCount = Math.Min(effectiveMissCount + countOk + countMeh, totalHits);

                multiplier *= 0.6;
            }

            double aimValue        = computeAimValue(score, osuAttributes);
            double speedValue      = computeSpeedValue(score, osuAttributes);
            double accuracyValue   = computeAccuracyValue(score, osuAttributes);
            double flashlightValue = computeFlashlightValue(score, osuAttributes);
            double totalValue      =
                Math.Pow(
                    Math.Pow(aimValue, 1.1) +
                    Math.Pow(speedValue, 1.1) +
                    Math.Pow(accuracyValue, 1.1) +
                    Math.Pow(flashlightValue, 1.1), 1.0 / 1.1
                    ) * multiplier;

            return(new OsuPerformanceAttributes
            {
                Aim = aimValue,
                Speed = speedValue,
                Accuracy = accuracyValue,
                Flashlight = flashlightValue,
                EffectiveMissCount = effectiveMissCount,
                Total = totalValue
            });
        }
コード例 #8
0
 public TimedDifficultyAttributes(double time, DifficultyAttributes attributes)
 {
     Time       = time;
     Attributes = attributes;
 }
コード例 #9
0
ファイル: StarDifficulty.cs プロジェクト: Wieku/osu
 public StarDifficulty(double starDifficulty, int maxCombo)
 {
     Stars      = starDifficulty;
     MaxCombo   = maxCombo;
     Attributes = null;
 }