diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index ee29f970bb..dc13329bde 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -84,6 +84,8 @@ namespace osu.Game.Rulesets.Catch } } + public override Mod GetAutoplayMod() => new ModAutoplay(); + public override string Description => "osu!catch"; public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o }; diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 0349427784..a8a89a57e0 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -105,6 +105,8 @@ namespace osu.Game.Rulesets.Mania } } + public override Mod GetAutoplayMod() => new ModAutoplay(); + public override string Description => "osu!mania"; public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o }; diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index da32b49262..9a1971d791 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -105,6 +105,8 @@ namespace osu.Game.Rulesets.Osu } } + public override Mod GetAutoplayMod() => new OsuModAutoplay(); + public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_osu_o }; public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap) => new OsuDifficultyCalculator(beatmap); diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 27b4cffbaf..83db9b35af 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -84,6 +84,8 @@ namespace osu.Game.Rulesets.Taiko } } + public override Mod GetAutoplayMod() => new TaikoModAutoplay(); + public override string Description => "osu!taiko"; public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o }; diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 0885fb05e5..bd53a80555 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -60,6 +60,8 @@ namespace osu.Game.Beatmaps { public override IEnumerable GetModsFor(ModType type) => new Mod[] { }; + public override Mod GetAutoplayMod() => new ModAutoplay(); + public override HitRenderer CreateHitRendererWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) { throw new NotImplementedException(); diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 42fff0f258..447daca75e 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -10,6 +10,9 @@ using System.Linq; namespace osu.Game.Graphics.UserInterface { + /// + /// A textbox which holds focus eagerly. + /// public class FocusedTextBox : OsuTextBox { protected override Color4 BackgroundUnfocused => new Color4(10, 10, 10, 255); diff --git a/osu.Game/Graphics/UserInterface/SearchTextBox.cs b/osu.Game/Graphics/UserInterface/SearchTextBox.cs index f39cdf5d24..ee5d3baf66 100644 --- a/osu.Game/Graphics/UserInterface/SearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/SearchTextBox.cs @@ -8,9 +8,6 @@ using OpenTK.Input; namespace osu.Game.Graphics.UserInterface { - /// - /// A textbox which holds focus eagerly. - /// public class SearchTextBox : FocusedTextBox { protected virtual bool AllowCommit => false; @@ -46,10 +43,16 @@ namespace osu.Game.Graphics.UserInterface case Key.Up: case Key.Down: return false; + } + } + + if (!AllowCommit) + { + switch (args.Key) + { case Key.KeypadEnter: case Key.Enter: - if (!AllowCommit) return false; - break; + return false; } } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index c5a9155da5..b3be36a983 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -19,6 +19,8 @@ namespace osu.Game.Rulesets public abstract IEnumerable GetModsFor(ModType type); + public abstract Mod GetAutoplayMod(); + /// /// Attempt to create a hit renderer for a beatmap /// diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index d215385ece..6e79d2b427 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -47,7 +47,7 @@ namespace osu.Game.Screens } } - private readonly Bindable ruleset = new Bindable(); + protected readonly Bindable Ruleset = new Bindable(); private SampleChannel sampleExit; @@ -64,7 +64,7 @@ namespace osu.Game.Screens } if (osuGame != null) - ruleset.BindTo(osuGame.Ruleset); + Ruleset.BindTo(osuGame.Ruleset); sampleExit = audio.Sample.Get(@"UI/melodic-1"); } @@ -77,7 +77,7 @@ namespace osu.Game.Screens { // we only want to apply these restrictions when we are inside a screen stack. // the use case for not applying is in visual/unit tests. - ruleset.Disabled = !AllowBeatmapRulesetChange; + Ruleset.Disabled = !AllowBeatmapRulesetChange; Beatmap.Disabled = !AllowBeatmapRulesetChange; } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 84261d509e..39128eb85e 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -4,7 +4,6 @@ using OpenTK; using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -111,13 +110,7 @@ namespace osu.Game.Screens.Play return; } - Track track = Beatmap.Value.Track; - - if (track != null) - adjustableSourceClock = track; - - adjustableSourceClock = (IAdjustableClock)track ?? new StopwatchClock(); - + adjustableSourceClock = (IAdjustableClock)Beatmap.Value.Track ?? new StopwatchClock(); decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false }; var firstObjectTime = HitRenderer.Objects.First().StartTime; diff --git a/osu.Game/Screens/Select/EditSongSelect.cs b/osu.Game/Screens/Select/EditSongSelect.cs index 1a9d37f069..907c080729 100644 --- a/osu.Game/Screens/Select/EditSongSelect.cs +++ b/osu.Game/Screens/Select/EditSongSelect.cs @@ -1,12 +1,14 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Input; + namespace osu.Game.Screens.Select { public class EditSongSelect : SongSelect { protected override bool ShowFooter => false; - protected override void OnSelected() => Exit(); + protected override void OnSelected(InputState state) => Exit(); } } diff --git a/osu.Game/Screens/Select/MatchSongSelect.cs b/osu.Game/Screens/Select/MatchSongSelect.cs index 282cd06126..2d3b198478 100644 --- a/osu.Game/Screens/Select/MatchSongSelect.cs +++ b/osu.Game/Screens/Select/MatchSongSelect.cs @@ -1,10 +1,12 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Input; + namespace osu.Game.Screens.Select { public class MatchSongSelect : SongSelect { - protected override void OnSelected() => Exit(); + protected override void OnSelected(InputState state) => Exit(); } } diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index e393caf931..662e1d55a2 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -1,10 +1,12 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Linq; using OpenTK.Input; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Input; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Graphics; @@ -20,6 +22,7 @@ namespace osu.Game.Screens.Select private OsuScreen player; private readonly ModSelectOverlay modSelect; private readonly BeatmapDetailArea beatmapDetails; + private bool removeAutoModOnResume; public PlaySongSelect() { @@ -71,6 +74,13 @@ namespace osu.Game.Screens.Select { player = null; + if (removeAutoModOnResume) + { + var autoType = Ruleset.Value.CreateInstance().GetAutoplayMod().GetType(); + modSelect.SelectedMods.Value = modSelect.SelectedMods.Value.Where(m => m.GetType() != autoType).ToArray(); + removeAutoModOnResume = false; + } + Beatmap.Value.Track.Looping = true; base.OnResuming(last); @@ -100,10 +110,23 @@ namespace osu.Game.Screens.Select return false; } - protected override void OnSelected() + protected override void OnSelected(InputState state) { if (player != null) return; + if (state?.Keyboard.ControlPressed == true) + { + var auto = Ruleset.Value.CreateInstance().GetAutoplayMod(); + var autoType = auto.GetType(); + + var mods = modSelect.SelectedMods.Value; + if (mods.All(m => m.GetType() != autoType)) + { + modSelect.SelectedMods.Value = mods.Concat(new[] { auto }); + removeAutoModOnResume = true; + } + } + Beatmap.Value.Track.Looping = false; Beatmap.Disabled = true; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 217baccf58..8f545240c8 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -9,7 +9,6 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Audio.Track; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; @@ -19,7 +18,6 @@ using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Overlays; -using osu.Game.Rulesets; using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Select.Options; @@ -27,7 +25,6 @@ namespace osu.Game.Screens.Select { public abstract class SongSelect : OsuScreen { - private readonly Bindable ruleset = new Bindable(); private BeatmapManager manager; protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(); @@ -109,7 +106,7 @@ namespace osu.Game.Screens.Select Origin = Anchor.CentreRight, SelectionChanged = carouselSelectionChanged, BeatmapsChanged = carouselBeatmapsLoaded, - StartRequested = carouselRaisedStart, + StartRequested = () => carouselRaisedStart(), }); Add(FilterControl = new FilterControl { @@ -151,7 +148,7 @@ namespace osu.Game.Screens.Select Add(Footer = new Footer { OnBack = Exit, - OnStart = carouselRaisedStart, + OnStart = () => carouselRaisedStart(), }); FooterPanels.Add(BeatmapOptions = new BeatmapOptionsOverlay()); @@ -173,7 +170,7 @@ namespace osu.Game.Screens.Select manager = beatmaps; if (osu != null) - ruleset.BindTo(osu.Ruleset); + Ruleset.BindTo(osu.Ruleset); manager.BeatmapSetAdded += onBeatmapSetAdded; manager.BeatmapSetRemoved += onBeatmapSetRemoved; @@ -201,7 +198,7 @@ namespace osu.Game.Screens.Select carousel.SelectNext(); } - private void carouselRaisedStart() + private void carouselRaisedStart(InputState state = null) { // if we have a pending filter operation, we want to run it now. // it could change selection (ie. if the ruleset has been changed). @@ -214,7 +211,7 @@ namespace osu.Game.Screens.Select selectionChangedDebounce = null; } - OnSelected(); + OnSelected(state); } private ScheduledDelegate selectionChangedDebounce; @@ -256,7 +253,7 @@ namespace osu.Game.Screens.Select } else { - ruleset.Value = beatmap.Ruleset; + Ruleset.Value = beatmap.Ruleset; if (beatmap.BeatmapSetInfoID == beatmapNoDebounce?.BeatmapSetInfoID) sampleChangeDifficulty.Play(); @@ -278,7 +275,7 @@ namespace osu.Game.Screens.Select carousel.SelectNextRandom(); } - protected abstract void OnSelected(); + protected abstract void OnSelected(InputState state); private void filterChanged(FilterCriteria criteria, bool debounce = true) { @@ -406,7 +403,7 @@ namespace osu.Game.Screens.Select { case Key.KeypadEnter: case Key.Enter: - carouselRaisedStart(); + carouselRaisedStart(state); return true; case Key.Delete: if (state.Keyboard.ShiftPressed)