1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-22 22:07:28 +08:00

Merge branch 'master' into master

This commit is contained in:
m2307 2019-01-08 17:53:58 +01:00 committed by GitHub
commit 42ba690809
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 480 additions and 230 deletions

View File

@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using osu.Framework;
@ -77,10 +76,10 @@ namespace osu.Desktop.Updater
switch (RuntimeInfo.OS)
{
case RuntimeInfo.Platform.Windows:
bestAsset = release.Assets?.FirstOrDefault(f => f.Name.EndsWith(".exe"));
bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".exe"));
break;
case RuntimeInfo.Platform.MacOsx:
bestAsset = release.Assets?.FirstOrDefault(f => f.Name.EndsWith(".app.zip"));
bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".app.zip"));
break;
}

View File

@ -1,6 +1,7 @@
// 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;
using osu.Framework.Graphics;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Objects.Types;
@ -23,60 +24,70 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
var osuBeatmap = (Beatmap<OsuHitObject>)Beatmap;
// Reset stacking
foreach (var h in osuBeatmap.HitObjects)
h.StackHeight = 0;
if (osuBeatmap.HitObjects.Count > 0)
{
// Reset stacking
foreach (var h in osuBeatmap.HitObjects)
h.StackHeight = 0;
if (Beatmap.BeatmapInfo.BeatmapVersion >= 6)
applyStacking(osuBeatmap);
else
applyStackingOld(osuBeatmap);
if (Beatmap.BeatmapInfo.BeatmapVersion >= 6)
applyStacking(osuBeatmap, 0, osuBeatmap.HitObjects.Count - 1);
else
applyStackingOld(osuBeatmap);
}
}
private void applyStacking(Beatmap<OsuHitObject> beatmap)
private void applyStacking(Beatmap<OsuHitObject> beatmap, int startIndex, int endIndex)
{
// Extend the end index to include objects they are stacked on
int extendedEndIndex = beatmap.HitObjects.Count - 1;
for (int i = beatmap.HitObjects.Count - 1; i >= 0; i--)
if (startIndex > endIndex) throw new ArgumentOutOfRangeException(nameof(startIndex), $"{nameof(startIndex)} cannot be greater than {nameof(endIndex)}.");
if (startIndex < 0) throw new ArgumentOutOfRangeException(nameof(startIndex), $"{nameof(startIndex)} cannot be less than 0.");
if (endIndex < 0) throw new ArgumentOutOfRangeException(nameof(endIndex), $"{nameof(endIndex)} cannot be less than 0.");
int extendedEndIndex = endIndex;
if (endIndex < beatmap.HitObjects.Count - 1)
{
int stackBaseIndex = i;
for (int n = stackBaseIndex + 1; n < beatmap.HitObjects.Count; n++)
// Extend the end index to include objects they are stacked on
for (int i = endIndex; i >= startIndex; i--)
{
OsuHitObject stackBaseObject = beatmap.HitObjects[stackBaseIndex];
if (stackBaseObject is Spinner) break;
OsuHitObject objectN = beatmap.HitObjects[n];
if (objectN is Spinner)
continue;
double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime;
double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo.StackLeniency;
if (objectN.StartTime - endTime > stackThreshold)
//We are no longer within stacking range of the next object.
break;
if (Vector2Extensions.Distance(stackBaseObject.Position, objectN.Position) < stack_distance ||
stackBaseObject is Slider && Vector2Extensions.Distance(stackBaseObject.EndPosition, objectN.Position) < stack_distance)
int stackBaseIndex = i;
for (int n = stackBaseIndex + 1; n < beatmap.HitObjects.Count; n++)
{
stackBaseIndex = n;
OsuHitObject stackBaseObject = beatmap.HitObjects[stackBaseIndex];
if (stackBaseObject is Spinner) break;
// HitObjects after the specified update range haven't been reset yet
objectN.StackHeight = 0;
OsuHitObject objectN = beatmap.HitObjects[n];
if (objectN is Spinner)
continue;
double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime;
double stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo.StackLeniency;
if (objectN.StartTime - endTime > stackThreshold)
//We are no longer within stacking range of the next object.
break;
if (Vector2Extensions.Distance(stackBaseObject.Position, objectN.Position) < stack_distance
|| stackBaseObject is Slider && Vector2Extensions.Distance(stackBaseObject.EndPosition, objectN.Position) < stack_distance)
{
stackBaseIndex = n;
// HitObjects after the specified update range haven't been reset yet
objectN.StackHeight = 0;
}
}
}
if (stackBaseIndex > extendedEndIndex)
{
extendedEndIndex = stackBaseIndex;
if (extendedEndIndex == beatmap.HitObjects.Count - 1)
break;
if (stackBaseIndex > extendedEndIndex)
{
extendedEndIndex = stackBaseIndex;
if (extendedEndIndex == beatmap.HitObjects.Count - 1)
break;
}
}
}
//Reverse pass for stack calculation.
int extendedStartIndex = 0;
for (int i = extendedEndIndex; i > 0; i--)
int extendedStartIndex = startIndex;
for (int i = extendedEndIndex; i > startIndex; i--)
{
int n = i;
/* We should check every note which has not yet got a stack.
@ -155,7 +166,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
/* We have hit the first slider in a possible stack.
* From this point on, we ALWAYS stack positive regardless.
*/
while (--n >= 0)
while (--n >= startIndex)
{
OsuHitObject objectN = beatmap.HitObjects[n];
if (objectN is Spinner) continue;

View File

@ -215,7 +215,7 @@ namespace osu.Game.Rulesets.Osu.Objects
var distanceProgress = d / length;
var timeProgress = reversed ? 1 - distanceProgress : distanceProgress;
var firstSample = Samples.FirstOrDefault(s => s.Name == SampleInfo.HIT_NORMAL)
var firstSample = Samples.Find(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>();

View File

@ -135,7 +135,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
if (userTriggered)
{
var nextTick = ticks.FirstOrDefault(j => !j.IsHit);
var nextTick = ticks.Find(j => !j.IsHit);
nextTick?.TriggerResult(HitResult.Great);

View File

@ -148,7 +148,7 @@ namespace osu.Game.Tests.Visual
private bool selectedBeatmapVisible()
{
var currentlySelected = carousel.Items.FirstOrDefault(s => s.Item is CarouselBeatmap && s.Item.State == CarouselItemState.Selected);
var currentlySelected = carousel.Items.Find(s => s.Item is CarouselBeatmap && s.Item.State == CarouselItemState.Selected);
if (currentlySelected == null)
return true;
return currentlySelected.Item.Visible;

View File

@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual
linkColour = colours.Blue;
var chatManager = new ChannelManager();
BindableCollection<Channel> availableChannels = (BindableCollection<Channel>)chatManager.AvailableChannels;
BindableList<Channel> availableChannels = (BindableList<Channel>)chatManager.AvailableChannels;
availableChannels.Add(new Channel { Name = "#english"});
availableChannels.Add(new Channel { Name = "#japanese" });
Dependencies.Cache(chatManager);

View File

@ -73,8 +73,8 @@ namespace osu.Game.Tests.Visual
{
public event Action RoomsUpdated;
public readonly BindableCollection<Room> Rooms = new BindableCollection<Room>();
IBindableCollection<Room> IRoomManager.Rooms => Rooms;
public readonly BindableList<Room> Rooms = new BindableList<Room>();
IBindableList<Room> IRoomManager.Rooms => Rooms;
public void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null) => Rooms.Add(room);

View File

@ -138,7 +138,7 @@ namespace osu.Game.Tests.Visual
public event Action RoomsUpdated;
public IBindableCollection<Room> Rooms { get; } = null;
public IBindableList<Room> Rooms { get; } = null;
public void CreateRoom(Room room, Action<Room> onSuccess = null, Action<string> onError = null)
{

View File

@ -49,7 +49,6 @@ namespace osu.Game.Tests.Visual
manager.UnreadCount.ValueChanged += count => { displayedCount.Text = $"displayed count: {count}"; };
setState(Visibility.Visible);
AddStep(@"simple #1", sendHelloNotification);
AddStep(@"simple #2", sendAmazingNotification);
@ -75,7 +74,6 @@ namespace osu.Game.Tests.Visual
checkProgressingCount(0);
setState(Visibility.Visible);
//AddStep(@"barrage", () => sendBarrage());
@ -111,7 +109,7 @@ namespace osu.Game.Tests.Visual
if (progressingNotifications.Count(n => n.State == ProgressNotificationState.Active) < 3)
{
var p = progressingNotifications.FirstOrDefault(n => n.State == ProgressNotificationState.Queued);
var p = progressingNotifications.Find(n => n.State == ProgressNotificationState.Queued);
if (p != null)
p.State = ProgressNotificationState.Active;
}

View File

@ -2,6 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
@ -9,6 +10,7 @@ using Newtonsoft.Json;
using osu.Game.Database;
using osu.Game.IO.Serialization;
using osu.Game.Rulesets;
using osu.Game.Scoring;
namespace osu.Game.Beatmaps
{
@ -112,6 +114,11 @@ namespace osu.Game.Beatmaps
[JsonProperty("difficulty_rating")]
public double StarDifficulty { get; set; }
/// <summary>
/// Currently only populated for beatmap deletion. Use <see cref="ScoreManager"/> to query scores.
/// </summary>
public List<ScoreInfo> Scores { get; set; }
public override string ToString() => $"{Metadata} [{Version}]";
public bool Equals(BeatmapInfo other)

View File

@ -36,7 +36,7 @@ namespace osu.Game.Beatmaps
public string Hash { get; set; }
public string StoryboardFile => Files?.FirstOrDefault(f => f.Filename.EndsWith(".osb"))?.Filename;
public string StoryboardFile => Files?.Find(f => f.Filename.EndsWith(".osb"))?.Filename;
public List<BeatmapSetFileInfo> Files { get; set; }

View File

@ -64,7 +64,8 @@ namespace osu.Game.Beatmaps
base.AddIncludesForDeletion(query)
.Include(s => s.Beatmaps).ThenInclude(b => b.Metadata)
.Include(s => s.Beatmaps).ThenInclude(b => b.BaseDifficulty)
.Include(s => s.Metadata);
.Include(s => s.Metadata)
.Include(s => s.Beatmaps).ThenInclude(b => b.Scores);
protected override IQueryable<BeatmapSetInfo> AddIncludesForConsumption(IQueryable<BeatmapSetInfo> query) =>
base.AddIncludesForConsumption(query)

View File

@ -151,7 +151,7 @@ namespace osu.Game.Beatmaps
public bool WaveformLoaded => waveform.IsResultAvailable;
public Waveform Waveform => waveform.Value;
protected virtual Waveform GetWaveform() => new Waveform();
protected virtual Waveform GetWaveform() => new Waveform(null);
private readonly RecyclableLazy<Waveform> waveform;
public bool StoryboardLoaded => storyboard.IsResultAvailable;

View File

@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Configuration;
using osu.Game.Rulesets;
@ -43,7 +42,7 @@ namespace osu.Game.Configuration
{
base.AddBindable(lookup, bindable);
var setting = databasedSettings.FirstOrDefault(s => (int)s.Key == (int)(object)lookup);
var setting = databasedSettings.Find(s => (int)s.Key == (int)(object)lookup);
if (setting != null)
{
bindable.Parse(setting.Value);

View File

@ -3,6 +3,7 @@
using osu.Framework.Configuration;
using osu.Framework.Configuration.Tracking;
using osu.Framework.Extensions;
using osu.Framework.Platform;
using osu.Game.Overlays;
using osu.Game.Rulesets.Scoring;
@ -96,15 +97,25 @@ namespace osu.Game.Configuration
Set(OsuSetting.ScreenshotCaptureMenuCursor, false);
Set(OsuSetting.SongSelectRightMouseScroll, false);
Set(OsuSetting.Scaling, ScalingMode.Off);
Set(OsuSetting.ScalingSizeX, 0.8f, 0.2f, 1f);
Set(OsuSetting.ScalingSizeY, 0.8f, 0.2f, 1f);
Set(OsuSetting.ScalingPositionX, 0.5f, 0f, 1f);
Set(OsuSetting.ScalingPositionY, 0.5f, 0f, 1f);
}
public OsuConfigManager(Storage storage) : base(storage)
public OsuConfigManager(Storage storage)
: base(storage)
{
}
public override TrackedSettings CreateTrackedSettings() => new TrackedSettings
{
new TrackedSetting<bool>(OsuSetting.MouseDisableButtons, v => new SettingDescription(!v, "gameplay mouse buttons", v ? "disabled" : "enabled"))
new TrackedSetting<bool>(OsuSetting.MouseDisableButtons, v => new SettingDescription(!v, "gameplay mouse buttons", v ? "disabled" : "enabled")),
new TrackedSetting<ScalingMode>(OsuSetting.Scaling, m => new SettingDescription(m, "scaling", m.GetDescription())),
};
}
@ -151,6 +162,11 @@ namespace osu.Game.Configuration
BeatmapHitsounds,
IncreaseFirstObjectVisibility,
ScoreDisplayMode,
ExternalLinkWarning
ExternalLinkWarning,
Scaling,
ScalingPositionX,
ScalingPositionY,
ScalingSizeX,
ScalingSizeY
}
}

View File

@ -0,0 +1,16 @@
// 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;
namespace osu.Game.Configuration
{
public enum ScalingMode
{
Off,
Everything,
[Description("Excluding overlays")]
ExcludeOverlays,
Gameplay,
}
}

View File

@ -0,0 +1,120 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// 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.Graphics.Containers;
using osu.Game.Configuration;
using osu.Game.Graphics.Backgrounds;
using osuTK;
namespace osu.Game.Graphics.Containers
{
/// <summary>
/// Handles user-defined scaling, allowing application at multiple levels defined by <see cref="ScalingMode"/>.
/// </summary>
public class ScalingContainer : Container
{
private Bindable<float> sizeX;
private Bindable<float> sizeY;
private Bindable<float> posX;
private Bindable<float> posY;
private readonly ScalingMode? targetMode;
private Bindable<ScalingMode> scalingMode;
private readonly Container content;
protected override Container<Drawable> Content => content;
private readonly Container sizableContainer;
private Drawable backgroundLayer;
/// <summary>
/// Create a new instance.
/// </summary>
/// <param name="targetMode">The mode which this container should be handling. Handles all modes if null.</param>
public ScalingContainer(ScalingMode? targetMode = null)
{
this.targetMode = targetMode;
RelativeSizeAxes = Axes.Both;
InternalChild = sizableContainer = new Container
{
RelativeSizeAxes = Axes.Both,
RelativePositionAxes = Axes.Both,
CornerRadius = 10,
Child = content = new DrawSizePreservingFillContainer()
};
}
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
scalingMode = config.GetBindable<ScalingMode>(OsuSetting.Scaling);
scalingMode.ValueChanged += _ => updateSize();
sizeX = config.GetBindable<float>(OsuSetting.ScalingSizeX);
sizeX.ValueChanged += _ => updateSize();
sizeY = config.GetBindable<float>(OsuSetting.ScalingSizeY);
sizeY.ValueChanged += _ => updateSize();
posX = config.GetBindable<float>(OsuSetting.ScalingPositionX);
posX.ValueChanged += _ => updateSize();
posY = config.GetBindable<float>(OsuSetting.ScalingPositionY);
posY.ValueChanged += _ => updateSize();
}
protected override void LoadComplete()
{
base.LoadComplete();
updateSize();
sizableContainer.FinishTransforms();
}
private bool requiresBackgroundVisible => (scalingMode == ScalingMode.Everything || scalingMode == ScalingMode.ExcludeOverlays) && (sizeX.Value != 1 || sizeY.Value != 1);
private void updateSize()
{
if (targetMode == ScalingMode.Everything)
{
// the top level scaling container manages the background to be displayed while scaling.
if (requiresBackgroundVisible)
{
if (backgroundLayer == null)
LoadComponentAsync(backgroundLayer = new Background("Menu/menu-background-1")
{
Colour = OsuColour.Gray(0.1f),
Alpha = 0,
Depth = float.MaxValue
}, d =>
{
AddInternal(d);
d.FadeTo(requiresBackgroundVisible ? 1 : 0, 4000, Easing.OutQuint);
});
else
backgroundLayer.FadeIn(500);
}
else
backgroundLayer?.FadeOut(500);
}
bool scaling = targetMode == null || scalingMode.Value == targetMode;
var targetSize = scaling ? new Vector2(sizeX, sizeY) : Vector2.One;
var targetPosition = scaling ? new Vector2(posX, posY) * (Vector2.One - targetSize) : Vector2.Zero;
bool requiresMasking = scaling && targetSize != Vector2.One;
if (requiresMasking)
sizableContainer.Masking = true;
sizableContainer.MoveTo(targetPosition, 500, Easing.OutQuart);
sizableContainer.ResizeTo(targetSize, 500, Easing.OutQuart).OnComplete(_ => { sizableContainer.Masking = requiresMasking; });
}
}
}

View File

@ -8,7 +8,6 @@ using osuTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Graphics.Cursor;
@ -33,38 +32,7 @@ namespace osu.Game.Graphics.UserInterface
private readonly Box leftBox;
private readonly Box rightBox;
public virtual string TooltipText
{
get
{
var bindableDouble = CurrentNumber as BindableNumber<double>;
var bindableFloat = CurrentNumber as BindableNumber<float>;
var floatValue = bindableDouble?.Value ?? bindableFloat?.Value;
var floatPrecision = bindableDouble?.Precision ?? bindableFloat?.Precision;
if (floatValue != null)
{
var floatMinValue = bindableDouble?.MinValue ?? bindableFloat.MinValue;
var floatMaxValue = bindableDouble?.MaxValue ?? bindableFloat.MaxValue;
if (floatMaxValue == 1 && (floatMinValue == 0 || floatMinValue == -1))
return floatValue.Value.ToString("P0");
var decimalPrecision = normalise((decimal)floatPrecision, max_decimal_digits);
// Find the number of significant digits (we could have less than 5 after normalize())
var significantDigits = findPrecision(decimalPrecision);
return floatValue.Value.ToString($"N{significantDigits}");
}
var bindableInt = CurrentNumber as BindableNumber<int>;
if (bindableInt != null)
return bindableInt.Value.ToString("N0");
return Current.Value.ToString(CultureInfo.InvariantCulture);
}
}
public virtual string TooltipText { get; private set; }
private Color4 accentColour;
public Color4 AccentColour
@ -136,21 +104,34 @@ namespace osu.Game.Graphics.UserInterface
base.OnHoverLost(e);
}
protected override void OnUserChange()
protected override bool OnMouseDown(MouseDownEvent e)
{
base.OnUserChange();
playSample();
Nub.Current.Value = true;
return base.OnMouseDown(e);
}
private void playSample()
protected override bool OnMouseUp(MouseUpEvent e)
{
Nub.Current.Value = false;
return base.OnMouseUp(e);
}
protected override void OnUserChange(T value)
{
base.OnUserChange(value);
playSample(value);
updateTooltipText(value);
}
private void playSample(T value)
{
if (Clock == null || Clock.CurrentTime - lastSampleTime <= 50)
return;
if (Current.Value.Equals(lastSampleValue))
if (value.Equals(lastSampleValue))
return;
lastSampleValue = Current.Value;
lastSampleValue = value;
lastSampleTime = Clock.CurrentTime;
sample.Frequency.Value = 1 + NormalizedValue * 0.2f;
@ -163,16 +144,28 @@ namespace osu.Game.Graphics.UserInterface
sample.Play();
}
protected override bool OnMouseDown(MouseDownEvent e)
private void updateTooltipText(T value)
{
Nub.Current.Value = true;
return base.OnMouseDown(e);
}
if (CurrentNumber.IsInteger)
TooltipText = ((int)Convert.ChangeType(value, typeof(int))).ToString("N0");
else
{
double floatValue = (double)Convert.ChangeType(value, typeof(double));
double floatMinValue = (double)Convert.ChangeType(CurrentNumber.MinValue, typeof(double));
double floatMaxValue = (double)Convert.ChangeType(CurrentNumber.MaxValue, typeof(double));
protected override bool OnMouseUp(MouseUpEvent e)
{
Nub.Current.Value = false;
return base.OnMouseUp(e);
if (floatMaxValue == 1 && floatMinValue >= -1)
TooltipText = floatValue.ToString("P0");
else
{
var decimalPrecision = normalise((decimal)Convert.ChangeType(CurrentNumber.Precision, typeof(decimal)), max_decimal_digits);
// Find the number of significant digits (we could have less than 5 after normalize())
var significantDigits = findPrecision(decimalPrecision);
TooltipText = floatValue.ToString($"N{significantDigits}");
}
}
}
protected override void UpdateAfterChildren()

View File

@ -62,6 +62,6 @@ namespace osu.Game.Graphics.UserInterface
fill.Width = value * UsableWidth;
}
protected override void OnUserChange() => OnSeek?.Invoke(Current);
protected override void OnUserChange(double value) => OnSeek?.Invoke(value);
}
}

View File

@ -14,7 +14,7 @@ namespace osu.Game.Migrations
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.1.4-rtm-31024");
.HasAnnotation("ProductVersion", "2.2.0-rtm-35687");
modelBuilder.Entity("osu.Game.Beatmaps.BeatmapDifficulty", b =>
{
@ -215,6 +215,25 @@ namespace osu.Game.Migrations
b.ToTable("Settings");
});
modelBuilder.Entity("osu.Game.IO.FileInfo", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<string>("Hash");
b.Property<int>("ReferenceCount");
b.HasKey("ID");
b.HasIndex("Hash")
.IsUnique();
b.HasIndex("ReferenceCount");
b.ToTable("FileInfo");
});
modelBuilder.Entity("osu.Game.Input.Bindings.DatabasedKeyBinding", b =>
{
b.Property<int>("ID")
@ -239,25 +258,6 @@ namespace osu.Game.Migrations
b.ToTable("KeyBinding");
});
modelBuilder.Entity("osu.Game.IO.FileInfo", b =>
{
b.Property<int>("ID")
.ValueGeneratedOnAdd();
b.Property<string>("Hash");
b.Property<int>("ReferenceCount");
b.HasKey("ID");
b.HasIndex("Hash")
.IsUnique();
b.HasIndex("ReferenceCount");
b.ToTable("FileInfo");
});
modelBuilder.Entity("osu.Game.Rulesets.RulesetInfo", b =>
{
b.Property<int?>("ID")
@ -454,7 +454,7 @@ namespace osu.Game.Migrations
modelBuilder.Entity("osu.Game.Scoring.ScoreInfo", b =>
{
b.HasOne("osu.Game.Beatmaps.BeatmapInfo", "Beatmap")
.WithMany()
.WithMany("Scores")
.HasForeignKey("BeatmapInfoID")
.OnDelete(DeleteBehavior.Cascade);

View File

@ -29,8 +29,8 @@ namespace osu.Game.Online.Chat
@"#lobby"
};
private readonly BindableCollection<Channel> availableChannels = new BindableCollection<Channel>();
private readonly BindableCollection<Channel> joinedChannels = new BindableCollection<Channel>();
private readonly BindableList<Channel> availableChannels = new BindableList<Channel>();
private readonly BindableList<Channel> joinedChannels = new BindableList<Channel>();
/// <summary>
/// The currently opened channel
@ -40,12 +40,12 @@ namespace osu.Game.Online.Chat
/// <summary>
/// The Channels the player has joined
/// </summary>
public IBindableCollection<Channel> JoinedChannels => joinedChannels;
public IBindableList<Channel> JoinedChannels => joinedChannels;
/// <summary>
/// The channels available for the player to join
/// </summary>
public IBindableCollection<Channel> AvailableChannels => availableChannels;
public IBindableList<Channel> AvailableChannels => availableChannels;
private IAPIProvider api;

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
@ -30,6 +31,7 @@ namespace osu.Game.Online.Leaderboards
private readonly LoadingAnimation loading;
private ScheduledDelegate showScoresDelegate;
private CancellationTokenSource showScoresCancellationSource;
private bool scoresLoadedOnce;
@ -49,6 +51,10 @@ namespace osu.Game.Online.Leaderboards
loading.Hide();
// schedule because we may not be loaded yet (LoadComponentAsync complains).
showScoresDelegate?.Cancel();
showScoresCancellationSource?.Cancel();
if (scores == null || !scores.Any())
return;
@ -58,8 +64,6 @@ namespace osu.Game.Online.Leaderboards
scrollFlow = CreateScoreFlow();
scrollFlow.ChildrenEnumerable = scores.Select((s, index) => CreateDrawableScore(s, index + 1));
// schedule because we may not be loaded yet (LoadComponentAsync complains).
showScoresDelegate?.Cancel();
if (!IsLoaded)
showScoresDelegate = Schedule(showScores);
else
@ -77,7 +81,7 @@ namespace osu.Game.Online.Leaderboards
}
scrollContainer.ScrollTo(0f, false);
});
}, (showScoresCancellationSource = new CancellationTokenSource()).Token);
}
}

