1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-26 18:03:11 +08:00

Rewrite ScoreProcessor to have a new method for when existing judgements are changed.

- OnNewJudgement: Keeps its previous functionality. It is now only invoked when a _new_ judgement has been added to the Judgements hashset.
- OnJudgementChanged: Has a similar funcitonality to OnNewJudgement, but is only invoked whenever a judgement that was _previously_ in the Judgements hashset is changed.
This commit is contained in:
smoogipooo 2017-03-30 10:51:14 +09:00
parent c2d6faa7c2
commit 6287ba321d
7 changed files with 75 additions and 44 deletions

View File

@ -55,7 +55,6 @@ namespace osu.Desktop.VisualTests.Tests
Result = HitResult.Hit,
TaikoResult = hitResult,
TimeOffset = 0,
ComboAtHit = 1,
SecondHit = RNG.Next(10) == 0
}
});
@ -68,8 +67,7 @@ namespace osu.Desktop.VisualTests.Tests
Judgement = new TaikoJudgement
{
Result = HitResult.Miss,
TimeOffset = 0,
ComboAtHit = 0
TimeOffset = 0
}
});
}

View File

@ -19,7 +19,7 @@ namespace osu.Game.Modes.Catch.Scoring
{
}
protected override void OnNewJugement(CatchJudgement judgement)
protected override void OnNewJudgement(CatchJudgement judgement)
{
}
}

View File

@ -19,7 +19,7 @@ namespace osu.Game.Modes.Mania.Scoring
{
}
protected override void OnNewJugement(ManiaJudgement judgement)
protected override void OnNewJudgement(ManiaJudgement judgement)
{
}
}

View File

