1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 21:02:55 +08:00

Merge branch 'bdl-cache-changes' into ruleset-configs

This commit is contained in:
smoogipoo 2018-01-22 13:11:45 +09:00
commit 9ac035f3d5
20 changed files with 185 additions and 35 deletions

View File

@ -11,7 +11,7 @@ using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Osu.Objects.Drawables namespace osu.Game.Rulesets.Osu.Objects.Drawables
{ {
public class DrawableRepeatPoint : DrawableOsuHitObject public class DrawableRepeatPoint : DrawableOsuHitObject, ITrackSnaking
{ {
private readonly RepeatPoint repeatPoint; private readonly RepeatPoint repeatPoint;
private readonly DrawableSlider drawableSlider; private readonly DrawableSlider drawableSlider;
@ -71,5 +71,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
break; break;
} }
} }
public void UpdateSnakingPosition(Vector2 start, Vector2 end) => Position = repeatPoint.RepeatIndex % 2 == 1 ? end : start;
} }
} }

View File

@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public readonly DrawableHitCircle InitialCircle; public readonly DrawableHitCircle InitialCircle;
private readonly List<ISliderProgress> components = new List<ISliderProgress>(); private readonly List<Drawable> components = new List<Drawable>();
private readonly Container<DrawableSliderTick> ticks; private readonly Container<DrawableSliderTick> ticks;
private readonly Container<DrawableRepeatPoint> repeatPoints; private readonly Container<DrawableRepeatPoint> repeatPoints;
@ -101,6 +101,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
}; };
repeatPoints.Add(drawableRepeatPoint); repeatPoints.Add(drawableRepeatPoint);
components.Add(drawableRepeatPoint);
AddNested(drawableRepeatPoint); AddNested(drawableRepeatPoint);
} }
} }
@ -126,7 +127,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
if (!InitialCircle.Judgements.Any(j => j.IsHit)) if (!InitialCircle.Judgements.Any(j => j.IsHit))
InitialCircle.Position = slider.Curve.PositionAt(progress); InitialCircle.Position = slider.Curve.PositionAt(progress);
foreach (var c in components) c.UpdateProgress(progress, repeat); foreach (var c in components.OfType<ISliderProgress>()) c.UpdateProgress(progress, repeat);
foreach (var c in components.OfType<ITrackSnaking>()) c.UpdateSnakingPosition(slider.Curve.PositionAt(Body.SnakedStart ?? 0), slider.Curve.PositionAt(Body.SnakedEnd ?? 0));
foreach (var t in ticks.Children) t.Tracking = Ball.Tracking; foreach (var t in ticks.Children) t.Tracking = Ball.Tracking;
} }

View File

@ -0,0 +1,15 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
/// <summary>
/// A component which tracks the current end snaking position of a slider.
/// </summary>
public interface ITrackSnaking
{
void UpdateSnakingPosition(Vector2 start, Vector2 end);
}
}

View File

@ -61,6 +61,7 @@ namespace osu.Game.Rulesets.Osu.Objects
public int RepeatCount { get; set; } = 1; public int RepeatCount { get; set; } = 1;
private int stackHeight; private int stackHeight;
public override int StackHeight public override int StackHeight
{ {
get { return stackHeight; } get { return stackHeight; }
@ -130,6 +131,17 @@ namespace osu.Game.Rulesets.Osu.Objects
var distanceProgress = d / length; var distanceProgress = d / length;
var timeProgress = reversed ? 1 - distanceProgress : distanceProgress; var timeProgress = reversed ? 1 - distanceProgress : distanceProgress;
var firstSample = Samples.FirstOrDefault(s => s.Name == SampleInfo.HIT_NORMAL) ?? Samples.FirstOrDefault(); // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933)
var sampleList = new List<SampleInfo>();
if (firstSample != null)
sampleList.Add(new SampleInfo
{
Bank = firstSample.Bank,
Volume = firstSample.Volume,
Name = @"slidertick",
});
AddNested(new SliderTick AddNested(new SliderTick
{ {
RepeatIndex = repeat, RepeatIndex = repeat,
@ -138,12 +150,7 @@ namespace osu.Game.Rulesets.Osu.Objects
StackHeight = StackHeight, StackHeight = StackHeight,
Scale = Scale, Scale = Scale,
ComboColour = ComboColour, ComboColour = ComboColour,
Samples = new List<SampleInfo>(Samples.Select(s => new SampleInfo Samples = sampleList
{
Bank = s.Bank,
Name = @"slidertick",
Volume = s.Volume
}))
}); });
} }
} }

View File

