mirror of
https://github.com/ppy/osu.git
synced 2025-01-27 11:12:59 +08:00
Migrate DrawableHit to use a nested hitobject for strong hits
This commit is contained in:
parent
2dff04392e
commit
fdf889359f
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
{
|
{
|
||||||
public class DrawableCentreHit : DrawableHit
|
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)
|
public DrawableCentreHit(Hit hit)
|
||||||
: base(hit)
|
: base(hit)
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,10 +3,8 @@
|
|||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Judgements;
|
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.Taiko.Judgements;
|
|
||||||
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||||
@ -16,21 +14,19 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of keys which can result in hits for this HitObject.
|
/// A list of keys which can result in hits for this HitObject.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected abstract TaikoAction[] HitActions { get; }
|
public abstract TaikoAction[] HitActions { get; }
|
||||||
|
|
||||||
protected readonly JudgementResult Result;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the last key pressed is a valid hit key.
|
/// The action that caused this <see cref="DrawableHit"/> to be hit.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool validKeyPressed;
|
public TaikoAction? HitAction { get; private set; }
|
||||||
|
|
||||||
|
private bool validActionPressed;
|
||||||
|
|
||||||
protected DrawableHit(Hit hit)
|
protected DrawableHit(Hit hit)
|
||||||
: base(hit)
|
: base(hit)
|
||||||
{
|
{
|
||||||
FillMode = FillMode.Fit;
|
FillMode = FillMode.Fit;
|
||||||
|
|
||||||
Result = Results.Single(r => !(r.Judgement is TaikoStrongHitJudgement));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
protected override void CheckForJudgements(bool userTriggered, double timeOffset)
|
||||||
@ -38,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
if (!userTriggered)
|
if (!userTriggered)
|
||||||
{
|
{
|
||||||
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
||||||
ApplyResult(Result, r => r.Type = HitResult.Miss);
|
ApplyResult(r => r.Type = HitResult.Miss);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,18 +42,33 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
if (result == HitResult.None)
|
if (result == HitResult.None)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!validKeyPressed)
|
if (!validActionPressed)
|
||||||
ApplyResult(Result, r => r.Type = HitResult.Miss);
|
ApplyResult(r => r.Type = HitResult.Miss);
|
||||||
else
|
else
|
||||||
ApplyResult(Result, r => r.Type = result);
|
ApplyResult(r => r.Type = result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool OnPressed(TaikoAction action)
|
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
|
// 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()
|
protected override void Update()
|
||||||
@ -78,7 +89,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
switch (State.Value)
|
switch (State.Value)
|
||||||
{
|
{
|
||||||
case ArmedState.Idle:
|
case ArmedState.Idle:
|
||||||
validKeyPressed = false;
|
validActionPressed = false;
|
||||||
|
|
||||||
UnproxyContent();
|
UnproxyContent();
|
||||||
this.Delay(HitObject.HitWindows.HalfWindowFor(HitResult.Miss)).Expire();
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,111 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// 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
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// The lenience for the second key press.
|
|
||||||
/// This does not adjust by map difficulty in ScoreV2 yet.
|
|
||||||
/// </summary>
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
{
|
{
|
||||||
public class DrawableRimHit : DrawableHit
|
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)
|
public DrawableRimHit(Hit hit)
|
||||||
: base(hit)
|
: base(hit)
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// 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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The lenience for the second key press.
|
||||||
|
/// This does not adjust by map difficulty in ScoreV2 yet.
|
||||||
|
/// </summary>
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Taiko.Judgements;
|
using osu.Game.Rulesets.Taiko.Judgements;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Objects
|
namespace osu.Game.Rulesets.Taiko.Objects
|
||||||
@ -35,7 +36,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
base.CreateNestedHitObjects();
|
base.CreateNestedHitObjects();
|
||||||
|
|
||||||
if (IsStrong)
|
if (IsStrong)
|
||||||
AddNested(new StrongHitObject());
|
AddNested(new StrongHitObject { StartTime = (this as IHasEndTime)?.EndTime ?? StartTime });
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Judgement CreateJudgement() => new TaikoJudgement();
|
protected override Judgement CreateJudgement() => new TaikoJudgement();
|
||||||
|
Loading…
Reference in New Issue
Block a user