diff --git a/osu.Game/Input/Bindings/GlobalActionContainer.cs b/osu.Game/Input/Bindings/GlobalActionContainer.cs index 2452852f6f..6e2d0eb25e 100644 --- a/osu.Game/Input/Bindings/GlobalActionContainer.cs +++ b/osu.Game/Input/Bindings/GlobalActionContainer.cs @@ -143,6 +143,7 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { InputKey.Control, InputKey.Shift, InputKey.MouseWheelLeft }, GlobalAction.EditorCycleNextBeatSnapDivisor), new KeyBinding(new[] { InputKey.Control, InputKey.R }, GlobalAction.EditorToggleRotateControl), new KeyBinding(new[] { InputKey.Control, InputKey.E }, GlobalAction.EditorToggleScaleControl), + new KeyBinding(new[] { InputKey.Tab }, GlobalAction.EditorTestPlayToggleAutoplay), }; private static IEnumerable inGameKeyBindings => new[] @@ -432,6 +433,9 @@ namespace osu.Game.Input.Bindings [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorToggleScaleControl))] EditorToggleScaleControl, + + [LocalisableDescription(typeof(GlobalActionKeyBindingStrings), nameof(GlobalActionKeyBindingStrings.EditorTestPlayToggleAutoplay))] + EditorTestPlayToggleAutoplay, } public enum GlobalActionCategory diff --git a/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs b/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs index 2e44b96625..735d82d9f5 100644 --- a/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs +++ b/osu.Game/Localisation/GlobalActionKeyBindingStrings.cs @@ -374,6 +374,11 @@ namespace osu.Game.Localisation /// public static LocalisableString EditorToggleScaleControl => new TranslatableString(getKey(@"editor_toggle_scale_control"), @"Toggle scale control"); + /// + /// "Test play: Toggle autoplay" + /// + public static LocalisableString EditorTestPlayToggleAutoplay => new TranslatableString(getKey(@"editor_test_play_toggle_autoplay"), @"Test play: Toggle autoplay"); + /// /// "Increase mod speed" /// diff --git a/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs b/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs index 69851d0d35..e70b0419ca 100644 --- a/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs +++ b/osu.Game/Screens/Edit/GameplayTest/EditorPlayer.cs @@ -4,17 +4,21 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Input.Bindings; +using osu.Framework.Input.Events; using osu.Framework.Screens; using osu.Game.Beatmaps; +using osu.Game.Input.Bindings; using osu.Game.Overlays; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; using osu.Game.Screens.Play; using osu.Game.Users; namespace osu.Game.Screens.Edit.GameplayTest { - public partial class EditorPlayer : Player + public partial class EditorPlayer : Player, IKeyBindingHandler { private readonly Editor editor; private readonly EditorState editorState; @@ -133,6 +137,47 @@ namespace osu.Game.Screens.Edit.GameplayTest protected override bool CheckModsAllowFailure() => false; // never fail. + public bool OnPressed(KeyBindingPressEvent e) + { + if (e.Repeat) + return false; + + switch (e.Action) + { + case GlobalAction.EditorTestPlayToggleAutoplay: + toggleAutoplay(); + return true; + + default: + return false; + } + } + + public void OnReleased(KeyBindingReleaseEvent e) + { + } + + private void toggleAutoplay() + { + if (DrawableRuleset.ReplayScore == null) + { + var autoplay = Ruleset.Value.CreateInstance().GetAutoplayMod(); + if (autoplay == null) + return; + + var score = autoplay.CreateScoreFromReplayData(GameplayState.Beatmap, [autoplay]); + + // remove past frames to prevent replay frame handler from seeking back to start in an attempt to play back the entirety of the replay. + score.Replay.Frames.RemoveAll(f => f.Time <= GameplayClockContainer.CurrentTime); + + DrawableRuleset.SetReplayScore(score); + // Without this schedule, the `GlobalCursorDisplay.Update()` machinery will fade the gameplay cursor out, but we still want it to show. + Schedule(() => DrawableRuleset.Cursor?.Show()); + } + else + DrawableRuleset.SetReplayScore(null); + } + public override void OnEntering(ScreenTransitionEvent e) { base.OnEntering(e);