1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 04:52:57 +08:00

Change catch scoring to match score V2

This commit is contained in:
Bartłomiej Dach 2024-01-02 21:58:44 +01:00
parent 16c7c14602
commit 8295ad1feb
No known key found for this signature in database
2 changed files with 69 additions and 15 deletions

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using System; using System;
using System.Collections.Generic;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring; using osu.Game.Scoring;
@ -20,20 +21,73 @@ namespace osu.Game.Rulesets.Catch.Scoring
private const int combo_cap = 200; private const int combo_cap = 200;
private const double combo_base = 4; private const double combo_base = 4;
private double fruitTinyScale;
public CatchScoreProcessor() public CatchScoreProcessor()
: base(new CatchRuleset()) : base(new CatchRuleset())
{ {
} }
protected override void Reset(bool storeResults)
{
base.Reset(storeResults);
// large ticks are *purposefully* not counted to match stable
int fruitTinyScaleDivisor = MaximumResultCounts.GetValueOrDefault(HitResult.SmallTickHit) + MaximumResultCounts.GetValueOrDefault(HitResult.Great);
fruitTinyScale = fruitTinyScaleDivisor == 0
? 0
: (double)MaximumResultCounts.GetValueOrDefault(HitResult.SmallTickHit) / fruitTinyScaleDivisor;
}
protected override double ComputeTotalScore(double comboProgress, double accuracyProgress, double bonusPortion) protected override double ComputeTotalScore(double comboProgress, double accuracyProgress, double bonusPortion)
{ {
return 600000 * comboProgress const int max_tiny_droplets_portion = 400000;
+ 400000 * Accuracy.Value * accuracyProgress
double comboPortion = 1000000 - max_tiny_droplets_portion + max_tiny_droplets_portion * (1 - fruitTinyScale);
double dropletsPortion = max_tiny_droplets_portion * fruitTinyScale;
double dropletsHit = MaximumResultCounts.GetValueOrDefault(HitResult.SmallTickHit) == 0
? 0
: (double)ScoreResultCounts.GetValueOrDefault(HitResult.SmallTickHit) / MaximumResultCounts.GetValueOrDefault(HitResult.SmallTickHit);
return comboPortion * comboProgress
+ dropletsPortion * dropletsHit
+ bonusPortion; + bonusPortion;
} }
public override int GetBaseScoreForResult(HitResult result)
{
switch (result)
{
// dirty hack to emulate accuracy on stable weighting every object equally in accuracy portion
case HitResult.Great:
case HitResult.LargeTickHit:
case HitResult.SmallTickHit:
return 300;
case HitResult.LargeBonus:
return 200;
}
return base.GetBaseScoreForResult(result);
}
protected override double GetComboScoreChange(JudgementResult result) protected override double GetComboScoreChange(JudgementResult result)
=> GetBaseScoreForResult(result.Type) * Math.Min(Math.Max(0.5, Math.Log(result.ComboAfterJudgement, combo_base)), Math.Log(combo_cap, combo_base)); {
double baseIncrease = 0;
switch (result.Type)
{
case HitResult.Great:
baseIncrease = 300;
break;
case HitResult.LargeTickHit:
baseIncrease = 100;
break;
}
return baseIncrease * Math.Min(Math.Max(0.5, Math.Log(result.ComboAfterJudgement, combo_base)), Math.Log(combo_cap, combo_base));
}
public override ScoreRank RankFromAccuracy(double accuracy) public override ScoreRank RankFromAccuracy(double accuracy)
{ {

View File

@ -167,14 +167,14 @@ namespace osu.Game.Rulesets.Scoring
if (!beatmapApplied) if (!beatmapApplied)
throw new InvalidOperationException($"Cannot access maximum statistics before calling {nameof(ApplyBeatmap)}."); throw new InvalidOperationException($"Cannot access maximum statistics before calling {nameof(ApplyBeatmap)}.");
return new Dictionary<HitResult, int>(maximumResultCounts); return new Dictionary<HitResult, int>(MaximumResultCounts);
} }
} }
private bool beatmapApplied; private bool beatmapApplied;
private readonly Dictionary<HitResult, int> scoreResultCounts = new Dictionary<HitResult, int>(); protected readonly Dictionary<HitResult, int> ScoreResultCounts = new Dictionary<HitResult, int>();
private readonly Dictionary<HitResult, int> maximumResultCounts = new Dictionary<HitResult, int>(); protected readonly Dictionary<HitResult, int> MaximumResultCounts = new Dictionary<HitResult, int>();
private readonly List<HitEvent> hitEvents = new List<HitEvent>(); private readonly List<HitEvent> hitEvents = new List<HitEvent>();
private HitObject? lastHitObject; private HitObject? lastHitObject;
@ -216,7 +216,7 @@ namespace osu.Game.Rulesets.Scoring
if (result.FailedAtJudgement) if (result.FailedAtJudgement)
return; return;
scoreResultCounts[result.Type] = scoreResultCounts.GetValueOrDefault(result.Type) + 1; ScoreResultCounts[result.Type] = ScoreResultCounts.GetValueOrDefault(result.Type) + 1;
if (result.Type.IncreasesCombo()) if (result.Type.IncreasesCombo())
Combo.Value++; Combo.Value++;
@ -272,7 +272,7 @@ namespace osu.Game.Rulesets.Scoring
if (result.FailedAtJudgement) if (result.FailedAtJudgement)
return; return;
scoreResultCounts[result.Type] = scoreResultCounts.GetValueOrDefault(result.Type) - 1; ScoreResultCounts[result.Type] = ScoreResultCounts.GetValueOrDefault(result.Type) - 1;
if (result.Judgement.MaxResult.AffectsAccuracy()) if (result.Judgement.MaxResult.AffectsAccuracy())
{ {
@ -394,13 +394,13 @@ namespace osu.Game.Rulesets.Scoring
maximumComboPortion = currentComboPortion; maximumComboPortion = currentComboPortion;
maximumAccuracyJudgementCount = currentAccuracyJudgementCount; maximumAccuracyJudgementCount = currentAccuracyJudgementCount;
maximumResultCounts.Clear(); MaximumResultCounts.Clear();
maximumResultCounts.AddRange(scoreResultCounts); MaximumResultCounts.AddRange(ScoreResultCounts);
MaximumTotalScore = TotalScore.Value; MaximumTotalScore = TotalScore.Value;
} }
scoreResultCounts.Clear(); ScoreResultCounts.Clear();
currentBaseScore = 0; currentBaseScore = 0;
currentMaximumBaseScore = 0; currentMaximumBaseScore = 0;
@ -430,10 +430,10 @@ namespace osu.Game.Rulesets.Scoring
score.MaximumStatistics.Clear(); score.MaximumStatistics.Clear();
foreach (var result in HitResultExtensions.ALL_TYPES) foreach (var result in HitResultExtensions.ALL_TYPES)
score.Statistics[result] = scoreResultCounts.GetValueOrDefault(result); score.Statistics[result] = ScoreResultCounts.GetValueOrDefault(result);
foreach (var result in HitResultExtensions.ALL_TYPES) foreach (var result in HitResultExtensions.ALL_TYPES)
score.MaximumStatistics[result] = maximumResultCounts.GetValueOrDefault(result); score.MaximumStatistics[result] = MaximumResultCounts.GetValueOrDefault(result);
// Populate total score after everything else. // Populate total score after everything else.
score.TotalScore = TotalScore.Value; score.TotalScore = TotalScore.Value;
@ -464,8 +464,8 @@ namespace osu.Game.Rulesets.Scoring
HighestCombo.Value = frame.Header.MaxCombo; HighestCombo.Value = frame.Header.MaxCombo;
TotalScore.Value = frame.Header.TotalScore; TotalScore.Value = frame.Header.TotalScore;
scoreResultCounts.Clear(); ScoreResultCounts.Clear();
scoreResultCounts.AddRange(frame.Header.Statistics); ScoreResultCounts.AddRange(frame.Header.Statistics);
SetScoreProcessorStatistics(frame.Header.ScoreProcessorStatistics); SetScoreProcessorStatistics(frame.Header.ScoreProcessorStatistics);