From 04805b78c31718a451737bd78b090e96e39a3859 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Nov 2020 23:19:59 +0900 Subject: [PATCH 1/2] Tighten osu! ruleset lifetime expiry for past hitobjects --- .../Objects/Drawables/DrawableHitCircle.cs | 2 ++ .../Objects/Drawables/DrawableOsuHitObject.cs | 5 +++++ .../Objects/Drawables/DrawableSlider.cs | 16 ++++++++-------- .../Objects/Drawables/DrawableSpinner.cs | 2 +- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 2e63160d36..d1ceca6d8f 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -180,6 +180,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables this.Delay(800).FadeOut(); break; } + + Expire(); } public Drawable ProxiedLayer => ApproachCircle; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index bcaf73d34f..c962d191a6 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -11,6 +11,7 @@ using osu.Game.Rulesets.Osu.Judgements; using osu.Game.Graphics.Containers; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.UI; +using osu.Game.Rulesets.Scoring; using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables @@ -91,6 +92,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables // Manually set to reduce the number of future alive objects to a bare minimum. LifetimeStart = HitObject.StartTime - HitObject.TimePreempt; + + // Arbitrary lifetime end to prevent past objects in idle states remaining alive in non-frame-stable contexts. + // An extra 1000ms is added to always overestimate the true lifetime, and a more exact value is set by hit transforms and the following expiry. + LifetimeEnd = HitObject.GetEndTime() + HitObject.HitWindows.WindowFor(HitResult.Miss) + 1000; } /// diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index f7b1894058..14c494d909 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -193,13 +193,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables return base.CreateNestedHitObject(hitObject); } - protected override void UpdateInitialTransforms() - { - base.UpdateInitialTransforms(); - - Body.FadeInFromZero(HitObject.TimeFadeIn); - } - public readonly Bindable Tracking = new Bindable(); protected override void Update() @@ -273,6 +266,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables base.PlaySamples(); } + protected override void UpdateInitialTransforms() + { + base.UpdateInitialTransforms(); + + Body.FadeInFromZero(HitObject.TimeFadeIn); + } + protected override void UpdateStartTimeStateTransforms() { base.UpdateStartTimeStateTransforms(); @@ -297,7 +297,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables break; } - this.FadeOut(fade_out_time, Easing.OutQuint); + this.FadeOut(fade_out_time, Easing.OutQuint).Expire(); } public Drawable ProxiedLayer => HeadCircle.ProxiedLayer; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 87c7146a64..2a14a7c975 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -157,7 +157,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { base.UpdateHitStateTransforms(state); - this.FadeOut(160); + this.FadeOut(160).Expire(); // skin change does a rewind of transforms, which will stop the spinning sound from playing if it's currently in playback. isSpinning?.TriggerChange(); From ce4baf328dba51f3f5006bbc69f0ad58b9d91dd6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 17 Nov 2020 23:35:36 +0900 Subject: [PATCH 2/2] Move into OnApply() to resolve one-frame issues --- .../Objects/Drawables/DrawableOsuHitObject.cs | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index c962d191a6..a26db06ede 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -61,6 +61,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables PositionBindable.BindTo(HitObject.PositionBindable); StackHeightBindable.BindTo(HitObject.StackHeightBindable); ScaleBindable.BindTo(HitObject.ScaleBindable); + + // Manually set to reduce the number of future alive objects to a bare minimum. + LifetimeStart = HitObject.StartTime - HitObject.TimePreempt; + + // Arbitrary lifetime end to prevent past objects in idle states remaining alive in non-frame-stable contexts. + // An extra 1000ms is added to always overestimate the true lifetime, and a more exact value is set by hit transforms and the following expiry. + LifetimeEnd = HitObject.GetEndTime() + HitObject.HitWindows.WindowFor(HitResult.Miss) + 1000; } protected override void OnFree(HitObject hitObject) @@ -86,18 +93,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public virtual void Shake(double maximumLength) => shakeContainer.Shake(maximumLength); - protected override void UpdateInitialTransforms() - { - base.UpdateInitialTransforms(); - - // Manually set to reduce the number of future alive objects to a bare minimum. - LifetimeStart = HitObject.StartTime - HitObject.TimePreempt; - - // Arbitrary lifetime end to prevent past objects in idle states remaining alive in non-frame-stable contexts. - // An extra 1000ms is added to always overestimate the true lifetime, and a more exact value is set by hit transforms and the following expiry. - LifetimeEnd = HitObject.GetEndTime() + HitObject.HitWindows.WindowFor(HitResult.Miss) + 1000; - } - /// /// Causes this to get missed, disregarding all conditions in implementations of . ///