diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs index a418df605f..50f9c5e775 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs @@ -5,9 +5,11 @@ using System.Linq; using NUnit.Framework; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Configuration; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; @@ -22,6 +24,9 @@ namespace osu.Game.Rulesets.Osu.Tests { private int depthIndex; + [Resolved] + private OsuConfigManager config { get; set; } + [Test] public void TestHits() { @@ -56,6 +61,13 @@ namespace osu.Game.Rulesets.Osu.Tests AddStep("Hit stream late", () => SetContents(_ => testStream(5, true, 150))); } + [Test] + public void TestHitLighting() + { + AddToggleStep("toggle hit lighting", v => config.SetValue(OsuSetting.HitLighting, v)); + AddStep("Hit Big Single", () => SetContents(_ => testSingle(2, true))); + } + private Drawable testSingle(float circleSize, bool auto = false, double timeOffset = 0, Vector2? positionOffset = null) { var playfield = new TestOsuPlayfield(); diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs index d50a3eba13..04a4d4bede 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonMainCirclePiece.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; +using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Rulesets.Objects.Drawables; @@ -45,6 +46,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon private readonly FlashPiece flash; private readonly KiaiFlash kiaiFlash; + private Bindable configHitLighting = null!; + [Resolved] private DrawableHitObject drawableObject { get; set; } = null!; @@ -65,21 +68,18 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon outerGradient = new Circle // renders the outer bright gradient { Size = new Vector2(OUTER_GRADIENT_SIZE), - Alpha = 1, Anchor = Anchor.Centre, Origin = Anchor.Centre, }, innerGradient = new Circle // renders the inner bright gradient { Size = new Vector2(INNER_GRADIENT_SIZE), - Alpha = 1, Anchor = Anchor.Centre, Origin = Anchor.Centre, }, innerFill = new Circle // renders the inner dark fill { Size = new Vector2(INNER_FILL_SIZE), - Alpha = 1, Anchor = Anchor.Centre, Origin = Anchor.Centre, }, @@ -106,12 +106,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon } [BackgroundDependencyLoader] - private void load() + private void load(OsuConfigManager config) { var drawableOsuObject = (DrawableOsuHitObject)drawableObject; accentColour.BindTo(drawableObject.AccentColour); indexInCurrentCombo.BindTo(drawableOsuObject.IndexInCurrentComboBindable); + + configHitLighting = config.GetBindable(OsuSetting.HitLighting); } protected override void LoadComplete() @@ -134,14 +136,18 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon // Accent colour may be changed many times during a paused gameplay state. // Schedule the change to avoid transforms piling up. - Scheduler.AddOnce(updateStateTransforms); + Scheduler.AddOnce(() => + { + ApplyTransformsAt(double.MinValue, true); + ClearTransformsAfter(double.MinValue, true); + + updateStateTransforms(drawableObject, drawableObject.State.Value); + }); }, true); drawableObject.ApplyCustomUpdateState += updateStateTransforms; } - private void updateStateTransforms() => updateStateTransforms(drawableObject, drawableObject.State.Value); - private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state) { using (BeginAbsoluteSequence(drawableObject.HitStateUpdateTime)) @@ -151,12 +157,15 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon case ArmedState.Hit: // Fade out time is at a maximum of 800. Must match `DrawableHitCircle`'s arbitrary lifetime spec. const double fade_out_time = 800; - const double flash_in_duration = 150; const double resize_duration = 400; const float shrink_size = 0.8f; + // When the user has hit lighting disabled, we won't be showing the bright white flash. + // To make things look good, the surrounding animations are also slightly adjusted. + bool showFlash = configHitLighting.Value; + // Animating with the number present is distracting. // The number disappearing is hidden by the bright flash. number.FadeOut(flash_in_duration / 2); @@ -187,15 +196,27 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon using (BeginDelayedSequence(flash_in_duration / 12)) { outerGradient.ResizeTo(OUTER_GRADIENT_SIZE * shrink_size, resize_duration, Easing.OutElasticHalf); - outerGradient - .FadeColour(Color4.White, 80) - .Then() - .FadeOut(flash_in_duration); + + if (showFlash) + { + outerGradient + .FadeColour(Color4.White, 80) + .Then() + .FadeOut(flash_in_duration); + } + else + { + outerGradient + .FadeColour(Color4.White, flash_in_duration * 8) + .FadeOut(flash_in_duration * 2); + } } - flash.FadeTo(1, flash_in_duration, Easing.OutQuint); + if (showFlash) + flash.FadeTo(1, flash_in_duration, Easing.OutQuint); + + this.FadeOut(showFlash ? fade_out_time : fade_out_time / 2, Easing.OutQuad); - this.FadeOut(fade_out_time, Easing.OutQuad); break; } }