diff --git a/osu-framework b/osu-framework index 6372fb22c1..6915954abd 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 6372fb22c1c85f600921a139849b8dedf71026d5 +Subproject commit 6915954abdba64e72f698aa58698b00159f3678d diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index f715ed075c..5b9ed4d259 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -12,7 +12,6 @@ using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Osu.Judgements; using osu.Framework.Graphics.Primitives; using osu.Game.Configuration; -using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Osu.Objects.Drawables @@ -55,8 +54,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables AlwaysPresent = true, Alpha = 0 }, - HeadCircle = new DrawableHitCircle(s.HeadCircle) { Position = s.TailCircle.Position - s.Position }, - TailCircle = new DrawableSliderTail(s.TailCircle) { Position = s.TailCircle.Position - s.Position } + HeadCircle = new DrawableSliderHead(s, s.HeadCircle), + TailCircle = new DrawableSliderTail(s, s.TailCircle) }; components.Add(Body); @@ -103,10 +102,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables double completionProgress = MathHelper.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1); - //todo: we probably want to reconsider this before adding scoring, but it looks and feels nice. - if (!HeadCircle.IsHit) - HeadCircle.Position = slider.CurvePositionAt(completionProgress); - foreach (var c in components.OfType()) c.UpdateProgress(completionProgress); foreach (var c in components.OfType()) c.UpdateSnakingPosition(slider.Curve.PositionAt(Body.SnakedStart ?? 0), slider.Curve.PositionAt(Body.SnakedEnd ?? 0)); foreach (var t in components.OfType()) t.Tracking = Ball.Tracking; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs new file mode 100644 index 0000000000..cf36d5fc14 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Objects.Types; +using OpenTK; + +namespace osu.Game.Rulesets.Osu.Objects.Drawables +{ + public class DrawableSliderHead : DrawableHitCircle + { + private readonly Slider slider; + + public DrawableSliderHead(Slider slider, HitCircle h) + : base(h) + { + this.slider = slider; + + Position = HitObject.Position - slider.Position; + } + + protected override void Update() + { + base.Update(); + + double completionProgress = MathHelper.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1); + + //todo: we probably want to reconsider this before adding scoring, but it looks and feels nice. + if (!IsHit) + Position = slider.CurvePositionAt(completionProgress); + } + } +} diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs index b907aea8c3..b277e7df7a 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public bool Tracking { get; set; } - public DrawableSliderTail(HitCircle hitCircle) + public DrawableSliderTail(Slider slider, HitCircle hitCircle) : base(hitCircle) { Origin = Anchor.Centre; @@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables FillMode = FillMode.Fit; AlwaysPresent = true; + + Position = HitObject.Position - slider.Position; } protected override void CheckForJudgements(bool userTriggered, double timeOffset) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 67b96f1fd9..d41331e3bd 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -68,6 +68,8 @@ namespace osu.Game.Rulesets.Osu.Scoring score.Statistics[HitResult.Miss] = scoreResultCounts.GetOrDefault(HitResult.Miss); } + private const double harshness = 0.01; + protected override void OnNewJudgement(Judgement judgement) { base.OnNewJudgement(judgement); @@ -83,15 +85,15 @@ namespace osu.Game.Rulesets.Osu.Scoring switch (judgement.Result) { case HitResult.Great: - Health.Value += (10.2 - hpDrainRate) * 0.02; + Health.Value += (10.2 - hpDrainRate) * harshness; break; case HitResult.Good: - Health.Value += (8 - hpDrainRate) * 0.02; + Health.Value += (8 - hpDrainRate) * harshness; break; case HitResult.Meh: - Health.Value += (4 - hpDrainRate) * 0.02; + Health.Value += (4 - hpDrainRate) * harshness; break; /*case HitResult.SliderTick: @@ -99,7 +101,7 @@ namespace osu.Game.Rulesets.Osu.Scoring break;*/ case HitResult.Miss: - Health.Value -= hpDrainRate * 0.04; + Health.Value -= hpDrainRate * (harshness * 2); break; } } diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index 8e8a01b009..92cac71ad3 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -87,6 +87,7 @@ + diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs index fe26366362..c68e548f44 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs @@ -12,6 +12,7 @@ using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Configuration; +using osu.Game.Rulesets; using osu.Game.Screens.Select; using osu.Game.Screens.Select.Carousel; using osu.Game.Screens.Select.Filter; @@ -22,6 +23,7 @@ namespace osu.Game.Tests.Visual public class TestCaseBeatmapCarousel : OsuTestCase { private TestBeatmapCarousel carousel; + private RulesetStore rulesets; public override IReadOnlyList RequiredTypes => new[] { @@ -46,8 +48,10 @@ namespace osu.Game.Tests.Visual private const int set_count = 5; [BackgroundDependencyLoader] - private void load() + private void load(RulesetStore rulesets) { + this.rulesets = rulesets; + Add(carousel = new TestBeatmapCarousel { RelativeSizeAxes = Axes.Both, @@ -75,6 +79,7 @@ namespace osu.Game.Tests.Visual testRemoveAll(); testEmptyTraversal(); testHiding(); + testSelectingFilteredRuleset(); } private void ensureRandomFetchSuccess() => @@ -363,6 +368,41 @@ namespace osu.Game.Tests.Visual } } + private void testSelectingFilteredRuleset() + { + var testMixed = createTestBeatmapSet(set_count + 1); + AddStep("add mixed ruleset beatmapset", () => + { + for (int i = 0; i <= 2; i++) + { + testMixed.Beatmaps[i].Ruleset = rulesets.AvailableRulesets.ElementAt(i); + testMixed.Beatmaps[i].RulesetID = i; + } + + carousel.UpdateBeatmapSet(testMixed); + }); + AddStep("filter to ruleset 0", () => + carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(0) }, false)); + AddStep("select filtered map skipping filtered", () => carousel.SelectBeatmap(testMixed.Beatmaps[1], false)); + AddAssert("unfiltered beatmap selected", () => carousel.SelectedBeatmap.Equals(testMixed.Beatmaps[0])); + + AddStep("remove mixed set", () => + { + carousel.RemoveBeatmapSet(testMixed); + testMixed = null; + }); + var testSingle = createTestBeatmapSet(set_count + 2); + testSingle.Beatmaps.ForEach(b => + { + b.Ruleset = rulesets.AvailableRulesets.ElementAt(1); + b.RulesetID = b.Ruleset.ID ?? 1; + }); + AddStep("add single ruleset beatmapset", () => carousel.UpdateBeatmapSet(testSingle)); + AddStep("select filtered map skipping filtered", () => carousel.SelectBeatmap(testSingle.Beatmaps[0], false)); + checkNoSelection(); + AddStep("remove single ruleset set", () => carousel.RemoveBeatmapSet(testSingle)); + } + private BeatmapSetInfo createTestBeatmapSet(int id) { return new BeatmapSetInfo diff --git a/osu.Game/Beatmaps/DifficultyCalculator.cs b/osu.Game/Beatmaps/DifficultyCalculator.cs index 798268d05f..39817df6a6 100644 --- a/osu.Game/Beatmaps/DifficultyCalculator.cs +++ b/osu.Game/Beatmaps/DifficultyCalculator.cs @@ -41,12 +41,12 @@ namespace osu.Game.Beatmaps foreach (var mod in Mods.OfType()) mod.ApplyToDifficulty(Beatmap.BeatmapInfo.BaseDifficulty); + foreach (var h in Beatmap.HitObjects) + h.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BaseDifficulty); + foreach (var mod in mods.OfType>()) foreach (var obj in Beatmap.HitObjects) mod.ApplyToHitObject(obj); - - foreach (var h in Beatmap.HitObjects) - h.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BaseDifficulty); } protected virtual void PreprocessHitObjects() diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 7f8881f463..dc3a8c075c 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -25,32 +25,29 @@ using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Play.BreaksOverlay; using osu.Game.Screens.Ranking; using osu.Game.Storyboards.Drawables; -using OpenTK; namespace osu.Game.Screens.Play { - public class Player : OsuScreen, IProvideCursor + public class Player : ScreenWithBeatmapBackground, IProvideCursor { - protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); - protected override float BackgroundParallaxAmount => 0.1f; public override bool ShowOverlaysOnEnter => false; public Action RestartRequested; - public override bool AllowBeatmapRulesetChange => false; - public bool HasFailed { get; private set; } public bool AllowPause { get; set; } = true; public bool AllowLeadIn { get; set; } = true; public bool AllowResults { get; set; } = true; + private Bindable mouseWheelDisabled; + private Bindable userAudioOffset; + public int RestartCount; public CursorContainer Cursor => RulesetContainer.Cursor; @@ -69,41 +66,27 @@ namespace osu.Game.Screens.Play private APIAccess api; - private ScoreProcessor scoreProcessor; - protected RulesetContainer RulesetContainer; - - #region User Settings - - private Bindable dimLevel; - private Bindable blurLevel; - private Bindable showStoryboard; - private Bindable mouseWheelDisabled; - private Bindable userAudioOffset; - private SampleChannel sampleRestart; - #endregion - - private Container storyboardContainer; - private DrawableStoryboard storyboard; + private ScoreProcessor scoreProcessor; + protected RulesetContainer RulesetContainer; private HUDOverlay hudOverlay; private FailOverlay failOverlay; + private DrawableStoryboard storyboard; + private Container storyboardContainer; + private bool loadedSuccessfully => RulesetContainer?.Objects.Any() == true; [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config, APIAccess api) + private void load(AudioManager audio, APIAccess api, OsuConfigManager config) { this.api = api; - - dimLevel = config.GetBindable(OsuSetting.DimLevel); - blurLevel = config.GetBindable(OsuSetting.BlurLevel); - showStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); + sampleRestart = audio.Sample.Get(@"Gameplay/restart"); mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); - - sampleRestart = audio.Sample.Get(@"Gameplay/restart"); + userAudioOffset = config.GetBindable(OsuSetting.AudioOffset); WorkingBeatmap working = Beatmap.Value; Beatmap beatmap; @@ -156,7 +139,6 @@ namespace osu.Game.Screens.Play // the final usable gameplay clock with user-set offsets applied. var offsetClock = new FramedOffsetClock(adjustableClock); - userAudioOffset = config.GetBindable(OsuSetting.AudioOffset); userAudioOffset.ValueChanged += v => offsetClock.Offset = v; userAudioOffset.TriggerChange(); @@ -225,7 +207,7 @@ namespace osu.Game.Screens.Play } }; - if (showStoryboard) + if (ShowStoryboard) initializeStoryboard(false); // Bind ScoreProcessor to ourselves @@ -245,19 +227,6 @@ namespace osu.Game.Screens.Play mod.ApplyToClock(sourceClock); } - private void initializeStoryboard(bool asyncLoad) - { - var beatmap = Beatmap.Value; - - storyboard = beatmap.Storyboard.CreateDrawable(Beatmap.Value); - storyboard.Masking = true; - - if (asyncLoad) - LoadComponentAsync(storyboard, storyboardContainer.Add); - else - storyboardContainer.Add(storyboard); - } - public void Restart() { sampleRestart?.Play(); @@ -316,11 +285,6 @@ namespace osu.Game.Screens.Play if (!loadedSuccessfully) return; - dimLevel.ValueChanged += _ => updateBackgroundElements(); - blurLevel.ValueChanged += _ => updateBackgroundElements(); - showStoryboard.ValueChanged += _ => updateBackgroundElements(); - updateBackgroundElements(); - Content.Alpha = 0; Content .ScaleTo(0.7f) @@ -374,28 +338,6 @@ namespace osu.Game.Screens.Play return true; } - private void updateBackgroundElements() - { - if (!IsCurrentScreen) return; - - const float duration = 800; - - var opacity = 1 - (float)dimLevel; - - if (showStoryboard && storyboard == null) - initializeStoryboard(true); - - var beatmap = Beatmap.Value; - var storyboardVisible = showStoryboard && beatmap.Storyboard.HasDrawable; - - storyboardContainer - .FadeColour(OsuColour.Gray(opacity), duration, Easing.OutQuint) - .FadeTo(storyboardVisible && opacity > 0 ? 1 : 0, duration, Easing.OutQuint); - - (Background as BackgroundScreenBeatmap)?.BlurTo(new Vector2((float)blurLevel.Value * 25), duration, Easing.OutQuint); - Background?.FadeTo(beatmap.Background != null && (!storyboardVisible || !beatmap.Storyboard.ReplacesBackground) ? opacity : 0, duration, Easing.OutQuint); - } - private void fadeOut() { const float fade_out_duration = 250; @@ -409,5 +351,41 @@ namespace osu.Game.Screens.Play } protected override bool OnWheel(InputState state) => mouseWheelDisabled.Value && !pauseContainer.IsPaused; + + private void initializeStoryboard(bool asyncLoad) + { + if (storyboardContainer == null) + return; + + var beatmap = Beatmap.Value; + + storyboard = beatmap.Storyboard.CreateDrawable(); + storyboard.Masking = true; + + if (asyncLoad) + LoadComponentAsync(storyboard, storyboardContainer.Add); + else + storyboardContainer.Add(storyboard); + } + + protected override void UpdateBackgroundElements() + { + if (!IsCurrentScreen) return; + + base.UpdateBackgroundElements(); + + if (ShowStoryboard && storyboard == null) + initializeStoryboard(true); + + var beatmap = Beatmap.Value; + var storyboardVisible = ShowStoryboard && beatmap.Storyboard.HasDrawable; + + storyboardContainer? + .FadeColour(OsuColour.Gray(BackgroundOpacity), BACKGROUND_FADE_DURATION, Easing.OutQuint) + .FadeTo(storyboardVisible && BackgroundOpacity > 0 ? 1 : 0, BACKGROUND_FADE_DURATION, Easing.OutQuint); + + if (storyboardVisible && beatmap.Storyboard.ReplacesBackground) + Background?.FadeTo(0, BACKGROUND_FADE_DURATION, Easing.OutQuint); + } } } diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 2950990779..784dcf7657 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -9,7 +9,6 @@ using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Screens.Backgrounds; using OpenTK; using osu.Framework.Localisation; using osu.Game.Screens.Menu; @@ -17,7 +16,7 @@ using osu.Game.Screens.Play.PlayerSettings; namespace osu.Game.Screens.Play { - public class PlayerLoader : OsuScreen + public class PlayerLoader : ScreenWithBeatmapBackground { private Player player; @@ -27,10 +26,6 @@ namespace osu.Game.Screens.Play private bool showOverlays = true; public override bool ShowOverlaysOnEnter => showOverlays; - public override bool AllowBeatmapRulesetChange => false; - - protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); - public PlayerLoader(Player player) { this.player = player; @@ -93,8 +88,6 @@ namespace osu.Game.Screens.Play { base.OnEntering(last); - Background.FadeTo(0.4f, 250); - Content.ScaleTo(0.7f); contentIn(); diff --git a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs new file mode 100644 index 0000000000..8e963a94a8 --- /dev/null +++ b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs @@ -0,0 +1,57 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Screens; +using osu.Game.Configuration; +using osu.Game.Screens.Backgrounds; +using OpenTK; + +namespace osu.Game.Screens.Play +{ + public abstract class ScreenWithBeatmapBackground : OsuScreen + { + protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); + + public override bool AllowBeatmapRulesetChange => false; + + protected const float BACKGROUND_FADE_DURATION = 800; + + protected float BackgroundOpacity => 1 - (float)DimLevel; + + #region User Settings + + protected Bindable DimLevel; + protected Bindable BlurLevel; + protected Bindable ShowStoryboard; + + #endregion + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + DimLevel = config.GetBindable(OsuSetting.DimLevel); + BlurLevel = config.GetBindable(OsuSetting.BlurLevel); + ShowStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); + } + + protected override void OnEntering(Screen last) + { + base.OnEntering(last); + DimLevel.ValueChanged += _ => UpdateBackgroundElements(); + BlurLevel.ValueChanged += _ => UpdateBackgroundElements(); + ShowStoryboard.ValueChanged += _ => UpdateBackgroundElements(); + UpdateBackgroundElements(); + } + + protected virtual void UpdateBackgroundElements() + { + if (!IsCurrentScreen) return; + + Background?.FadeTo(BackgroundOpacity, BACKGROUND_FADE_DURATION, Easing.OutQuint); + (Background as BackgroundScreenBeatmap)?.BlurTo(new Vector2((float)BlurLevel.Value * 25), BACKGROUND_FADE_DURATION, Easing.OutQuint); + } + } +} diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 9793440348..c2bb155753 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -169,20 +169,43 @@ namespace osu.Game.Screens.Select }); } - public void SelectBeatmap(BeatmapInfo beatmap) + /// + /// Selects a given beatmap on the carousel. + /// + /// If bypassFilters is false, we will try to select another unfiltered beatmap in the same set. If the + /// entire set is filtered, no selection is made. + /// + /// The beatmap to select. + /// Whether to select the beatmap even if it is filtered (i.e., not visible on carousel). + /// True if a selection was made, False if it wasn't. + public bool SelectBeatmap(BeatmapInfo beatmap, bool bypassFilters = true) { if (beatmap?.Hidden != false) - return; + return false; - foreach (CarouselBeatmapSet group in beatmapSets) + foreach (CarouselBeatmapSet set in beatmapSets) { - var item = group.Beatmaps.FirstOrDefault(p => p.Beatmap.Equals(beatmap)); + if (!bypassFilters && set.Filtered) + continue; + + var item = set.Beatmaps.FirstOrDefault(p => p.Beatmap.Equals(beatmap)); + + if (item == null) + // The beatmap that needs to be selected doesn't exist in this set + continue; + + if (!bypassFilters && item.Filtered) + // The beatmap exists in this set but is filtered, so look for the first unfiltered map in the set + item = set.Beatmaps.FirstOrDefault(b => !b.Filtered); + if (item != null) { select(item); - return; + return true; } } + + return false; } /// diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 43d7cb637a..ca8a1cae41 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -214,11 +214,7 @@ namespace osu.Game.Screens.Select Beatmap.DisabledChanged += disabled => Carousel.AllowSelection = !disabled; Beatmap.TriggerChange(); - Beatmap.ValueChanged += b => - { - if (IsCurrentScreen) - Carousel.SelectBeatmap(b?.BeatmapInfo); - }; + Beatmap.ValueChanged += workingBeatmapChanged; } public void Edit(BeatmapInfo beatmap) @@ -261,6 +257,17 @@ namespace osu.Game.Screens.Select // We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds. private BeatmapInfo beatmapNoDebounce; + private void workingBeatmapChanged(WorkingBeatmap beatmap) + { + if (IsCurrentScreen && !Carousel.SelectBeatmap(beatmap?.BeatmapInfo, false)) + // 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; + Carousel.SelectBeatmap(beatmap.BeatmapInfo); + } + } + /// /// selection has been changed as the result of interaction with the carousel. /// @@ -450,16 +457,14 @@ namespace osu.Game.Screens.Select private void carouselBeatmapsLoaded() { - if (!Beatmap.IsDefault && Beatmap.Value.BeatmapSetInfo?.DeletePending == false && Beatmap.Value.BeatmapSetInfo?.Protected == 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()) { - Carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo); - } - else if (Carousel.SelectedBeatmapSet == null) - { - if (!Carousel.SelectNextRandom()) - // in the case random selection failed, we want to trigger selectionChanged - // to show the dummy beatmap (we have nothing else to display). - carouselSelectionChanged(null); + // in the case random selection failed, we want to trigger selectionChanged + // to show the dummy beatmap (we have nothing else to display). + carouselSelectionChanged(null); } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index fdcf1152d0..5121b1439d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -378,10 +378,11 @@ - + +