mirror of
https://github.com/ppy/osu.git
synced 2025-01-12 11:42:54 +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
|
||||
{
|
||||
protected override TaikoAction[] HitActions { get; } = { TaikoAction.LeftCentre, TaikoAction.RightCentre };
|
||||
public override TaikoAction[] HitActions { get; } = { TaikoAction.LeftCentre, TaikoAction.RightCentre };
|
||||
|
||||
public DrawableCentreHit(Hit 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 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
|
||||
/// <summary>
|
||||
/// A list of keys which can result in hits for this HitObject.
|
||||
/// </summary>
|
||||
protected abstract TaikoAction[] HitActions { get; }
|
||||
|
||||
protected readonly JudgementResult Result;
|
||||
public abstract TaikoAction[] HitActions { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether the last key pressed is a valid hit key.
|
||||
/// The action that caused this <see cref="DrawableHit"/> to be hit.
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
protected override TaikoAction[] HitActions { get; } = { TaikoAction.LeftRim, TaikoAction.RightRim };
|
||||
public override TaikoAction[] HitActions { get; } = { TaikoAction.LeftRim, TaikoAction.RightRim };
|
||||
|
||||
public DrawableRimHit(Hit 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.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();
|
||||
|
Loading…
Reference in New Issue
Block a user