diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModHidden.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModHidden.cs index ed9da36b05..71b575abe2 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModHidden.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModHidden.cs @@ -117,6 +117,42 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods PassCondition = checkSomeHit }); + [Test] + public void TestApproachCirclesOnly() => CreateModTest(new ModTestData + { + Mod = new OsuModHidden { OnlyFadeApproachCircles = { Value = true } }, + Autoplay = true, + Beatmap = new Beatmap + { + HitObjects = new List + { + new HitCircle + { + StartTime = 1000, + Position = new Vector2(206, 142) + }, + new HitCircle + { + StartTime = 2000, + Position = new Vector2(306, 142) + }, + new Slider + { + StartTime = 3000, + Position = new Vector2(156, 242), + Path = new SliderPath(PathType.Linear, new[] { Vector2.Zero, new Vector2(200, 0), }) + }, + new Spinner + { + Position = new Vector2(256, 192), + StartTime = 7000, + EndTime = 9000 + } + } + }, + PassCondition = checkSomeHit + }); + private bool checkSomeHit() => Player.ScoreProcessor.JudgedHits >= 4; private bool objectWithIncreasedVisibilityHasIndex(int index) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 9c7784a00a..e162f805a1 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -5,6 +5,8 @@ using System; using System.Diagnostics; using System.Linq; using osu.Framework.Graphics; +using osu.Framework.Bindables; +using osu.Game.Configuration; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; @@ -17,6 +19,9 @@ namespace osu.Game.Rulesets.Osu.Mods { public class OsuModHidden : ModHidden, IHidesApproachCircles { + [SettingSource("Only fade approach circles", "The main object body will not fade when enabled.")] + public Bindable OnlyFadeApproachCircles { get; } = new BindableBool(); + public override string Description => @"Play with no approach circles and fading circles/sliders."; public override double ScoreMultiplier => 1.06; @@ -44,15 +49,15 @@ namespace osu.Game.Rulesets.Osu.Mods protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) { - applyState(hitObject, true); + applyHiddenState(hitObject, true); } protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) { - applyState(hitObject, false); + applyHiddenState(hitObject, false); } - private void applyState(DrawableHitObject drawableObject, bool increaseVisibility) + private void applyHiddenState(DrawableHitObject drawableObject, bool increaseVisibility) { if (!(drawableObject is DrawableOsuHitObject drawableOsuObject)) return; @@ -61,6 +66,24 @@ namespace osu.Game.Rulesets.Osu.Mods (double fadeStartTime, double fadeDuration) = getFadeOutParameters(drawableOsuObject); + // process approach circle hiding first (to allow for early return below). + if (!increaseVisibility) + { + if (drawableObject is DrawableHitCircle circle) + { + using (circle.BeginAbsoluteSequence(hitObject.StartTime - hitObject.TimePreempt)) + circle.ApproachCircle.Hide(); + } + else if (drawableObject is DrawableSpinner spinner) + { + spinner.Body.OnSkinChanged += () => hideSpinnerApproachCircle(spinner); + hideSpinnerApproachCircle(spinner); + } + } + + if (OnlyFadeApproachCircles.Value) + return; + switch (drawableObject) { case DrawableSliderTail _: @@ -84,12 +107,6 @@ namespace osu.Game.Rulesets.Osu.Mods // only fade the circle piece (not the approach circle) for the increased visibility object. fadeTarget = circle.CirclePiece; } - else - { - // we don't want to see the approach circle - using (circle.BeginAbsoluteSequence(hitObject.StartTime - hitObject.TimePreempt)) - circle.ApproachCircle.Hide(); - } using (drawableObject.BeginAbsoluteSequence(fadeStartTime)) fadeTarget.FadeOut(fadeDuration); @@ -111,9 +128,6 @@ namespace osu.Game.Rulesets.Osu.Mods // hide elements we don't care about. // todo: hide background - spinner.Body.OnSkinChanged += () => hideSpinnerApproachCircle(spinner); - hideSpinnerApproachCircle(spinner); - using (spinner.BeginAbsoluteSequence(fadeStartTime)) spinner.FadeOut(fadeDuration);