From 42853b5af645e4ead92c2d1ed7d9077c4d924189 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 23 Dec 2019 15:43:58 +0900 Subject: [PATCH] Separate head/tail notes from hold note class --- .../Objects/Drawables/DrawableHoldNote.cs | 129 +++--------------- .../Objects/Drawables/DrawableHoldNoteHead.cs | 37 +++++ .../Objects/Drawables/DrawableHoldNoteTail.cs | 74 ++++++++++ 3 files changed, 127 insertions(+), 113 deletions(-) create mode 100644 osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs create mode 100644 osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 87b9633c80..ca3b966d40 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Diagnostics; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; @@ -24,8 +23,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables public DrawableNote Head => headContainer.Child; public DrawableNote Tail => tailContainer.Child; - private readonly Container headContainer; - private readonly Container tailContainer; + private readonly Container headContainer; + private readonly Container tailContainer; private readonly Container tickContainer; private readonly BodyPiece bodyPiece; @@ -33,12 +32,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// /// Time at which the user started holding this hold note. Null if the user is not holding this hold note. /// - private double? holdStartTime; + internal double? HoldStartTime; /// /// Whether the hold note has been released too early and shouldn't give full score for the release. /// - private bool hasBroken; + internal bool HasBroken; public DrawableHoldNote(HoldNote hitObject) : base(hitObject) @@ -49,8 +48,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { bodyPiece = new BodyPiece { RelativeSizeAxes = Axes.X }, tickContainer = new Container { RelativeSizeAxes = Axes.Both }, - headContainer = new Container { RelativeSizeAxes = Axes.Both }, - tailContainer = new Container { RelativeSizeAxes = Axes.Both }, + headContainer = new Container { RelativeSizeAxes = Axes.Both }, + tailContainer = new Container { RelativeSizeAxes = Axes.Both }, }); AccentColour.BindValueChanged(colour => @@ -65,11 +64,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables switch (hitObject) { - case DrawableHeadNote head: + case DrawableHoldNoteHead head: headContainer.Child = head; break; - case DrawableTailNote tail: + case DrawableHoldNoteTail tail: tailContainer.Child = tail; break; @@ -92,7 +91,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables switch (hitObject) { case TailNote _: - return new DrawableTailNote(this) + return new DrawableHoldNoteTail(this) { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -100,7 +99,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables }; case Note _: - return new DrawableHeadNote(this) + return new DrawableHoldNoteHead(this) { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, @@ -110,7 +109,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables case HoldNoteTick tick: return new DrawableHoldNoteTick(tick) { - HoldStartTime = () => holdStartTime, + HoldStartTime = () => HoldStartTime, AccentColour = { BindTarget = AccentColour } }; } @@ -146,15 +145,15 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables base.UpdateStateTransforms(state); } - protected void BeginHold() + internal void BeginHold() { - holdStartTime = Time.Current; + HoldStartTime = Time.Current; bodyPiece.Hitting = true; } protected void EndHold() { - holdStartTime = null; + HoldStartTime = null; bodyPiece.Hitting = false; } @@ -177,7 +176,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables public bool OnReleased(ManiaAction action) { // Make sure that the user started holding the key during the hold note - if (!holdStartTime.HasValue) + if (!HoldStartTime.HasValue) return false; if (action != Action.Value) @@ -187,105 +186,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables // If the key has been released too early, the user should not receive full score for the release if (!Tail.IsHit) - hasBroken = true; + HasBroken = true; return true; } - - /// - /// The head note of a hold. - /// - private class DrawableHeadNote : DrawableNote - { - private readonly DrawableHoldNote holdNote; - - public DrawableHeadNote(DrawableHoldNote holdNote) - : base(holdNote.HitObject.Head) - { - this.holdNote = holdNote; - } - - public override bool OnPressed(ManiaAction action) - { - if (!base.OnPressed(action)) - return false; - - // If the key has been released too early, the user should not receive full score for the release - if (Result.Type == HitResult.Miss) - holdNote.hasBroken = true; - - // The head note also handles early hits before the body, but we want accurate early hits to count as the body being held - // The body doesn't handle these early early hits, so we have to explicitly set the holding state here - holdNote.BeginHold(); - - return true; - } - } - - /// - /// The tail note of a hold. - /// - private class DrawableTailNote : DrawableNote - { - /// - /// Lenience of release hit windows. This is to make cases where the hold note release - /// is timed alongside presses of other hit objects less awkward. - /// Todo: This shouldn't exist for non-LegacyBeatmapDecoder beatmaps - /// - private const double release_window_lenience = 1.5; - - private readonly DrawableHoldNote holdNote; - - public DrawableTailNote(DrawableHoldNote holdNote) - : base(holdNote.HitObject.Tail) - { - this.holdNote = holdNote; - } - - protected override void CheckForResult(bool userTriggered, double timeOffset) - { - Debug.Assert(HitObject.HitWindows != null); - - // Factor in the release lenience - timeOffset /= release_window_lenience; - - if (!userTriggered) - { - if (!HitObject.HitWindows.CanBeHit(timeOffset)) - ApplyResult(r => r.Type = HitResult.Miss); - - return; - } - - var result = HitObject.HitWindows.ResultFor(timeOffset); - if (result == HitResult.None) - return; - - ApplyResult(r => - { - if (holdNote.hasBroken && (result == HitResult.Perfect || result == HitResult.Perfect)) - result = HitResult.Good; - - r.Type = result; - }); - } - - public override bool OnPressed(ManiaAction action) => false; // Tail doesn't handle key down - - public override bool OnReleased(ManiaAction action) - { - // Make sure that the user started holding the key during the hold note - if (!holdNote.holdStartTime.HasValue) - return false; - - if (action != Action.Value) - return false; - - UpdateResult(true); - - // Handled by the hold note, which will set holding = false - return false; - } - } } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs new file mode 100644 index 0000000000..a1c9a09014 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteHead.cs @@ -0,0 +1,37 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Mania.Objects.Drawables +{ + /// + /// The head of a . + /// + public class DrawableHoldNoteHead : DrawableNote + { + private readonly DrawableHoldNote holdNote; + + public DrawableHoldNoteHead(DrawableHoldNote holdNote) + : base(holdNote.HitObject.Head) + { + this.holdNote = holdNote; + } + + public override bool OnPressed(ManiaAction action) + { + if (!base.OnPressed(action)) + return false; + + // If the key has been released too early, the user should not receive full score for the release + if (Result.Type == HitResult.Miss) + holdNote.HasBroken = true; + + // The head note also handles early hits before the body, but we want accurate early hits to count as the body being held + // The body doesn't handle these early early hits, so we have to explicitly set the holding state here + holdNote.BeginHold(); + + return true; + } + } +} diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs new file mode 100644 index 0000000000..2b23fb1eef --- /dev/null +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTail.cs @@ -0,0 +1,74 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Diagnostics; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Mania.Objects.Drawables +{ + /// + /// The tail of a . + /// + public class DrawableHoldNoteTail : DrawableNote + { + /// + /// Lenience of release hit windows. This is to make cases where the hold note release + /// is timed alongside presses of other hit objects less awkward. + /// Todo: This shouldn't exist for non-LegacyBeatmapDecoder beatmaps + /// + private const double release_window_lenience = 1.5; + + private readonly DrawableHoldNote holdNote; + + public DrawableHoldNoteTail(DrawableHoldNote holdNote) + : base(holdNote.HitObject.Tail) + { + this.holdNote = holdNote; + } + + protected override void CheckForResult(bool userTriggered, double timeOffset) + { + Debug.Assert(HitObject.HitWindows != null); + + // Factor in the release lenience + timeOffset /= release_window_lenience; + + if (!userTriggered) + { + if (!HitObject.HitWindows.CanBeHit(timeOffset)) + ApplyResult(r => r.Type = HitResult.Miss); + + return; + } + + var result = HitObject.HitWindows.ResultFor(timeOffset); + if (result == HitResult.None) + return; + + ApplyResult(r => + { + if (holdNote.HasBroken && (result == HitResult.Perfect || result == HitResult.Perfect)) + result = HitResult.Good; + + r.Type = result; + }); + } + + public override bool OnPressed(ManiaAction action) => false; // Tail doesn't handle key down + + public override bool OnReleased(ManiaAction action) + { + // Make sure that the user started holding the key during the hold note + if (!holdNote.HoldStartTime.HasValue) + return false; + + if (action != Action.Value) + return false; + + UpdateResult(true); + + // Handled by the hold note, which will set holding = false + return false; + } + } +}