View File

@ -37,10 +37,10 @@ namespace osu.Game.Online.Multiplayer
public RulesetInfo Ruleset { get; set; }
[JsonIgnore]
public readonly BindableCollection<Mod> AllowedMods = new BindableCollection<Mod>();
public readonly BindableList<Mod> AllowedMods = new BindableList<Mod>();
[JsonIgnore]
public readonly BindableCollection<Mod> RequiredMods = new BindableCollection<Mod>();
public readonly BindableList<Mod> RequiredMods = new BindableList<Mod>();
[JsonProperty("beatmap")]
private APIBeatmap apiBeatmap { get; set; }

View File

@ -24,7 +24,7 @@ namespace osu.Game.Online.Multiplayer
public Bindable<User> Host { get; private set; } = new Bindable<User>();
[JsonProperty("playlist")]
public BindableCollection<PlaylistItem> Playlist { get; set; } = new BindableCollection<PlaylistItem>();
public BindableList<PlaylistItem> Playlist { get; set; } = new BindableList<PlaylistItem>();
[JsonProperty("channel_id")]
public Bindable<int> ChannelId { get; private set; } = new Bindable<int>();

View File

@ -26,6 +26,7 @@ using osu.Framework.Platform;
using osu.Framework.Threading;
using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Input;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets;
@ -187,6 +188,7 @@ namespace osu.Game
}
private ExternalLinkOpener externalLinkOpener;
public void OpenUrlExternally(string url)
{
if (url.StartsWith("/"))
@ -222,7 +224,7 @@ namespace osu.Game
var databasedSet = BeatmapManager.QueryBeatmapSet(s => s.OnlineBeatmapSetID == beatmap.OnlineBeatmapSetID);
// Use first beatmap available for current ruleset, else switch ruleset.
var first = databasedSet.Beatmaps.FirstOrDefault(b => b.Ruleset == ruleset.Value) ?? databasedSet.Beatmaps.First();
var first = databasedSet.Beatmaps.Find(b => b.Ruleset == ruleset.Value) ?? databasedSet.Beatmaps.First();
ruleset.Value = first.Ruleset;
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(first);
@ -353,7 +355,11 @@ namespace osu.Game
ActionRequested = action => volume.Adjust(action),
ScrollActionRequested = (action, amount, isPrecise) => volume.Adjust(action, amount, isPrecise),
},
mainContent = new Container { RelativeSizeAxes = Axes.Both },
screenContainer = new ScalingContainer(ScalingMode.ExcludeOverlays)
{
RelativeSizeAxes = Axes.Both,
},
mainContent = new DrawSizePreservingFillContainer(),
overlayContent = new Container { RelativeSizeAxes = Axes.Both, Depth = float.MinValue },
idleTracker = new IdleTracker(6000)
});
@ -362,7 +368,7 @@ namespace osu.Game
{
screenStack.ModePushed += screenAdded;
screenStack.Exited += screenRemoved;
mainContent.Add(screenStack);
screenContainer.Add(screenStack);
});
loadComponentSingleFile(Toolbar = new Toolbar
@ -497,7 +503,7 @@ namespace osu.Game
if (notifications.State == Visibility.Visible)
offset -= ToolbarButton.WIDTH / 2;
screenStack.MoveToX(offset, SettingsOverlay.TRANSITION_LENGTH, Easing.OutQuint);
screenContainer.MoveToX(offset, SettingsOverlay.TRANSITION_LENGTH, Easing.OutQuint);
}
settings.StateChanged += _ => updateScreenOffset();
@ -555,7 +561,7 @@ namespace osu.Game
focused.StateChanged += s =>
{
visibleOverlayCount += s == Visibility.Visible ? 1 : -1;
screenStack.FadeColour(visibleOverlayCount > 0 ? OsuColour.Gray(0.5f) : Color4.White, 500, Easing.OutQuint);
screenContainer.FadeColour(visibleOverlayCount > 0 ? OsuColour.Gray(0.5f) : Color4.White, 500, Easing.OutQuint);
};
}
@ -646,6 +652,7 @@ namespace osu.Game
private OsuScreen currentScreen;
private FrameworkConfigManager frameworkConfig;
private ScalingContainer screenContainer;
protected override bool OnExiting()
{
@ -685,7 +692,7 @@ namespace osu.Game
ruleset.Disabled = applyBeatmapRulesetRestrictions;
Beatmap.Disabled = applyBeatmapRulesetRestrictions;
mainContent.Padding = new MarginPadding { Top = ToolbarOffset };
screenContainer.Padding = new MarginPadding { Top = ToolbarOffset };
MenuCursorContainer.CanShowCursor = currentScreen?.CursorVisible ?? false;
}