@ -28,7 +28,7 @@ namespace osu.Game.Modes.Osu.Scoring
Accuracy.Value = 1;
}
protected override void OnNewJugement(OsuJudgement judgement)
protected override void OnNewJudgement(OsuJudgement judgement)
{
if (judgement != null)
{

View File

@ -96,9 +96,9 @@ namespace osu.Game.Modes.Taiko.Scoring
/// <summary>
/// The multiple of the original score added to the combo portion of the score
/// for correctly hitting an accented hit object with both keys.
/// for correctly hitting a strong hit object with both keys.
/// </summary>
private double accentedHitScale;
private double strongHitScale;
private double hpIncreaseTick;
private double hpIncreaseGreat;
@ -128,12 +128,12 @@ namespace osu.Game.Modes.Taiko.Scoring
hpIncreaseGood = hpMultiplierNormal * hp_hit_good;
hpIncreaseMiss = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.Difficulty.DrainRate, hp_miss_min, hp_miss_mid, hp_miss_max);
var accentedHits = beatmap.HitObjects.FindAll(o => o is Hit && o.IsStrong);
var strongHits = beatmap.HitObjects.FindAll(o => o is Hit && o.IsStrong);
// This is a linear function that awards:
// 10 times bonus points for hitting an accented hit object with both keys with 30 accented hit objects in the map
// 3 times bonus points for hitting an accented hit object with both keys with 120 accented hit objects in the map
accentedHitScale = -7d / 90d * MathHelper.Clamp(accentedHits.Count, 30, 120) + 111d / 9d;
// 10 times bonus points for hitting a strong hit object with both keys with 30 strong hit objects in the map
// 3 times bonus points for hitting a strong hit object with both keys with 120 strong hit objects in the map
strongHitScale = -7d / 90d * MathHelper.Clamp(strongHits.Count, 30, 120) + 111d / 9d;
foreach (var obj in beatmap.HitObjects)
{
@ -179,7 +179,7 @@ namespace osu.Game.Modes.Taiko.Scoring
maxComboPortion = comboPortion;
}
protected override void OnNewJugement(TaikoJudgement judgement)
protected override void OnNewJudgement(TaikoJudgement judgement)
{
bool isTick = judgement is TaikoDrumRollTickJudgement;
@ -187,29 +187,12 @@ namespace osu.Game.Modes.Taiko.Scoring
if (!isTick)
totalHits++;
// Apply combo changes, must be done before the hit score is added
if (!isTick && judgement.Result == HitResult.Hit)
Combo.Value++;
// Apply score changes
if (judgement.Result == HitResult.Hit)
{
double baseValue = judgement.ResultValueForScore;
// Add bonus points for hitting an accented hit object with the second key
if (judgement.SecondHit)
baseValue += baseValue * accentedHitScale;
// Add score to portions
if (isTick)
bonusScore += baseValue;
else
{
Combo.Value++;
// A relevance factor that needs to be applied to make higher combos more relevant
// Value is capped at 400 combo
double comboRelevance = Math.Min(Math.Log(400, combo_base), Math.Max(0.5, Math.Log(Combo.Value, combo_base)));
comboPortion += baseValue * comboRelevance;
}
}
addHitScore(judgement);
// Apply HP changes
switch (judgement.Result)
@ -235,7 +218,43 @@ namespace osu.Game.Modes.Taiko.Scoring
break;
}
// Compute the new score + accuracy
calculateScore();
}
protected override void OnJudgementChanged(TaikoJudgement judgement)
{
// Apply score changes
addHitScore(judgement);
calculateScore();
}
private void addHitScore(TaikoJudgement judgement)
{
if (judgement.Result != HitResult.Hit)
return;
double baseValue = judgement.ResultValueForScore;
// Add increased score for hitting a strong hit object with the second key
if (judgement.SecondHit)
baseValue *= strongHitScale;
// Add score to portions
if (judgement is TaikoDrumRollTickJudgement)
bonusScore += baseValue;
else
{
// A relevance factor that needs to be applied to make higher combos more relevant
// Value is capped at 400 combo
double comboRelevance = Math.Min(Math.Log(400, combo_base), Math.Max(0.5, Math.Log(Combo.Value, combo_base)));
comboPortion += baseValue * comboRelevance;
}
}
private void calculateScore()
{
int scoreForAccuracy = 0;
int maxScoreForAccuracy = 0;

View File

@ -20,7 +20,7 @@ namespace osu.Game.Modes.Judgements
/// <summary>
/// The combo after this judgement was processed.
/// </summary>
public ulong? ComboAtHit;
public int ComboAtHit;
/// <summary>
/// The string representation for the result achieved.

View File

@ -139,11 +139,13 @@ namespace osu.Game.Modes.Scoring
/// <param name="judgement">The judgement to add.</param>
protected void AddJudgement(TJudgement judgement)
{
Judgements.Add(judgement);
OnNewJugement(judgement);
judgement.ComboAtHit = (ulong)Combo.Value;
if (Judgements.Add(judgement))
{
OnNewJudgement(judgement);
judgement.ComboAtHit = Combo.Value;
}
else
OnJudgementChanged(judgement);
UpdateFailed();
}
@ -154,9 +156,21 @@ namespace osu.Game.Modes.Scoring
}
/// <summary>
/// Update any values that potentially need post-processing on a judgement change.
/// Updates any values that need post-processing. Invoked when a new judgement has occurred.
/// <para>
/// This is not triggered when existing judgements are changed - for that see <see cref="OnJudgementChanged(TJudgement)"/>.
/// </para>
/// </summary>
/// <param name="judgement">The judgement that triggered this calculation.</param>
protected abstract void OnNewJugement(TJudgement judgement);
protected abstract void OnNewJudgement(TJudgement judgement);
/// <summary>
/// Updates any values that need post-processing. Invoked when an existing judgement has changed.
/// <para>
/// This is not triggered when a new judgement has occurred - for that see <see cref="OnNewJudgement(TJudgement)"/>.
/// </para>
/// </summary>
/// <param name="judgement">The judgement that triggered this calculation.</param>
protected virtual void OnJudgementChanged(TJudgement judgement) { }
}
}