1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-13 08:32:57 +08:00

Move strong hit handling to DrumSamplePlayer and separte trigger sources

This commit is contained in:
Dean Herbert 2023-06-30 17:02:08 +09:00
parent 27af07b74b
commit a9587fd1aa
4 changed files with 95 additions and 21 deletions

View File

@ -195,7 +195,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
/// The lenience for the second key press. /// The lenience for the second key press.
/// This does not adjust by map difficulty in ScoreV2 yet. /// This does not adjust by map difficulty in ScoreV2 yet.
/// </summary> /// </summary>
private const double second_hit_window = 30; public const double SECOND_HIT_WINDOW = 30;
public StrongNestedHit() public StrongNestedHit()
: this(null) : this(null)
@ -223,12 +223,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
if (!userTriggered) if (!userTriggered)
{ {
if (timeOffset - ParentHitObject.Result.TimeOffset > second_hit_window) if (timeOffset - ParentHitObject.Result.TimeOffset > SECOND_HIT_WINDOW)
ApplyResult(r => r.Type = r.Judgement.MinResult); ApplyResult(r => r.Type = r.Judgement.MinResult);
return; return;
} }
if (Math.Abs(timeOffset - ParentHitObject.Result.TimeOffset) <= second_hit_window) if (Math.Abs(timeOffset - ParentHitObject.Result.TimeOffset) <= SECOND_HIT_WINDOW)
ApplyResult(r => r.Type = r.Judgement.MaxResult); ApplyResult(r => r.Type = r.Judgement.MaxResult);
} }

View File

