mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 12:33:01 +08:00
Merge pull request #28771 from frenzibyte/sorted-breaks
Fix breaks not showing unless already ordered in the beatmap file
This commit is contained in:
commit
4dd20ccf79
70
osu.Game.Tests/Visual/Gameplay/TestSceneUnorderedBreaks.cs
Normal file
70
osu.Game.Tests/Visual/Gameplay/TestSceneUnorderedBreaks.cs
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Framework.Timing;
|
||||
using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Storyboards;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Gameplay
|
||||
{
|
||||
public partial class TestSceneUnorderedBreaks : OsuPlayerTestScene
|
||||
{
|
||||
[Resolved]
|
||||
private AudioManager audioManager { get; set; } = null!;
|
||||
|
||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||
{
|
||||
var beatmap = new OsuBeatmap();
|
||||
beatmap.HitObjects.Add(new HitCircle { StartTime = 0 });
|
||||
beatmap.HitObjects.Add(new HitCircle { StartTime = 5000 });
|
||||
beatmap.HitObjects.Add(new HitCircle { StartTime = 10000 });
|
||||
beatmap.Breaks.Add(new BreakPeriod(6000, 9000));
|
||||
beatmap.Breaks.Add(new BreakPeriod(1000, 4000));
|
||||
return beatmap;
|
||||
}
|
||||
|
||||
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard? storyboard = null) =>
|
||||
new ClockBackedTestWorkingBeatmap(beatmap, storyboard, new FramedClock(new ManualClock { Rate = 1 }), audioManager);
|
||||
|
||||
[SetUpSteps]
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
base.SetUpSteps();
|
||||
|
||||
AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBreakOverlayVisibility()
|
||||
{
|
||||
AddAssert("break overlay hidden", () => !this.ChildrenOfType<BreakOverlay>().Single().Child.IsPresent);
|
||||
addSeekStep(2000);
|
||||
AddUntilStep("break overlay visible", () => this.ChildrenOfType<BreakOverlay>().Single().Child.IsPresent);
|
||||
addSeekStep(5000);
|
||||
AddAssert("break overlay hidden", () => !this.ChildrenOfType<BreakOverlay>().Single().Child.IsPresent);
|
||||
addSeekStep(7000);
|
||||
AddUntilStep("break overlay visible", () => this.ChildrenOfType<BreakOverlay>().Single().Child.IsPresent);
|
||||
addSeekStep(10000);
|
||||
AddAssert("break overlay hidden", () => !this.ChildrenOfType<BreakOverlay>().Single().Child.IsPresent);
|
||||
}
|
||||
|
||||
private void addSeekStep(double time)
|
||||
{
|
||||
AddStep($"seek to {time}", () => Beatmap.Value.Track.Seek(time));
|
||||
|
||||
// Allow a few frames of lenience
|
||||
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
|
||||
}
|
||||
}
|
||||
}
|
@ -8,6 +8,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework.Lists;
|
||||
using osu.Game.IO.Serialization.Converters;
|
||||
|
||||
namespace osu.Game.Beatmaps
|
||||
@ -61,7 +62,7 @@ namespace osu.Game.Beatmaps
|
||||
|
||||
public ControlPointInfo ControlPointInfo { get; set; } = new ControlPointInfo();
|
||||
|
||||
public List<BreakPeriod> Breaks { get; set; } = new List<BreakPeriod>();
|
||||
public SortedList<BreakPeriod> Breaks { get; set; } = new SortedList<BreakPeriod>(Comparer<BreakPeriod>.Default);
|
||||
|
||||
public List<string> UnhandledEventLines { get; set; } = new List<string>();
|
||||
|
||||
|
@ -7,6 +7,8 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using osu.Framework.Lists;
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
|
||||
@ -50,7 +52,8 @@ namespace osu.Game.Beatmaps
|
||||
original.ControlPointInfo = original.ControlPointInfo.DeepClone();
|
||||
|
||||
// Used in osu!mania conversion.
|
||||
original.Breaks = original.Breaks.ToList();
|
||||
original.Breaks = new SortedList<BreakPeriod>(Comparer<BreakPeriod>.Default);
|
||||
original.Breaks.AddRange(Beatmap.Breaks);
|
||||
|
||||
return ConvertBeatmap(original, cancellationToken);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.Framework.Lists;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
@ -40,7 +41,7 @@ namespace osu.Game.Beatmaps
|
||||
/// <summary>
|
||||
/// The breaks in this beatmap.
|
||||
/// </summary>
|
||||
List<BreakPeriod> Breaks { get; set; }
|
||||
SortedList<BreakPeriod> Breaks { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// All lines from the [Events] section which aren't handled in the encoding process yet.
|
||||
|
@ -6,7 +6,7 @@ using osu.Game.Screens.Play;
|
||||
|
||||
namespace osu.Game.Beatmaps.Timing
|
||||
{
|
||||
public class BreakPeriod : IEquatable<BreakPeriod>
|
||||
public class BreakPeriod : IEquatable<BreakPeriod>, IComparable<BreakPeriod>
|
||||
{
|
||||
/// <summary>
|
||||
/// The minimum gap between the start of the break and the previous object.
|
||||
@ -76,5 +76,17 @@ namespace osu.Game.Beatmaps.Timing
|
||||
&& EndTime == other.EndTime;
|
||||
|
||||
public override int GetHashCode() => HashCode.Combine(StartTime, EndTime);
|
||||
|
||||
public int CompareTo(BreakPeriod? other)
|
||||
{
|
||||
if (ReferenceEquals(this, other)) return 0;
|
||||
if (ReferenceEquals(null, other)) return 1;
|
||||
|
||||
int result = StartTime.CompareTo(other.StartTime);
|
||||
if (result != 0)
|
||||
return result;
|
||||
|
||||
return EndTime.CompareTo(other.EndTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ using System.Threading;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Lists;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Beatmaps.Timing;
|
||||
@ -327,7 +328,7 @@ namespace osu.Game.Rulesets.Difficulty
|
||||
set => baseBeatmap.Difficulty = value;
|
||||
}
|
||||
|
||||
public List<BreakPeriod> Breaks
|
||||
public SortedList<BreakPeriod> Breaks
|
||||
{
|
||||
get => baseBeatmap.Breaks;
|
||||
set => baseBeatmap.Breaks = value;
|
||||
|
@ -10,6 +10,7 @@ using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Lists;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Beatmaps.Legacy;
|
||||
@ -111,7 +112,11 @@ namespace osu.Game.Screens.Edit
|
||||
trackStartTime(obj);
|
||||
|
||||
Breaks = new BindableList<BreakPeriod>(playableBeatmap.Breaks);
|
||||
Breaks.BindCollectionChanged((_, _) => playableBeatmap.Breaks = Breaks.ToList());
|
||||
Breaks.BindCollectionChanged((_, _) =>
|
||||
{
|
||||
playableBeatmap.Breaks.Clear();
|
||||
playableBeatmap.Breaks.AddRange(Breaks);
|
||||
});
|
||||
|
||||
PreviewTime = new BindableInt(BeatmapInfo.Metadata.PreviewTime);
|
||||
PreviewTime.BindValueChanged(s =>
|
||||
@ -177,7 +182,7 @@ namespace osu.Game.Screens.Edit
|
||||
|
||||
public readonly BindableList<BreakPeriod> Breaks;
|
||||
|
||||
List<BreakPeriod> IBeatmap.Breaks
|
||||
SortedList<BreakPeriod> IBeatmap.Breaks
|
||||
{
|
||||
get => PlayableBeatmap.Breaks;
|
||||
set => PlayableBeatmap.Breaks = value;
|
||||
|
Loading…
Reference in New Issue
Block a user