@ -71,6 +71,7 @@
<Compile Include="Objects\Drawables\Connections\FollowPointRenderer.cs" /> <Compile Include="Objects\Drawables\Connections\FollowPointRenderer.cs" />
<Compile Include="Judgements\OsuJudgement.cs" /> <Compile Include="Judgements\OsuJudgement.cs" />
<Compile Include="Objects\Drawables\DrawableRepeatPoint.cs" /> <Compile Include="Objects\Drawables\DrawableRepeatPoint.cs" />
<Compile Include="Objects\Drawables\ITrackSnaking.cs" />
<Compile Include="Objects\Drawables\Pieces\ApproachCircle.cs" /> <Compile Include="Objects\Drawables\Pieces\ApproachCircle.cs" />
<Compile Include="Objects\Drawables\Pieces\SpinnerBackground.cs" /> <Compile Include="Objects\Drawables\Pieces\SpinnerBackground.cs" />
<Compile Include="Objects\Drawables\Pieces\CirclePiece.cs" /> <Compile Include="Objects\Drawables\Pieces\CirclePiece.cs" />

View File

@ -0,0 +1,21 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.ComponentModel;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual
{
[Description("Player instantiated with an autoplay mod.")]
public class TestCaseAutoplay : TestCasePlayer
{
protected override Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset)
{
beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
return base.CreatePlayer(beatmap, ruleset);
}
}
}

View File

@ -1,19 +1,35 @@
// 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.ComponentModel;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets; using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Play; using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual namespace osu.Game.Tests.Visual
{ {
[Description("Player instantiated with a replay.")]
public class TestCaseReplay : TestCasePlayer public class TestCaseReplay : TestCasePlayer
{ {
protected override Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset) protected override Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset)
{ {
// We create a dummy RulesetContainer just to get the replay - we don't want to use mods here
// to simulate setting a replay rather than having the replay already set for us
beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
return base.CreatePlayer(beatmap, ruleset); var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(beatmap, false);
// We have the replay
var replay = dummyRulesetContainer.Replay;
// Reset the mods
beatmap.Mods.Value = beatmap.Mods.Value.Where(m => !(m is ModAutoplay));
return new ReplayPlayer(replay)
{
InitialBeatmap = beatmap
};
} }
} }
} }

View File

@ -137,6 +137,7 @@
<Compile Include="Visual\TestCasePlaySongSelect.cs" /> <Compile Include="Visual\TestCasePlaySongSelect.cs" />
<Compile Include="Visual\TestCasePopupDialog.cs" /> <Compile Include="Visual\TestCasePopupDialog.cs" />
<Compile Include="Visual\TestCaseRankGraph.cs" /> <Compile Include="Visual\TestCaseRankGraph.cs" />
<Compile Include="Visual\TestCaseAutoplay.cs" />
<Compile Include="Visual\TestCaseReplay.cs" /> <Compile Include="Visual\TestCaseReplay.cs" />
<Compile Include="Visual\TestCaseReplaySettingsOverlay.cs" /> <Compile Include="Visual\TestCaseReplaySettingsOverlay.cs" />
<Compile Include="Visual\TestCaseResults.cs" /> <Compile Include="Visual\TestCaseResults.cs" />

View File

@ -156,6 +156,7 @@ namespace osu.Game.Beatmaps
public IQueryable<BeatmapInfo> Beatmaps => GetContext().BeatmapInfo public IQueryable<BeatmapInfo> Beatmaps => GetContext().BeatmapInfo
.Include(b => b.BeatmapSet).ThenInclude(s => s.Metadata) .Include(b => b.BeatmapSet).ThenInclude(s => s.Metadata)
.Include(b => b.BeatmapSet).ThenInclude(s => s.Files).ThenInclude(f => f.FileInfo)
.Include(b => b.Metadata) .Include(b => b.Metadata)
.Include(b => b.Ruleset) .Include(b => b.Ruleset)
.Include(b => b.BaseDifficulty); .Include(b => b.BaseDifficulty);

View File

@ -111,7 +111,7 @@ namespace osu.Game
Task.Run(() => BeatmapManager.Import(paths.ToArray())); Task.Run(() => BeatmapManager.Import(paths.ToArray()));
} }
dependencies.Cache(this); dependencies.CacheAs<OsuGame>(this);
configRuleset = LocalConfig.GetBindable<int>(OsuSetting.Ruleset); configRuleset = LocalConfig.GetBindable<int>(OsuSetting.Ruleset);
Ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First(); Ruleset.Value = RulesetStore.GetRuleset(configRuleset.Value) ?? RulesetStore.AvailableRulesets.First();

