From fdf889359f702a60870d6d4532a0e1b180e39447 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 3 Aug 2018 16:12:38 +0900 Subject: [PATCH] Migrate DrawableHit to use a nested hitobject for strong hits --- .../Objects/Drawables/DrawableCentreHit.cs | 2 +- .../Drawables/DrawableCentreHitStrong.cs | 26 ---- .../Objects/Drawables/DrawableHit.cs | 45 ++++--- .../Objects/Drawables/DrawableHitStrong.cs | 111 ------------------ .../Objects/Drawables/DrawableRimHit.cs | 2 +- .../Objects/Drawables/DrawableRimHitStrong.cs | 26 ---- .../Objects/Drawables/DrawableStrongHit.cs | 68 +++++++++++ .../Objects/TaikoHitObject.cs | 3 +- 8 files changed, 101 insertions(+), 182 deletions(-) delete mode 100644 osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHitStrong.cs delete mode 100644 osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs delete mode 100644 osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHitStrong.cs create mode 100644 osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongHit.cs diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHit.cs index dda96c2caf..a6e9972dd3 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHit.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { public class DrawableCentreHit : DrawableHit { - protected override TaikoAction[] HitActions { get; } = { TaikoAction.LeftCentre, TaikoAction.RightCentre }; + public override TaikoAction[] HitActions { get; } = { TaikoAction.LeftCentre, TaikoAction.RightCentre }; public DrawableCentreHit(Hit hit) : base(hit) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHitStrong.cs deleted file mode 100644 index a2dabf2b18..0000000000 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableCentreHitStrong.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Allocation; -using osu.Game.Graphics; -using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; - -namespace osu.Game.Rulesets.Taiko.Objects.Drawables -{ - public class DrawableCentreHitStrong : DrawableHitStrong - { - protected override TaikoAction[] HitActions { get; } = { TaikoAction.LeftCentre, TaikoAction.RightCentre }; - - public DrawableCentreHitStrong(Hit hit) - : base(hit) - { - MainPiece.Add(new CentreHitSymbolPiece()); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - MainPiece.AccentColour = colours.PinkDarker; - } - } -} diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index 18177ad089..35fa5eb344 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -3,10 +3,8 @@ using System.Linq; using osu.Framework.Graphics; -using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.Taiko.Judgements; using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; namespace osu.Game.Rulesets.Taiko.Objects.Drawables @@ -16,21 +14,19 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables /// /// A list of keys which can result in hits for this HitObject. /// - protected abstract TaikoAction[] HitActions { get; } - - protected readonly JudgementResult Result; + public abstract TaikoAction[] HitActions { get; } /// - /// Whether the last key pressed is a valid hit key. + /// The action that caused this to be hit. /// - private bool validKeyPressed; + public TaikoAction? HitAction { get; private set; } + + private bool validActionPressed; protected DrawableHit(Hit hit) : base(hit) { FillMode = FillMode.Fit; - - Result = Results.Single(r => !(r.Judgement is TaikoStrongHitJudgement)); } protected override void CheckForJudgements(bool userTriggered, double timeOffset) @@ -38,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (!userTriggered) { if (!HitObject.HitWindows.CanBeHit(timeOffset)) - ApplyResult(Result, r => r.Type = HitResult.Miss); + ApplyResult(r => r.Type = HitResult.Miss); return; } @@ -46,18 +42,33 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (result == HitResult.None) return; - if (!validKeyPressed) - ApplyResult(Result, r => r.Type = HitResult.Miss); + if (!validActionPressed) + ApplyResult(r => r.Type = HitResult.Miss); else - ApplyResult(Result, r => r.Type = result); + ApplyResult(r => r.Type = result); } public override bool OnPressed(TaikoAction action) { - validKeyPressed = HitActions.Contains(action); + if (Judged) + return false; + + validActionPressed = HitActions.Contains(action); // Only count this as handled if the new judgement is a hit - return UpdateJudgement(true); + var result = UpdateJudgement(true); + + if (IsHit) + HitAction = action; + + return result; + } + + public override bool OnReleased(TaikoAction action) + { + if (action == HitAction) + HitAction = null; + return base.OnReleased(action); } protected override void Update() @@ -78,7 +89,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables switch (State.Value) { case ArmedState.Idle: - validKeyPressed = false; + validActionPressed = false; UnproxyContent(); this.Delay(HitObject.HitWindows.HalfWindowFor(HitResult.Miss)).Expire(); @@ -114,5 +125,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables } } } + + protected override DrawableStrongHitObject CreateStrongObject(StrongHitObject hitObject) => new DrawableStrongHit(hitObject, this); } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs deleted file mode 100644 index 7ec0c08f0f..0000000000 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHitStrong.cs +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Linq; -using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.Taiko.Judgements; - -namespace osu.Game.Rulesets.Taiko.Objects.Drawables -{ - public abstract class DrawableHitStrong : DrawableHit - { - /// - /// The lenience for the second key press. - /// This does not adjust by map difficulty in ScoreV2 yet. - /// - private const double second_hit_window = 30; - - private readonly JudgementResult strongResult; - - private double firstHitTime; - private bool firstKeyHeld; - private TaikoAction firstHitAction; - - protected DrawableHitStrong(Hit hit) - : base(hit) - { - strongResult = Results.SingleOrDefault(r => r.Judgement is TaikoStrongHitJudgement); - } - - protected override void CheckForJudgements(bool userTriggered, double timeOffset) - { - if (!Result.HasResult) - { - base.CheckForJudgements(userTriggered, timeOffset); - return; - } - - if (!Result.IsHit) - { - ApplyResult(strongResult, r => r.Type = HitResult.Miss); - return; - } - - if (!userTriggered) - { - if (timeOffset > second_hit_window) - ApplyResult(strongResult, r => r.Type = HitResult.Miss); - return; - } - - if (Math.Abs(firstHitTime - Time.Current) < second_hit_window) - ApplyResult(strongResult, r => r.Type = HitResult.Great); - } - - protected override void UpdateState(ArmedState state) - { - base.UpdateState(state); - - switch (state) - { - case ArmedState.Idle: - firstHitTime = 0; - firstKeyHeld = false; - break; - } - } - - public override bool OnReleased(TaikoAction action) - { - if (action == firstHitAction) - firstKeyHeld = false; - return base.OnReleased(action); - } - - public override bool OnPressed(TaikoAction action) - { - if (AllJudged) - return false; - - // Check if we've handled the first key - if (!Result.HasResult) - { - // First key hasn't been handled yet, attempt to handle it - bool handled = base.OnPressed(action); - - if (handled) - { - firstHitTime = Time.Current; - firstHitAction = action; - firstKeyHeld = true; - } - - return handled; - } - - // Don't handle represses of the first key - if (firstHitAction == action) - return false; - - // Don't handle invalid hit action presses - if (!HitActions.Contains(action)) - return false; - - // Assume the intention was to hit the strong hit with both keys only if the first key is still being held down - return firstKeyHeld && UpdateJudgement(true); - } - } -} diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHit.cs index f2194c6d56..188cafe1db 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHit.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { public class DrawableRimHit : DrawableHit { - protected override TaikoAction[] HitActions { get; } = { TaikoAction.LeftRim, TaikoAction.RightRim }; + public override TaikoAction[] HitActions { get; } = { TaikoAction.LeftRim, TaikoAction.RightRim }; public DrawableRimHit(Hit hit) : base(hit) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHitStrong.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHitStrong.cs deleted file mode 100644 index 728fe416f7..0000000000 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableRimHitStrong.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Allocation; -using osu.Game.Graphics; -using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces; - -namespace osu.Game.Rulesets.Taiko.Objects.Drawables -{ - public class DrawableRimHitStrong : DrawableHitStrong - { - protected override TaikoAction[] HitActions { get; } = { TaikoAction.LeftRim, TaikoAction.RightRim }; - - public DrawableRimHitStrong(Hit hit) - : base(hit) - { - MainPiece.Add(new RimHitSymbolPiece()); - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - MainPiece.AccentColour = colours.BlueDarker; - } - } -} diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongHit.cs new file mode 100644 index 0000000000..c9767c9aec --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableStrongHit.cs @@ -0,0 +1,68 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Taiko.Objects.Drawables +{ + public class DrawableStrongHit : DrawableStrongHitObject + { + /// + /// The lenience for the second key press. + /// This does not adjust by map difficulty in ScoreV2 yet. + /// + private const double second_hit_window = 30; + + private readonly DrawableHit hit; + + public DrawableStrongHit(StrongHitObject strong, DrawableHit hit) + : base(strong) + { + this.hit = hit; + } + + protected override void CheckForJudgements(bool userTriggered, double timeOffset) + { + if (!hit.Result.HasResult) + { + base.CheckForJudgements(userTriggered, timeOffset); + return; + } + + if (!hit.Result.IsHit) + { + ApplyResult(r => r.Type = HitResult.Miss); + return; + } + + if (!userTriggered) + { + if (timeOffset > second_hit_window) + ApplyResult(r => r.Type = HitResult.Miss); + return; + } + + if (Math.Abs(hit.Result.TimeOffset - timeOffset) < second_hit_window) + ApplyResult(r => r.Type = HitResult.Great); + } + + public override bool OnPressed(TaikoAction action) + { + // Don't process actions until the main hitobject is hit + if (!hit.IsHit) + return false; + + // Don't process actions if the pressed button was released + if (hit.HitAction == null) + return false; + + // Don't handle invalid hit action presses + if (!hit.HitActions.Contains(action)) + return false; + + return UpdateJudgement(true); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs index e0b229d96d..702b6d73b6 100644 --- a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs @@ -3,6 +3,7 @@ using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Taiko.Judgements; namespace osu.Game.Rulesets.Taiko.Objects @@ -35,7 +36,7 @@ namespace osu.Game.Rulesets.Taiko.Objects base.CreateNestedHitObjects(); if (IsStrong) - AddNested(new StrongHitObject()); + AddNested(new StrongHitObject { StartTime = (this as IHasEndTime)?.EndTime ?? StartTime }); } protected override Judgement CreateJudgement() => new TaikoJudgement();