View File

@ -24,6 +24,7 @@ using osu.Framework.Input;
using osu.Framework.Logging;
using osu.Game.Audio;
using osu.Game.Database;
using osu.Game.Graphics.Containers;
using osu.Game.Input;
using osu.Game.Input.Bindings;
using osu.Game.IO;
@ -189,7 +190,7 @@ namespace osu.Game
Child = content = new OsuTooltipContainer(MenuCursorContainer.Cursor) { RelativeSizeAxes = Axes.Both }
};
base.Content.Add(new DrawSizePreservingFillContainer { Child = MenuCursorContainer });
base.Content.Add(new ScalingContainer(ScalingMode.Everything) { Child = MenuCursorContainer });
KeyBindingStore.Register(globalBinding);
dependencies.Cache(globalBinding);
@ -247,7 +248,8 @@ namespace osu.Game
var extension = Path.GetExtension(paths.First())?.ToLowerInvariant();
foreach (var importer in fileImporters)
if (importer.HandledExtensions.Contains(extension)) importer.Import(paths);
if (importer.HandledExtensions.Contains(extension))
importer.Import(paths);
}
public string[] HandledExtensions => fileImporters.SelectMany(i => i.HandledExtensions).ToArray();

View File

@ -1,6 +1,7 @@
// 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;
using System.Collections.Generic;
using System.Linq;
using osuTK;
@ -18,7 +19,7 @@ namespace osu.Game.Overlays.Chat.Selection
public readonly FillFlowContainer<ChannelListItem> ChannelFlow;
public IEnumerable<IFilterable> FilterableChildren => ChannelFlow.Children;
public IEnumerable<string> FilterTerms => new[] { Header };
public IEnumerable<string> FilterTerms => Array.Empty<string>();
public bool MatchingFilter
{
set

View File

@ -6,9 +6,14 @@ using System.Drawing;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Configuration;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osuTK.Graphics;
namespace osu.Game.Overlays.Settings.Sections.Graphics
{
@ -16,24 +21,33 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
{
protected override string Header => "Layout";
private FillFlowContainer letterboxSettings;
private FillFlowContainer<SettingsSlider<float>> scalingSettings;
private Bindable<bool> letterboxing;
private Bindable<ScalingMode> scalingMode;
private Bindable<Size> sizeFullscreen;
private OsuGameBase game;
private SettingsDropdown<Size> resolutionDropdown;
private SettingsEnumDropdown<WindowMode> windowModeDropdown;
private Bindable<float> scalingPositionX;
private Bindable<float> scalingPositionY;
private Bindable<float> scalingSizeX;
private Bindable<float> scalingSizeY;
private const int transition_duration = 400;
[BackgroundDependencyLoader]
private void load(FrameworkConfigManager config, OsuGameBase game)
private void load(FrameworkConfigManager config, OsuConfigManager osuConfig, OsuGameBase game)
{
this.game = game;
letterboxing = config.GetBindable<bool>(FrameworkSetting.Letterboxing);
scalingMode = osuConfig.GetBindable<ScalingMode>(OsuSetting.Scaling);
sizeFullscreen = config.GetBindable<Size>(FrameworkSetting.SizeFullscreen);
scalingSizeX = osuConfig.GetBindable<float>(OsuSetting.ScalingSizeX);
scalingSizeY = osuConfig.GetBindable<float>(OsuSetting.ScalingSizeY);
scalingPositionX = osuConfig.GetBindable<float>(OsuSetting.ScalingPositionX);
scalingPositionY = osuConfig.GetBindable<float>(OsuSetting.ScalingPositionY);
Container resolutionSettingsContainer;
@ -49,12 +63,12 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
},
new SettingsCheckbox
new SettingsEnumDropdown<ScalingMode>
{
LabelText = "Letterboxing",
Bindable = letterboxing,
LabelText = "Scaling",
Bindable = osuConfig.GetBindable<ScalingMode>(OsuSetting.Scaling),
},
letterboxSettings = new FillFlowContainer
scalingSettings = new FillFlowContainer<SettingsSlider<float>>
{
Direction = FillDirection.Vertical,
RelativeSizeAxes = Axes.X,
@ -62,25 +76,38 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
AutoSizeDuration = transition_duration,
AutoSizeEasing = Easing.OutQuint,
Masking = true,
Children = new Drawable[]
Children = new []
{
new SettingsSlider<double>
new SettingsSlider<float>
{
LabelText = "Horizontal position",
Bindable = config.GetBindable<double>(FrameworkSetting.LetterboxPositionX),
Bindable = scalingPositionX,
KeyboardStep = 0.01f
},
new SettingsSlider<double>
new SettingsSlider<float>
{
LabelText = "Vertical position",
Bindable = config.GetBindable<double>(FrameworkSetting.LetterboxPositionY),
Bindable = scalingPositionY,
KeyboardStep = 0.01f
},
new SettingsSlider<float>
{
LabelText = "Horizontal scale",
Bindable = scalingSizeX,
KeyboardStep = 0.01f
},
new SettingsSlider<float>
{
LabelText = "Vertical scale",
Bindable = scalingSizeY,
KeyboardStep = 0.01f
},
}
},
};
scalingSettings.ForEach(s => bindPreviewEvent(s.Bindable));
var resolutions = getResolutions();
if (resolutions.Count > 1)
@ -105,16 +132,46 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
}, true);
}
letterboxing.BindValueChanged(isVisible =>
scalingMode.BindValueChanged(mode =>
{
letterboxSettings.ClearTransforms();
letterboxSettings.AutoSizeAxes = isVisible ? Axes.Y : Axes.None;
scalingSettings.ClearTransforms();
scalingSettings.AutoSizeAxes = mode != ScalingMode.Off ? Axes.Y : Axes.None;
if (!isVisible)
letterboxSettings.ResizeHeightTo(0, transition_duration, Easing.OutQuint);
if (mode == ScalingMode.Off)
scalingSettings.ResizeHeightTo(0, transition_duration, Easing.OutQuint);
scalingSettings.ForEach(s => s.TransferValueOnCommit = mode == ScalingMode.Everything);
}, true);
}
/// <summary>
/// Create a delayed bindable which only updates when a condition is met.
/// </summary>
/// <param name="bindable">The config bindable.</param>
/// <returns>A bindable which will propagate updates with a delay.</returns>
private void bindPreviewEvent(Bindable<float> bindable)
{
bindable.ValueChanged += v =>
{
switch (scalingMode.Value)
{
case ScalingMode.Gameplay:
showPreview();
break;
}
};
}
private Drawable preview;
private void showPreview()
{
if (preview?.IsAlive != true)
game.Add(preview = new ScalingPreview());
preview.FadeOutFromOne(1500);
preview.Expire();
}
private IReadOnlyList<Size> getResolutions()
{
var resolutions = new List<Size> { new Size(9999, 9999) };
@ -132,6 +189,19 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
return resolutions;
}
private class ScalingPreview : ScalingContainer
{
public ScalingPreview()
{
Child = new Box
{
Colour = Color4.White,
RelativeSizeAxes = Axes.Both,
Alpha = 0.5f,
};
}
}
private class ResolutionSettingsDropdown : SettingsDropdown<Size>
{
protected override OsuDropdown<Size> CreateDropdown() => new ResolutionDropdownControl { Items = Items };

View File

@ -1,20 +0,0 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Graphics;
namespace osu.Game.Overlays.Settings
{
public class SettingsLabel : SettingsItem<string>
{
protected override Drawable CreateControl() => null;
[BackgroundDependencyLoader]
private void load(OsuColour colour)
{
Colour = colour.Gray6;
}
}
}

View File

@ -2,7 +2,6 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Graphics.UserInterface;
@ -23,14 +22,16 @@ namespace osu.Game.Overlays.Settings
RelativeSizeAxes = Axes.X
};
public float KeyboardStep;
[BackgroundDependencyLoader]
private void load()
public bool TransferValueOnCommit
{
var slider = Control as U;
if (slider != null)
slider.KeyboardStep = KeyboardStep;
get => ((U)Control).TransferValueOnCommit;
set => ((U)Control).TransferValueOnCommit = value;
}
public float KeyboardStep
{
get => ((U)Control).KeyboardStep;
set => ((U)Control).KeyboardStep = value;
}
}
}

