1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-13 18:07:25 +08:00

Fix incorrect fade of slider ends after a rewind

This commit is contained in:
Bartłomiej Dach 2020-11-11 21:46:58 +01:00
parent 41a1730927
commit 0ae6f82291

View File

@ -3,6 +3,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
@ -46,9 +47,6 @@ namespace osu.Game.Rulesets.Osu.Mods
applyFadeInAdjustment(nested); applyFadeInAdjustment(nested);
} }
private double lastSliderHeadFadeOutStartTime;
private double lastSliderHeadFadeOutDuration;
protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state)
{ {
base.ApplyIncreasedVisibilityState(hitObject, state); base.ApplyIncreasedVisibilityState(hitObject, state);
@ -78,33 +76,24 @@ namespace osu.Game.Rulesets.Osu.Mods
{ {
case DrawableSliderTail sliderTail: case DrawableSliderTail sliderTail:
// use stored values from head circle to achieve same fade sequence. // use stored values from head circle to achieve same fade sequence.
fadeOutDuration = lastSliderHeadFadeOutDuration; var tailFadeOutParameters = getFadeOutParametersFromSliderHead(h);
fadeOutStartTime = lastSliderHeadFadeOutStartTime;
using (drawable.BeginAbsoluteSequence(fadeOutStartTime, true)) using (drawable.BeginAbsoluteSequence(tailFadeOutParameters.startTime, true))
sliderTail.FadeOut(fadeOutDuration); sliderTail.FadeOut(tailFadeOutParameters.duration);
break; break;
case DrawableSliderRepeat sliderRepeat: case DrawableSliderRepeat sliderRepeat:
// use stored values from head circle to achieve same fade sequence. // use stored values from head circle to achieve same fade sequence.
fadeOutDuration = lastSliderHeadFadeOutDuration; var repeatFadeOutParameters = getFadeOutParametersFromSliderHead(h);
fadeOutStartTime = lastSliderHeadFadeOutStartTime;
using (drawable.BeginAbsoluteSequence(fadeOutStartTime, true)) using (drawable.BeginAbsoluteSequence(repeatFadeOutParameters.startTime, true))
// only apply to circle piece reverse arrow is not affected by hidden. // only apply to circle piece reverse arrow is not affected by hidden.
sliderRepeat.CirclePiece.FadeOut(fadeOutDuration); sliderRepeat.CirclePiece.FadeOut(repeatFadeOutParameters.duration);
break; break;
case DrawableHitCircle circle: case DrawableHitCircle circle:
if (circle is DrawableSliderHead)
{
lastSliderHeadFadeOutDuration = fadeOutDuration;
lastSliderHeadFadeOutStartTime = fadeOutStartTime;
}
Drawable fadeTarget = circle; Drawable fadeTarget = circle;
if (increaseVisibility) if (increaseVisibility)
@ -125,6 +114,8 @@ namespace osu.Game.Rulesets.Osu.Mods
break; break;
case DrawableSlider slider: case DrawableSlider slider:
associateNestedSliderCirclesWithHead(slider.HitObject);
using (slider.BeginAbsoluteSequence(fadeOutStartTime, true)) using (slider.BeginAbsoluteSequence(fadeOutStartTime, true))
slider.Body.FadeOut(longFadeDuration, Easing.Out); slider.Body.FadeOut(longFadeDuration, Easing.Out);
@ -149,5 +140,24 @@ namespace osu.Game.Rulesets.Osu.Mods
break; break;
} }
} }
private readonly Dictionary<HitObject, SliderHeadCircle> correspondingSliderHeadForObject = new Dictionary<HitObject, SliderHeadCircle>();
private void associateNestedSliderCirclesWithHead(Slider slider)
{
var sliderHead = slider.NestedHitObjects.Single(obj => obj is SliderHeadCircle);
foreach (var nested in slider.NestedHitObjects)
{
if ((nested is SliderRepeat || nested is SliderEndCircle) && !correspondingSliderHeadForObject.ContainsKey(nested))
correspondingSliderHeadForObject[nested] = (SliderHeadCircle)sliderHead;
}
}
private (double startTime, double duration) getFadeOutParametersFromSliderHead(OsuHitObject h)
{
var sliderHead = correspondingSliderHeadForObject[h];
return (sliderHead.StartTime - sliderHead.TimePreempt + sliderHead.TimeFadeIn, sliderHead.TimePreempt * fade_out_duration_multiplier);
}
} }
} }