From e28a6107578ae52d17298a6fc929d49ce17e5ca1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Jul 2018 12:40:55 +0900 Subject: [PATCH 1/9] Fix mods not correctly resetting when changing ruleset at song select --- .../ManiaSettingsSubsection.cs | 5 ++- osu.Game/Overlays/Mods/ModSelectOverlay.cs | 7 +++- .../Settings/RulesetSettingsSubsection.cs | 9 +++-- osu.Game/Rulesets/Mods/ModAutoplay.cs | 2 +- osu.Game/Screens/Select/PlaySongSelect.cs | 4 +- osu.Game/Screens/Select/SongSelect.cs | 38 +++++++++++++------ osu.Game/osu.Game.csproj | 2 +- 7 files changed, 46 insertions(+), 21 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs index 54a7bf954d..8d1fad8a82 100644 --- a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs +++ b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Overlays.Settings; +using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Mania.Configuration; using osu.Game.Rulesets.Mania.UI; @@ -19,14 +20,14 @@ namespace osu.Game.Rulesets.Mania } [BackgroundDependencyLoader] - private void load(ManiaConfigManager config) + private void load() { Children = new Drawable[] { new SettingsEnumDropdown { LabelText = "Scrolling direction", - Bindable = config.GetBindable(ManiaSetting.ScrollDirection) + Bindable = (Config as RulesetConfigManager)?.GetBindable(ManiaSetting.ScrollDirection) } }; } diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index c584a32a82..98cf111ba0 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -44,6 +44,8 @@ namespace osu.Game.Overlays.Mods private void rulesetChanged(RulesetInfo newRuleset) { + if (newRuleset == null) return; + var instance = newRuleset.CreateInstance(); foreach (ModSection section in ModSectionsContainer.Children) @@ -173,7 +175,10 @@ namespace osu.Game.Overlays.Mods refreshSelectedMods(); } - private void refreshSelectedMods() => SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray(); + private void refreshSelectedMods() + { + SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray(); + } public ModSelectOverlay() { diff --git a/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs b/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs index 05104018cd..5340a01743 100644 --- a/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs +++ b/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Game.Rulesets; +using osu.Game.Rulesets.Configuration; namespace osu.Game.Overlays.Settings { @@ -14,6 +15,8 @@ namespace osu.Game.Overlays.Settings { private readonly Ruleset ruleset; + protected IRulesetConfigManager Config; + protected RulesetSettingsSubsection(Ruleset ruleset) { this.ruleset = ruleset; @@ -25,9 +28,9 @@ namespace osu.Game.Overlays.Settings { dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - var config = dependencies.Get().GetConfigFor(ruleset); - if (config != null) - dependencies.Cache(config); + Config = dependencies.Get().GetConfigFor(ruleset); + if (Config != null) + dependencies.Cache(Config); return dependencies; } diff --git a/osu.Game/Rulesets/Mods/ModAutoplay.cs b/osu.Game/Rulesets/Mods/ModAutoplay.cs index 7058d1bed6..8f73ff4c2d 100644 --- a/osu.Game/Rulesets/Mods/ModAutoplay.cs +++ b/osu.Game/Rulesets/Mods/ModAutoplay.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Mods { - public class ModAutoplay : ModAutoplay, IApplicableToRulesetContainer + public abstract class ModAutoplay : ModAutoplay, IApplicableToRulesetContainer where T : HitObject { protected virtual Score CreateReplayScore(Beatmap beatmap) => new Score { Replay = new Replay() }; diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 8ce40fcfa0..a346911ca2 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -84,10 +84,10 @@ namespace osu.Game.Screens.Select protected override void UpdateBeatmap(WorkingBeatmap beatmap) { - base.UpdateBeatmap(beatmap); - beatmap.Mods.BindTo(SelectedMods); + base.UpdateBeatmap(beatmap); + BeatmapDetails.Beatmap = beatmap; if (beatmap.Track != null) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 94c16f1797..e940cac419 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Linq; using OpenTK; using OpenTK.Input; using osu.Framework.Allocation; @@ -19,6 +20,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Overlays; using osu.Game.Rulesets; +using osu.Game.Rulesets.Mods; using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Edit; using osu.Game.Screens.Menu; @@ -67,8 +69,17 @@ namespace osu.Game.Screens.Select protected new readonly Bindable Ruleset = new Bindable(); private DependencyContainer dependencies; + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + { + dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + + dependencies.CacheAs(this); + dependencies.CacheAs(Ruleset); + dependencies.CacheAs>(Ruleset); + + return dependencies; + } protected SongSelect() { @@ -183,11 +194,9 @@ namespace osu.Game.Screens.Select [BackgroundDependencyLoader(true)] private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours) { - dependencies.CacheAs(this); - dependencies.CacheAs(Ruleset); - dependencies.CacheAs>(Ruleset); - + // manual binding to parent ruleset to allow for delayed load in the incoming direction. base.Ruleset.ValueChanged += r => updateSelectedBeatmap(beatmapNoDebounce); + Ruleset.ValueChanged += r => base.Ruleset.Value = r; if (Footer != null) { @@ -263,7 +272,7 @@ namespace osu.Game.Screens.Select // If selecting new beatmap without bypassing filters failed, there's possibly a ruleset mismatch if (beatmap?.BeatmapInfo?.Ruleset != null && beatmap.BeatmapInfo.Ruleset != Ruleset.Value) { - Ruleset.Value = beatmap.BeatmapInfo.Ruleset; + base.Ruleset.Value = beatmap.BeatmapInfo.Ruleset; Carousel.SelectBeatmap(beatmap.BeatmapInfo); } } @@ -281,16 +290,22 @@ namespace osu.Game.Screens.Select void performLoad() { + WorkingBeatmap working = Beatmap.Value; + bool preview = false; + // We may be arriving here due to another component changing the bindable Beatmap. // In these cases, the other component has already loaded the beatmap, so we don't need to do so again. if (beatmap?.Equals(Beatmap.Value.BeatmapInfo) != true) { - bool preview = beatmap?.BeatmapSetInfoID != Beatmap.Value?.BeatmapInfo.BeatmapSetInfoID; - - Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); - ensurePlayingSelected(preview); + preview = beatmap?.BeatmapSetInfoID != Beatmap.Value?.BeatmapInfo.BeatmapSetInfoID; + working = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); } + ensurePlayingSelected(preview); + + working.Mods.Value = Enumerable.Empty(); + + Beatmap.Value = working; Ruleset.Value = ruleset; UpdateBeatmap(Beatmap.Value); @@ -464,7 +479,8 @@ namespace osu.Game.Screens.Select private void carouselBeatmapsLoaded() { - if (!Beatmap.IsDefault && Beatmap.Value.BeatmapSetInfo?.DeletePending == false && Beatmap.Value.BeatmapSetInfo?.Protected == false && Carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo, false)) + if (!Beatmap.IsDefault && Beatmap.Value.BeatmapSetInfo?.DeletePending == false && Beatmap.Value.BeatmapSetInfo?.Protected == false + && Carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo, false)) return; if (Carousel.SelectedBeatmapSet == null && !Carousel.SelectNextRandom()) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 56c33c47af..74da553bfe 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - + From 1418d1369fe76c5e76a0cfaeda57b331334d090f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Jul 2018 01:32:10 +0900 Subject: [PATCH 2/9] Add the ability to click completed download notifications to select beatmap Closes #2731. --- osu.Game/Beatmaps/BeatmapManager.cs | 15 ++++++++++++++- osu.Game/OsuGame.cs | 27 +++++++++++++++++++++++++++ osu.Game/Screens/Menu/MainMenu.cs | 6 +++++- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index fd24e4297b..e63f70610e 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -45,6 +45,11 @@ namespace osu.Game.Beatmaps /// public event Action BeatmapDownloadBegan; + /// + /// Fired when a beatmap load is requested (into the interactive game UI). + /// + public Action PresentBeatmap; + /// /// A default representation of a WorkingBeatmap to use when no beatmap is available. /// @@ -163,12 +168,20 @@ namespace osu.Game.Beatmaps Task.Factory.StartNew(() => { + BeatmapSetInfo importedBeatmap; + // This gets scheduled back to the update thread, but we want the import to run in the background. using (var stream = new MemoryStream(data)) using (var archive = new ZipArchiveReader(stream, beatmapSetInfo.ToString())) - Import(archive); + importedBeatmap = Import(archive); + downloadNotification.CompletionClickAction = () => + { + PresentBeatmap?.Invoke(importedBeatmap); + return true; + }; downloadNotification.State = ProgressNotificationState.Completed; + currentDownloads.Remove(request); }, TaskCreationOptions.LongRunning); }; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 922d228701..f8fdaf368c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -23,6 +23,7 @@ using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Framework.Platform; using osu.Framework.Threading; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Rulesets.Scoring; using osu.Game.Overlays.Notifications; @@ -33,6 +34,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Skinning; using OpenTK.Graphics; using osu.Game.Overlays.Volume; +using osu.Game.Screens.Select; namespace osu.Game { @@ -178,6 +180,30 @@ namespace osu.Game /// The set to display. public void ShowBeatmapSet(int setId) => beatmapSetOverlay.FetchAndShowBeatmapSet(setId); + /// + /// Present a beatmap at song select. + /// + /// The beatmap to select. + public void PresentBeatmap(BeatmapSetInfo beatmap) + { + CloseAllOverlays(); + + Beatmap.Value = BeatmapManager.GetWorkingBeatmap(beatmap.Beatmaps.First()); + + switch (currentScreen) + { + case SongSelect _: + break; + default: + // navigate to song select if we are not already there. + var menu = (MainMenu)intro.ChildScreen; + + menu.MakeCurrent(); + menu.LoadToSolo(); + break; + } + } + /// /// Show a user's profile as an overlay. /// @@ -244,6 +270,7 @@ namespace osu.Game BeatmapManager.PostNotification = n => notifications?.Post(n); BeatmapManager.GetStableStorage = GetStorageForStableInstall; + BeatmapManager.PresentBeatmap = PresentBeatmap; AddRange(new Drawable[] { diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index d922f49ce3..4790996833 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Menu OnChart = delegate { Push(new ChartListing()); }, OnDirect = delegate { Push(new OnlineListing()); }, OnEdit = delegate { Push(new Editor()); }, - OnSolo = delegate { Push(consumeSongSelect()); }, + OnSolo = onSolo, OnMulti = delegate { Push(new Multiplayer()); }, OnExit = Exit, } @@ -85,6 +85,10 @@ namespace osu.Game.Screens.Menu LoadComponentAsync(songSelect = new PlaySongSelect()); } + public void LoadToSolo() => Schedule(onSolo); + + private void onSolo() => Push(consumeSongSelect()); + private Screen consumeSongSelect() { var s = songSelect; From b33a0f772e585d77d8aaaeb59fbc57dd59341d07 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jul 2018 21:00:52 +0900 Subject: [PATCH 3/9] Don't close toolbar --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index f8fdaf368c..bed4c98b53 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -186,7 +186,7 @@ namespace osu.Game /// The beatmap to select. public void PresentBeatmap(BeatmapSetInfo beatmap) { - CloseAllOverlays(); + CloseAllOverlays(false); Beatmap.Value = BeatmapManager.GetWorkingBeatmap(beatmap.Beatmaps.First()); From 95f314d9499dce6ae165d8c206bb6481756428a4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jul 2018 21:04:10 +0900 Subject: [PATCH 4/9] Fix crash when clicking notification from player --- osu.Game/OsuGame.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index bed4c98b53..a96768629e 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -188,17 +188,19 @@ namespace osu.Game { CloseAllOverlays(false); - Beatmap.Value = BeatmapManager.GetWorkingBeatmap(beatmap.Beatmaps.First()); + void setBeatmap() => Beatmap.Value = BeatmapManager.GetWorkingBeatmap(beatmap.Beatmaps.First()); switch (currentScreen) { case SongSelect _: + setBeatmap(); break; default: // navigate to song select if we are not already there. var menu = (MainMenu)intro.ChildScreen; menu.MakeCurrent(); + setBeatmap(); menu.LoadToSolo(); break; } From 6d8923a37cc1a14772538d455cbc819332d3b423 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jul 2018 21:08:41 +0900 Subject: [PATCH 5/9] Use better logic --- osu.Game/OsuGame.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 17c8ad8aa0..e2b93d0599 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -189,22 +189,31 @@ namespace osu.Game { CloseAllOverlays(false); - void setBeatmap() => Beatmap.Value = BeatmapManager.GetWorkingBeatmap(beatmap.Beatmaps.First()); + void setBeatmap() + { + if (Beatmap.Disabled) + { + Schedule(setBeatmap); + return; + } + + Beatmap.Value = BeatmapManager.GetWorkingBeatmap(beatmap.Beatmaps.First()); + }; switch (currentScreen) { case SongSelect _: - setBeatmap(); break; default: // navigate to song select if we are not already there. var menu = (MainMenu)intro.ChildScreen; menu.MakeCurrent(); - setBeatmap(); menu.LoadToSolo(); break; } + + setBeatmap(); } /// From ac35e8bd9939fd3d227915213dca699565e7ef38 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jul 2018 21:27:09 +0900 Subject: [PATCH 6/9] Remove redundant empty statement --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index e2b93d0599..18a1d018d0 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -198,7 +198,7 @@ namespace osu.Game } Beatmap.Value = BeatmapManager.GetWorkingBeatmap(beatmap.Beatmaps.First()); - }; + } switch (currentScreen) { From 63c40e9051c0125aa41cdb50902873d65aca98a1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jul 2018 21:45:42 +0900 Subject: [PATCH 7/9] Remove unnecessary cache operations --- osu.Game/Screens/Select/SongSelect.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index a695aedda7..e6f33a7d29 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -202,10 +202,6 @@ namespace osu.Game.Screens.Select base.Ruleset.ValueChanged += r => updateSelectedBeatmap(beatmapNoDebounce); Ruleset.ValueChanged += r => base.Ruleset.Value = r; - dependencies.CacheAs(this); - dependencies.CacheAs(Ruleset); - dependencies.CacheAs>(Ruleset); - if (Footer != null) { Footer.AddButton(@"random", colours.Green, triggerRandom, Key.F2); From 4f5578245efc81f29a81a86b178150ad036ba2e7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Jul 2018 21:45:49 +0900 Subject: [PATCH 8/9] Fix regression causing previews to not play --- osu.Game/Screens/Select/SongSelect.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index e6f33a7d29..234508a195 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -315,13 +315,14 @@ namespace osu.Game.Screens.Select working = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); } - ensurePlayingSelected(preview); working.Mods.Value = Enumerable.Empty(); Beatmap.Value = working; Ruleset.Value = ruleset; + ensurePlayingSelected(preview); + UpdateBeatmap(Beatmap.Value); } From b967fe714b8ef7b13c6266efe52043ad94a488d1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 17 Jul 2018 14:29:22 +0900 Subject: [PATCH 9/9] Fix lead-in time now being long enough in many cases --- osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs | 10 ++++++++++ osu.Game/Rulesets/UI/RulesetContainer.cs | 6 ++++++ osu.Game/Screens/Play/Player.cs | 7 +++---- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs index 33d4e16662..c18d180783 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System.Linq; using osu.Framework.Graphics.Cursor; using osu.Framework.Input; using OpenTK; @@ -46,6 +47,15 @@ namespace osu.Game.Rulesets.Osu.UI protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new OsuReplayInputHandler(replay); + public override double GameplayStartTime + { + get + { + var first = (OsuHitObject)Objects.First(); + return first.StartTime - first.TimePreempt; + } + } + protected override Vector2 GetAspectAdjustedSize() { var aspectSize = DrawSize.X * 0.75f < DrawSize.Y ? new Vector2(DrawSize.X, DrawSize.X * 0.75f) : new Vector2(DrawSize.Y * 4f / 3f, DrawSize.Y); diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 0bfde148e7..d68afdfedc 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -56,6 +56,12 @@ namespace osu.Game.Rulesets.UI public abstract IEnumerable Objects { get; } + /// + /// The point in time at which gameplay starts, including any required lead-in for display purposes. + /// Defaults to two seconds before the first . Override as necessary. + /// + public virtual double GameplayStartTime => Objects.First().StartTime - 2000; + private readonly Lazy playfield; /// diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 49a180902b..fc439a48c5 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -138,10 +138,9 @@ namespace osu.Game.Screens.Play sourceClock = (IAdjustableClock)working.Track ?? new StopwatchClock(); adjustableClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false }; - var firstObjectTime = RulesetContainer.Objects.First().StartTime; adjustableClock.Seek(AllowLeadIn - ? Math.Min(0, firstObjectTime - Math.Max(beatmap.ControlPointInfo.TimingPointAt(firstObjectTime).BeatLength * 4, beatmap.BeatmapInfo.AudioLeadIn)) - : firstObjectTime); + ? Math.Min(RulesetContainer.GameplayStartTime, beatmap.HitObjects.First().StartTime - beatmap.BeatmapInfo.AudioLeadIn) + : RulesetContainer.GameplayStartTime); adjustableClock.ProcessFrame(); @@ -199,7 +198,7 @@ namespace osu.Game.Screens.Play Anchor = Anchor.Centre, Origin = Anchor.Centre }, - new SkipOverlay(firstObjectTime) + new SkipOverlay(RulesetContainer.GameplayStartTime) { Clock = Clock, // skip button doesn't want to use the audio clock directly ProcessCustomClock = false,