diff --git a/osu.Game.Rulesets.Osu/Mods/InputBlockingMod.cs b/osu.Game.Rulesets.Osu/Mods/InputBlockingMod.cs index 7db4e2625b..b56fdbdf74 100644 --- a/osu.Game.Rulesets.Osu/Mods/InputBlockingMod.cs +++ b/osu.Game.Rulesets.Osu/Mods/InputBlockingMod.cs @@ -11,6 +11,7 @@ using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play; @@ -26,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Mods private const double flash_duration = 1000; - private DrawableRuleset ruleset = null!; + private DrawableOsuRuleset ruleset = null!; protected OsuAction? LastAcceptedAction { get; private set; } @@ -42,8 +43,8 @@ namespace osu.Game.Rulesets.Osu.Mods public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { - ruleset = drawableRuleset; - drawableRuleset.KeyBindingInputManager.Add(new InputInterceptor(this)); + ruleset = (DrawableOsuRuleset)drawableRuleset; + ruleset.KeyBindingInputManager.Add(new InputInterceptor(this)); var periods = new List(); diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs index 9eb0a46bfb..4782a0e49c 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs @@ -11,6 +11,7 @@ using osu.Game.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Replays; +using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Osu.Mods @@ -55,7 +56,7 @@ namespace osu.Game.Rulesets.Osu.Mods public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { // Grab the input manager to disable the user's cursor, and for future use - inputManager = (OsuInputManager)drawableRuleset.KeyBindingInputManager; + inputManager = ((DrawableOsuRuleset)drawableRuleset).KeyBindingInputManager; inputManager.AllowUserCursorMovement = false; // Generate the replay frames the cursor should follow diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index 753de6231a..32ffb545e0 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -10,6 +10,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play; @@ -42,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Mods public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { // grab the input manager for future use. - osuInputManager = (OsuInputManager)drawableRuleset.KeyBindingInputManager; + osuInputManager = ((DrawableOsuRuleset)drawableRuleset).KeyBindingInputManager; } public void ApplyToPlayer(Player player) diff --git a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs index d1fa0d09cc..c3efd48053 100644 --- a/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/UI/DrawableOsuRuleset.cs @@ -26,6 +26,8 @@ namespace osu.Game.Rulesets.Osu.UI { protected new OsuRulesetConfigManager Config => (OsuRulesetConfigManager)base.Config; + public new OsuInputManager KeyBindingInputManager => (OsuInputManager)base.KeyBindingInputManager; + public new OsuPlayfield Playfield => (OsuPlayfield)base.Playfield; public DrawableOsuRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null) diff --git a/osu.Game.Tests/NonVisual/FirstAvailableHitWindowsTest.cs b/osu.Game.Tests/NonVisual/FirstAvailableHitWindowsTest.cs index 9a32b8e894..0bdd0ceae6 100644 --- a/osu.Game.Tests/NonVisual/FirstAvailableHitWindowsTest.cs +++ b/osu.Game.Tests/NonVisual/FirstAvailableHitWindowsTest.cs @@ -7,6 +7,7 @@ using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using NUnit.Framework; +using osu.Framework.Audio; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mods; @@ -93,6 +94,7 @@ namespace osu.Game.Tests.NonVisual remove => throw new InvalidOperationException($"{nameof(RevertResult)} operations not supported in test context"); } + public override IAdjustableAudioComponent Audio { get; } public override Playfield Playfield { get; } public override Container Overlays { get; } public override Container FrameStableComponents { get; } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs index e2ff2780e0..56900a0549 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs @@ -9,6 +9,7 @@ using System.Diagnostics.CodeAnalysis; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -281,6 +282,7 @@ namespace osu.Game.Tests.Visual.Gameplay remove => throw new InvalidOperationException($"{nameof(RevertResult)} operations not supported in test context"); } + public override IAdjustableAudioComponent Audio { get; } public override Playfield Playfield { get; } public override Container Overlays { get; } public override Container FrameStableComponents { get; } diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index 45fa55c7f2..9fe0864c7a 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -82,7 +82,7 @@ namespace osu.Game.Rulesets.Mods flashlight.Colour = Color4.Black; flashlight.Combo.BindTo(Combo); - drawableRuleset.KeyBindingInputManager.Add(flashlight); + drawableRuleset.Overlays.Add(flashlight); } protected abstract Flashlight CreateFlashlight(); diff --git a/osu.Game/Rulesets/Mods/ModMuted.cs b/osu.Game/Rulesets/Mods/ModMuted.cs index 367ceeb446..131f501630 100644 --- a/osu.Game/Rulesets/Mods/ModMuted.cs +++ b/osu.Game/Rulesets/Mods/ModMuted.cs @@ -67,7 +67,8 @@ namespace osu.Game.Rulesets.Mods { MetronomeBeat metronomeBeat; - drawableRuleset.Overlays.Add(metronomeBeat = new MetronomeBeat(drawableRuleset.Beatmap.HitObjects.First().StartTime)); + // Importantly, this is added to FrameStableComponents and not Overlays as the latter would cause it to be self-muted by the mod's volume adjustment. + drawableRuleset.FrameStableComponents.Add(metronomeBeat = new MetronomeBeat(drawableRuleset.Beatmap.HitObjects.First().StartTime)); metronomeBeat.AddAdjustment(AdjustableProperty.Volume, metronomeVolumeAdjust); } diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index 4f4640872f..64fe9c8a86 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.UI /// /// The key conversion input manager for this DrawableRuleset. /// - public PassThroughInputManager KeyBindingInputManager; + protected PassThroughInputManager KeyBindingInputManager; public override double GameplayStartTime => Objects.FirstOrDefault()?.StartTime - 2000 ?? 0; @@ -66,6 +66,10 @@ namespace osu.Game.Rulesets.UI public override Container Overlays { get; } = new Container { RelativeSizeAxes = Axes.Both }; + public override IAdjustableAudioComponent Audio => audioContainer; + + private readonly AudioContainer audioContainer = new AudioContainer { RelativeSizeAxes = Axes.Both }; + public override Container FrameStableComponents { get; } = new Container { RelativeSizeAxes = Axes.Both }; public override IFrameStableClock FrameStableClock => frameStabilityContainer; @@ -102,14 +106,6 @@ namespace osu.Game.Rulesets.UI private DrawableRulesetDependencies dependencies; - /// - /// Audio adjustments which are applied to the playfield. - /// - /// - /// Does not affect . - /// - public IAdjustableAudioComponent Audio { get; private set; } - /// /// Creates a ruleset visualisation for the provided ruleset and beatmap. /// @@ -172,28 +168,22 @@ namespace osu.Game.Rulesets.UI [BackgroundDependencyLoader] private void load(CancellationToken? cancellationToken) { - AudioContainer audioContainer; - InternalChild = frameStabilityContainer = new FrameStabilityContainer(GameplayStartTime) { FrameStablePlayback = FrameStablePlayback, Children = new Drawable[] { FrameStableComponents, - audioContainer = new AudioContainer - { - RelativeSizeAxes = Axes.Both, - Child = KeyBindingInputManager - .WithChild(CreatePlayfieldAdjustmentContainer() - .WithChild(Playfield) - ), - }, - Overlays, + audioContainer.WithChild(KeyBindingInputManager + .WithChildren(new Drawable[] + { + CreatePlayfieldAdjustmentContainer() + .WithChild(Playfield), + Overlays + })), } }; - Audio = audioContainer; - if ((ResumeOverlay = CreateResumeOverlay()) != null) { AddInternal(CreateInputManager() @@ -436,13 +426,18 @@ namespace osu.Game.Rulesets.UI /// public readonly BindableBool IsPaused = new BindableBool(); + /// + /// Audio adjustments which are applied to the playfield. + /// + public abstract IAdjustableAudioComponent Audio { get; } + /// /// The playfield. /// public abstract Playfield Playfield { get; } /// - /// Content to be placed above hitobjects. Will be affected by frame stability. + /// Content to be placed above hitobjects. Will be affected by frame stability and adjustments applied to . /// public abstract Container Overlays { get; }