diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs
index 9b54b48de3..ba84c21845 100644
--- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs
+++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs
@@ -7,6 +7,10 @@ namespace osu.Game.Rulesets.Mania.Scoring
{
internal class ManiaScoreProcessor : ScoreProcessor
{
+ protected override double DefaultAccuracyPortion => 0.8;
+
+ protected override double DefaultComboPortion => 0.2;
+
public override HitWindows CreateHitWindows() => new ManiaHitWindows();
}
}
diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs
index 003d40af56..e29ea87d25 100644
--- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs
+++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs
@@ -7,6 +7,10 @@ namespace osu.Game.Rulesets.Taiko.Scoring
{
internal class TaikoScoreProcessor : ScoreProcessor
{
+ protected override double DefaultAccuracyPortion => 0.75;
+
+ protected override double DefaultComboPortion => 0.25;
+
public override HitWindows CreateHitWindows() => new TaikoHitWindows();
}
}
diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs
index eb49638d59..f1cdfd93c8 100644
--- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs
+++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs
@@ -7,6 +7,7 @@
using System.Linq;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
+using osu.Framework.Utils;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
@@ -16,8 +17,6 @@ namespace osu.Game.Rulesets.Scoring
{
public class ScoreProcessor : JudgementProcessor
{
- private const double base_portion = 0.3;
- private const double combo_portion = 0.7;
private const double max_score = 1000000;
///
@@ -55,8 +54,20 @@ public class ScoreProcessor : JudgementProcessor
///
public readonly Bindable Mode = new Bindable();
- private double maxHighestCombo;
+ ///
+ /// The default portion of awarded for hitting s accurately. Defaults to 30%.
+ ///
+ protected virtual double DefaultAccuracyPortion => 0.3;
+ ///
+ /// The default portion of awarded for achieving a high combo. Default to 70%.
+ ///
+ protected virtual double DefaultComboPortion => 0.7;
+
+ private readonly double accuracyPortion;
+ private readonly double comboPortion;
+
+ private double maxHighestCombo;
private double maxBaseScore;
private double rollingMaxBaseScore;
private double baseScore;
@@ -69,7 +80,11 @@ public class ScoreProcessor : JudgementProcessor
public ScoreProcessor()
{
- Debug.Assert(base_portion + combo_portion == 1.0);
+ accuracyPortion = DefaultAccuracyPortion;
+ comboPortion = DefaultComboPortion;
+
+ if (!Precision.AlmostEquals(1.0, accuracyPortion + comboPortion))
+ throw new InvalidOperationException($"{nameof(DefaultAccuracyPortion)} + {nameof(DefaultComboPortion)} must equal 1.");
Combo.ValueChanged += combo => HighestCombo.Value = Math.Max(HighestCombo.Value, combo.NewValue);
Accuracy.ValueChanged += accuracy =>
@@ -189,7 +204,10 @@ private double getScore(ScoringMode mode)
{
default:
case ScoringMode.Standardised:
- return (max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo.Value / maxHighestCombo) + bonusScore) * scoreMultiplier;
+ double accuracyScore = accuracyPortion * baseScore / maxBaseScore;
+ double comboScore = comboPortion * HighestCombo.Value / maxHighestCombo;
+
+ return (max_score * (accuracyScore + comboScore) + bonusScore) * scoreMultiplier;
case ScoringMode.Classic:
// should emulate osu-stable's scoring as closely as we can (https://osu.ppy.sh/help/wiki/Score/ScoreV1)