diff --git a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs index d883b91abc..567bf6968f 100644 --- a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs +++ b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs @@ -84,6 +84,7 @@ public void TestSingleOsuHit(ScoringMode scoringMode, HitResult hitResult, int e [TestCase(ScoringMode.Standardised, HitResult.SmallTickHit, HitResult.SmallTickHit, 493_652)] [TestCase(ScoringMode.Standardised, HitResult.LargeTickMiss, HitResult.LargeTickHit, 0)] [TestCase(ScoringMode.Standardised, HitResult.LargeTickHit, HitResult.LargeTickHit, 326_963)] + [TestCase(ScoringMode.Standardised, HitResult.SliderTailHit, HitResult.SliderTailHit, 326_963)] [TestCase(ScoringMode.Standardised, HitResult.SmallBonus, HitResult.SmallBonus, 1_000_030)] [TestCase(ScoringMode.Standardised, HitResult.LargeBonus, HitResult.LargeBonus, 1_000_150)] [TestCase(ScoringMode.Classic, HitResult.Miss, HitResult.Great, 0)] @@ -96,6 +97,7 @@ public void TestSingleOsuHit(ScoringMode scoringMode, HitResult hitResult, int e [TestCase(ScoringMode.Classic, HitResult.SmallTickHit, HitResult.SmallTickHit, 49_365)] [TestCase(ScoringMode.Classic, HitResult.LargeTickMiss, HitResult.LargeTickHit, 0)] [TestCase(ScoringMode.Classic, HitResult.LargeTickHit, HitResult.LargeTickHit, 32_696)] + [TestCase(ScoringMode.Classic, HitResult.SliderTailHit, HitResult.SliderTailHit, 32_696)] [TestCase(ScoringMode.Classic, HitResult.SmallBonus, HitResult.SmallBonus, 100_003)] [TestCase(ScoringMode.Classic, HitResult.LargeBonus, HitResult.LargeBonus, 100_015)] public void TestFourVariousResultsOneMiss(ScoringMode scoringMode, HitResult hitResult, HitResult maxResult, int expectedScore) @@ -167,6 +169,7 @@ public void TestEmptyBeatmap( [TestCase(HitResult.Perfect, HitResult.Miss)] [TestCase(HitResult.SmallTickHit, HitResult.SmallTickMiss)] [TestCase(HitResult.LargeTickHit, HitResult.LargeTickMiss)] + [TestCase(HitResult.SliderTailHit, HitResult.LargeTickMiss)] [TestCase(HitResult.SmallBonus, HitResult.IgnoreMiss)] [TestCase(HitResult.LargeBonus, HitResult.IgnoreMiss)] public void TestMinResults(HitResult hitResult, HitResult expectedMinResult) @@ -187,6 +190,7 @@ public void TestMinResults(HitResult hitResult, HitResult expectedMinResult) [TestCase(HitResult.SmallTickHit, false)] [TestCase(HitResult.LargeTickMiss, true)] [TestCase(HitResult.LargeTickHit, true)] + [TestCase(HitResult.SliderTailHit, true)] [TestCase(HitResult.SmallBonus, false)] [TestCase(HitResult.LargeBonus, false)] public void TestAffectsCombo(HitResult hitResult, bool expectedReturnValue) @@ -207,6 +211,7 @@ public void TestAffectsCombo(HitResult hitResult, bool expectedReturnValue) [TestCase(HitResult.SmallTickHit, true)] [TestCase(HitResult.LargeTickMiss, true)] [TestCase(HitResult.LargeTickHit, true)] + [TestCase(HitResult.SliderTailHit, true)] [TestCase(HitResult.SmallBonus, false)] [TestCase(HitResult.LargeBonus, false)] public void TestAffectsAccuracy(HitResult hitResult, bool expectedReturnValue) @@ -227,6 +232,7 @@ public void TestAffectsAccuracy(HitResult hitResult, bool expectedReturnValue) [TestCase(HitResult.SmallTickHit, false)] [TestCase(HitResult.LargeTickMiss, false)] [TestCase(HitResult.LargeTickHit, false)] + [TestCase(HitResult.SliderTailHit, false)] [TestCase(HitResult.SmallBonus, true)] [TestCase(HitResult.LargeBonus, true)] public void TestIsBonus(HitResult hitResult, bool expectedReturnValue) @@ -247,6 +253,7 @@ public void TestIsBonus(HitResult hitResult, bool expectedReturnValue) [TestCase(HitResult.SmallTickHit, true)] [TestCase(HitResult.LargeTickMiss, false)] [TestCase(HitResult.LargeTickHit, true)] + [TestCase(HitResult.SliderTailHit, true)] [TestCase(HitResult.SmallBonus, true)] [TestCase(HitResult.LargeBonus, true)] public void TestIsHit(HitResult hitResult, bool expectedReturnValue) @@ -267,6 +274,7 @@ public void TestIsHit(HitResult hitResult, bool expectedReturnValue) [TestCase(HitResult.SmallTickHit, true)] [TestCase(HitResult.LargeTickMiss, true)] [TestCase(HitResult.LargeTickHit, true)] + [TestCase(HitResult.SliderTailHit, true)] [TestCase(HitResult.SmallBonus, true)] [TestCase(HitResult.LargeBonus, true)] public void TestIsScorable(HitResult hitResult, bool expectedReturnValue) diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs index 27402d522c..93386de483 100644 --- a/osu.Game/Rulesets/Judgements/Judgement.cs +++ b/osu.Game/Rulesets/Judgements/Judgement.cs @@ -73,6 +73,7 @@ public virtual HitResult MinResult return HitResult.SmallTickMiss; case HitResult.LargeTickHit: + case HitResult.SliderTailHit: return HitResult.LargeTickMiss; default: @@ -104,6 +105,7 @@ protected virtual double HealthIncreaseFor(HitResult result) case HitResult.SmallTickMiss: return -DEFAULT_MAX_HEALTH_INCREASE * 0.5; + case HitResult.SliderTailHit: case HitResult.LargeTickHit: return DEFAULT_MAX_HEALTH_INCREASE; diff --git a/osu.Game/Rulesets/Scoring/HitResult.cs b/osu.Game/Rulesets/Scoring/HitResult.cs index 2d55f1a649..f307344347 100644 --- a/osu.Game/Rulesets/Scoring/HitResult.cs +++ b/osu.Game/Rulesets/Scoring/HitResult.cs @@ -139,6 +139,13 @@ public enum HitResult [Order(15)] ComboBreak, + /// + /// A special judgement similar to that's used to increase the valuation of the final tick of a slider. + /// + [EnumMember(Value = "slider_tail_hit")] + [Order(16)] + SliderTailHit, + /// /// 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). /// @@ -188,6 +195,7 @@ public static bool AffectsCombo(this HitResult result) case HitResult.LargeTickMiss: case HitResult.LegacyComboIncrease: case HitResult.ComboBreak: + case HitResult.SliderTailHit: return true; default: @@ -246,6 +254,7 @@ public static bool IsTick(this HitResult result) case HitResult.LargeTickMiss: case HitResult.SmallTickHit: case HitResult.SmallTickMiss: + case HitResult.SliderTailHit: return true; default: @@ -329,6 +338,9 @@ public static bool IsScorable(this HitResult result) case HitResult.ComboBreak: return true; + case HitResult.SliderTailHit: + return true; + default: // Note that IgnoreHit and IgnoreMiss are excluded as they do not affect score. return result >= HitResult.Miss && result < HitResult.IgnoreMiss; @@ -383,6 +395,9 @@ public static void ValidateHitResultPair(HitResult maxResult, HitResult minResul if (minResult == HitResult.IgnoreMiss) return; + if (maxResult == HitResult.SliderTailHit && minResult != HitResult.LargeTickMiss) + throw new ArgumentOutOfRangeException(nameof(minResult), $"{HitResult.LargeTickMiss} is the only valid minimum result for a {maxResult} judgement."); + if (maxResult == HitResult.LargeTickHit && minResult != HitResult.LargeTickMiss) throw new ArgumentOutOfRangeException(nameof(minResult), $"{HitResult.LargeTickMiss} is the only valid minimum result for a {maxResult} judgement."); diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 5123668e54..837bb4080e 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -322,6 +322,9 @@ public virtual int GetBaseScoreForResult(HitResult result) case HitResult.LargeTickHit: return 30; + case HitResult.SliderTailHit: + return 150; + case HitResult.Meh: return 50;