1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 18:47:27 +08:00

Add HitWindows to JudgementResult to indicate timing errors

This commit is contained in:
smoogipoo 2019-09-02 16:28:14 +09:00
parent f3656475de
commit f2bdf94a1d
10 changed files with 34 additions and 14 deletions

View File

@ -7,6 +7,7 @@ using System.Linq;
using osu.Framework.Extensions; using osu.Framework.Extensions;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
@ -24,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Tests
{ {
foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Skip(1)) foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Skip(1))
AddStep("Show " + result.GetDescription(), () => SetContents(() => AddStep("Show " + result.GetDescription(), () => SetContents(() =>
new DrawableOsuJudgement(new JudgementResult(null) { Type = result }, null) new DrawableOsuJudgement(new JudgementResult(null, new HitWindows()) { Type = result }, null)
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
namespace osu.Game.Rulesets.Osu.Judgements namespace osu.Game.Rulesets.Osu.Judgements
{ {
@ -9,8 +10,8 @@ namespace osu.Game.Rulesets.Osu.Judgements
{ {
public ComboResult ComboType; public ComboResult ComboType;
public OsuJudgementResult(Judgement judgement) public OsuJudgementResult(Judgement judgement, HitWindows hitWindows)
: base(judgement) : base(judgement, hitWindows)
{ {
} }
} }

View File

@ -6,6 +6,7 @@ using osu.Framework.Graphics;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Rulesets.Osu.Judgements;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Rulesets.Objects;
namespace osu.Game.Rulesets.Osu.Objects.Drawables namespace osu.Game.Rulesets.Osu.Objects.Drawables
{ {
@ -41,6 +42,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
protected virtual void Shake(double maximumLength) => shakeContainer.Shake(maximumLength); protected virtual void Shake(double maximumLength) => shakeContainer.Shake(maximumLength);
protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(judgement); protected override JudgementResult CreateResult(Judgement judgement, HitWindows hitWindows) => new OsuJudgementResult(judgement, hitWindows);
} }
} }

View File

@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Osu.Scoring
} }
} }
protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(judgement); protected override JudgementResult CreateResult(Judgement judgement) => new OsuJudgementResult(judgement, null);
public override HitWindows CreateHitWindows() => new OsuHitWindows(); public override HitWindows CreateHitWindows() => new OsuHitWindows();
} }

View File