View File

@ -31,7 +31,7 @@ namespace osu.Game.Scoring
[Column(TypeName="DECIMAL(1,4)")]
public double Accuracy { get; set; }
[JsonIgnore]
[JsonProperty(@"pp")]
public double? PP { get; set; }
[JsonProperty("max_combo")]

View File

@ -0,0 +1,27 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Screens;
using osuTK.Graphics;
namespace osu.Game.Screens.Backgrounds
{
public class BackgroundScreenBlack : BackgroundScreen
{
public BackgroundScreenBlack()
{
Child = new Box
{
Colour = Color4.Black,
RelativeSizeAxes = Axes.Both,
};
}
protected override void OnEntering(Screen last)
{
Show();
}
}
}

View File

@ -1,9 +0,0 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
namespace osu.Game.Screens.Backgrounds
{
public class BackgroundScreenEmpty : BackgroundScreen
{
}
}

View File

@ -238,11 +238,11 @@ namespace osu.Game.Screens.Edit.Compose.Components
{
case Key.Right:
beatDivisor.Next();
OnUserChange();
OnUserChange(Current);
return true;
case Key.Left:
beatDivisor.Previous();
OnUserChange();
OnUserChange(Current);
return true;
default:
return false;
@ -279,7 +279,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
var xPosition = (ToLocalSpace(screenSpaceMousePosition).X - RangePadding) / UsableWidth;
CurrentNumber.Value = availableDivisors.OrderBy(d => Math.Abs(getMappedPosition(d) - xPosition)).First();
OnUserChange();
OnUserChange(Current);
}
private float getMappedPosition(float divisor) => (float)Math.Pow((divisor - 1) / (availableDivisors.Last() - 1), 0.90f);

