mirror of
https://github.com/osukey/osukey.git
synced 2025-08-03 22:56:36 +09:00
Revamp score processing to once more unify scoring methods
This commit is contained in:
@ -15,27 +15,6 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
||||
{
|
||||
internal class TaikoScoreProcessor : ScoreProcessor<TaikoHitObject>
|
||||
{
|
||||
/// <summary>
|
||||
/// The maximum score achievable.
|
||||
/// Does _not_ include bonus score - for bonus score see <see cref="bonusScore"/>.
|
||||
/// </summary>
|
||||
private const int max_score = 1000000;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of the score attributed to combo.
|
||||
/// </summary>
|
||||
private const double combo_portion_max = max_score * 0.2;
|
||||
|
||||
/// <summary>
|
||||
/// The amount of the score attributed to accuracy.
|
||||
/// </summary>
|
||||
private const double accuracy_portion_max = max_score * 0.8;
|
||||
|
||||
/// <summary>
|
||||
/// The factor used to determine relevance of combos.
|
||||
/// </summary>
|
||||
private const double combo_base = 4;
|
||||
|
||||
/// <summary>
|
||||
/// The HP awarded by a <see cref="HitResult.Great"/> hit.
|
||||
/// </summary>
|
||||
@ -76,40 +55,16 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
||||
/// <summary>
|
||||
/// Taiko fails at the end of the map if the player has not half-filled their HP bar.
|
||||
/// </summary>
|
||||
public override bool HasFailed => totalHits == maxTotalHits && Health.Value <= 0.5;
|
||||
public override bool HasFailed => Hits == MaxHits && Health.Value <= 0.5;
|
||||
|
||||
/// <summary>
|
||||
/// The cumulative combo portion of the score.
|
||||
/// </summary>
|
||||
private double comboScore => combo_portion_max * comboPortion / maxComboPortion;
|
||||
|
||||
/// <summary>
|
||||
/// The cumulative accuracy portion of the score.
|
||||
/// </summary>
|
||||
private double accuracyScore => accuracy_portion_max * Math.Pow(Accuracy, 3.6) * totalHits / maxTotalHits;
|
||||
|
||||
/// <summary>
|
||||
/// The cumulative bonus score.
|
||||
/// This is added on top of <see cref="max_score"/>, thus the total score can exceed <see cref="max_score"/>.
|
||||
/// </summary>
|
||||
private double bonusScore;
|
||||
|
||||
/// <summary>
|
||||
/// The multiple of the original score added to the combo portion of the score
|
||||
/// for correctly hitting a strong hit object with both keys.
|
||||
/// </summary>
|
||||
private double strongHitScale;
|
||||
protected override double ComboPortion => 0.2;
|
||||
protected override double AccuracyPortion => 0.8;
|
||||
|
||||
private double hpIncreaseTick;
|
||||
private double hpIncreaseGreat;
|
||||
private double hpIncreaseGood;
|
||||
private double hpIncreaseMiss;
|
||||
|
||||
private double maxComboPortion;
|
||||
private double comboPortion;
|
||||
private int maxTotalHits;
|
||||
private int totalHits;
|
||||
|
||||
public TaikoScoreProcessor()
|
||||
{
|
||||
}
|
||||
@ -128,13 +83,6 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
||||
hpIncreaseGood = hpMultiplierNormal * hp_hit_good;
|
||||
hpIncreaseMiss = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.Difficulty.DrainRate, hp_miss_min, hp_miss_mid, hp_miss_max);
|
||||
|
||||
var strongHits = beatmap.HitObjects.FindAll(o => o is Hit && o.IsStrong);
|
||||
|
||||
// This is a linear function that awards:
|
||||
// 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)
|
||||
{
|
||||
if (obj is Hit)
|
||||
@ -163,46 +111,14 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
||||
AddJudgement(new TaikoJudgement { Result = HitResult.Great });
|
||||
}
|
||||
}
|
||||
|
||||
maxTotalHits = totalHits;
|
||||
maxComboPortion = comboPortion;
|
||||
}
|
||||
|
||||
protected override void OnNewJudgement(Judgement judgement)
|
||||
{
|
||||
bool isStrong = judgement is TaikoStrongHitJudgement;
|
||||
base.OnNewJudgement(judgement);
|
||||
|
||||
bool isTick = judgement is TaikoDrumRollTickJudgement;
|
||||
|
||||
// Don't consider ticks and strong hits as a type of hit that counts towards map completion
|
||||
if (!isTick && !isStrong)
|
||||
totalHits++;
|
||||
|
||||
// Apply score changes
|
||||
if (judgement.IsHit)
|
||||
{
|
||||
double baseValue = judgement.NumericResult;
|
||||
|
||||
if (isStrong)
|
||||
{
|
||||
// Add increased score for the previous judgement by hitting a strong hit object with the second key
|
||||
var prevJudgement = Judgements[Judgements.Count - 1];
|
||||
baseValue = prevJudgement.NumericResult * 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;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply HP changes
|
||||
switch (judgement.Result)
|
||||
{
|
||||
@ -221,20 +137,6 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
||||
Health.Value += hpIncreaseGreat;
|
||||
break;
|
||||
}
|
||||
|
||||
int scoreForAccuracy = 0;
|
||||
int maxScoreForAccuracy = 0;
|
||||
|
||||
foreach (var j in Judgements)
|
||||
{
|
||||
var taikoJudgement = (TaikoJudgement)j;
|
||||
|
||||
scoreForAccuracy += taikoJudgement.ResultNumericForAccuracy;
|
||||
maxScoreForAccuracy += taikoJudgement.MaxResultValueForAccuracy;
|
||||
}
|
||||
|
||||
Accuracy.Value = (double)scoreForAccuracy / maxScoreForAccuracy;
|
||||
TotalScore.Value = comboScore + accuracyScore + bonusScore;
|
||||
}
|
||||
|
||||
protected override void Reset()
|
||||
@ -242,10 +144,6 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
||||
base.Reset();
|
||||
|
||||
Health.Value = 0;
|
||||
|
||||
bonusScore = 0;
|
||||
comboPortion = 0;
|
||||
totalHits = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user