1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 16:27:26 +08:00

Merge branch 'master' into reduce-panel-width

This commit is contained in:
Dean Herbert 2018-07-17 16:36:05 +09:00 committed by GitHub
commit 97e71245e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 127 additions and 42 deletions

View File

@ -23,8 +23,10 @@ namespace osu.Game.Rulesets.Catch.UI
private readonly CatcherArea catcherArea; private readonly CatcherArea catcherArea;
public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation) public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation)
: base(ScrollingDirection.Down, BASE_WIDTH) : base(BASE_WIDTH)
{ {
Direction.Value = ScrollingDirection.Down;
Container explodingFruitContainer; Container explodingFruitContainer;
Anchor = Anchor.TopCentre; Anchor = Anchor.TopCentre;

View File

@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Mania.Tests
private Drawable createColumn(ScrollingDirection direction, ManiaAction action) private Drawable createColumn(ScrollingDirection direction, ManiaAction action)
{ {
var column = new Column(direction) var column = new Column
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,

View File

@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Mania.Tests
{ {
var specialAction = ManiaAction.Special1; var specialAction = ManiaAction.Special1;
var stage = new ManiaStage(direction, 0, new StageDefinition { Columns = 2 }, ref action, ref specialAction) { VisibleTimeRange = { Value = 2000 } }; var stage = new ManiaStage(0, new StageDefinition { Columns = 2 }, ref action, ref specialAction) { VisibleTimeRange = { Value = 2000 } };
stages.Add(stage); stages.Add(stage);
return new ScrollingTestContainer(direction) return new ScrollingTestContainer(direction)

View File

@ -32,8 +32,7 @@ namespace osu.Game.Rulesets.Mania.UI
protected override Container<Drawable> Content => hitObjectArea; protected override Container<Drawable> Content => hitObjectArea;
public Column(ScrollingDirection direction) public Column()
: base(direction)
{ {
RelativeSizeAxes = Axes.Y; RelativeSizeAxes = Axes.Y;
Width = column_width; Width = column_width;

View File

@ -12,7 +12,6 @@ using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Mania.Configuration; using osu.Game.Rulesets.Mania.Configuration;
using osu.Game.Rulesets.UI.Scrolling;
namespace osu.Game.Rulesets.Mania.UI namespace osu.Game.Rulesets.Mania.UI
{ {
@ -21,8 +20,7 @@ namespace osu.Game.Rulesets.Mania.UI
public List<Column> Columns => stages.SelectMany(x => x.Columns).ToList(); public List<Column> Columns => stages.SelectMany(x => x.Columns).ToList();
private readonly List<ManiaStage> stages = new List<ManiaStage>(); private readonly List<ManiaStage> stages = new List<ManiaStage>();
public ManiaPlayfield(ScrollingDirection direction, List<StageDefinition> stageDefinitions) public ManiaPlayfield(List<StageDefinition> stageDefinitions)
: base(direction)
{ {
if (stageDefinitions == null) if (stageDefinitions == null)
throw new ArgumentNullException(nameof(stageDefinitions)); throw new ArgumentNullException(nameof(stageDefinitions));
@ -42,7 +40,7 @@ namespace osu.Game.Rulesets.Mania.UI
int firstColumnIndex = 0; int firstColumnIndex = 0;
for (int i = 0; i < stageDefinitions.Count; i++) for (int i = 0; i < stageDefinitions.Count; i++)
{ {
var newStage = new ManiaStage(direction, firstColumnIndex, stageDefinitions[i], ref normalColumnAction, ref specialColumnAction); var newStage = new ManiaStage(firstColumnIndex, stageDefinitions[i], ref normalColumnAction, ref specialColumnAction);
newStage.VisibleTimeRange.BindTo(VisibleTimeRange); newStage.VisibleTimeRange.BindTo(VisibleTimeRange);
playfieldGrid.Content[0][i] = newStage; playfieldGrid.Content[0][i] = newStage;

View File

@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Mania.UI
return dependencies; return dependencies;
} }
protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(scrollingInfo.Direction, Beatmap.Stages) protected sealed override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages)
{ {
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = Anchor.Centre, Origin = Anchor.Centre,

View File

@ -11,11 +11,6 @@ namespace osu.Game.Rulesets.Mania.UI
{ {
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>(); private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
public ManiaScrollingPlayfield(ScrollingDirection direction)
: base(direction)
{
}
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(IScrollingInfo scrollingInfo) private void load(IScrollingInfo scrollingInfo)
{ {

View File

@ -43,8 +43,7 @@ namespace osu.Game.Rulesets.Mania.UI
private readonly int firstColumnIndex; private readonly int firstColumnIndex;
public ManiaStage(ScrollingDirection direction, int firstColumnIndex, StageDefinition definition, ref ManiaAction normalColumnStartAction, ref ManiaAction specialColumnStartAction) public ManiaStage(int firstColumnIndex, StageDefinition definition, ref ManiaAction normalColumnStartAction, ref ManiaAction specialColumnStartAction)
: base(direction)
{ {
this.firstColumnIndex = firstColumnIndex; this.firstColumnIndex = firstColumnIndex;
@ -124,7 +123,7 @@ namespace osu.Game.Rulesets.Mania.UI
for (int i = 0; i < definition.Columns; i++) for (int i = 0; i < definition.Columns; i++)
{ {
var isSpecial = definition.IsSpecialColumn(i); var isSpecial = definition.IsSpecialColumn(i);
var column = new Column(direction) var column = new Column
{ {
IsSpecial = isSpecial, IsSpecial = isSpecial,
Action = { Value = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++ } Action = { Value = isSpecial ? specialColumnStartAction++ : normalColumnStartAction++ }

View File

@ -1,6 +1,7 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>. // Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Linq;
using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Cursor;
using osu.Framework.Input; using osu.Framework.Input;
using OpenTK; using OpenTK;
@ -46,6 +47,15 @@ namespace osu.Game.Rulesets.Osu.UI
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new OsuReplayInputHandler(replay); 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() 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); var aspectSize = DrawSize.X * 0.75f < DrawSize.Y ? new Vector2(DrawSize.X, DrawSize.X * 0.75f) : new Vector2(DrawSize.Y * 4f / 3f, DrawSize.Y);

View File

@ -58,8 +58,9 @@ namespace osu.Game.Rulesets.Taiko.UI
private readonly Box background; private readonly Box background;
public TaikoPlayfield(ControlPointInfo controlPoints) public TaikoPlayfield(ControlPointInfo controlPoints)
: base(ScrollingDirection.Left)
{ {
Direction.Value = ScrollingDirection.Left;
AddRangeInternal(new Drawable[] AddRangeInternal(new Drawable[]
{ {
backgroundContainer = new Container backgroundContainer = new Container

View File

@ -117,7 +117,6 @@ namespace osu.Game.Tests.Visual
public new readonly ScrollingDirection Direction; public new readonly ScrollingDirection Direction;
public TestPlayfield(ScrollingDirection direction) public TestPlayfield(ScrollingDirection direction)
: base(direction)
{ {
Direction = direction; Direction = direction;

View File

@ -50,6 +50,11 @@ namespace osu.Game.Beatmaps
/// </summary> /// </summary>
public event Action<DownloadBeatmapSetRequest> BeatmapDownloadFailed; public event Action<DownloadBeatmapSetRequest> BeatmapDownloadFailed;
/// <summary>
/// Fired when a beatmap load is requested (into the interactive game UI).
/// </summary>
public Action<BeatmapSetInfo> PresentBeatmap;
/// <summary> /// <summary>
/// A default representation of a WorkingBeatmap to use when no beatmap is available. /// A default representation of a WorkingBeatmap to use when no beatmap is available.
/// </summary> /// </summary>
@ -168,12 +173,20 @@ namespace osu.Game.Beatmaps
Task.Factory.StartNew(() => Task.Factory.StartNew(() =>
{ {
BeatmapSetInfo importedBeatmap;
// This gets scheduled back to the update thread, but we want the import to run in the background. // 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 stream = new MemoryStream(data))
using (var archive = new ZipArchiveReader(stream, beatmapSetInfo.ToString())) using (var archive = new ZipArchiveReader(stream, beatmapSetInfo.ToString()))
Import(archive); importedBeatmap = Import(archive);
downloadNotification.CompletionClickAction = () =>
{
PresentBeatmap?.Invoke(importedBeatmap);
return true;
};
downloadNotification.State = ProgressNotificationState.Completed; downloadNotification.State = ProgressNotificationState.Completed;
currentDownloads.Remove(request); currentDownloads.Remove(request);
}, TaskCreationOptions.LongRunning); }, TaskCreationOptions.LongRunning);
}; };

View File

@ -24,6 +24,7 @@ using osu.Framework.Input;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Framework.Platform; using osu.Framework.Platform;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Game.Beatmaps;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Notifications;
@ -34,6 +35,7 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Skinning; using osu.Game.Skinning;
using OpenTK.Graphics; using OpenTK.Graphics;
using osu.Game.Overlays.Volume; using osu.Game.Overlays.Volume;
using osu.Game.Screens.Select;
namespace osu.Game namespace osu.Game
{ {
@ -179,6 +181,41 @@ namespace osu.Game
/// <param name="setId">The set to display.</param> /// <param name="setId">The set to display.</param>
public void ShowBeatmapSet(int setId) => beatmapSetOverlay.FetchAndShowBeatmapSet(setId); public void ShowBeatmapSet(int setId) => beatmapSetOverlay.FetchAndShowBeatmapSet(setId);
/// <summary>
/// Present a beatmap at song select.
/// </summary>
/// <param name="beatmap">The beatmap to select.</param>
public void PresentBeatmap(BeatmapSetInfo beatmap)
{
CloseAllOverlays(false);
void setBeatmap()
{
if (Beatmap.Disabled)
{
Schedule(setBeatmap);
return;
}
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;
}
setBeatmap();
}
/// <summary> /// <summary>
/// Show a user's profile as an overlay. /// Show a user's profile as an overlay.
/// </summary> /// </summary>
@ -245,6 +282,7 @@ namespace osu.Game
BeatmapManager.PostNotification = n => notifications?.Post(n); BeatmapManager.PostNotification = n => notifications?.Post(n);
BeatmapManager.GetStableStorage = GetStorageForStableInstall; BeatmapManager.GetStableStorage = GetStorageForStableInstall;
BeatmapManager.PresentBeatmap = PresentBeatmap;
AddRange(new Drawable[] AddRange(new Drawable[]
{ {

View File

@ -44,6 +44,8 @@ namespace osu.Game.Overlays.Mods
private void rulesetChanged(RulesetInfo newRuleset) private void rulesetChanged(RulesetInfo newRuleset)
{ {
if (newRuleset == null) return;
var instance = newRuleset.CreateInstance(); var instance = newRuleset.CreateInstance();
foreach (ModSection section in ModSectionsContainer.Children) foreach (ModSection section in ModSectionsContainer.Children)
@ -173,7 +175,10 @@ namespace osu.Game.Overlays.Mods
refreshSelectedMods(); 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() public ModSelectOverlay()
{ {

View File

@ -11,7 +11,7 @@ using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Mods namespace osu.Game.Rulesets.Mods
{ {
public class ModAutoplay<T> : ModAutoplay, IApplicableToRulesetContainer<T> public abstract class ModAutoplay<T> : ModAutoplay, IApplicableToRulesetContainer<T>
where T : HitObject where T : HitObject
{ {
protected virtual Score CreateReplayScore(Beatmap<T> beatmap) => new Score { Replay = new Replay() }; protected virtual Score CreateReplayScore(Beatmap<T> beatmap) => new Score { Replay = new Replay() };

View File

@ -56,6 +56,12 @@ namespace osu.Game.Rulesets.UI
public abstract IEnumerable<HitObject> Objects { get; } public abstract IEnumerable<HitObject> Objects { get; }
/// <summary>
/// The point in time at which gameplay starts, including any required lead-in for display purposes.
/// Defaults to two seconds before the first <see cref="HitObject"/>. Override as necessary.
/// </summary>
public virtual double GameplayStartTime => Objects.First().StartTime - 2000;
private readonly Lazy<Playfield> playfield; private readonly Lazy<Playfield> playfield;
/// <summary> /// <summary>

View File

@ -57,22 +57,23 @@ namespace osu.Game.Rulesets.UI.Scrolling
/// </summary> /// </summary>
public new ScrollingHitObjectContainer HitObjects => (ScrollingHitObjectContainer)base.HitObjects; public new ScrollingHitObjectContainer HitObjects => (ScrollingHitObjectContainer)base.HitObjects;
/// <summary>
/// The direction in which <see cref="DrawableHitObject"/>s in this <see cref="ScrollingPlayfield"/> should scroll.
/// </summary>
protected readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>(); protected readonly Bindable<ScrollingDirection> Direction = new Bindable<ScrollingDirection>();
/// <summary> /// <summary>
/// Creates a new <see cref="ScrollingPlayfield"/>. /// Creates a new <see cref="ScrollingPlayfield"/>.
/// </summary> /// </summary>
/// <param name="direction">The direction in which <see cref="DrawableHitObject"/>s in this container should scroll.</param>
/// <param name="customWidth">The width to scale the internal coordinate space to. /// <param name="customWidth">The width to scale the internal coordinate space to.
/// May be null if scaling based on <paramref name="customHeight"/> is desired. If <paramref name="customHeight"/> is also null, no scaling will occur. /// May be null if scaling based on <paramref name="customHeight"/> is desired. If <paramref name="customHeight"/> is also null, no scaling will occur.
/// </param> /// </param>
/// <param name="customHeight">The height to scale the internal coordinate space to. /// <param name="customHeight">The height to scale the internal coordinate space to.
/// May be null if scaling based on <paramref name="customWidth"/> is desired. If <paramref name="customWidth"/> is also null, no scaling will occur. /// May be null if scaling based on <paramref name="customWidth"/> is desired. If <paramref name="customWidth"/> is also null, no scaling will occur.
/// </param> /// </param>
protected ScrollingPlayfield(ScrollingDirection direction, float? customWidth = null, float? customHeight = null) protected ScrollingPlayfield(float? customWidth = null, float? customHeight = null)
: base(customWidth, customHeight) : base(customWidth, customHeight)
{ {
Direction.Value = direction;
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]

View File

@ -55,7 +55,7 @@ namespace osu.Game.Screens.Menu
OnChart = delegate { Push(new ChartListing()); }, OnChart = delegate { Push(new ChartListing()); },
OnDirect = delegate { Push(new OnlineListing()); }, OnDirect = delegate { Push(new OnlineListing()); },
OnEdit = delegate { Push(new Editor()); }, OnEdit = delegate { Push(new Editor()); },
OnSolo = delegate { Push(consumeSongSelect()); }, OnSolo = onSolo,
OnMulti = delegate { Push(new Multiplayer()); }, OnMulti = delegate { Push(new Multiplayer()); },
OnExit = Exit, OnExit = Exit,
} }
@ -85,6 +85,10 @@ namespace osu.Game.Screens.Menu
LoadComponentAsync(songSelect = new PlaySongSelect()); LoadComponentAsync(songSelect = new PlaySongSelect());
} }
public void LoadToSolo() => Schedule(onSolo);
private void onSolo() => Push(consumeSongSelect());
private Screen consumeSongSelect() private Screen consumeSongSelect()
{ {
var s = songSelect; var s = songSelect;

View File

@ -138,10 +138,9 @@ namespace osu.Game.Screens.Play
sourceClock = (IAdjustableClock)working.Track ?? new StopwatchClock(); sourceClock = (IAdjustableClock)working.Track ?? new StopwatchClock();
adjustableClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false }; adjustableClock = new DecoupleableInterpolatingFramedClock { IsCoupled = false };
var firstObjectTime = RulesetContainer.Objects.First().StartTime;
adjustableClock.Seek(AllowLeadIn adjustableClock.Seek(AllowLeadIn
? Math.Min(0, firstObjectTime - Math.Max(beatmap.ControlPointInfo.TimingPointAt(firstObjectTime).BeatLength * 4, beatmap.BeatmapInfo.AudioLeadIn)) ? Math.Min(RulesetContainer.GameplayStartTime, beatmap.HitObjects.First().StartTime - beatmap.BeatmapInfo.AudioLeadIn)
: firstObjectTime); : RulesetContainer.GameplayStartTime);
adjustableClock.ProcessFrame(); adjustableClock.ProcessFrame();
@ -199,7 +198,7 @@ namespace osu.Game.Screens.Play
Anchor = Anchor.Centre, Anchor = Anchor.Centre,
Origin = 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 Clock = Clock, // skip button doesn't want to use the audio clock directly
ProcessCustomClock = false, ProcessCustomClock = false,

View File

@ -84,10 +84,10 @@ namespace osu.Game.Screens.Select
protected override void UpdateBeatmap(WorkingBeatmap beatmap) protected override void UpdateBeatmap(WorkingBeatmap beatmap)
{ {
base.UpdateBeatmap(beatmap);
beatmap.Mods.BindTo(SelectedMods); beatmap.Mods.BindTo(SelectedMods);
base.UpdateBeatmap(beatmap);
BeatmapDetails.Beatmap = beatmap; BeatmapDetails.Beatmap = beatmap;
if (beatmap.Track != null) if (beatmap.Track != null)

View File

@ -2,6 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System; using System;
using System.Linq;
using OpenTK; using OpenTK;
using OpenTK.Input; using OpenTK.Input;
using osu.Framework.Allocation; using osu.Framework.Allocation;
@ -20,6 +21,7 @@ using osu.Game.Graphics.Containers;
using osu.Game.Input.Bindings; using osu.Game.Input.Bindings;
using osu.Game.Overlays; using osu.Game.Overlays;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Backgrounds;
using osu.Game.Screens.Edit; using osu.Game.Screens.Edit;
using osu.Game.Screens.Menu; using osu.Game.Screens.Menu;
@ -70,7 +72,14 @@ namespace osu.Game.Screens.Select
private DependencyContainer dependencies; private DependencyContainer dependencies;
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
=> dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); {
dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
dependencies.CacheAs(this);
dependencies.CacheAs(Ruleset);
dependencies.CacheAs<IBindable<RulesetInfo>>(Ruleset);
return dependencies;
}
protected SongSelect() protected SongSelect()
{ {
@ -189,9 +198,9 @@ namespace osu.Game.Screens.Select
[BackgroundDependencyLoader(true)] [BackgroundDependencyLoader(true)]
private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours) private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuColour colours)
{ {
dependencies.CacheAs(this); // manual binding to parent ruleset to allow for delayed load in the incoming direction.
dependencies.CacheAs(Ruleset); base.Ruleset.ValueChanged += r => updateSelectedBeatmap(beatmapNoDebounce);
dependencies.CacheAs<IBindable<RulesetInfo>>(Ruleset); Ruleset.ValueChanged += r => base.Ruleset.Value = r;
if (Footer != null) if (Footer != null)
{ {
@ -277,7 +286,7 @@ namespace osu.Game.Screens.Select
// If selecting new beatmap without bypassing filters failed, there's possibly a ruleset mismatch // If selecting new beatmap without bypassing filters failed, there's possibly a ruleset mismatch
if (beatmap?.BeatmapInfo?.Ruleset != null && beatmap.BeatmapInfo.Ruleset != Ruleset.Value) 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); Carousel.SelectBeatmap(beatmap.BeatmapInfo);
} }
} }
@ -295,18 +304,25 @@ namespace osu.Game.Screens.Select
void performLoad() void performLoad()
{ {
WorkingBeatmap working = Beatmap.Value;
bool preview = false;
// We may be arriving here due to another component changing the bindable Beatmap. // 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. // 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) if (beatmap?.Equals(Beatmap.Value.BeatmapInfo) != true)
{ {
bool preview = beatmap?.BeatmapSetInfoID != Beatmap.Value?.BeatmapInfo.BeatmapSetInfoID; preview = beatmap?.BeatmapSetInfoID != Beatmap.Value?.BeatmapInfo.BeatmapSetInfoID;
working = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value);
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value);
ensurePlayingSelected(preview);
} }
working.Mods.Value = Enumerable.Empty<Mod>();
Beatmap.Value = working;
Ruleset.Value = ruleset; Ruleset.Value = ruleset;
ensurePlayingSelected(preview);
UpdateBeatmap(Beatmap.Value); UpdateBeatmap(Beatmap.Value);
} }