@ -144,7 +144,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) }; var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) };
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new TaikoJudgement()) { Type = hitResult }); ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new TaikoJudgement(), new TaikoHitWindows()) { Type = hitResult });
} }
private void addStrongHitJudgement(bool kiai) private void addStrongHitJudgement(bool kiai)
@ -159,13 +159,13 @@ namespace osu.Game.Rulesets.Taiko.Tests
var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) }; var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) };
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new TaikoJudgement()) { Type = hitResult }); ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(h, new JudgementResult(new TaikoJudgement(), new TaikoHitWindows()) { Type = hitResult });
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new TestStrongNestedHit(h), new JudgementResult(new TaikoStrongJudgement()) { Type = HitResult.Great }); ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new TestStrongNestedHit(h), new JudgementResult(new TaikoStrongJudgement(), new TaikoHitWindows()) { Type = HitResult.Great });
} }
private void addMissJudgement() private void addMissJudgement()
{ {
((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new DrawableTestHit(new Hit()), new JudgementResult(new TaikoJudgement()) { Type = HitResult.Miss }); ((TaikoPlayfield)drawableRuleset.Playfield).OnNewResult(new DrawableTestHit(new Hit()), new JudgementResult(new TaikoJudgement(), new TaikoHitWindows()) { Type = HitResult.Miss });
} }
private void addBarLine(bool major, double delay = scroll_time) private void addBarLine(bool major, double delay = scroll_time)

View File

@ -106,7 +106,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private void newJudgement(double offset = 0) private void newJudgement(double offset = 0)
{ {
var judgement = new JudgementResult(new Judgement()) var judgement = new JudgementResult(new Judgement(), hitWindows)
{ {
TimeOffset = offset == 0 ? RNG.Next(-150, 150) : offset, TimeOffset = offset == 0 ? RNG.Next(-150, 150) : offset,
Type = HitResult.Perfect, Type = HitResult.Perfect,

View File

@ -1,6 +1,8 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text. // See the LICENCE file in the repository root for full licence text.
using JetBrains.Annotations;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
@ -21,6 +23,13 @@ namespace osu.Game.Rulesets.Judgements
/// </summary> /// </summary>
public readonly Judgement Judgement; public readonly Judgement Judgement;
/// <summary>
/// The <see cref="HitWindows"/> which the <see cref="HitObject"/> was judged against.
/// May be null to indicate that the timing error should not be displayed to the user.
/// </summary>
[CanBeNull]
public readonly HitWindows HitWindows;
/// <summary> /// <summary>
/// The offset from a perfect hit at which this <see cref="JudgementResult"/> occurred. /// The offset from a perfect hit at which this <see cref="JudgementResult"/> occurred.
/// Populated when this <see cref="JudgementResult"/> is applied via <see cref="DrawableHitObject.ApplyResult"/>. /// Populated when this <see cref="JudgementResult"/> is applied via <see cref="DrawableHitObject.ApplyResult"/>.
@ -56,9 +65,12 @@ namespace osu.Game.Rulesets.Judgements
/// Creates a new <see cref="JudgementResult"/>. /// Creates a new <see cref="JudgementResult"/>.
/// </summary> /// </summary>
/// <param name="judgement">The <see cref="Judgement"/> to refer to for scoring information.</param> /// <param name="judgement">The <see cref="Judgement"/> to refer to for scoring information.</param>
public JudgementResult(Judgement judgement) /// <param name="hitWindows">The <see cref="HitWindows"/> which the <see cref="HitObject"/> was judged against.
/// May be null to indicate that the timing error should not be displayed to the user.</param>
public JudgementResult([NotNull] Judgement judgement, [CanBeNull] HitWindows hitWindows)
{ {
Judgement = judgement; Judgement = judgement;
HitWindows = hitWindows;
} }
public override string ToString() => $"{Type} (Score:{Judgement.NumericResultFor(this)} HP:{Judgement.HealthIncreaseFor(this)} {Judgement})"; public override string ToString() => $"{Type} (Score:{Judgement.NumericResultFor(this)} HP:{Judgement.HealthIncreaseFor(this)} {Judgement})";

View File

@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
if (judgement != null) if (judgement != null)
{ {
Result = CreateResult(judgement); Result = CreateResult(judgement, HitObject.HitWindows);
if (Result == null) if (Result == null)
throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}."); throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}.");
} }
@ -401,7 +401,9 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// Creates the <see cref="JudgementResult"/> that represents the scoring result for this <see cref="DrawableHitObject"/>. /// Creates the <see cref="JudgementResult"/> that represents the scoring result for this <see cref="DrawableHitObject"/>.
/// </summary> /// </summary>
/// <param name="judgement">The <see cref="Judgement"/> that provides the scoring information.</param> /// <param name="judgement">The <see cref="Judgement"/> that provides the scoring information.</param>
protected virtual JudgementResult CreateResult(Judgement judgement) => new JudgementResult(judgement); /// <param name="hitWindows">The <see cref="HitWindows"/> which the <see cref="HitObject"/> was judged against.
/// May be null to indicate that the timing error should not be displayed to the user.</param>
protected virtual JudgementResult CreateResult(Judgement judgement, HitWindows hitWindows) => new JudgementResult(judgement, hitWindows);
} }
public abstract class DrawableHitObject<TObject> : DrawableHitObject public abstract class DrawableHitObject<TObject> : DrawableHitObject

View File

@ -442,7 +442,7 @@ namespace osu.Game.Rulesets.Scoring
/// Creates the <see cref="JudgementResult"/> that represents the scoring result for a <see cref="HitObject"/>. /// Creates the <see cref="JudgementResult"/> that represents the scoring result for a <see cref="HitObject"/>.
/// </summary> /// </summary>
/// <param name="judgement">The <see cref="Judgement"/> that provides the scoring information.</param> /// <param name="judgement">The <see cref="Judgement"/> that provides the scoring information.</param>
protected virtual JudgementResult CreateResult(Judgement judgement) => new JudgementResult(judgement); protected virtual JudgementResult CreateResult(Judgement judgement) => new JudgementResult(judgement, null);
} }
public enum ScoringMode public enum ScoringMode

View File

@ -49,6 +49,9 @@ namespace osu.Game.Screens.Play.HUD
private void onNewJudgement(JudgementResult result) private void onNewJudgement(JudgementResult result)
{ {
if (result.HitWindows == null)
return;
foreach (var c in Children) foreach (var c in Children)
c.OnNewJudgement(result); c.OnNewJudgement(result);
} }