mirror of
https://github.com/osukey/osukey.git
synced 2025-07-02 08:49:59 +09:00
Update judgement processors with new hit results
This commit is contained in:
@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Catch.Scoring
|
|||||||
{
|
{
|
||||||
public class CatchScoreProcessor : ScoreProcessor
|
public class CatchScoreProcessor : ScoreProcessor
|
||||||
{
|
{
|
||||||
public override HitWindows CreateHitWindows() => new CatchHitWindows();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,5 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
|||||||
protected override double DefaultAccuracyPortion => 0.95;
|
protected override double DefaultAccuracyPortion => 0.95;
|
||||||
|
|
||||||
protected override double DefaultComboPortion => 0.05;
|
protected override double DefaultComboPortion => 0.05;
|
||||||
|
|
||||||
public override HitWindows CreateHitWindows() => new ManiaHitWindows();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,5 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
|||||||
return new OsuJudgementResult(hitObject, judgement);
|
return new OsuJudgementResult(hitObject, judgement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override HitWindows CreateHitWindows() => new OsuHitWindows();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,5 @@ namespace osu.Game.Rulesets.Taiko.Scoring
|
|||||||
protected override double DefaultAccuracyPortion => 0.75;
|
protected override double DefaultAccuracyPortion => 0.75;
|
||||||
|
|
||||||
protected override double DefaultComboPortion => 0.25;
|
protected override double DefaultComboPortion => 0.25;
|
||||||
|
|
||||||
public override HitWindows CreateHitWindows() => new TaikoHitWindows();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -167,7 +167,7 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
|
|
||||||
beatmap.HitObjects.Add(new JudgeableHitObject { StartTime = 0 });
|
beatmap.HitObjects.Add(new JudgeableHitObject { StartTime = 0 });
|
||||||
for (double time = 0; time < 5000; time += 100)
|
for (double time = 0; time < 5000; time += 100)
|
||||||
beatmap.HitObjects.Add(new JudgeableHitObject(false) { StartTime = time });
|
beatmap.HitObjects.Add(new JudgeableHitObject(HitResult.LargeBonus) { StartTime = time });
|
||||||
beatmap.HitObjects.Add(new JudgeableHitObject { StartTime = 5000 });
|
beatmap.HitObjects.Add(new JudgeableHitObject { StartTime = 5000 });
|
||||||
|
|
||||||
createProcessor(beatmap);
|
createProcessor(beatmap);
|
||||||
@ -215,23 +215,23 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
|
|
||||||
private class JudgeableHitObject : HitObject
|
private class JudgeableHitObject : HitObject
|
||||||
{
|
{
|
||||||
private readonly bool affectsCombo;
|
private readonly HitResult maxResult;
|
||||||
|
|
||||||
public JudgeableHitObject(bool affectsCombo = true)
|
public JudgeableHitObject(HitResult maxResult = HitResult.Perfect)
|
||||||
{
|
{
|
||||||
this.affectsCombo = affectsCombo;
|
this.maxResult = maxResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Judgement CreateJudgement() => new TestJudgement(affectsCombo);
|
public override Judgement CreateJudgement() => new TestJudgement(maxResult);
|
||||||
protected override HitWindows CreateHitWindows() => new HitWindows();
|
protected override HitWindows CreateHitWindows() => new HitWindows();
|
||||||
|
|
||||||
private class TestJudgement : Judgement
|
private class TestJudgement : Judgement
|
||||||
{
|
{
|
||||||
public override bool AffectsCombo { get; }
|
public override HitResult MaxResult { get; }
|
||||||
|
|
||||||
public TestJudgement(bool affectsCombo)
|
public TestJudgement(HitResult maxResult)
|
||||||
{
|
{
|
||||||
AffectsCombo = affectsCombo;
|
MaxResult = maxResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,13 +17,13 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestNoScoreIncreaseFromMiss()
|
public void TestNoScoreIncreaseFromMiss()
|
||||||
{
|
{
|
||||||
var beatmap = new Beatmap<TestHitObject> { HitObjects = { new TestHitObject() } };
|
var beatmap = new Beatmap<HitObject> { HitObjects = { new HitObject() } };
|
||||||
|
|
||||||
var scoreProcessor = new ScoreProcessor();
|
var scoreProcessor = new ScoreProcessor();
|
||||||
scoreProcessor.ApplyBeatmap(beatmap);
|
scoreProcessor.ApplyBeatmap(beatmap);
|
||||||
|
|
||||||
// Apply a miss judgement
|
// Apply a miss judgement
|
||||||
scoreProcessor.ApplyResult(new JudgementResult(new TestHitObject(), new TestJudgement()) { Type = HitResult.Miss });
|
scoreProcessor.ApplyResult(new JudgementResult(new HitObject(), new TestJudgement()) { Type = HitResult.Miss });
|
||||||
|
|
||||||
Assert.That(scoreProcessor.TotalScore.Value, Is.EqualTo(0.0));
|
Assert.That(scoreProcessor.TotalScore.Value, Is.EqualTo(0.0));
|
||||||
}
|
}
|
||||||
@ -31,37 +31,25 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestOnlyBonusScore()
|
public void TestOnlyBonusScore()
|
||||||
{
|
{
|
||||||
var beatmap = new Beatmap<TestBonusHitObject> { HitObjects = { new TestBonusHitObject() } };
|
var beatmap = new Beatmap<HitObject> { HitObjects = { new HitObject() } };
|
||||||
|
|
||||||
var scoreProcessor = new ScoreProcessor();
|
var scoreProcessor = new ScoreProcessor();
|
||||||
scoreProcessor.ApplyBeatmap(beatmap);
|
scoreProcessor.ApplyBeatmap(beatmap);
|
||||||
|
|
||||||
// Apply a judgement
|
// Apply a judgement
|
||||||
scoreProcessor.ApplyResult(new JudgementResult(new TestBonusHitObject(), new TestBonusJudgement()) { Type = HitResult.Perfect });
|
scoreProcessor.ApplyResult(new JudgementResult(new HitObject(), new TestJudgement(HitResult.LargeBonus)) { Type = HitResult.LargeBonus });
|
||||||
|
|
||||||
Assert.That(scoreProcessor.TotalScore.Value, Is.EqualTo(100));
|
Assert.That(scoreProcessor.TotalScore.Value, Is.EqualTo(Judgement.LARGE_BONUS_SCORE));
|
||||||
}
|
|
||||||
|
|
||||||
private class TestHitObject : HitObject
|
|
||||||
{
|
|
||||||
public override Judgement CreateJudgement() => new TestJudgement();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestJudgement : Judgement
|
private class TestJudgement : Judgement
|
||||||
{
|
{
|
||||||
protected override int NumericResultFor(HitResult result) => 100;
|
public override HitResult MaxResult { get; }
|
||||||
}
|
|
||||||
|
|
||||||
private class TestBonusHitObject : HitObject
|
public TestJudgement(HitResult maxResult = HitResult.Perfect)
|
||||||
{
|
{
|
||||||
public override Judgement CreateJudgement() => new TestBonusJudgement();
|
MaxResult = maxResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestBonusJudgement : Judgement
|
|
||||||
{
|
|
||||||
public override bool AffectsCombo => false;
|
|
||||||
|
|
||||||
protected override int NumericResultFor(HitResult result) => 100;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +115,7 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
{
|
{
|
||||||
base.ApplyResultInternal(result);
|
base.ApplyResultInternal(result);
|
||||||
|
|
||||||
if (!result.Judgement.IsBonus)
|
if (!result.Type.IsBonus())
|
||||||
healthIncreases.Add((result.HitObject.GetEndTime() + result.TimeOffset, GetHealthIncreaseFor(result)));
|
healthIncreases.Add((result.HitObject.GetEndTime() + result.TimeOffset, GetHealthIncreaseFor(result)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,6 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
private double maxBaseScore;
|
private double maxBaseScore;
|
||||||
private double rollingMaxBaseScore;
|
private double rollingMaxBaseScore;
|
||||||
private double baseScore;
|
private double baseScore;
|
||||||
private double bonusScore;
|
|
||||||
|
|
||||||
private readonly List<HitEvent> hitEvents = new List<HitEvent>();
|
private readonly List<HitEvent> hitEvents = new List<HitEvent>();
|
||||||
private HitObject lastHitObject;
|
private HitObject lastHitObject;
|
||||||
@ -116,14 +115,15 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
if (result.FailedAtJudgement)
|
if (result.FailedAtJudgement)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (result.Judgement.AffectsCombo)
|
if (!result.Type.IsScorable())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (result.Type.AffectsCombo())
|
||||||
{
|
{
|
||||||
switch (result.Type)
|
switch (result.Type)
|
||||||
{
|
{
|
||||||
case HitResult.None:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case HitResult.Miss:
|
case HitResult.Miss:
|
||||||
|
case HitResult.LargeTickMiss:
|
||||||
Combo.Value = 0;
|
Combo.Value = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -133,22 +133,16 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
double scoreIncrease = result.Type == HitResult.Miss ? 0 : result.Judgement.NumericResultFor(result);
|
double scoreIncrease = result.Type.IsHit() ? result.Judgement.NumericResultFor(result) : 0;
|
||||||
|
|
||||||
if (result.Judgement.IsBonus)
|
if (!result.Type.IsBonus())
|
||||||
{
|
{
|
||||||
if (result.IsHit)
|
|
||||||
bonusScore += scoreIncrease;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (result.HasResult)
|
|
||||||
scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1;
|
|
||||||
|
|
||||||
baseScore += scoreIncrease;
|
baseScore += scoreIncrease;
|
||||||
rollingMaxBaseScore += result.Judgement.MaxNumericResult;
|
rollingMaxBaseScore += result.Judgement.MaxNumericResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) + 1;
|
||||||
|
|
||||||
hitEvents.Add(CreateHitEvent(result));
|
hitEvents.Add(CreateHitEvent(result));
|
||||||
lastHitObject = result.HitObject;
|
lastHitObject = result.HitObject;
|
||||||
|
|
||||||
@ -171,22 +165,19 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
if (result.FailedAtJudgement)
|
if (result.FailedAtJudgement)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double scoreIncrease = result.Type == HitResult.Miss ? 0 : result.Judgement.NumericResultFor(result);
|
if (!result.Type.IsScorable())
|
||||||
|
return;
|
||||||
|
|
||||||
if (result.Judgement.IsBonus)
|
double scoreIncrease = result.Type.IsHit() ? result.Judgement.NumericResultFor(result) : 0;
|
||||||
{
|
|
||||||
if (result.IsHit)
|
|
||||||
bonusScore -= scoreIncrease;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (result.HasResult)
|
|
||||||
scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) - 1;
|
|
||||||
|
|
||||||
|
if (!result.Type.IsBonus())
|
||||||
|
{
|
||||||
baseScore -= scoreIncrease;
|
baseScore -= scoreIncrease;
|
||||||
rollingMaxBaseScore -= result.Judgement.MaxNumericResult;
|
rollingMaxBaseScore -= result.Judgement.MaxNumericResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scoreResultCounts[result.Type] = scoreResultCounts.GetOrDefault(result.Type) - 1;
|
||||||
|
|
||||||
Debug.Assert(hitEvents.Count > 0);
|
Debug.Assert(hitEvents.Count > 0);
|
||||||
lastHitObject = hitEvents[^1].LastHitObject;
|
lastHitObject = hitEvents[^1].LastHitObject;
|
||||||
hitEvents.RemoveAt(hitEvents.Count - 1);
|
hitEvents.RemoveAt(hitEvents.Count - 1);
|
||||||
@ -207,7 +198,7 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
return GetScore(mode, maxHighestCombo,
|
return GetScore(mode, maxHighestCombo,
|
||||||
maxBaseScore > 0 ? baseScore / maxBaseScore : 0,
|
maxBaseScore > 0 ? baseScore / maxBaseScore : 0,
|
||||||
maxHighestCombo > 0 ? (double)HighestCombo.Value / maxHighestCombo : 0,
|
maxHighestCombo > 0 ? (double)HighestCombo.Value / maxHighestCombo : 0,
|
||||||
bonusScore);
|
scoreResultCounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -217,9 +208,9 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
/// <param name="maxCombo">The maximum combo achievable in the beatmap.</param>
|
/// <param name="maxCombo">The maximum combo achievable in the beatmap.</param>
|
||||||
/// <param name="accuracyRatio">The accuracy percentage achieved by the player.</param>
|
/// <param name="accuracyRatio">The accuracy percentage achieved by the player.</param>
|
||||||
/// <param name="comboRatio">The proportion of <paramref name="maxCombo"/> achieved by the player.</param>
|
/// <param name="comboRatio">The proportion of <paramref name="maxCombo"/> achieved by the player.</param>
|
||||||
/// <param name="bonusScore">Any bonus score to be added.</param>
|
/// <param name="statistics">Any statistics to be factored in.</param>
|
||||||
/// <returns>The total score.</returns>
|
/// <returns>The total score.</returns>
|
||||||
public double GetScore(ScoringMode mode, int maxCombo, double accuracyRatio, double comboRatio, double bonusScore)
|
public double GetScore(ScoringMode mode, int maxCombo, double accuracyRatio, double comboRatio, Dictionary<HitResult, int> statistics)
|
||||||
{
|
{
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
@ -228,14 +219,18 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
double accuracyScore = accuracyPortion * accuracyRatio;
|
double accuracyScore = accuracyPortion * accuracyRatio;
|
||||||
double comboScore = comboPortion * comboRatio;
|
double comboScore = comboPortion * comboRatio;
|
||||||
|
|
||||||
return (max_score * (accuracyScore + comboScore) + bonusScore) * scoreMultiplier;
|
return (max_score * (accuracyScore + comboScore) + getBonusScore(statistics)) * scoreMultiplier;
|
||||||
|
|
||||||
case ScoringMode.Classic:
|
case ScoringMode.Classic:
|
||||||
// should emulate osu-stable's scoring as closely as we can (https://osu.ppy.sh/help/wiki/Score/ScoreV1)
|
// should emulate osu-stable's scoring as closely as we can (https://osu.ppy.sh/help/wiki/Score/ScoreV1)
|
||||||
return bonusScore + (accuracyRatio * maxCombo * 300) * (1 + Math.Max(0, (comboRatio * maxCombo) - 1) * scoreMultiplier / 25);
|
return getBonusScore(statistics) + (accuracyRatio * maxCombo * 300) * (1 + Math.Max(0, (comboRatio * maxCombo) - 1) * scoreMultiplier / 25);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private double getBonusScore(Dictionary<HitResult, int> statistics)
|
||||||
|
=> statistics.GetOrDefault(HitResult.SmallBonus) * Judgement.SMALL_BONUS_SCORE
|
||||||
|
+ statistics.GetOrDefault(HitResult.LargeBonus) * Judgement.LARGE_BONUS_SCORE;
|
||||||
|
|
||||||
private ScoreRank rankFrom(double acc)
|
private ScoreRank rankFrom(double acc)
|
||||||
{
|
{
|
||||||
if (acc == 1)
|
if (acc == 1)
|
||||||
@ -282,7 +277,6 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
|
|
||||||
baseScore = 0;
|
baseScore = 0;
|
||||||
rollingMaxBaseScore = 0;
|
rollingMaxBaseScore = 0;
|
||||||
bonusScore = 0;
|
|
||||||
|
|
||||||
TotalScore.Value = 0;
|
TotalScore.Value = 0;
|
||||||
Accuracy.Value = 1;
|
Accuracy.Value = 1;
|
||||||
@ -309,9 +303,7 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
score.Rank = Rank.Value;
|
score.Rank = Rank.Value;
|
||||||
score.Date = DateTimeOffset.Now;
|
score.Date = DateTimeOffset.Now;
|
||||||
|
|
||||||
var hitWindows = CreateHitWindows();
|
foreach (var result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Where(r => r.IsScorable()))
|
||||||
|
|
||||||
foreach (var result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Where(r => r > HitResult.None && hitWindows.IsHitResultAllowed(r)))
|
|
||||||
score.Statistics[result] = GetStatistic(result);
|
score.Statistics[result] = GetStatistic(result);
|
||||||
|
|
||||||
score.HitEvents = hitEvents;
|
score.HitEvents = hitEvents;
|
||||||
@ -320,6 +312,7 @@ namespace osu.Game.Rulesets.Scoring
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a <see cref="HitWindows"/> for this processor.
|
/// Create a <see cref="HitWindows"/> for this processor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[Obsolete("Method is now unused.")] // Can be removed 20210328
|
||||||
public virtual HitWindows CreateHitWindows() => new HitWindows();
|
public virtual HitWindows CreateHitWindows() => new HitWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ namespace osu.Game.Scoring
|
|||||||
|
|
||||||
scoreProcessor.Mods.Value = score.Mods;
|
scoreProcessor.Mods.Value = score.Mods;
|
||||||
|
|
||||||
Value = (long)Math.Round(scoreProcessor.GetScore(ScoringMode.Value, beatmapMaxCombo, score.Accuracy, (double)score.MaxCombo / beatmapMaxCombo, 0));
|
Value = (long)Math.Round(scoreProcessor.GetScore(ScoringMode.Value, beatmapMaxCombo, score.Accuracy, (double)score.MaxCombo / beatmapMaxCombo, score.Statistics));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user