From 5241c999c1f3300f36723a1d070c23240936c8da Mon Sep 17 00:00:00 2001 From: Arthur Araujo Date: Mon, 18 Mar 2024 16:08:41 -0300 Subject: [PATCH] Add different warning to maps with storyboard/video --- .../Checks/CheckUnusedAudioAtEndTest.cs | 51 +++++++++++++++++-- .../Edit/Checks/CheckUnusedAudioAtEnd.cs | 37 +++++++++++++- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Editing/Checks/CheckUnusedAudioAtEndTest.cs b/osu.Game.Tests/Editing/Checks/CheckUnusedAudioAtEndTest.cs index 29c5cb96fd..33d73a8086 100644 --- a/osu.Game.Tests/Editing/Checks/CheckUnusedAudioAtEndTest.cs +++ b/osu.Game.Tests/Editing/Checks/CheckUnusedAudioAtEndTest.cs @@ -4,12 +4,15 @@ using System.Linq; using Moq; using NUnit.Framework; +using osu.Framework.Graphics; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit.Checks; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Storyboards; +using osuTK; using static osu.Game.Tests.Visual.OsuTestScene.ClockBackedTestWorkingBeatmap; namespace osu.Game.Tests.Editing.Checks @@ -47,7 +50,7 @@ namespace osu.Game.Tests.Editing.Checks }, BeatmapInfo = new BeatmapInfo { - Metadata = new BeatmapMetadata { AudioFile = "abc123.jpg" } + Metadata = new BeatmapMetadata { AudioFile = "abc123.jpg" }, } }; } @@ -62,6 +65,42 @@ namespace osu.Game.Tests.Editing.Checks Assert.That(issues.Single().Template is CheckUnusedAudioAtEnd.IssueTemplateUnusedAudioAtEnd); } + [Test] + public void TestAudioNotFullyUsedWithVideo() + { + var storyboard = new Storyboard(); + + var video = new StoryboardVideo("abc123.mp4", 0); + + storyboard.GetLayer("Video").Add(video); + + var mockWorkingBeatmap = getMockWorkingBeatmap(beatmapNotFullyMapped, storyboard); + + var context = getContext(beatmapNotFullyMapped, mockWorkingBeatmap); + var issues = check.Run(context).ToList(); + + Assert.That(issues, Has.Count.EqualTo(1)); + Assert.That(issues.Single().Template is CheckUnusedAudioAtEnd.IssueTemplateUnusedAudioAtEndStoryboardOrVideo); + } + + [Test] + public void TestAudioNotFullyUsedWithStoryboardElement() + { + var storyboard = new Storyboard(); + + var sprite = new StoryboardSprite("unknown", Anchor.TopLeft, Vector2.Zero); + + storyboard.GetLayer("Background").Add(sprite); + + var mockWorkingBeatmap = getMockWorkingBeatmap(beatmapNotFullyMapped, storyboard); + + var context = getContext(beatmapNotFullyMapped, mockWorkingBeatmap); + var issues = check.Run(context).ToList(); + + Assert.That(issues, Has.Count.EqualTo(1)); + Assert.That(issues.Single().Template is CheckUnusedAudioAtEnd.IssueTemplateUnusedAudioAtEndStoryboardOrVideo); + } + [Test] public void TestAudioFullyUsed() { @@ -73,16 +112,22 @@ namespace osu.Game.Tests.Editing.Checks private BeatmapVerifierContext getContext(IBeatmap beatmap) { - return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(beatmap).Object); + return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(beatmap, new Storyboard()).Object); } - private Mock getMockWorkingBeatmap(IBeatmap beatmap) + private BeatmapVerifierContext getContext(IBeatmap beatmap, Mock workingBeatmap) + { + return new BeatmapVerifierContext(beatmap, workingBeatmap.Object); + } + + private Mock getMockWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard) { var mockTrack = new TrackVirtualStore(new FramedClock()).GetVirtual(10000, "virtual"); var mockWorkingBeatmap = new Mock(); mockWorkingBeatmap.SetupGet(w => w.Beatmap).Returns(beatmap); mockWorkingBeatmap.SetupGet(w => w.Track).Returns(mockTrack); + mockWorkingBeatmap.SetupGet(w => w.Storyboard).Returns(storyboard); return mockWorkingBeatmap; } diff --git a/osu.Game/Rulesets/Edit/Checks/CheckUnusedAudioAtEnd.cs b/osu.Game/Rulesets/Edit/Checks/CheckUnusedAudioAtEnd.cs index d9a675fd17..2f768b6ffa 100644 --- a/osu.Game/Rulesets/Edit/Checks/CheckUnusedAudioAtEnd.cs +++ b/osu.Game/Rulesets/Edit/Checks/CheckUnusedAudioAtEnd.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Edit.Checks.Components; +using osu.Game.Storyboards; namespace osu.Game.Rulesets.Edit.Checks { @@ -15,6 +16,7 @@ namespace osu.Game.Rulesets.Edit.Checks public IEnumerable PossibleTemplates => new IssueTemplate[] { new IssueTemplateUnusedAudioAtEnd(this), + new IssueTemplateUnusedAudioAtEndStoryboardOrVideo(this), }; public IEnumerable Run(BeatmapVerifierContext context) @@ -27,10 +29,33 @@ namespace osu.Game.Rulesets.Edit.Checks if (mappedPercentage < 80) { double percentageLeft = Math.Abs(mappedPercentage - 100); - yield return new IssueTemplateUnusedAudioAtEnd(this).Create(percentageLeft); + + bool storyboardIsPresent = isAnyStoryboardElementPresent(context.WorkingBeatmap.Storyboard); + + if (storyboardIsPresent) + { + yield return new IssueTemplateUnusedAudioAtEndStoryboardOrVideo(this).Create(percentageLeft); + } + else + { + yield return new IssueTemplateUnusedAudioAtEnd(this).Create(percentageLeft); + } } } + private bool isAnyStoryboardElementPresent(Storyboard storyboard) + { + foreach (var layer in storyboard.Layers) + { + foreach (var _ in layer.Elements) + { + return true; + } + } + + return false; + } + public class IssueTemplateUnusedAudioAtEnd : IssueTemplate { public IssueTemplateUnusedAudioAtEnd(ICheck check) @@ -40,5 +65,15 @@ namespace osu.Game.Rulesets.Edit.Checks public Issue Create(double percentageLeft) => new Issue(this, percentageLeft); } + + public class IssueTemplateUnusedAudioAtEndStoryboardOrVideo : IssueTemplate + { + public IssueTemplateUnusedAudioAtEndStoryboardOrVideo(ICheck check) + : base(check, IssueType.Warning, "Currently there is {0}% unused audio at the end. Ensure the outro significantly contributes to the song, or is being occupied by the video or storyboard, otherwise cut the outro.") + { + } + + public Issue Create(double percentageLeft) => new Issue(this, percentageLeft); + } } }