diff --git a/osu.Desktop/Updater/SimpleUpdateManager.cs b/osu.Desktop/Updater/SimpleUpdateManager.cs index e404ccd2b3..6956eb30b0 100644 --- a/osu.Desktop/Updater/SimpleUpdateManager.cs +++ b/osu.Desktop/Updater/SimpleUpdateManager.cs @@ -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; } diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index db80948c94..483ff2d409 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // 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)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 beatmap) + private void applyStacking(Beatmap 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; diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index 2af1de7355..44185fb83a 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -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(); diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 1412bd3cea..153e5733e5 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -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); diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs index db66c01814..f156728981 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs @@ -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; diff --git a/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs b/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs index 2c56f08f42..66ae2d3012 100644 --- a/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseNotificationOverlay.cs @@ -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; } diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index 8c541e9344..a5399ce8c7 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -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 Files { get; set; } diff --git a/osu.Game/Configuration/DatabasedConfigManager.cs b/osu.Game/Configuration/DatabasedConfigManager.cs index 0ede6de0f2..334fed2b5a 100644 --- a/osu.Game/Configuration/DatabasedConfigManager.cs +++ b/osu.Game/Configuration/DatabasedConfigManager.cs @@ -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); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 2a4c812401..702b1ae108 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -222,7 +222,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); diff --git a/osu.Game/Screens/Edit/EditorClock.cs b/osu.Game/Screens/Edit/EditorClock.cs index aa30b1a9f5..05ba1ab732 100644 --- a/osu.Game/Screens/Edit/EditorClock.cs +++ b/osu.Game/Screens/Edit/EditorClock.cs @@ -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; diff --git a/osu.Game/Screens/Tournament/Drawings.cs b/osu.Game/Screens/Tournament/Drawings.cs index 0a428ea289..754f34f00f 100644 --- a/osu.Game/Screens/Tournament/Drawings.cs +++ b/osu.Game/Screens/Tournament/Drawings.cs @@ -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; diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 25a9813ad6..23367c58c9 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -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; } diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs index 8f860c5f53..2330c25443 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs @@ -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; diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs index 485f9bf61c..b03285b419 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs @@ -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;