View File

@ -93,7 +93,7 @@ namespace osu.Game
dependencies.Cache(new LargeTextureStore(new RawTextureLoaderStore(new NamespacedResourceStore<byte[]>(Resources, @"Textures")))); dependencies.Cache(new LargeTextureStore(new RawTextureLoaderStore(new NamespacedResourceStore<byte[]>(Resources, @"Textures"))));
dependencies.Cache(this); dependencies.CacheAs<OsuGameBase>(this);
dependencies.Cache(LocalConfig); dependencies.Cache(LocalConfig);
runMigrations(); runMigrations();
@ -112,7 +112,7 @@ namespace osu.Game
dependencies.Cache(new OsuColour()); dependencies.Cache(new OsuColour());
//this completely overrides the framework default. will need to change once we make a proper FontStore. //this completely overrides the framework default. will need to change once we make a proper FontStore.
dependencies.Cache(Fonts = new FontStore { ScaleAdjust = 100 }, true); dependencies.Cache(Fonts = new FontStore { ScaleAdjust = 100 });
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/FontAwesome")); Fonts.AddStore(new GlyphStore(Resources, @"Fonts/FontAwesome"));
Fonts.AddStore(new GlyphStore(Resources, @"Fonts/osuFont")); Fonts.AddStore(new GlyphStore(Resources, @"Fonts/osuFont"));

View File

@ -82,7 +82,8 @@ namespace osu.Game.Overlays.BeatmapSet
if (Playing.Value && preview != null) if (Playing.Value && preview != null)
{ {
progress.Width = (float)(preview.CurrentTime / preview.Length); // prevent negative (potential infinite) width if a track without length was loaded
progress.Width = preview.Length > 0 ? (float)(preview.CurrentTime / preview.Length) : 0f;
} }
} }

View File

@ -9,6 +9,7 @@ using osu.Framework.Configuration;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Framework.IO.Stores;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface; using osu.Game.Graphics.UserInterface;
@ -39,6 +40,8 @@ namespace osu.Game.Overlays.Direct
private readonly SpriteIcon icon; private readonly SpriteIcon icon;
private readonly LoadingAnimation loadingAnimation; private readonly LoadingAnimation loadingAnimation;
private readonly BindableDouble muteBindable = new BindableDouble();
private const float transition_duration = 500; private const float transition_duration = 500;
private bool loading private bool loading
@ -83,9 +86,10 @@ namespace osu.Game.Overlays.Direct
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colour) private void load(OsuColour colour, AudioManager audio)
{ {
hoverColour = colour.Yellow; hoverColour = colour.Yellow;
this.audio = audio;
} }
protected override bool OnClick(InputState state) protected override bool OnClick(InputState state)
@ -128,21 +132,30 @@ namespace osu.Game.Overlays.Direct
return; return;
} }
Preview.Seek(0); Preview.Restart();
Preview.Start();
audio.Track.AddAdjustment(AdjustableProperty.Volume, muteBindable);
} }
else else
{ {
audio.Track.RemoveAdjustment(AdjustableProperty.Volume, muteBindable);
Preview?.Stop(); Preview?.Stop();
loading = false; loading = false;
} }
} }
private TrackLoader trackLoader; private TrackLoader trackLoader;
private AudioManager audio;
private void beginAudioLoad() private void beginAudioLoad()
{ {
if (trackLoader != null) return; if (trackLoader != null)
{
Preview = trackLoader.Preview;
Playing.TriggerChange();
return;
}
loading = true; loading = true;
@ -164,6 +177,7 @@ namespace osu.Game.Overlays.Direct
private readonly string preview; private readonly string preview;
public Track Preview; public Track Preview;
private TrackManager trackManager;
public TrackLoader(string preview) public TrackLoader(string preview)
{ {
@ -171,10 +185,22 @@ namespace osu.Game.Overlays.Direct
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(AudioManager audio) private void load(AudioManager audio, FrameworkConfigManager config)
{ {
// create a local trackManager to bypass the mute we are applying above.
audio.AddItem(trackManager = new TrackManager(new OnlineStore()));
// add back the user's music volume setting (since we are no longer in the global TrackManager's hierarchy).
config.BindWith(FrameworkSetting.VolumeMusic, trackManager.Volume);
if (!string.IsNullOrEmpty(preview)) if (!string.IsNullOrEmpty(preview))
Preview = audio.Track.Get(preview); Preview = trackManager.Get(preview);
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
trackManager?.Dispose();
} }
} }
} }

View File