@ -11,7 +11,7 @@ using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko.Skinning.Argon namespace osu.Game.Rulesets.Taiko.Skinning.Argon
{ {
public partial class ArgonDrumSamplePlayer : DrumSamplePlayer internal partial class ArgonDrumSamplePlayer : DrumSamplePlayer
{ {
protected override DrumSampleTriggerSource CreateTriggerSource(HitObjectContainer hitObjectContainer, SampleBalance balance) => protected override DrumSampleTriggerSource CreateTriggerSource(HitObjectContainer hitObjectContainer, SampleBalance balance) =>
new ArgonDrumSampleTriggerSource(hitObjectContainer, balance); new ArgonDrumSampleTriggerSource(hitObjectContainer, balance);
@ -45,6 +45,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Argon
// let the magic begin... // let the magic begin...
// TODO: should we only play strong samples if the user correctly hits them? arguable.
if ((hitObject as TaikoStrongableHitObject)?.IsStrong == true || hitObject is StrongNestedHitObject) if ((hitObject as TaikoStrongableHitObject)?.IsStrong == true || hitObject is StrongNestedHitObject)
{ {
PlaySamples(new ISampleInfo[] PlaySamples(new ISampleInfo[]

View File

@ -7,28 +7,35 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Rulesets.Taiko.Objects; using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Objects.Drawables;
using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Taiko.UI namespace osu.Game.Rulesets.Taiko.UI
{ {
public partial class DrumSamplePlayer : CompositeDrawable, IKeyBindingHandler<TaikoAction> internal partial class DrumSamplePlayer : CompositeDrawable, IKeyBindingHandler<TaikoAction>
{ {
private DrumSampleTriggerSource leftRimSampleTriggerSource = null!; private DrumSampleTriggerSource leftCentreTrigger = null!;
private DrumSampleTriggerSource leftCentreSampleTriggerSource = null!; private DrumSampleTriggerSource rightCentreTrigger = null!;
private DrumSampleTriggerSource rightCentreSampleTriggerSource = null!; private DrumSampleTriggerSource leftRimTrigger = null!;
private DrumSampleTriggerSource rightRimSampleTriggerSource = null!; private DrumSampleTriggerSource rightRimTrigger = null!;
private DrumSampleTriggerSource strongCentreTrigger = null!;
private DrumSampleTriggerSource strongRimTrigger = null!;
private double lastHitTime;
private TaikoAction? lastAction;
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(DrawableRuleset drawableRuleset) private void load(DrawableRuleset drawableRuleset)
{ {
var hitObjectContainer = drawableRuleset.Playfield.HitObjectContainer; var hitObjectContainer = drawableRuleset.Playfield.HitObjectContainer;
InternalChildren = new Drawable[] InternalChildren = new Drawable[]
{ {
leftRimSampleTriggerSource = CreateTriggerSource(hitObjectContainer, SampleBalance.Left), leftCentreTrigger = CreateTriggerSource(hitObjectContainer, SampleBalance.Left),
leftCentreSampleTriggerSource = CreateTriggerSource(hitObjectContainer, SampleBalance.Left), rightCentreTrigger = CreateTriggerSource(hitObjectContainer, SampleBalance.Right),
rightCentreSampleTriggerSource = CreateTriggerSource(hitObjectContainer, SampleBalance.Right), leftRimTrigger = CreateTriggerSource(hitObjectContainer, SampleBalance.Left),
rightRimSampleTriggerSource = CreateTriggerSource(hitObjectContainer, SampleBalance.Right), rightRimTrigger = CreateTriggerSource(hitObjectContainer, SampleBalance.Right),
strongCentreTrigger = CreateTriggerSource(hitObjectContainer, SampleBalance.Centre),
strongRimTrigger = CreateTriggerSource(hitObjectContainer, SampleBalance.Centre)
}; };
} }
@ -37,28 +44,93 @@ namespace osu.Game.Rulesets.Taiko.UI
public bool OnPressed(KeyBindingPressEvent<TaikoAction> e) public bool OnPressed(KeyBindingPressEvent<TaikoAction> e)
{ {
HitType hitType;
DrumSampleTriggerSource triggerSource;
bool strong = checkStrongValidity(e.Action, lastAction, Time.Current - lastHitTime);
switch (e.Action) switch (e.Action)
{ {
case TaikoAction.LeftRim:
leftRimSampleTriggerSource.Play(HitType.Rim);
break;
case TaikoAction.LeftCentre: case TaikoAction.LeftCentre:
leftCentreSampleTriggerSource.Play(HitType.Centre); hitType = HitType.Centre;
triggerSource = strong ? strongCentreTrigger : leftCentreTrigger;
break; break;
case TaikoAction.RightCentre: case TaikoAction.RightCentre:
rightCentreSampleTriggerSource.Play(HitType.Centre); hitType = HitType.Centre;
triggerSource = strong ? strongCentreTrigger : rightCentreTrigger;
break;
case TaikoAction.LeftRim:
hitType = HitType.Rim;
triggerSource = strong ? strongRimTrigger : leftRimTrigger;
break; break;
case TaikoAction.RightRim: case TaikoAction.RightRim:
rightRimSampleTriggerSource.Play(HitType.Rim); hitType = HitType.Rim;
triggerSource = strong ? strongRimTrigger : rightRimTrigger;
break; break;
default:
return false;
} }
if (strong && hitType == HitType.Centre)
flushCenterTriggerSources();
if (strong && hitType == HitType.Rim)
flushRimTriggerSources();
triggerSource.Play(hitType);
lastHitTime = Time.Current;
lastAction = e.Action;
return false; return false;
} }
private bool checkStrongValidity(TaikoAction newAction, TaikoAction? lastAction, double timeBetweenActions)
{
if (lastAction == null)
return false;
if (timeBetweenActions > DrawableHit.StrongNestedHit.SECOND_HIT_WINDOW)
return false;
switch (newAction)
{
case TaikoAction.LeftCentre:
return lastAction == TaikoAction.RightCentre;
case TaikoAction.RightCentre:
return lastAction == TaikoAction.LeftCentre;
case TaikoAction.LeftRim:
return lastAction == TaikoAction.RightRim;
case TaikoAction.RightRim:
return lastAction == TaikoAction.LeftRim;
default:
return false;
}
}
private void flushCenterTriggerSources()
{
leftCentreTrigger.StopAllPlayback();
rightCentreTrigger.StopAllPlayback();
strongCentreTrigger.StopAllPlayback();
}
private void flushRimTriggerSources()
{
leftRimTrigger.StopAllPlayback();
rightRimTrigger.StopAllPlayback();
strongRimTrigger.StopAllPlayback();
}
public void OnReleased(KeyBindingReleaseEvent<TaikoAction> e) public void OnReleased(KeyBindingReleaseEvent<TaikoAction> e)
{ {
} }

View File

@ -42,6 +42,7 @@ namespace osu.Game.Rulesets.Taiko.UI
var baseSample = hitObject.CreateHitSampleInfo(hitType == HitType.Rim ? HitSampleInfo.HIT_CLAP : HitSampleInfo.HIT_NORMAL); var baseSample = hitObject.CreateHitSampleInfo(hitType == HitType.Rim ? HitSampleInfo.HIT_CLAP : HitSampleInfo.HIT_NORMAL);
// TODO: should we only play strong samples if the user correctly hits them? arguable.
if ((hitObject as TaikoStrongableHitObject)?.IsStrong == true || hitObject is StrongNestedHitObject) if ((hitObject as TaikoStrongableHitObject)?.IsStrong == true || hitObject is StrongNestedHitObject)
{ {
PlaySamples(new ISampleInfo[] PlaySamples(new ISampleInfo[]