mirror of
https://github.com/ppy/osu.git
synced 2025-02-05 18:35:26 +08:00
Merge branch 'master' into scrolldirection-cleanup
This commit is contained in:
commit
569d0f7993
@ -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);
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
@ -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[]
|
||||||
{
|
{
|
||||||
|
@ -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()
|
||||||
{
|
{
|
||||||
|
@ -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() };
|
||||||
|
@ -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>
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user