View File

@ -57,7 +57,7 @@ namespace osu.Game.Screens.Edit
// Depending on beatSnapLength, we may snap to a beat that is beyond timingPoint's end time, but we want to instead snap to
// the next timing point's start time
var nextTimingPoint = ControlPointInfo.TimingPoints.FirstOrDefault(t => t.Time > timingPoint.Time);
var nextTimingPoint = ControlPointInfo.TimingPoints.Find(t => t.Time > timingPoint.Time);
if (position > nextTimingPoint?.Time)
position = nextTimingPoint.Time;
@ -123,7 +123,7 @@ namespace osu.Game.Screens.Edit
if (seekTime < timingPoint.Time && timingPoint != ControlPointInfo.TimingPoints.First())
seekTime = timingPoint.Time;
var nextTimingPoint = ControlPointInfo.TimingPoints.FirstOrDefault(t => t.Time > timingPoint.Time);
var nextTimingPoint = ControlPointInfo.TimingPoints.Find(t => t.Time > timingPoint.Time);
if (seekTime > nextTimingPoint?.Time)
seekTime = nextTimingPoint.Time;

View File

@ -39,7 +39,7 @@ namespace osu.Game.Screens.Menu
public override bool CursorVisible => false;
protected override BackgroundScreen CreateBackground() => new BackgroundScreenEmpty();
protected override BackgroundScreen CreateBackground() => new BackgroundScreenBlack();
private Bindable<bool> menuVoice;
private Bindable<bool> menuMusic;

