mirror of
https://github.com/ppy/osu
synced 2024-12-15 11:25:29 +00:00
Merge pull request #19940 from smoogipoo/legacy-combo-increase
Add `legacy_combo_increase` hit result type for legacy scores
This commit is contained in:
commit
0d6b7fde92
@ -3,6 +3,7 @@
|
||||
|
||||
#nullable disable
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
@ -314,15 +315,55 @@ namespace osu.Game.Tests.Rulesets.Scoring
|
||||
}), Is.EqualTo(expectedScore).Within(0.5d));
|
||||
}
|
||||
|
||||
#pragma warning disable CS0618
|
||||
[Test]
|
||||
public void TestLegacyComboIncrease()
|
||||
{
|
||||
Assert.That(HitResult.LegacyComboIncrease.IncreasesCombo(), Is.True);
|
||||
Assert.That(HitResult.LegacyComboIncrease.BreaksCombo(), Is.False);
|
||||
Assert.That(HitResult.LegacyComboIncrease.AffectsCombo(), Is.True);
|
||||
Assert.That(HitResult.LegacyComboIncrease.AffectsAccuracy(), Is.False);
|
||||
Assert.That(HitResult.LegacyComboIncrease.IsBasic(), Is.False);
|
||||
Assert.That(HitResult.LegacyComboIncrease.IsTick(), Is.False);
|
||||
Assert.That(HitResult.LegacyComboIncrease.IsBonus(), Is.False);
|
||||
Assert.That(HitResult.LegacyComboIncrease.IsHit(), Is.True);
|
||||
Assert.That(HitResult.LegacyComboIncrease.IsScorable(), Is.True);
|
||||
Assert.That(HitResultExtensions.ALL_TYPES, Does.Not.Contain(HitResult.LegacyComboIncrease));
|
||||
|
||||
// Cannot be used to apply results.
|
||||
Assert.Throws<ArgumentException>(() => scoreProcessor.ApplyBeatmap(new Beatmap
|
||||
{
|
||||
HitObjects = { new TestHitObject(HitResult.LegacyComboIncrease) }
|
||||
}));
|
||||
|
||||
ScoreInfo testScore = new ScoreInfo
|
||||
{
|
||||
MaxCombo = 1,
|
||||
Statistics = new Dictionary<HitResult, int>
|
||||
{
|
||||
{ HitResult.Great, 1 }
|
||||
},
|
||||
MaximumStatistics = new Dictionary<HitResult, int>
|
||||
{
|
||||
{ HitResult.Great, 1 },
|
||||
{ HitResult.LegacyComboIncrease, 1 }
|
||||
}
|
||||
};
|
||||
|
||||
double totalScore = new TestScoreProcessor().ComputeFinalScore(ScoringMode.Standardised, testScore);
|
||||
Assert.That(totalScore, Is.EqualTo(750_000)); // 500K from accuracy (100%), and 250K from combo (50%).
|
||||
}
|
||||
#pragma warning restore CS0618
|
||||
|
||||
private class TestRuleset : Ruleset
|
||||
{
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type) => throw new System.NotImplementedException();
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type) => throw new NotImplementedException();
|
||||
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => throw new System.NotImplementedException();
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => throw new NotImplementedException();
|
||||
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new System.NotImplementedException();
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new NotImplementedException();
|
||||
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => throw new System.NotImplementedException();
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => throw new NotImplementedException();
|
||||
|
||||
public override string Description => string.Empty;
|
||||
public override string ShortName => string.Empty;
|
||||
@ -352,5 +393,33 @@ namespace osu.Game.Tests.Rulesets.Scoring
|
||||
this.maxResult = maxResult;
|
||||
}
|
||||
}
|
||||
|
||||
private class TestScoreProcessor : ScoreProcessor
|
||||
{
|
||||
protected override double DefaultAccuracyPortion => 0.5;
|
||||
protected override double DefaultComboPortion => 0.5;
|
||||
|
||||
public TestScoreProcessor()
|
||||
: base(new TestRuleset())
|
||||
{
|
||||
}
|
||||
|
||||
// ReSharper disable once MemberHidesStaticFromOuterClass
|
||||
private class TestRuleset : Ruleset
|
||||
{
|
||||
protected override IEnumerable<HitResult> GetValidHitResults() => new[] { HitResult.Great };
|
||||
|
||||
public override IEnumerable<Mod> GetModsFor(ModType type) => throw new NotImplementedException();
|
||||
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => throw new NotImplementedException();
|
||||
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new NotImplementedException();
|
||||
|
||||
public override DifficultyCalculator CreateDifficultyCalculator(IWorkingBeatmap beatmap) => throw new NotImplementedException();
|
||||
|
||||
public override string Description => string.Empty;
|
||||
public override string ShortName => string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -119,8 +119,20 @@ namespace osu.Game.Rulesets.Scoring
|
||||
[EnumMember(Value = "ignore_hit")]
|
||||
[Order(12)]
|
||||
IgnoreHit,
|
||||
|
||||
/// <summary>
|
||||
/// A special result used as a padding value for legacy rulesets. It is a hit type and affects combo, but does not affect the base score (does not affect accuracy).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// DO NOT USE.
|
||||
/// </remarks>
|
||||
[EnumMember(Value = "legacy_combo_increase")]
|
||||
[Order(99)]
|
||||
[Obsolete("Do not use.")]
|
||||
LegacyComboIncrease = 99
|
||||
}
|
||||
|
||||
#pragma warning disable CS0618
|
||||
public static class HitResultExtensions
|
||||
{
|
||||
/// <summary>
|
||||
@ -150,6 +162,7 @@ namespace osu.Game.Rulesets.Scoring
|
||||
case HitResult.Perfect:
|
||||
case HitResult.LargeTickHit:
|
||||
case HitResult.LargeTickMiss:
|
||||
case HitResult.LegacyComboIncrease:
|
||||
return true;
|
||||
|
||||
default:
|
||||
@ -161,13 +174,25 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// Whether a <see cref="HitResult"/> affects the accuracy portion of the score.
|
||||
/// </summary>
|
||||
public static bool AffectsAccuracy(this HitResult result)
|
||||
=> IsScorable(result) && !IsBonus(result);
|
||||
{
|
||||
// LegacyComboIncrease is a special type which is neither a basic, tick, bonus, or accuracy-affecting result.
|
||||
if (result == HitResult.LegacyComboIncrease)
|
||||
return false;
|
||||
|
||||
return IsScorable(result) && !IsBonus(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether a <see cref="HitResult"/> is a non-tick and non-bonus result.
|
||||
/// </summary>
|
||||
public static bool IsBasic(this HitResult result)
|
||||
=> IsScorable(result) && !IsTick(result) && !IsBonus(result);
|
||||
{
|
||||
// LegacyComboIncrease is a special type which is neither a basic, tick, bonus, or accuracy-affecting result.
|
||||
if (result == HitResult.LegacyComboIncrease)
|
||||
return false;
|
||||
|
||||
return IsScorable(result) && !IsTick(result) && !IsBonus(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether a <see cref="HitResult"/> should be counted as a tick.
|
||||
@ -225,12 +250,19 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// <summary>
|
||||
/// Whether a <see cref="HitResult"/> is scorable.
|
||||
/// </summary>
|
||||
public static bool IsScorable(this HitResult result) => result >= HitResult.Miss && result < HitResult.IgnoreMiss;
|
||||
public static bool IsScorable(this HitResult result)
|
||||
{
|
||||
// LegacyComboIncrease is not actually scorable (in terms of usable by rulesets for that purpose), but needs to be defined as such to be correctly included in statistics output.
|
||||
if (result == HitResult.LegacyComboIncrease)
|
||||
return true;
|
||||
|
||||
return result >= HitResult.Miss && result < HitResult.IgnoreMiss;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An array of all scorable <see cref="HitResult"/>s.
|
||||
/// </summary>
|
||||
public static readonly HitResult[] ALL_TYPES = ((HitResult[])Enum.GetValues(typeof(HitResult))).ToArray();
|
||||
public static readonly HitResult[] ALL_TYPES = ((HitResult[])Enum.GetValues(typeof(HitResult))).Except(new[] { HitResult.LegacyComboIncrease }).ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Whether a <see cref="HitResult"/> is valid within a given <see cref="HitResult"/> range.
|
||||
@ -251,4 +283,5 @@ namespace osu.Game.Rulesets.Scoring
|
||||
return result > minResult && result < maxResult;
|
||||
}
|
||||
}
|
||||
#pragma warning restore CS0618
|
||||
}
|
||||
|
@ -61,6 +61,11 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// <param name="result">The <see cref="JudgementResult"/> to apply.</param>
|
||||
public void ApplyResult(JudgementResult result)
|
||||
{
|
||||
#pragma warning disable CS0618
|
||||
if (result.Type == HitResult.LegacyComboIncrease)
|
||||
throw new ArgumentException(@$"A {nameof(HitResult.LegacyComboIncrease)} hit result cannot be applied.");
|
||||
#pragma warning restore CS0618
|
||||
|
||||
JudgedHits++;
|
||||
lastAppliedResult = result;
|
||||
|
||||
|
@ -536,6 +536,9 @@ namespace osu.Game.Rulesets.Scoring
|
||||
{
|
||||
extractScoringValues(scoreInfo.Statistics, out current, out maximum);
|
||||
current.MaxCombo = scoreInfo.MaxCombo;
|
||||
|
||||
if (scoreInfo.MaximumStatistics.Count > 0)
|
||||
extractScoringValues(scoreInfo.MaximumStatistics, out _, out maximum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -591,7 +594,8 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
if (result.IsBonus())
|
||||
current.BonusScore += count * Judgement.ToNumericResult(result);
|
||||
else
|
||||
|
||||
if (result.AffectsAccuracy())
|
||||
{
|
||||
// The maximum result of this judgement if it wasn't a miss.
|
||||
// E.g. For a GOOD judgement, the max result is either GREAT/PERFECT depending on which one the ruleset uses (osu!: GREAT, osu!mania: PERFECT).
|
||||
|
Loading…
Reference in New Issue
Block a user