mirror of
https://github.com/osukey/osukey.git
synced 2025-06-09 21:37:59 +09:00
Merge branch 'master' into single-bind-reset-button
This commit is contained in:
commit
b5e1f78c06
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Osu.Edit.Checks;
|
using osu.Game.Rulesets.Osu.Edit.Checks;
|
||||||
@ -224,12 +225,14 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks
|
|||||||
|
|
||||||
private void assertOk(IBeatmap beatmap)
|
private void assertOk(IBeatmap beatmap)
|
||||||
{
|
{
|
||||||
Assert.That(check.Run(beatmap, new TestWorkingBeatmap(beatmap)), Is.Empty);
|
var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
|
||||||
|
Assert.That(check.Run(context), Is.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertOffscreenCircle(IBeatmap beatmap)
|
private void assertOffscreenCircle(IBeatmap beatmap)
|
||||||
{
|
{
|
||||||
var issues = check.Run(beatmap, new TestWorkingBeatmap(beatmap)).ToList();
|
var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
|
||||||
|
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 CheckOffscreenObjects.IssueTemplateOffscreenCircle);
|
Assert.That(issues.Single().Template is CheckOffscreenObjects.IssueTemplateOffscreenCircle);
|
||||||
@ -237,7 +240,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks
|
|||||||
|
|
||||||
private void assertOffscreenSlider(IBeatmap beatmap)
|
private void assertOffscreenSlider(IBeatmap beatmap)
|
||||||
{
|
{
|
||||||
var issues = check.Run(beatmap, new TestWorkingBeatmap(beatmap)).ToList();
|
var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
|
||||||
|
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 CheckOffscreenObjects.IssueTemplateOffscreenSlider);
|
Assert.That(issues.Single().Template is CheckOffscreenObjects.IssueTemplateOffscreenSlider);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Checks.Components;
|
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -31,9 +31,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Checks
|
|||||||
new IssueTemplateOffscreenSlider(this)
|
new IssueTemplateOffscreenSlider(this)
|
||||||
};
|
};
|
||||||
|
|
||||||
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap)
|
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
|
||||||
{
|
{
|
||||||
foreach (var hitobject in playableBeatmap.HitObjects)
|
foreach (var hitobject in context.Beatmap.HitObjects)
|
||||||
{
|
{
|
||||||
switch (hitobject)
|
switch (hitobject)
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Checks.Components;
|
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||||
using osu.Game.Rulesets.Osu.Edit.Checks;
|
using osu.Game.Rulesets.Osu.Edit.Checks;
|
||||||
@ -17,9 +16,9 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
new CheckOffscreenObjects()
|
new CheckOffscreenObjects()
|
||||||
};
|
};
|
||||||
|
|
||||||
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, WorkingBeatmap workingBeatmap)
|
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
|
||||||
{
|
{
|
||||||
return checks.SelectMany(check => check.Run(playableBeatmap, workingBeatmap));
|
return checks.SelectMany(check => check.Run(context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using Moq;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Checks;
|
using osu.Game.Rulesets.Edit.Checks;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
|
||||||
@ -40,23 +41,23 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
mock.SetupGet(w => w.Beatmap).Returns(beatmap);
|
mock.SetupGet(w => w.Beatmap).Returns(beatmap);
|
||||||
mock.SetupGet(w => w.Track).Returns((Track)null);
|
mock.SetupGet(w => w.Track).Returns((Track)null);
|
||||||
|
|
||||||
Assert.That(check.Run(beatmap, mock.Object), Is.Empty);
|
Assert.That(check.Run(new BeatmapVerifierContext(beatmap, mock.Object)), Is.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestAcceptable()
|
public void TestAcceptable()
|
||||||
{
|
{
|
||||||
var mock = getMockWorkingBeatmap(192);
|
var context = getContext(192);
|
||||||
|
|
||||||
Assert.That(check.Run(beatmap, mock.Object), Is.Empty);
|
Assert.That(check.Run(context), Is.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestNullBitrate()
|
public void TestNullBitrate()
|
||||||
{
|
{
|
||||||
var mock = getMockWorkingBeatmap(null);
|
var context = getContext(null);
|
||||||
|
|
||||||
var issues = check.Run(beatmap, mock.Object).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 CheckAudioQuality.IssueTemplateNoBitrate);
|
Assert.That(issues.Single().Template is CheckAudioQuality.IssueTemplateNoBitrate);
|
||||||
@ -65,9 +66,9 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestZeroBitrate()
|
public void TestZeroBitrate()
|
||||||
{
|
{
|
||||||
var mock = getMockWorkingBeatmap(0);
|
var context = getContext(0);
|
||||||
|
|
||||||
var issues = check.Run(beatmap, mock.Object).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 CheckAudioQuality.IssueTemplateNoBitrate);
|
Assert.That(issues.Single().Template is CheckAudioQuality.IssueTemplateNoBitrate);
|
||||||
@ -76,9 +77,9 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestTooHighBitrate()
|
public void TestTooHighBitrate()
|
||||||
{
|
{
|
||||||
var mock = getMockWorkingBeatmap(320);
|
var context = getContext(320);
|
||||||
|
|
||||||
var issues = check.Run(beatmap, mock.Object).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 CheckAudioQuality.IssueTemplateTooHighBitrate);
|
Assert.That(issues.Single().Template is CheckAudioQuality.IssueTemplateTooHighBitrate);
|
||||||
@ -87,14 +88,19 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestTooLowBitrate()
|
public void TestTooLowBitrate()
|
||||||
{
|
{
|
||||||
var mock = getMockWorkingBeatmap(64);
|
var context = getContext(64);
|
||||||
|
|
||||||
var issues = check.Run(beatmap, mock.Object).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 CheckAudioQuality.IssueTemplateTooLowBitrate);
|
Assert.That(issues.Single().Template is CheckAudioQuality.IssueTemplateTooLowBitrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BeatmapVerifierContext getContext(int? audioBitrate)
|
||||||
|
{
|
||||||
|
return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(audioBitrate).Object);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the mock of the working beatmap with the given audio properties.
|
/// Returns the mock of the working beatmap with the given audio properties.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -9,6 +9,7 @@ using Moq;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Checks;
|
using osu.Game.Rulesets.Edit.Checks;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using FileInfo = osu.Game.IO.FileInfo;
|
using FileInfo = osu.Game.IO.FileInfo;
|
||||||
@ -53,25 +54,25 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
{
|
{
|
||||||
// While this is a problem, it is out of scope for this check and is caught by a different one.
|
// While this is a problem, it is out of scope for this check and is caught by a different one.
|
||||||
beatmap.Metadata.BackgroundFile = null;
|
beatmap.Metadata.BackgroundFile = null;
|
||||||
var mock = getMockWorkingBeatmap(null, System.Array.Empty<byte>());
|
var context = getContext(null, System.Array.Empty<byte>());
|
||||||
|
|
||||||
Assert.That(check.Run(beatmap, mock.Object), Is.Empty);
|
Assert.That(check.Run(context), Is.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestAcceptable()
|
public void TestAcceptable()
|
||||||
{
|
{
|
||||||
var mock = getMockWorkingBeatmap(new Texture(1920, 1080));
|
var context = getContext(new Texture(1920, 1080));
|
||||||
|
|
||||||
Assert.That(check.Run(beatmap, mock.Object), Is.Empty);
|
Assert.That(check.Run(context), Is.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestTooHighResolution()
|
public void TestTooHighResolution()
|
||||||
{
|
{
|
||||||
var mock = getMockWorkingBeatmap(new Texture(3840, 2160));
|
var context = getContext(new Texture(3840, 2160));
|
||||||
|
|
||||||
var issues = check.Run(beatmap, mock.Object).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 CheckBackgroundQuality.IssueTemplateTooHighResolution);
|
Assert.That(issues.Single().Template is CheckBackgroundQuality.IssueTemplateTooHighResolution);
|
||||||
@ -80,9 +81,9 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestLowResolution()
|
public void TestLowResolution()
|
||||||
{
|
{
|
||||||
var mock = getMockWorkingBeatmap(new Texture(640, 480));
|
var context = getContext(new Texture(640, 480));
|
||||||
|
|
||||||
var issues = check.Run(beatmap, mock.Object).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 CheckBackgroundQuality.IssueTemplateLowResolution);
|
Assert.That(issues.Single().Template is CheckBackgroundQuality.IssueTemplateLowResolution);
|
||||||
@ -91,9 +92,9 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestTooLowResolution()
|
public void TestTooLowResolution()
|
||||||
{
|
{
|
||||||
var mock = getMockWorkingBeatmap(new Texture(100, 100));
|
var context = getContext(new Texture(100, 100));
|
||||||
|
|
||||||
var issues = check.Run(beatmap, mock.Object).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 CheckBackgroundQuality.IssueTemplateTooLowResolution);
|
Assert.That(issues.Single().Template is CheckBackgroundQuality.IssueTemplateTooLowResolution);
|
||||||
@ -102,14 +103,19 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestTooUncompressed()
|
public void TestTooUncompressed()
|
||||||
{
|
{
|
||||||
var mock = getMockWorkingBeatmap(new Texture(1920, 1080), new byte[1024 * 1024 * 3]);
|
var context = getContext(new Texture(1920, 1080), new byte[1024 * 1024 * 3]);
|
||||||
|
|
||||||
var issues = check.Run(beatmap, mock.Object).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 CheckBackgroundQuality.IssueTemplateTooUncompressed);
|
Assert.That(issues.Single().Template is CheckBackgroundQuality.IssueTemplateTooUncompressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BeatmapVerifierContext getContext(Texture background, [CanBeNull] byte[] fileBytes = null)
|
||||||
|
{
|
||||||
|
return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(background, fileBytes).Object);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the mock of the working beatmap with the given background and filesize.
|
/// Returns the mock of the working beatmap with the given background and filesize.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -6,11 +6,13 @@ using System.Linq;
|
|||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Checks;
|
using osu.Game.Rulesets.Edit.Checks;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Editing.Checks
|
namespace osu.Game.Tests.Editing.Checks
|
||||||
{
|
{
|
||||||
@ -105,7 +107,7 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
new HitCircle { StartTime = 300 }
|
new HitCircle { StartTime = 300 }
|
||||||
};
|
};
|
||||||
|
|
||||||
var issues = check.Run(getPlayableBeatmap(hitobjects), null).ToList();
|
var issues = check.Run(getContext(hitobjects)).ToList();
|
||||||
|
|
||||||
Assert.That(issues, Has.Count.EqualTo(3));
|
Assert.That(issues, Has.Count.EqualTo(3));
|
||||||
Assert.That(issues.Where(issue => issue.Template is CheckConcurrentObjects.IssueTemplateConcurrentDifferent).ToList(), Has.Count.EqualTo(2));
|
Assert.That(issues.Where(issue => issue.Template is CheckConcurrentObjects.IssueTemplateConcurrentDifferent).ToList(), Has.Count.EqualTo(2));
|
||||||
@ -164,12 +166,12 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
|
|
||||||
private void assertOk(List<HitObject> hitobjects)
|
private void assertOk(List<HitObject> hitobjects)
|
||||||
{
|
{
|
||||||
Assert.That(check.Run(getPlayableBeatmap(hitobjects), null), Is.Empty);
|
Assert.That(check.Run(getContext(hitobjects)), Is.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertConcurrentSame(List<HitObject> hitobjects, int count = 1)
|
private void assertConcurrentSame(List<HitObject> hitobjects, int count = 1)
|
||||||
{
|
{
|
||||||
var issues = check.Run(getPlayableBeatmap(hitobjects), null).ToList();
|
var issues = check.Run(getContext(hitobjects)).ToList();
|
||||||
|
|
||||||
Assert.That(issues, Has.Count.EqualTo(count));
|
Assert.That(issues, Has.Count.EqualTo(count));
|
||||||
Assert.That(issues.All(issue => issue.Template is CheckConcurrentObjects.IssueTemplateConcurrentSame));
|
Assert.That(issues.All(issue => issue.Template is CheckConcurrentObjects.IssueTemplateConcurrentSame));
|
||||||
@ -177,18 +179,16 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
|
|
||||||
private void assertConcurrentDifferent(List<HitObject> hitobjects, int count = 1)
|
private void assertConcurrentDifferent(List<HitObject> hitobjects, int count = 1)
|
||||||
{
|
{
|
||||||
var issues = check.Run(getPlayableBeatmap(hitobjects), null).ToList();
|
var issues = check.Run(getContext(hitobjects)).ToList();
|
||||||
|
|
||||||
Assert.That(issues, Has.Count.EqualTo(count));
|
Assert.That(issues, Has.Count.EqualTo(count));
|
||||||
Assert.That(issues.All(issue => issue.Template is CheckConcurrentObjects.IssueTemplateConcurrentDifferent));
|
Assert.That(issues.All(issue => issue.Template is CheckConcurrentObjects.IssueTemplateConcurrentDifferent));
|
||||||
}
|
}
|
||||||
|
|
||||||
private IBeatmap getPlayableBeatmap(List<HitObject> hitobjects)
|
private BeatmapVerifierContext getContext(List<HitObject> hitobjects)
|
||||||
{
|
{
|
||||||
return new Beatmap<HitObject>
|
var beatmap = new Beatmap<HitObject> { HitObjects = hitobjects };
|
||||||
{
|
return new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
|
||||||
HitObjects = hitobjects
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using System.Linq;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Checks;
|
using osu.Game.Rulesets.Edit.Checks;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
@ -45,7 +46,8 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestBackgroundSetAndInFiles()
|
public void TestBackgroundSetAndInFiles()
|
||||||
{
|
{
|
||||||
Assert.That(check.Run(beatmap, new TestWorkingBeatmap(beatmap)), Is.Empty);
|
var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
|
||||||
|
Assert.That(check.Run(context), Is.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -53,7 +55,8 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
{
|
{
|
||||||
beatmap.BeatmapInfo.BeatmapSet.Files.Clear();
|
beatmap.BeatmapInfo.BeatmapSet.Files.Clear();
|
||||||
|
|
||||||
var issues = check.Run(beatmap, new TestWorkingBeatmap(beatmap)).ToList();
|
var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
|
||||||
|
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 CheckFilePresence.IssueTemplateDoesNotExist);
|
Assert.That(issues.Single().Template is CheckFilePresence.IssueTemplateDoesNotExist);
|
||||||
@ -64,7 +67,8 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
{
|
{
|
||||||
beatmap.Metadata.BackgroundFile = null;
|
beatmap.Metadata.BackgroundFile = null;
|
||||||
|
|
||||||
var issues = check.Run(beatmap, new TestWorkingBeatmap(beatmap)).ToList();
|
var context = new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
|
||||||
|
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 CheckFilePresence.IssueTemplateNoneSet);
|
Assert.That(issues.Single().Template is CheckFilePresence.IssueTemplateNoneSet);
|
||||||
|
@ -7,10 +7,12 @@ using Moq;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Edit.Checks;
|
using osu.Game.Rulesets.Edit.Checks;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Editing.Checks
|
namespace osu.Game.Tests.Editing.Checks
|
||||||
{
|
{
|
||||||
@ -100,12 +102,12 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
}, count: 2);
|
}, count: 2);
|
||||||
|
|
||||||
// Start and end are 2 ms and 1.25 ms off respectively, hence two different issues in one object.
|
// Start and end are 2 ms and 1.25 ms off respectively, hence two different issues in one object.
|
||||||
var hitobjects = new List<HitObject>
|
var hitObjects = new List<HitObject>
|
||||||
{
|
{
|
||||||
getSliderMock(startTime: 98, endTime: 398.75d).Object
|
getSliderMock(startTime: 98, endTime: 398.75d).Object
|
||||||
};
|
};
|
||||||
|
|
||||||
var issues = check.Run(getPlayableBeatmap(hitobjects), null).ToList();
|
var issues = check.Run(getContext(hitObjects)).ToList();
|
||||||
|
|
||||||
Assert.That(issues, Has.Count.EqualTo(2));
|
Assert.That(issues, Has.Count.EqualTo(2));
|
||||||
Assert.That(issues.Any(issue => issue.Template is CheckUnsnappedObjects.IssueTemplateSmallUnsnap));
|
Assert.That(issues.Any(issue => issue.Template is CheckUnsnappedObjects.IssueTemplateSmallUnsnap));
|
||||||
@ -122,34 +124,36 @@ namespace osu.Game.Tests.Editing.Checks
|
|||||||
return mockSlider;
|
return mockSlider;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertOk(List<HitObject> hitobjects)
|
private void assertOk(List<HitObject> hitObjects)
|
||||||
{
|
{
|
||||||
Assert.That(check.Run(getPlayableBeatmap(hitobjects), null), Is.Empty);
|
Assert.That(check.Run(getContext(hitObjects)), Is.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assert1Ms(List<HitObject> hitobjects, int count = 1)
|
private void assert1Ms(List<HitObject> hitObjects, int count = 1)
|
||||||
{
|
{
|
||||||
var issues = check.Run(getPlayableBeatmap(hitobjects), null).ToList();
|
var issues = check.Run(getContext(hitObjects)).ToList();
|
||||||
|
|
||||||
Assert.That(issues, Has.Count.EqualTo(count));
|
Assert.That(issues, Has.Count.EqualTo(count));
|
||||||
Assert.That(issues.All(issue => issue.Template is CheckUnsnappedObjects.IssueTemplateSmallUnsnap));
|
Assert.That(issues.All(issue => issue.Template is CheckUnsnappedObjects.IssueTemplateSmallUnsnap));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assert2Ms(List<HitObject> hitobjects, int count = 1)
|
private void assert2Ms(List<HitObject> hitObjects, int count = 1)
|
||||||
{
|
{
|
||||||
var issues = check.Run(getPlayableBeatmap(hitobjects), null).ToList();
|
var issues = check.Run(getContext(hitObjects)).ToList();
|
||||||
|
|
||||||
Assert.That(issues, Has.Count.EqualTo(count));
|
Assert.That(issues, Has.Count.EqualTo(count));
|
||||||
Assert.That(issues.All(issue => issue.Template is CheckUnsnappedObjects.IssueTemplateLargeUnsnap));
|
Assert.That(issues.All(issue => issue.Template is CheckUnsnappedObjects.IssueTemplateLargeUnsnap));
|
||||||
}
|
}
|
||||||
|
|
||||||
private IBeatmap getPlayableBeatmap(List<HitObject> hitobjects)
|
private BeatmapVerifierContext getContext(List<HitObject> hitObjects)
|
||||||
{
|
{
|
||||||
return new Beatmap<HitObject>
|
var beatmap = new Beatmap<HitObject>
|
||||||
{
|
{
|
||||||
ControlPointInfo = cpi,
|
ControlPointInfo = cpi,
|
||||||
HitObjects = hitobjects
|
HitObjects = hitObjects
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return new BeatmapVerifierContext(beatmap, new TestWorkingBeatmap(beatmap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,65 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Screens.Ranking.Expanded;
|
using osu.Game.Screens.Ranking.Expanded;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Ranking
|
namespace osu.Game.Tests.Visual.Ranking
|
||||||
{
|
{
|
||||||
public class TestSceneStarRatingDisplay : OsuTestScene
|
public class TestSceneStarRatingDisplay : OsuTestScene
|
||||||
{
|
{
|
||||||
public TestSceneStarRatingDisplay()
|
[Test]
|
||||||
|
public void TestDisplay()
|
||||||
{
|
{
|
||||||
Child = new FillFlowContainer
|
AddStep("load displays", () => Child = new FillFlowContainer
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Children = new Drawable[]
|
ChildrenEnumerable = new[]
|
||||||
{
|
{
|
||||||
new StarRatingDisplay(new StarDifficulty(1.23, 0)),
|
1.23,
|
||||||
new StarRatingDisplay(new StarDifficulty(2.34, 0)),
|
2.34,
|
||||||
new StarRatingDisplay(new StarDifficulty(3.45, 0)),
|
3.45,
|
||||||
new StarRatingDisplay(new StarDifficulty(4.56, 0)),
|
4.56,
|
||||||
new StarRatingDisplay(new StarDifficulty(5.67, 0)),
|
5.67,
|
||||||
new StarRatingDisplay(new StarDifficulty(6.78, 0)),
|
6.78,
|
||||||
new StarRatingDisplay(new StarDifficulty(10.11, 0)),
|
10.11,
|
||||||
|
}.Select(starRating => new StarRatingDisplay(new StarDifficulty(starRating, 0))
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre
|
||||||
|
})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
[Test]
|
||||||
|
public void TestChangingStarRatingDisplay()
|
||||||
|
{
|
||||||
|
StarRatingDisplay starRating = null;
|
||||||
|
|
||||||
|
AddStep("load display", () => Child = starRating = new StarRatingDisplay(new StarDifficulty(5.55, 1))
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Scale = new Vector2(3f),
|
||||||
|
});
|
||||||
|
|
||||||
|
AddRepeatStep("set random value", () =>
|
||||||
|
{
|
||||||
|
starRating.Current.Value = new StarDifficulty(RNG.NextDouble(0.0, 11.0), 1);
|
||||||
|
}, 10);
|
||||||
|
|
||||||
|
AddSliderStep("set exact stars", 0.0, 11.0, 5.55, d =>
|
||||||
|
{
|
||||||
|
if (starRating != null)
|
||||||
|
starRating.Current.Value = new StarDifficulty(d, 1);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,151 @@
|
|||||||
|
// 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Utils;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Screens.Menu;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.SongSelect
|
||||||
|
{
|
||||||
|
public class TestSceneBeatmapMetadataDisplay : OsuTestScene
|
||||||
|
{
|
||||||
|
private BeatmapMetadataDisplay display;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private BeatmapManager manager { get; set; }
|
||||||
|
|
||||||
|
[Cached(typeof(BeatmapDifficultyCache))]
|
||||||
|
private readonly TestBeatmapDifficultyCache testDifficultyCache = new TestBeatmapDifficultyCache();
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestLocal([Values("Beatmap", "Some long title and stuff")]
|
||||||
|
string title,
|
||||||
|
[Values("Trial", "Some1's very hardest difficulty")]
|
||||||
|
string version)
|
||||||
|
{
|
||||||
|
showMetadataForBeatmap(() => CreateWorkingBeatmap(new Beatmap
|
||||||
|
{
|
||||||
|
BeatmapInfo =
|
||||||
|
{
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Title = title,
|
||||||
|
},
|
||||||
|
Version = version,
|
||||||
|
StarDifficulty = RNG.NextDouble(0, 10),
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDelayedStarRating()
|
||||||
|
{
|
||||||
|
AddStep("block calculation", () => testDifficultyCache.BlockCalculation = true);
|
||||||
|
|
||||||
|
showMetadataForBeatmap(() => CreateWorkingBeatmap(new Beatmap
|
||||||
|
{
|
||||||
|
BeatmapInfo =
|
||||||
|
{
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Title = "Heavy beatmap",
|
||||||
|
},
|
||||||
|
Version = "10k objects",
|
||||||
|
StarDifficulty = 99.99f,
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
AddStep("allow calculation", () => testDifficultyCache.BlockCalculation = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestRandomFromDatabase()
|
||||||
|
{
|
||||||
|
showMetadataForBeatmap(() =>
|
||||||
|
{
|
||||||
|
var allBeatmapSets = manager.GetAllUsableBeatmapSets(IncludedDetails.Minimal);
|
||||||
|
if (allBeatmapSets.Count == 0)
|
||||||
|
return manager.DefaultBeatmap;
|
||||||
|
|
||||||
|
var randomBeatmapSet = allBeatmapSets[RNG.Next(0, allBeatmapSets.Count - 1)];
|
||||||
|
var randomBeatmap = randomBeatmapSet.Beatmaps[RNG.Next(0, randomBeatmapSet.Beatmaps.Count - 1)];
|
||||||
|
|
||||||
|
return manager.GetWorkingBeatmap(randomBeatmap);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showMetadataForBeatmap(Func<WorkingBeatmap> getBeatmap)
|
||||||
|
{
|
||||||
|
AddStep("setup display", () =>
|
||||||
|
{
|
||||||
|
var randomMods = Ruleset.Value.CreateInstance().GetAllMods().OrderBy(_ => RNG.Next()).Take(5).ToList();
|
||||||
|
|
||||||
|
OsuLogo logo = new OsuLogo { Scale = new Vector2(0.15f) };
|
||||||
|
|
||||||
|
Remove(testDifficultyCache);
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
testDifficultyCache,
|
||||||
|
display = new BeatmapMetadataDisplay(getBeatmap(), new Bindable<IReadOnlyList<Mod>>(randomMods), logo)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Alpha = 0f,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
display.FadeIn(400, Easing.OutQuint);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddWaitStep("wait a bit", 5);
|
||||||
|
|
||||||
|
AddStep("finish loading", () => display.Loading = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestBeatmapDifficultyCache : BeatmapDifficultyCache
|
||||||
|
{
|
||||||
|
private TaskCompletionSource<bool> calculationBlocker;
|
||||||
|
|
||||||
|
private bool blockCalculation;
|
||||||
|
|
||||||
|
public bool BlockCalculation
|
||||||
|
{
|
||||||
|
get => blockCalculation;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == blockCalculation)
|
||||||
|
return;
|
||||||
|
|
||||||
|
blockCalculation = value;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
calculationBlocker = new TaskCompletionSource<bool>();
|
||||||
|
else
|
||||||
|
calculationBlocker?.SetResult(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<StarDifficulty> GetDifficultyAsync(BeatmapInfo beatmapInfo, RulesetInfo rulesetInfo = null, IEnumerable<Mod> mods = null, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
if (blockCalculation)
|
||||||
|
await calculationBlocker.Task;
|
||||||
|
|
||||||
|
return await base.GetDifficultyAsync(beatmapInfo, rulesetInfo, mods, cancellationToken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -103,8 +103,8 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <param name="mods">The <see cref="Mod"/>s to get the difficulty with.</param>
|
/// <param name="mods">The <see cref="Mod"/>s to get the difficulty with.</param>
|
||||||
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops computing the star difficulty.</param>
|
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops computing the star difficulty.</param>
|
||||||
/// <returns>The <see cref="StarDifficulty"/>.</returns>
|
/// <returns>The <see cref="StarDifficulty"/>.</returns>
|
||||||
public Task<StarDifficulty> GetDifficultyAsync([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo rulesetInfo = null, [CanBeNull] IEnumerable<Mod> mods = null,
|
public virtual Task<StarDifficulty> GetDifficultyAsync([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo rulesetInfo = null,
|
||||||
CancellationToken cancellationToken = default)
|
[CanBeNull] IEnumerable<Mod> mods = null, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
// In the case that the user hasn't given us a ruleset, use the beatmap's default ruleset.
|
// In the case that the user hasn't given us a ruleset, use the beatmap's default ruleset.
|
||||||
rulesetInfo ??= beatmapInfo.Ruleset;
|
rulesetInfo ??= beatmapInfo.Ruleset;
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Edit.Checks;
|
using osu.Game.Rulesets.Edit.Checks;
|
||||||
using osu.Game.Rulesets.Edit.Checks.Components;
|
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||||
|
|
||||||
@ -29,9 +28,9 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
new CheckConcurrentObjects()
|
new CheckConcurrentObjects()
|
||||||
};
|
};
|
||||||
|
|
||||||
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, WorkingBeatmap workingBeatmap)
|
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
|
||||||
{
|
{
|
||||||
return checks.SelectMany(check => check.Run(playableBeatmap, workingBeatmap));
|
return checks.SelectMany(check => check.Run(context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
38
osu.Game/Rulesets/Edit/BeatmapVerifierContext.cs
Normal file
38
osu.Game/Rulesets/Edit/BeatmapVerifierContext.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// 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 osu.Game.Beatmaps;
|
||||||
|
|
||||||
|
#nullable enable
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Edit
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the context provided by the beatmap verifier to the checks it runs.
|
||||||
|
/// Contains information about what is being checked and how it should be checked.
|
||||||
|
/// </summary>
|
||||||
|
public class BeatmapVerifierContext
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The playable beatmap instance of the current beatmap.
|
||||||
|
/// </summary>
|
||||||
|
public readonly IBeatmap Beatmap;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The working beatmap instance of the current beatmap.
|
||||||
|
/// </summary>
|
||||||
|
public readonly IWorkingBeatmap WorkingBeatmap;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The difficulty level which the current beatmap is considered to be.
|
||||||
|
/// </summary>
|
||||||
|
public DifficultyRating InterpretedDifficulty;
|
||||||
|
|
||||||
|
public BeatmapVerifierContext(IBeatmap beatmap, IWorkingBeatmap workingBeatmap, DifficultyRating difficultyRating = DifficultyRating.ExpertPlus)
|
||||||
|
{
|
||||||
|
Beatmap = beatmap;
|
||||||
|
WorkingBeatmap = workingBeatmap;
|
||||||
|
InterpretedDifficulty = difficultyRating;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Edit.Checks
|
|||||||
{
|
{
|
||||||
protected override CheckCategory Category => CheckCategory.Audio;
|
protected override CheckCategory Category => CheckCategory.Audio;
|
||||||
protected override string TypeOfFile => "audio";
|
protected override string TypeOfFile => "audio";
|
||||||
protected override string GetFilename(IBeatmap playableBeatmap) => playableBeatmap.Metadata?.AudioFile;
|
protected override string GetFilename(IBeatmap beatmap) => beatmap.Metadata?.AudioFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Edit.Checks.Components;
|
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Edit.Checks
|
namespace osu.Game.Rulesets.Edit.Checks
|
||||||
@ -26,13 +25,13 @@ namespace osu.Game.Rulesets.Edit.Checks
|
|||||||
new IssueTemplateNoBitrate(this)
|
new IssueTemplateNoBitrate(this)
|
||||||
};
|
};
|
||||||
|
|
||||||
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap)
|
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
|
||||||
{
|
{
|
||||||
var audioFile = playableBeatmap.Metadata?.AudioFile;
|
var audioFile = context.Beatmap.Metadata?.AudioFile;
|
||||||
if (audioFile == null)
|
if (audioFile == null)
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
var track = workingBeatmap.Track;
|
var track = context.WorkingBeatmap.Track;
|
||||||
|
|
||||||
if (track?.Bitrate == null || track.Bitrate.Value == 0)
|
if (track?.Bitrate == null || track.Bitrate.Value == 0)
|
||||||
yield return new IssueTemplateNoBitrate(this).Create();
|
yield return new IssueTemplateNoBitrate(this).Create();
|
||||||
|
@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Edit.Checks
|
|||||||
{
|
{
|
||||||
protected override CheckCategory Category => CheckCategory.Resources;
|
protected override CheckCategory Category => CheckCategory.Resources;
|
||||||
protected override string TypeOfFile => "background";
|
protected override string TypeOfFile => "background";
|
||||||
protected override string GetFilename(IBeatmap playableBeatmap) => playableBeatmap.Metadata?.BackgroundFile;
|
protected override string GetFilename(IBeatmap beatmap) => beatmap.Metadata?.BackgroundFile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Edit.Checks.Components;
|
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Edit.Checks
|
namespace osu.Game.Rulesets.Edit.Checks
|
||||||
@ -30,13 +29,13 @@ namespace osu.Game.Rulesets.Edit.Checks
|
|||||||
new IssueTemplateTooUncompressed(this)
|
new IssueTemplateTooUncompressed(this)
|
||||||
};
|
};
|
||||||
|
|
||||||
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap)
|
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
|
||||||
{
|
{
|
||||||
var backgroundFile = playableBeatmap.Metadata?.BackgroundFile;
|
var backgroundFile = context.Beatmap.Metadata?.BackgroundFile;
|
||||||
if (backgroundFile == null)
|
if (backgroundFile == null)
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
var texture = workingBeatmap.Background;
|
var texture = context.WorkingBeatmap.Background;
|
||||||
if (texture == null)
|
if (texture == null)
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
@ -48,8 +47,8 @@ namespace osu.Game.Rulesets.Edit.Checks
|
|||||||
else if (texture.Width < low_width || texture.Height < low_height)
|
else if (texture.Width < low_width || texture.Height < low_height)
|
||||||
yield return new IssueTemplateLowResolution(this).Create(texture.Width, texture.Height);
|
yield return new IssueTemplateLowResolution(this).Create(texture.Width, texture.Height);
|
||||||
|
|
||||||
string storagePath = playableBeatmap.BeatmapInfo.BeatmapSet.GetPathForFile(backgroundFile);
|
string storagePath = context.Beatmap.BeatmapInfo.BeatmapSet.GetPathForFile(backgroundFile);
|
||||||
double filesizeMb = workingBeatmap.GetStream(storagePath).Length / (1024d * 1024d);
|
double filesizeMb = context.WorkingBeatmap.GetStream(storagePath).Length / (1024d * 1024d);
|
||||||
|
|
||||||
if (filesizeMb > max_filesize_mb)
|
if (filesizeMb > max_filesize_mb)
|
||||||
yield return new IssueTemplateTooUncompressed(this).Create(filesizeMb);
|
yield return new IssueTemplateTooUncompressed(this).Create(filesizeMb);
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Edit.Checks.Components;
|
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
@ -22,15 +21,17 @@ namespace osu.Game.Rulesets.Edit.Checks
|
|||||||
new IssueTemplateConcurrentDifferent(this)
|
new IssueTemplateConcurrentDifferent(this)
|
||||||
};
|
};
|
||||||
|
|
||||||
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap)
|
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < playableBeatmap.HitObjects.Count - 1; ++i)
|
var hitObjects = context.Beatmap.HitObjects;
|
||||||
{
|
|
||||||
var hitobject = playableBeatmap.HitObjects[i];
|
|
||||||
|
|
||||||
for (int j = i + 1; j < playableBeatmap.HitObjects.Count; ++j)
|
for (int i = 0; i < hitObjects.Count - 1; ++i)
|
||||||
{
|
{
|
||||||
var nextHitobject = playableBeatmap.HitObjects[j];
|
var hitobject = hitObjects[i];
|
||||||
|
|
||||||
|
for (int j = i + 1; j < hitObjects.Count; ++j)
|
||||||
|
{
|
||||||
|
var nextHitobject = hitObjects[j];
|
||||||
|
|
||||||
// Accounts for rulesets with hitobjects separated by columns, such as Mania.
|
// Accounts for rulesets with hitobjects separated by columns, such as Mania.
|
||||||
// In these cases we only care about concurrent objects within the same column.
|
// In these cases we only care about concurrent objects within the same column.
|
||||||
|
@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Edit.Checks
|
|||||||
{
|
{
|
||||||
protected abstract CheckCategory Category { get; }
|
protected abstract CheckCategory Category { get; }
|
||||||
protected abstract string TypeOfFile { get; }
|
protected abstract string TypeOfFile { get; }
|
||||||
protected abstract string GetFilename(IBeatmap playableBeatmap);
|
protected abstract string GetFilename(IBeatmap beatmap);
|
||||||
|
|
||||||
public CheckMetadata Metadata => new CheckMetadata(Category, $"Missing {TypeOfFile}");
|
public CheckMetadata Metadata => new CheckMetadata(Category, $"Missing {TypeOfFile}");
|
||||||
|
|
||||||
@ -21,9 +21,9 @@ namespace osu.Game.Rulesets.Edit.Checks
|
|||||||
new IssueTemplateDoesNotExist(this)
|
new IssueTemplateDoesNotExist(this)
|
||||||
};
|
};
|
||||||
|
|
||||||
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap)
|
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
|
||||||
{
|
{
|
||||||
var filename = GetFilename(playableBeatmap);
|
var filename = GetFilename(context.Beatmap);
|
||||||
|
|
||||||
if (filename == null)
|
if (filename == null)
|
||||||
{
|
{
|
||||||
@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Edit.Checks
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the file is set, also make sure it still exists.
|
// If the file is set, also make sure it still exists.
|
||||||
var storagePath = playableBeatmap.BeatmapInfo.BeatmapSet.GetPathForFile(filename);
|
var storagePath = context.Beatmap.BeatmapInfo.BeatmapSet.GetPathForFile(filename);
|
||||||
if (storagePath != null)
|
if (storagePath != null)
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Edit.Checks.Components;
|
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
@ -22,11 +21,11 @@ namespace osu.Game.Rulesets.Edit.Checks
|
|||||||
new IssueTemplateSmallUnsnap(this)
|
new IssueTemplateSmallUnsnap(this)
|
||||||
};
|
};
|
||||||
|
|
||||||
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap)
|
public IEnumerable<Issue> Run(BeatmapVerifierContext context)
|
||||||
{
|
{
|
||||||
var controlPointInfo = playableBeatmap.ControlPointInfo;
|
var controlPointInfo = context.Beatmap.ControlPointInfo;
|
||||||
|
|
||||||
foreach (var hitobject in playableBeatmap.HitObjects)
|
foreach (var hitobject in context.Beatmap.HitObjects)
|
||||||
{
|
{
|
||||||
double startUnsnap = hitobject.StartTime - controlPointInfo.GetClosestSnappedTime(hitobject.StartTime);
|
double startUnsnap = hitobject.StartTime - controlPointInfo.GetClosestSnappedTime(hitobject.StartTime);
|
||||||
string startPostfix = hitobject is IHasDuration ? "start" : "";
|
string startPostfix = hitobject is IHasDuration ? "start" : "";
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Edit.Checks.Components
|
namespace osu.Game.Rulesets.Edit.Checks.Components
|
||||||
{
|
{
|
||||||
@ -24,8 +23,7 @@ namespace osu.Game.Rulesets.Edit.Checks.Components
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Runs this check and returns any issues detected for the provided beatmap.
|
/// Runs this check and returns any issues detected for the provided beatmap.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="playableBeatmap">The playable beatmap of the beatmap to run the check on.</param>
|
/// <param name="context">The beatmap verifier context associated with the beatmap.</param>
|
||||||
/// <param name="workingBeatmap">The working beatmap of the beatmap to run the check on.</param>
|
public IEnumerable<Issue> Run(BeatmapVerifierContext context);
|
||||||
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, IWorkingBeatmap workingBeatmap);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Edit.Checks.Components;
|
using osu.Game.Rulesets.Edit.Checks.Components;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Edit
|
namespace osu.Game.Rulesets.Edit
|
||||||
@ -12,6 +11,6 @@ namespace osu.Game.Rulesets.Edit
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IBeatmapVerifier
|
public interface IBeatmapVerifier
|
||||||
{
|
{
|
||||||
public IEnumerable<Issue> Run(IBeatmap playableBeatmap, WorkingBeatmap workingBeatmap);
|
public IEnumerable<Issue> Run(BeatmapVerifierContext context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ namespace osu.Game.Screens.Edit.Verify
|
|||||||
|
|
||||||
private IBeatmapVerifier rulesetVerifier;
|
private IBeatmapVerifier rulesetVerifier;
|
||||||
private BeatmapVerifier generalVerifier;
|
private BeatmapVerifier generalVerifier;
|
||||||
|
private BeatmapVerifierContext context;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OverlayColourProvider colours)
|
private void load(OverlayColourProvider colours)
|
||||||
@ -44,6 +45,9 @@ namespace osu.Game.Screens.Edit.Verify
|
|||||||
generalVerifier = new BeatmapVerifier();
|
generalVerifier = new BeatmapVerifier();
|
||||||
rulesetVerifier = beatmap.BeatmapInfo.Ruleset?.CreateInstance()?.CreateBeatmapVerifier();
|
rulesetVerifier = beatmap.BeatmapInfo.Ruleset?.CreateInstance()?.CreateBeatmapVerifier();
|
||||||
|
|
||||||
|
context = new BeatmapVerifierContext(beatmap, workingBeatmap.Value, verify.InterpretedDifficulty.Value);
|
||||||
|
verify.InterpretedDifficulty.BindValueChanged(difficulty => context.InterpretedDifficulty = difficulty.NewValue);
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.Both;
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
@ -91,10 +95,10 @@ namespace osu.Game.Screens.Edit.Verify
|
|||||||
|
|
||||||
private void refresh()
|
private void refresh()
|
||||||
{
|
{
|
||||||
var issues = generalVerifier.Run(beatmap, workingBeatmap.Value);
|
var issues = generalVerifier.Run(context);
|
||||||
|
|
||||||
if (rulesetVerifier != null)
|
if (rulesetVerifier != null)
|
||||||
issues = issues.Concat(rulesetVerifier.Run(beatmap, workingBeatmap.Value));
|
issues = issues.Concat(rulesetVerifier.Run(context));
|
||||||
|
|
||||||
issues = filter(issues);
|
issues = filter(issues);
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -14,6 +15,7 @@ using osu.Game.Graphics.Sprites;
|
|||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Screens.Play.HUD;
|
using osu.Game.Screens.Play.HUD;
|
||||||
|
using osu.Game.Screens.Ranking.Expanded;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play
|
namespace osu.Game.Screens.Play
|
||||||
@ -25,7 +27,7 @@ namespace osu.Game.Screens.Play
|
|||||||
{
|
{
|
||||||
private readonly WorkingBeatmap beatmap;
|
private readonly WorkingBeatmap beatmap;
|
||||||
private readonly Bindable<IReadOnlyList<Mod>> mods;
|
private readonly Bindable<IReadOnlyList<Mod>> mods;
|
||||||
private readonly Drawable facade;
|
private readonly Drawable logoFacade;
|
||||||
private LoadingSpinner loading;
|
private LoadingSpinner loading;
|
||||||
|
|
||||||
public IBindable<IReadOnlyList<Mod>> Mods => mods;
|
public IBindable<IReadOnlyList<Mod>> Mods => mods;
|
||||||
@ -41,19 +43,24 @@ namespace osu.Game.Screens.Play
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public BeatmapMetadataDisplay(WorkingBeatmap beatmap, Bindable<IReadOnlyList<Mod>> mods, Drawable facade)
|
public BeatmapMetadataDisplay(WorkingBeatmap beatmap, Bindable<IReadOnlyList<Mod>> mods, Drawable logoFacade)
|
||||||
{
|
{
|
||||||
this.beatmap = beatmap;
|
this.beatmap = beatmap;
|
||||||
this.facade = facade;
|
this.logoFacade = logoFacade;
|
||||||
|
|
||||||
this.mods = new Bindable<IReadOnlyList<Mod>>();
|
this.mods = new Bindable<IReadOnlyList<Mod>>();
|
||||||
this.mods.BindTo(mods);
|
this.mods.BindTo(mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IBindable<StarDifficulty?> starDifficulty;
|
||||||
|
|
||||||
|
private FillFlowContainer versionFlow;
|
||||||
|
private StarRatingDisplay starRatingDisplay;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load(BeatmapDifficultyCache difficultyCache)
|
||||||
{
|
{
|
||||||
var metadata = beatmap.BeatmapInfo?.Metadata ?? new BeatmapMetadata();
|
var metadata = beatmap.BeatmapInfo.Metadata;
|
||||||
|
|
||||||
AutoSizeAxes = Axes.Both;
|
AutoSizeAxes = Axes.Both;
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
@ -66,7 +73,7 @@ namespace osu.Game.Screens.Play
|
|||||||
Direction = FillDirection.Vertical,
|
Direction = FillDirection.Vertical,
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
facade.With(d =>
|
logoFacade.With(d =>
|
||||||
{
|
{
|
||||||
d.Anchor = Anchor.TopCentre;
|
d.Anchor = Anchor.TopCentre;
|
||||||
d.Origin = Anchor.TopCentre;
|
d.Origin = Anchor.TopCentre;
|
||||||
@ -107,16 +114,30 @@ namespace osu.Game.Screens.Play
|
|||||||
loading = new LoadingLayer(true)
|
loading = new LoadingLayer(true)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
versionFlow = new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
Direction = FillDirection.Vertical,
|
||||||
|
Spacing = new Vector2(5f),
|
||||||
|
Margin = new MarginPadding { Bottom = 40 },
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = beatmap?.BeatmapInfo?.Version,
|
Text = beatmap?.BeatmapInfo?.Version,
|
||||||
Font = OsuFont.GetFont(size: 26, italics: true),
|
Font = OsuFont.GetFont(size: 26, italics: true),
|
||||||
Origin = Anchor.TopCentre,
|
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Margin = new MarginPadding
|
Origin = Anchor.TopCentre,
|
||||||
{
|
|
||||||
Bottom = 40
|
|
||||||
},
|
},
|
||||||
|
starRatingDisplay = new StarRatingDisplay(default)
|
||||||
|
{
|
||||||
|
Alpha = 0f,
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
new GridContainer
|
new GridContainer
|
||||||
{
|
{
|
||||||
@ -159,9 +180,38 @@ namespace osu.Game.Screens.Play
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
starDifficulty = difficultyCache.GetBindableDifficulty(beatmap.BeatmapInfo);
|
||||||
|
|
||||||
Loading = true;
|
Loading = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
if (starDifficulty.Value != null)
|
||||||
|
{
|
||||||
|
starRatingDisplay.Current.Value = starDifficulty.Value.Value;
|
||||||
|
starRatingDisplay.Show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
starRatingDisplay.Hide();
|
||||||
|
|
||||||
|
starDifficulty.ValueChanged += d =>
|
||||||
|
{
|
||||||
|
Debug.Assert(d.NewValue != null);
|
||||||
|
|
||||||
|
starRatingDisplay.Current.Value = d.NewValue.Value;
|
||||||
|
|
||||||
|
versionFlow.AutoSizeDuration = 300;
|
||||||
|
versionFlow.AutoSizeEasing = Easing.OutQuint;
|
||||||
|
|
||||||
|
starRatingDisplay.FadeIn(300, Easing.InQuint);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class MetadataLineLabel : OsuSpriteText
|
private class MetadataLineLabel : OsuSpriteText
|
||||||
{
|
{
|
||||||
public MetadataLineLabel(string text)
|
public MetadataLineLabel(string text)
|
||||||
|
@ -3,12 +3,14 @@
|
|||||||
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Colour;
|
using osu.Framework.Graphics.Colour;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
@ -20,9 +22,21 @@ namespace osu.Game.Screens.Ranking.Expanded
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A pill that displays the star rating of a <see cref="BeatmapInfo"/>.
|
/// A pill that displays the star rating of a <see cref="BeatmapInfo"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class StarRatingDisplay : CompositeDrawable
|
public class StarRatingDisplay : CompositeDrawable, IHasCurrentValue<StarDifficulty>
|
||||||
{
|
{
|
||||||
private readonly StarDifficulty difficulty;
|
private Box background;
|
||||||
|
private OsuTextFlowContainer textFlow;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private OsuColour colours { get; set; }
|
||||||
|
|
||||||
|
private readonly BindableWithCurrent<StarDifficulty> current = new BindableWithCurrent<StarDifficulty>();
|
||||||
|
|
||||||
|
public Bindable<StarDifficulty> Current
|
||||||
|
{
|
||||||
|
get => current.Current;
|
||||||
|
set => current.Current = value;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="StarRatingDisplay"/> using an already computed <see cref="StarDifficulty"/>.
|
/// Creates a new <see cref="StarRatingDisplay"/> using an already computed <see cref="StarDifficulty"/>.
|
||||||
@ -30,7 +44,7 @@ namespace osu.Game.Screens.Ranking.Expanded
|
|||||||
/// <param name="starDifficulty">The already computed <see cref="StarDifficulty"/> to display the star difficulty of.</param>
|
/// <param name="starDifficulty">The already computed <see cref="StarDifficulty"/> to display the star difficulty of.</param>
|
||||||
public StarRatingDisplay(StarDifficulty starDifficulty)
|
public StarRatingDisplay(StarDifficulty starDifficulty)
|
||||||
{
|
{
|
||||||
difficulty = starDifficulty;
|
Current.Value = starDifficulty;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -38,15 +52,6 @@ namespace osu.Game.Screens.Ranking.Expanded
|
|||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both;
|
AutoSizeAxes = Axes.Both;
|
||||||
|
|
||||||
var starRatingParts = difficulty.Stars.ToString("0.00", CultureInfo.InvariantCulture).Split('.');
|
|
||||||
string wholePart = starRatingParts[0];
|
|
||||||
string fractionPart = starRatingParts[1];
|
|
||||||
string separator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
|
|
||||||
|
|
||||||
ColourInfo backgroundColour = difficulty.DifficultyRating == DifficultyRating.ExpertPlus
|
|
||||||
? ColourInfo.GradientVertical(Color4Extensions.FromHex("#C1C1C1"), Color4Extensions.FromHex("#595959"))
|
|
||||||
: (ColourInfo)colours.ForDifficultyRating(difficulty.DifficultyRating);
|
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
new CircularContainer
|
new CircularContainer
|
||||||
@ -55,10 +60,9 @@ namespace osu.Game.Screens.Ranking.Expanded
|
|||||||
Masking = true,
|
Masking = true,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new Box
|
background = new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = backgroundColour
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -78,32 +82,54 @@ namespace osu.Game.Screens.Ranking.Expanded
|
|||||||
Icon = FontAwesome.Solid.Star,
|
Icon = FontAwesome.Solid.Star,
|
||||||
Colour = Color4.Black
|
Colour = Color4.Black
|
||||||
},
|
},
|
||||||
new OsuTextFlowContainer(s => s.Font = OsuFont.Numeric.With(weight: FontWeight.Black))
|
textFlow = new OsuTextFlowContainer(s => s.Font = OsuFont.Numeric.With(weight: FontWeight.Black))
|
||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
Direction = FillDirection.Horizontal,
|
Direction = FillDirection.Horizontal,
|
||||||
TextAnchor = Anchor.BottomLeft,
|
TextAnchor = Anchor.BottomLeft,
|
||||||
}.With(t =>
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
t.AddText($"{wholePart}", s =>
|
base.LoadComplete();
|
||||||
|
|
||||||
|
Current.BindValueChanged(_ => updateDisplay(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDisplay()
|
||||||
|
{
|
||||||
|
var starRatingParts = Current.Value.Stars.ToString("0.00", CultureInfo.InvariantCulture).Split('.');
|
||||||
|
string wholePart = starRatingParts[0];
|
||||||
|
string fractionPart = starRatingParts[1];
|
||||||
|
string separator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
|
||||||
|
|
||||||
|
var rating = Current.Value.DifficultyRating;
|
||||||
|
|
||||||
|
background.Colour = rating == DifficultyRating.ExpertPlus
|
||||||
|
? ColourInfo.GradientVertical(Color4Extensions.FromHex("#C1C1C1"), Color4Extensions.FromHex("#595959"))
|
||||||
|
: (ColourInfo)colours.ForDifficultyRating(rating);
|
||||||
|
|
||||||
|
textFlow.Clear();
|
||||||
|
|
||||||
|
textFlow.AddText($"{wholePart}", s =>
|
||||||
{
|
{
|
||||||
s.Colour = Color4.Black;
|
s.Colour = Color4.Black;
|
||||||
s.Font = s.Font.With(size: 14);
|
s.Font = s.Font.With(size: 14);
|
||||||
s.UseFullGlyphHeight = false;
|
s.UseFullGlyphHeight = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
t.AddText($"{separator}{fractionPart}", s =>
|
textFlow.AddText($"{separator}{fractionPart}", s =>
|
||||||
{
|
{
|
||||||
s.Colour = Color4.Black;
|
s.Colour = Color4.Black;
|
||||||
s.Font = s.Font.With(size: 7);
|
s.Font = s.Font.With(size: 7);
|
||||||
s.UseFullGlyphHeight = false;
|
s.UseFullGlyphHeight = false;
|
||||||
});
|
});
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user