View File

@ -58,6 +58,7 @@ namespace osu.Game.Screens.Menu
Origin = Anchor.CentreLeft,
RelativeSizeAxes = Axes.Y,
Width = box_width * 2,
Height = 1.5f,
// align off-screen to make sure our edges don't become visible during parallax.
X = -box_width,
Alpha = 0,
@ -70,6 +71,7 @@ namespace osu.Game.Screens.Menu
Origin = Anchor.CentreRight,
RelativeSizeAxes = Axes.Y,
Width = box_width * 2,
Height = 1.5f,
X = box_width,
Alpha = 0,
Blending = BlendingMode.Additive,

View File

@ -18,7 +18,7 @@ namespace osu.Game.Screens.Multi
/// <summary>
/// All the active <see cref="Room"/>s.
/// </summary>
IBindableCollection<Room> Rooms { get; }
IBindableList<Room> Rooms { get; }
/// <summary>
/// Creates a new <see cref="Room"/>.

View File

@ -22,7 +22,7 @@ namespace osu.Game.Screens.Multi.Lounge.Components
private readonly Bindable<Room> selectedRoom = new Bindable<Room>();
public IBindable<Room> SelectedRoom => selectedRoom;
private readonly IBindableCollection<Room> rooms = new BindableCollection<Room>();
private readonly IBindableList<Room> rooms = new BindableList<Room>();
private readonly FillFlowContainer<DrawableRoom> roomFlow;
public IReadOnlyList<DrawableRoom> Rooms => roomFlow;

