diff --git a/osu.Game.Tests/Editing/Checks/CheckDrainTimeTest.cs b/osu.Game.Tests/Editing/Checks/CheckDrainLengthTest.cs similarity index 87% rename from osu.Game.Tests/Editing/Checks/CheckDrainTimeTest.cs rename to osu.Game.Tests/Editing/Checks/CheckDrainLengthTest.cs index f845d3c4c1..1b5c5c398f 100644 --- a/osu.Game.Tests/Editing/Checks/CheckDrainTimeTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckDrainLengthTest.cs @@ -14,14 +14,14 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Tests.Editing.Checks { - public class CheckDrainTimeTest + public class CheckDrainLengthTest { - private CheckDrainTime check = null!; + private CheckDrainLength check = null!; [SetUp] public void Setup() { - check = new CheckDrainTime(); + check = new CheckDrainLength(); } [Test] @@ -40,7 +40,7 @@ namespace osu.Game.Tests.Editing.Checks var issues = check.Run(context).ToList(); Assert.That(issues, Has.Count.EqualTo(1)); - Assert.That(issues.Single().Template is CheckDrainTime.IssueTemplateTooShort); + Assert.That(issues.Single().Template is CheckDrainLength.IssueTemplateTooShort); } [Test] @@ -63,7 +63,7 @@ namespace osu.Game.Tests.Editing.Checks var issues = check.Run(context).ToList(); Assert.That(issues, Has.Count.EqualTo(1)); - Assert.That(issues.Single().Template is CheckDrainTime.IssueTemplateTooShort); + Assert.That(issues.Single().Template is CheckDrainLength.IssueTemplateTooShort); } [Test] diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index fbe1a9b462..d97eb00d7e 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -110,6 +110,11 @@ namespace osu.Game.Beatmaps /// public static double CalculatePlayableLength(this IBeatmap beatmap) => CalculatePlayableLength(beatmap.HitObjects); + /// + /// Find the total milliseconds between the first and last hittable objects, excluding any break time. + /// + public static double CalculateDrainLength(this IBeatmap beatmap) => CalculatePlayableLength(beatmap.HitObjects) - beatmap.TotalBreakTime; + /// /// Find the timestamps in milliseconds of the start and end of the playable region. /// diff --git a/osu.Game/Rulesets/Edit/BeatmapVerifier.cs b/osu.Game/Rulesets/Edit/BeatmapVerifier.cs index 4bcf74db45..6782c4324a 100644 --- a/osu.Game/Rulesets/Edit/BeatmapVerifier.cs +++ b/osu.Game/Rulesets/Edit/BeatmapVerifier.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Edit new CheckUnsnappedObjects(), new CheckConcurrentObjects(), new CheckZeroLengthObjects(), - new CheckDrainTime(), + new CheckDrainLength(), // Timing new CheckPreviewTime(), diff --git a/osu.Game/Rulesets/Edit/Checks/CheckDrainTime.cs b/osu.Game/Rulesets/Edit/Checks/CheckDrainLength.cs similarity index 86% rename from osu.Game/Rulesets/Edit/Checks/CheckDrainTime.cs rename to osu.Game/Rulesets/Edit/Checks/CheckDrainLength.cs index 21f053f2c2..ac65dfadff 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckDrainTime.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckDrainLength.cs @@ -7,10 +7,11 @@ using osu.Game.Rulesets.Edit.Checks.Components; namespace osu.Game.Rulesets.Edit.Checks { - public class CheckDrainTime : ICheck + public class CheckDrainLength : ICheck { 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 PossibleTemplates => new IssueTemplate[] { @@ -19,7 +20,7 @@ namespace osu.Game.Rulesets.Edit.Checks public IEnumerable Run(BeatmapVerifierContext context) { - double drainTime = context.Beatmap.CalculatePlayableLength() - context.Beatmap.TotalBreakTime; + double drainTime = context.Beatmap.CalculateDrainLength(); if (drainTime < min_drain_threshold) yield return new IssueTemplateTooShort(this).Create((int)(drainTime / 1000)); diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 3605e3d706..81759f6787 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -352,29 +352,6 @@ namespace osu.Game.Screens.Select if (working.Beatmap?.HitObjects.Any() != true) 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 { IBeatmap playableBeatmap; @@ -390,14 +367,30 @@ namespace osu.Game.Screens.Select playableBeatmap = working.GetPlayableBeatmap(working.BeatmapInfo.Ruleset, Array.Empty()); } - 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) { Logger.Error(e, "Could not load beatmap successfully!"); } - - return Array.Empty(); } private void refreshBPMLabel()