@ -313,6 +313,14 @@ namespace osu.Game.Overlays
api.Queue(getSetsRequest); api.Queue(getSetsRequest);
} }
protected override void PopOut()
{
base.PopOut();
if (playing != null)
playing.PreviewPlaying.Value = false;
}
private int distinctCount(List<string> list) => list.Distinct().ToArray().Length; private int distinctCount(List<string> list) => list.Distinct().ToArray().Length;
public class ResultCounts public class ResultCounts

View File

@ -10,6 +10,7 @@ using osu.Game.Database;
using osu.Game.IO.Legacy; using osu.Game.IO.Legacy;
using osu.Game.IPC; using osu.Game.IPC;
using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Replays;
using osu.Game.Users;
using SharpCompress.Compressors.LZMA; using SharpCompress.Compressors.LZMA;
namespace osu.Game.Rulesets.Scoring namespace osu.Game.Rulesets.Scoring
@ -54,7 +55,7 @@ namespace osu.Game.Rulesets.Scoring
var beatmapHash = sr.ReadString(); var beatmapHash = sr.ReadString();
score.Beatmap = beatmaps.QueryBeatmap(b => b.MD5Hash == beatmapHash); score.Beatmap = beatmaps.QueryBeatmap(b => b.MD5Hash == beatmapHash);
/* score.PlayerName = */ /* score.PlayerName = */
sr.ReadString(); score.User = new User { Username = sr.ReadString() };
/* var localScoreChecksum = */ /* var localScoreChecksum = */
sr.ReadString(); sr.ReadString();
/* score.Count300 = */ /* score.Count300 = */
@ -107,7 +108,10 @@ namespace osu.Game.Rulesets.Scoring
using (var lzma = new LzmaStream(properties, replayInStream, compressedSize, outSize)) using (var lzma = new LzmaStream(properties, replayInStream, compressedSize, outSize))
using (var reader = new StreamReader(lzma)) using (var reader = new StreamReader(lzma))
{
score.Replay = createLegacyReplay(reader); score.Replay = createLegacyReplay(reader);
score.Replay.User = score.User;
}
} }
} }
@ -129,9 +133,22 @@ namespace osu.Game.Rulesets.Scoring
{ {
var split = l.Split('|'); var split = l.Split('|');
if (split.Length < 4 || float.Parse(split[0]) < 0) continue; if (split.Length < 4)
continue;
lastTime += float.Parse(split[0]); if (split[0] == "-12345")
{
// Todo: The seed is provided in split[3], which we'll need to use at some point
continue;
}
var diff = float.Parse(split[0]);
lastTime += diff;
// Todo: At some point we probably want to rewind and play back the negative-time frames
// but for now we'll achieve equal playback to stable by skipping negative frames
if (diff < 0)
continue;
frames.Add(new ReplayFrame( frames.Add(new ReplayFrame(
lastTime, lastTime,

View File

@ -13,6 +13,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using osu.Framework.Configuration;
using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Cursor;
using osu.Framework.Input; using osu.Framework.Input;
using osu.Framework.Platform; using osu.Framework.Platform;
@ -48,9 +49,9 @@ namespace osu.Game.Rulesets.UI
public PassThroughInputManager KeyBindingInputManager; public PassThroughInputManager KeyBindingInputManager;
/// <summary> /// <summary>
/// Whether we have a replay loaded currently. /// Whether a replay is currently loaded.
/// </summary> /// </summary>
public bool HasReplayLoaded => ReplayInputManager?.ReplayInputHandler != null; public readonly BindableBool HasReplayLoaded = new BindableBool();
public abstract IEnumerable<HitObject> Objects { get; } public abstract IEnumerable<HitObject> Objects { get; }
@ -124,6 +125,8 @@ namespace osu.Game.Rulesets.UI
Replay = replay; Replay = replay;
ReplayInputManager.ReplayInputHandler = replay != null ? CreateReplayInputHandler(replay) : null; ReplayInputManager.ReplayInputHandler = replay != null ? CreateReplayInputHandler(replay) : null;
HasReplayLoaded.Value = ReplayInputManager.ReplayInputHandler != null;
} }

View File

@ -35,7 +35,7 @@ namespace osu.Game.Screens.Play
public readonly ReplaySettingsOverlay ReplaySettingsOverlay; public readonly ReplaySettingsOverlay ReplaySettingsOverlay;
private Bindable<bool> showHud; private Bindable<bool> showHud;
private bool replayLoaded; private readonly BindableBool replayLoaded = new BindableBool();
private static bool hasShownNotificationOnce; private static bool hasShownNotificationOnce;
@ -91,22 +91,39 @@ namespace osu.Game.Screens.Play
} }
} }
public virtual void BindRulesetContainer(RulesetContainer rulesetContainer) protected override void LoadComplete()
{ {
(rulesetContainer.KeyBindingInputManager as ICanAttachKeyCounter)?.Attach(KeyCounter); base.LoadComplete();
replayLoaded = rulesetContainer.HasReplayLoaded; replayLoaded.ValueChanged += replayLoadedValueChanged;
replayLoaded.TriggerChange();
}
ReplaySettingsOverlay.ReplayLoaded = replayLoaded; private void replayLoadedValueChanged(bool loaded)
{
ReplaySettingsOverlay.ReplayLoaded = loaded;
// in the case a replay isn't loaded, we want some elements to only appear briefly. if (loaded)
if (!replayLoaded) {
ReplaySettingsOverlay.Show();
ModDisplay.FadeIn(200);
}
else
{ {
ReplaySettingsOverlay.Hide(); ReplaySettingsOverlay.Hide();
ModDisplay.Delay(2000).FadeOut(200); ModDisplay.Delay(2000).FadeOut(200);
} }
} }
public virtual void BindRulesetContainer(RulesetContainer rulesetContainer)
{
(rulesetContainer.KeyBindingInputManager as ICanAttachKeyCounter)?.Attach(KeyCounter);
replayLoaded.BindTo(rulesetContainer.HasReplayLoaded);
Progress.BindRulestContainer(rulesetContainer);
}
protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) protected override bool OnKeyDown(InputState state, KeyDownEventArgs args)
{ {
if (args.Repeat) return false; if (args.Repeat) return false;

View File

@ -52,7 +52,7 @@ namespace osu.Game.Screens.Play
public int RestartCount; public int RestartCount;
public CursorContainer Cursor => RulesetContainer.Cursor; public CursorContainer Cursor => RulesetContainer.Cursor;
public bool ProvidingUserCursor => RulesetContainer?.Cursor != null && !RulesetContainer.HasReplayLoaded; public bool ProvidingUserCursor => RulesetContainer?.Cursor != null && !RulesetContainer.HasReplayLoaded.Value;
private IAdjustableClock adjustableSourceClock; private IAdjustableClock adjustableSourceClock;
private FramedOffsetClock offsetClock; private FramedOffsetClock offsetClock;
@ -226,7 +226,6 @@ namespace osu.Game.Screens.Play
hudOverlay.Progress.Objects = RulesetContainer.Objects; hudOverlay.Progress.Objects = RulesetContainer.Objects;
hudOverlay.Progress.AudioClock = decoupledClock; hudOverlay.Progress.AudioClock = decoupledClock;
hudOverlay.Progress.AllowSeeking = RulesetContainer.HasReplayLoaded;
hudOverlay.Progress.OnSeek = pos => decoupledClock.Seek(pos); hudOverlay.Progress.OnSeek = pos => decoupledClock.Seek(pos);
hudOverlay.ModDisplay.Current.BindTo(working.Mods); hudOverlay.ModDisplay.Current.BindTo(working.Mods);

View File

@ -9,9 +9,12 @@ using System.Collections.Generic;
using osu.Game.Graphics; using osu.Game.Graphics;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using System.Linq; using System.Linq;
using osu.Framework.Configuration;
using osu.Framework.Timing; using osu.Framework.Timing;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.UI;
namespace osu.Game.Screens.Play namespace osu.Game.Screens.Play
{ {
public class SongProgress : OverlayContainer public class SongProgress : OverlayContainer
@ -54,6 +57,8 @@ namespace osu.Game.Screens.Play
} }
} }
private readonly BindableBool replayLoaded = new BindableBool();
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load(OsuColour colours) private void load(OsuColour colours)
{ {
@ -98,6 +103,14 @@ namespace osu.Game.Screens.Play
protected override void LoadComplete() protected override void LoadComplete()
{ {
State = Visibility.Visible; State = Visibility.Visible;
replayLoaded.ValueChanged += v => AllowSeeking = v;
replayLoaded.TriggerChange();
}
public void BindRulestContainer(RulesetContainer rulesetContainer)
{
replayLoaded.BindTo(rulesetContainer.HasReplayLoaded);
} }
private bool allowSeeking; private bool allowSeeking;

View File

@ -181,7 +181,7 @@ namespace osu.Game.Screens.Select
[BackgroundDependencyLoader(permitNulls: true)] [BackgroundDependencyLoader(permitNulls: true)]
private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours) private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours)
{ {
dependencies.Cache(this); dependencies.CacheAs<SongSelect>(this);
if (Footer != null) if (Footer != null)
{ {