View File

@ -86,7 +86,7 @@ namespace osu.Game.Screens.Multi
public readonly Bindable<User> Host = new Bindable<User>();
public readonly Bindable<RoomStatus> Status = new Bindable<RoomStatus>();
public readonly Bindable<GameType> Type = new Bindable<GameType>();
public readonly BindableCollection<PlaylistItem> Playlist = new BindableCollection<PlaylistItem>();
public readonly BindableList<PlaylistItem> Playlist = new BindableList<PlaylistItem>();
public readonly Bindable<IEnumerable<User>> Participants = new Bindable<IEnumerable<User>>();
public readonly Bindable<int> ParticipantCount = new Bindable<int>();
public readonly Bindable<int?> MaxParticipants = new Bindable<int?>();

View File

@ -21,8 +21,8 @@ namespace osu.Game.Screens.Multi
{
public event Action RoomsUpdated;
private readonly BindableCollection<Room> rooms = new BindableCollection<Room>();
public IBindableCollection<Room> Rooms => rooms;
private readonly BindableList<Room> rooms = new BindableList<Room>();
public IBindableList<Room> Rooms => rooms;
private Room currentRoom;

View File

@ -20,6 +20,7 @@ using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Cursor;
using osu.Game.Online.API;
using osu.Game.Overlays;
@ -179,10 +180,13 @@ namespace osu.Game.Screens.Play
RelativeSizeAxes = Axes.Both,
Alpha = 0,
},
new LocalSkinOverrideContainer(working.Skin)
new ScalingContainer(ScalingMode.Gameplay)
{
RelativeSizeAxes = Axes.Both,
Child = RulesetContainer
Child = new LocalSkinOverrideContainer(working.Skin)
{
RelativeSizeAxes = Axes.Both,
Child = RulesetContainer
}
},
new BreakOverlay(beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor)
{
@ -191,7 +195,10 @@ namespace osu.Game.Screens.Play
ProcessCustomClock = false,
Breaks = beatmap.Breaks
},
RulesetContainer.Cursor?.CreateProxy() ?? new Container(),
new ScalingContainer(ScalingMode.Gameplay)
{
Child = RulesetContainer.Cursor?.CreateProxy() ?? new Container(),
},
hudOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working, offsetClock, adjustableClock)
{
Clock = Clock, // hud overlay doesn't want to use the audio clock directly

View File

@ -112,6 +112,6 @@ namespace osu.Game.Screens.Play
handleBase.X = xFill;
}
protected override void OnUserChange() => OnSeek?.Invoke(Current);
protected override void OnUserChange(double value) => OnSeek?.Invoke(value);
}
}

