mirror of
https://github.com/ppy/osu
synced 2025-01-12 09:09:44 +00:00
Merge pull request #24358 from peppy/song-select-drain-length
Show break time in tooltip at song select
This commit is contained in:
commit
0b5be51ee0
@ -14,14 +14,14 @@ using osu.Game.Tests.Beatmaps;
|
|||||||
|
|
||||||
namespace osu.Game.Tests.Editing.Checks
|
namespace osu.Game.Tests.Editing.Checks
|
||||||
{
|
{
|
||||||
public class CheckDrainTimeTest
|
public class CheckDrainLengthTest
|
||||||
{
|
{
|
||||||
private CheckDrainTime check = null!;
|
private CheckDrainLength check = null!;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
check = new CheckDrainTime();
|
check = new CheckDrainLength();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -40,7 +40,7 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
var issues = check.Run(context).ToList();
|
var issues = check.Run(context).ToList();
|
||||||
|
|
||||||
Assert.That(issues, Has.Count.EqualTo(1));
|
Assert.That(issues, Has.Count.EqualTo(1));
|
||||||
Assert.That(issues.Single().Template is CheckDrainTime.IssueTemplateTooShort);
|
Assert.That(issues.Single().Template is CheckDrainLength.IssueTemplateTooShort);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -63,7 +63,7 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
var issues = check.Run(context).ToList();
|
var issues = check.Run(context).ToList();
|
||||||
|
|
||||||
Assert.That(issues, Has.Count.EqualTo(1));
|
Assert.That(issues, Has.Count.EqualTo(1));
|
||||||
Assert.That(issues.Single().Template is CheckDrainTime.IssueTemplateTooShort);
|
Assert.That(issues.Single().Template is CheckDrainLength.IssueTemplateTooShort);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
@ -110,6 +110,11 @@ namespace osu.Game.Beatmaps
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
public static double CalculatePlayableLength(this IBeatmap beatmap) => CalculatePlayableLength(beatmap.HitObjects);
|
public static double CalculatePlayableLength(this IBeatmap beatmap) => CalculatePlayableLength(beatmap.HitObjects);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Find the total milliseconds between the first and last hittable objects, excluding any break time.
|
||||||
|
/// </summary>
|
||||||
|
public static double CalculateDrainLength(this IBeatmap beatmap) => CalculatePlayableLength(beatmap.HitObjects) - beatmap.TotalBreakTime;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Find the timestamps in milliseconds of the start and end of the playable region.
|
/// Find the timestamps in milliseconds of the start and end of the playable region.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
new CheckUnsnappedObjects(),
|
new CheckUnsnappedObjects(),
|
||||||
new CheckConcurrentObjects(),
|
new CheckConcurrentObjects(),
|
||||||
new CheckZeroLengthObjects(),
|
new CheckZeroLengthObjects(),
|
||||||
new CheckDrainTime(),
|
new CheckDrainLength(),
|
||||||
|
|
||||||
// Timing
|
// Timing
|
||||||
new CheckPreviewTime(),
|
new CheckPreviewTime(),
|
||||||
|
@ -7,10 +7,11 @@ using osu.Game.Rulesets.Edit.Checks.Components;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Edit.Checks
|
namespace osu.Game.Rulesets.Edit.Checks
|
||||||
{
|
{
|
||||||
public class CheckDrainTime : ICheck
|
public class CheckDrainLength : ICheck
|
||||||
{
|
{
|
||||||
private const int min_drain_threshold = 30 * 1000;
|
private const int min_drain_threshold = 30 * 1000;
|
||||||
public CheckMetadata Metadata => new CheckMetadata(CheckCategory.Compose, "Too short drain time");
|
|
||||||
|
public CheckMetadata Metadata => new CheckMetadata(CheckCategory.Compose, "Drain length is too short");
|
||||||
|
|
||||||
public IEnumerable<IssueTemplate> PossibleTemplates => new IssueTemplate[]
|
public IEnumerable<IssueTemplate> PossibleTemplates => new IssueTemplate[]
|
||||||
{
|
{
|
||||||
@ -19,7 +20,7 @@ namespace osu.Game.Rulesets.Edit.Checks
|
|||||||
|
|
||||||
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
|
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
|
||||||
{
|
{
|
||||||
double drainTime = context.Beatmap.CalculatePlayableLength() - context.Beatmap.TotalBreakTime;
|
double drainTime = context.Beatmap.CalculateDrainLength();
|
||||||
|
|
||||||
if (drainTime < min_drain_threshold)
|
if (drainTime < min_drain_threshold)
|
||||||
yield return new IssueTemplateTooShort(this).Create((int)(drainTime / 1000));
|
yield return new IssueTemplateTooShort(this).Create((int)(drainTime / 1000));
|
@ -352,29 +352,6 @@ namespace osu.Game.Screens.Select
|
|||||||
if (working.Beatmap?.HitObjects.Any() != true)
|
if (working.Beatmap?.HitObjects.Any() != true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
infoLabelContainer.Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new InfoLabel(new BeatmapStatistic
|
|
||||||
{
|
|
||||||
Name = "Length",
|
|
||||||
CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Length),
|
|
||||||
Content = working.BeatmapInfo.Length.ToFormattedDuration().ToString(),
|
|
||||||
}),
|
|
||||||
bpmLabelContainer = new Container
|
|
||||||
{
|
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
},
|
|
||||||
new FillFlowContainer
|
|
||||||
{
|
|
||||||
AutoSizeAxes = Axes.Both,
|
|
||||||
Spacing = new Vector2(20, 0),
|
|
||||||
Children = getRulesetInfoLabels()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private InfoLabel[] getRulesetInfoLabels()
|
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IBeatmap playableBeatmap;
|
IBeatmap playableBeatmap;
|
||||||
@ -390,14 +367,30 @@ namespace osu.Game.Screens.Select
|
|||||||
playableBeatmap = working.GetPlayableBeatmap(working.BeatmapInfo.Ruleset, Array.Empty<Mod>());
|
playableBeatmap = working.GetPlayableBeatmap(working.BeatmapInfo.Ruleset, Array.Empty<Mod>());
|
||||||
}
|
}
|
||||||
|
|
||||||
return playableBeatmap.GetStatistics().Select(s => new InfoLabel(s)).ToArray();
|
infoLabelContainer.Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new InfoLabel(new BeatmapStatistic
|
||||||
|
{
|
||||||
|
Name = $"Length (Drain: {playableBeatmap.CalculateDrainLength().ToFormattedDuration().ToString()})",
|
||||||
|
CreateIcon = () => new BeatmapStatisticIcon(BeatmapStatisticsIconType.Length),
|
||||||
|
Content = working.BeatmapInfo.Length.ToFormattedDuration().ToString(),
|
||||||
|
}),
|
||||||
|
bpmLabelContainer = new Container
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Spacing = new Vector2(20, 0),
|
||||||
|
Children = playableBeatmap.GetStatistics().Select(s => new InfoLabel(s)).ToArray()
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Logger.Error(e, "Could not load beatmap successfully!");
|
Logger.Error(e, "Could not load beatmap successfully!");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Array.Empty<InfoLabel>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void refreshBPMLabel()
|
private void refreshBPMLabel()
|
||||||
|
Loading…
Reference in New Issue
Block a user