mirror of
https://github.com/ppy/osu.git
synced 2025-03-25 18:57:18 +08:00
Merge pull request #31864 from peppy/fix-follow-circle-rewind-display
Fix weird follow circle display when rewinding through sliders in editor
This commit is contained in:
commit
c13bc8beca
@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
@ -13,8 +14,9 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
{
|
||||
public abstract partial class FollowCircle : CompositeDrawable
|
||||
{
|
||||
[Resolved]
|
||||
protected DrawableHitObject? ParentObject { get; private set; }
|
||||
protected DrawableSlider? DrawableObject { get; private set; }
|
||||
|
||||
private readonly IBindable<bool> tracking = new Bindable<bool>();
|
||||
|
||||
protected FollowCircle()
|
||||
{
|
||||
@ -22,65 +24,73 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
private void load(DrawableHitObject? hitObject)
|
||||
{
|
||||
((DrawableSlider?)ParentObject)?.Tracking.BindValueChanged(tracking =>
|
||||
DrawableObject = hitObject as DrawableSlider;
|
||||
|
||||
if (DrawableObject != null)
|
||||
{
|
||||
Debug.Assert(ParentObject != null);
|
||||
|
||||
if (ParentObject.Judged)
|
||||
return;
|
||||
|
||||
using (BeginAbsoluteSequence(Math.Max(Time.Current, ParentObject.HitObject?.StartTime ?? 0)))
|
||||
tracking.BindTo(DrawableObject.Tracking);
|
||||
tracking.BindValueChanged(tracking =>
|
||||
{
|
||||
if (tracking.NewValue)
|
||||
OnSliderPress();
|
||||
else
|
||||
OnSliderRelease();
|
||||
}
|
||||
}, true);
|
||||
if (DrawableObject.Judged)
|
||||
return;
|
||||
|
||||
using (BeginAbsoluteSequence(Math.Max(Time.Current, DrawableObject.HitObject?.StartTime ?? 0)))
|
||||
{
|
||||
if (tracking.NewValue)
|
||||
OnSliderPress();
|
||||
else
|
||||
OnSliderRelease();
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
if (ParentObject != null)
|
||||
if (DrawableObject != null)
|
||||
{
|
||||
ParentObject.HitObjectApplied += onHitObjectApplied;
|
||||
onHitObjectApplied(ParentObject);
|
||||
DrawableObject.HitObjectApplied += onHitObjectApplied;
|
||||
onHitObjectApplied(DrawableObject);
|
||||
|
||||
ParentObject.ApplyCustomUpdateState += updateStateTransforms;
|
||||
updateStateTransforms(ParentObject, ParentObject.State.Value);
|
||||
DrawableObject.ApplyCustomUpdateState += updateStateTransforms;
|
||||
updateStateTransforms(DrawableObject, DrawableObject.State.Value);
|
||||
}
|
||||
}
|
||||
|
||||
private void onHitObjectApplied(DrawableHitObject drawableObject)
|
||||
{
|
||||
// Sane defaults when a new hitobject is applied to the drawable slider.
|
||||
this.ScaleTo(1f)
|
||||
.FadeOut();
|
||||
|
||||
// Immediately play out any pending transforms from press/release
|
||||
FinishTransforms(true);
|
||||
}
|
||||
|
||||
private void updateStateTransforms(DrawableHitObject drawableObject, ArmedState state)
|
||||
private void updateStateTransforms(DrawableHitObject d, ArmedState state)
|
||||
{
|
||||
Debug.Assert(ParentObject != null);
|
||||
Debug.Assert(DrawableObject != null);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case ArmedState.Hit:
|
||||
switch (drawableObject)
|
||||
switch (d)
|
||||
{
|
||||
case DrawableSliderTail:
|
||||
// Use ParentObject instead of drawableObject because slider tail's
|
||||
// Use DrawableObject instead of local object because slider tail's
|
||||
// HitStateUpdateTime is ~36ms before the actual slider end (aka slider
|
||||
// tail leniency)
|
||||
using (BeginAbsoluteSequence(ParentObject.HitStateUpdateTime))
|
||||
using (BeginAbsoluteSequence(DrawableObject.HitStateUpdateTime))
|
||||
OnSliderEnd();
|
||||
break;
|
||||
|
||||
case DrawableSliderTick:
|
||||
case DrawableSliderRepeat:
|
||||
using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime))
|
||||
using (BeginAbsoluteSequence(d.HitStateUpdateTime))
|
||||
OnSliderTick();
|
||||
break;
|
||||
}
|
||||
@ -88,15 +98,15 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
break;
|
||||
|
||||
case ArmedState.Miss:
|
||||
switch (drawableObject)
|
||||
switch (d)
|
||||
{
|
||||
case DrawableSliderTail:
|
||||
case DrawableSliderTick:
|
||||
case DrawableSliderRepeat:
|
||||
// Despite above comment, ok to use drawableObject.HitStateUpdateTime
|
||||
// Despite above comment, ok to use d.HitStateUpdateTime
|
||||
// here, since on stable, the break anim plays right when the tail is
|
||||
// missed, not when the slider ends
|
||||
using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime))
|
||||
using (BeginAbsoluteSequence(d.HitStateUpdateTime))
|
||||
OnSliderBreak();
|
||||
break;
|
||||
}
|
||||
@ -109,10 +119,10 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
if (ParentObject != null)
|
||||
if (DrawableObject != null)
|
||||
{
|
||||
ParentObject.HitObjectApplied -= onHitObjectApplied;
|
||||
ParentObject.ApplyCustomUpdateState -= updateStateTransforms;
|
||||
DrawableObject.HitObjectApplied -= onHitObjectApplied;
|
||||
DrawableObject.ApplyCustomUpdateState -= updateStateTransforms;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -22,9 +22,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||
|
||||
protected override void OnSliderPress()
|
||||
{
|
||||
Debug.Assert(ParentObject != null);
|
||||
Debug.Assert(DrawableObject != null);
|
||||
|
||||
double remainingTime = Math.Max(0, ParentObject.HitStateUpdateTime - Time.Current);
|
||||
double remainingTime = Math.Max(0, DrawableObject.HitStateUpdateTime - Time.Current);
|
||||
|
||||
// Note that the scale adjust here is 2 instead of DrawableSliderBall.FOLLOW_AREA to match legacy behaviour.
|
||||
// This means the actual tracking area for gameplay purposes is larger than the sprite (but skins may be accounting for this).
|
||||
|
Loading…
x
Reference in New Issue
Block a user