View File

@ -327,7 +327,7 @@ namespace osu.Game.Screens.Tournament
continue;
// ReSharper disable once AccessToModifiedClosure
DrawingsTeam teamToAdd = allTeams.FirstOrDefault(t => t.FullName == line);
DrawingsTeam teamToAdd = allTeams.Find(t => t.FullName == line);
if (teamToAdd == null)
continue;

View File

@ -102,7 +102,7 @@ namespace osu.Game.Skinning
string lastPiece = filename.Split('/').Last();
var file = source.Files.FirstOrDefault(f =>
var file = source.Files.Find(f =>
string.Equals(hasExtension ? f.Filename : Path.ChangeExtension(f.Filename, null), lastPiece, StringComparison.InvariantCultureIgnoreCase));
return file?.FileInfo.StoragePath;
}

View File

@ -6,7 +6,6 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations;
using osu.Framework.Graphics.Textures;
using System.Linq;
using osu.Game.Beatmaps;
namespace osu.Game.Storyboards.Drawables
@ -71,7 +70,7 @@ namespace osu.Game.Storyboards.Drawables
{
var framePath = basePath.Replace(".", frame + ".");
var path = beatmap.Value.BeatmapSetInfo.Files.FirstOrDefault(f => f.Filename.ToLowerInvariant() == framePath)?.FileInfo.StoragePath;
var path = beatmap.Value.BeatmapSetInfo.Files.Find(f => f.Filename.ToLowerInvariant() == framePath)?.FileInfo.StoragePath;
if (path == null)
continue;

View File

@ -6,7 +6,6 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using System.Linq;
using osu.Game.Beatmaps;
namespace osu.Game.Storyboards.Drawables
@ -66,7 +65,7 @@ namespace osu.Game.Storyboards.Drawables
private void load(IBindableBeatmap beatmap, TextureStore textureStore)
{
var spritePath = Sprite.Path.ToLowerInvariant();
var path = beatmap.Value.BeatmapSetInfo.Files.FirstOrDefault(f => f.Filename.ToLowerInvariant() == spritePath)?.FileInfo.StoragePath;
var path = beatmap.Value.BeatmapSetInfo.Files.Find(f => f.Filename.ToLowerInvariant() == spritePath)?.FileInfo.StoragePath;
if (path == null)
return;

View File

@ -18,7 +18,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="ppy.osu.Framework" Version="2018.1226.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.108.0" />
<PackageReference Include="SharpCompress" Version="0.22.0" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" />