From 22a0f99f35496d22b5b610626b057c36d1bea82d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 12 Jan 2021 17:49:18 +0900 Subject: [PATCH 01/10] Add failing test --- .../TaikoBeatmapConversionTest.cs | 1 + ...rating-drumroll-2-expected-conversion.json | 18 ++++++++++++++++++ .../Beatmaps/slider-generating-drumroll-2.osu | 19 +++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-2-expected-conversion.json create mode 100644 osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-2.osu diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs index 3d77fb05db..b6db333dc9 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs @@ -23,6 +23,7 @@ namespace osu.Game.Rulesets.Taiko.Tests [TestCase("sample-to-type-conversions")] [TestCase("slider-conversion-v6")] [TestCase("slider-conversion-v14")] + [TestCase("slider-generating-drumroll-2")] public void Test(string name) => base.Test(name); protected override IEnumerable CreateConvertValue(HitObject hitObject) diff --git a/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-2-expected-conversion.json b/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-2-expected-conversion.json new file mode 100644 index 0000000000..b4ee98c86a --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-2-expected-conversion.json @@ -0,0 +1,18 @@ +{ + "Mappings": [ + { + "StartTime": 51532, + "Objects": [ + { + "StartTime": 51532, + "EndTime": 52301, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + } + ] + } + ] +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-2.osu b/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-2.osu new file mode 100644 index 0000000000..d81b09ee26 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-2.osu @@ -0,0 +1,19 @@ +osu file format v14 + +[General] +Mode: 0 + +[Difficulty] +HPDrainRate:2 +CircleSize:3.2 +OverallDifficulty:2 +ApproachRate:3 +SliderMultiplier:0.999999999999999 +SliderTickRate:1 + +[TimingPoints] +763,384.615384615385,4,2,0,70,1,0 +49993,-90.9090909090909,4,2,0,75,0,1 + +[HitObjects] +51,245,51532,2,0,P|18:150|17:122,2,110.000003356934,0|8|0,0:0|0:0|0:0,0:0:0:0: From 9a22df2b88029de3f22b51938ad6b163322d95ec Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 12 Jan 2021 17:50:22 +0900 Subject: [PATCH 02/10] Fix BPM multiplier not working in all cases --- .../Beatmaps/TaikoBeatmapConverter.cs | 6 +- ...er-conversion-v14-expected-conversion.json | 307 +----------------- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 5 +- 3 files changed, 18 insertions(+), 300 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index 1214c594aa..b51f096d7d 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -160,7 +160,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps } } - private bool shouldConvertSliderToHits(HitObject obj, IBeatmap beatmap, IHasDistance distanceData, out double taikoDuration, out double tickSpacing) + private bool shouldConvertSliderToHits(HitObject obj, IBeatmap beatmap, IHasDistance distanceData, out int taikoDuration, out double tickSpacing) { // DO NOT CHANGE OR REFACTOR ANYTHING IN HERE WITHOUT TESTING AGAINST _ALL_ BEATMAPS. // Some of these calculations look redundant, but they are not - extremely small floating point errors are introduced to maintain 1:1 compatibility with stable. @@ -185,7 +185,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps // The velocity and duration of the taiko hit object - calculated as the velocity of a drum roll. double taikoVelocity = sliderScoringPointDistance * beatmap.BeatmapInfo.BaseDifficulty.SliderTickRate; - taikoDuration = distance / taikoVelocity * beatLength; + taikoDuration = (int)(distance / taikoVelocity * beatLength); if (isForCurrentRuleset) { @@ -200,7 +200,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps beatLength = timingPoint.BeatLength; // If the drum roll is to be split into hit circles, assume the ticks are 1/8 spaced within the duration of one beat - tickSpacing = Math.Min(beatLength / beatmap.BeatmapInfo.BaseDifficulty.SliderTickRate, taikoDuration / spans); + tickSpacing = Math.Min(beatLength / beatmap.BeatmapInfo.BaseDifficulty.SliderTickRate, (double)taikoDuration / spans); return tickSpacing > 0 && distance / osuVelocity * 1000 < 2 * beatLength; diff --git a/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-conversion-v14-expected-conversion.json b/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-conversion-v14-expected-conversion.json index 6a6063cb74..b7ad128cab 100644 --- a/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-conversion-v14-expected-conversion.json +++ b/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-conversion-v14-expected-conversion.json @@ -1,7 +1,9 @@ { - "Mappings": [{ + "Mappings": [ + { "StartTime": 2000, - "Objects": [{ + "Objects": [ + { "StartTime": 2000, "EndTime": 2000, "IsRim": false, @@ -23,7 +25,8 @@ }, { "StartTime": 4000, - "Objects": [{ + "Objects": [ + { "StartTime": 4000, "EndTime": 4000, "IsRim": false, @@ -45,7 +48,8 @@ }, { "StartTime": 6000, - "Objects": [{ + "Objects": [ + { "StartTime": 6000, "EndTime": 6000, "IsRim": true, @@ -76,300 +80,13 @@ }, { "StartTime": 8000, - "Objects": [{ + "Objects": [ + { "StartTime": 8000, - "EndTime": 8000, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8026, - "EndTime": 8026, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8053, - "EndTime": 8053, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8080, - "EndTime": 8080, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8107, - "EndTime": 8107, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8133, - "EndTime": 8133, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8160, - "EndTime": 8160, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8187, - "EndTime": 8187, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8214, - "EndTime": 8214, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8241, - "EndTime": 8241, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8267, - "EndTime": 8267, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8294, - "EndTime": 8294, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8321, - "EndTime": 8321, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8348, - "EndTime": 8348, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8374, - "EndTime": 8374, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8401, - "EndTime": 8401, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8428, - "EndTime": 8428, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8455, - "EndTime": 8455, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8482, - "EndTime": 8482, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8508, - "EndTime": 8508, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8535, - "EndTime": 8535, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8562, - "EndTime": 8562, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8589, - "EndTime": 8589, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8615, - "EndTime": 8615, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8642, - "EndTime": 8642, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8669, - "EndTime": 8669, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8696, - "EndTime": 8696, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8723, - "EndTime": 8723, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8749, - "EndTime": 8749, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8776, - "EndTime": 8776, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8803, - "EndTime": 8803, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8830, - "EndTime": 8830, - "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, - "IsSwell": false, - "IsStrong": false - }, - { - "StartTime": 8857, "EndTime": 8857, "IsRim": false, - "IsCentre": true, - "IsDrumRoll": false, + "IsCentre": false, + "IsDrumRoll": true, "IsSwell": false, "IsStrong": false } diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index 069a25b83d..2fb24c24e0 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -164,12 +164,13 @@ namespace osu.Game.Beatmaps.Formats /// Legacy BPM multiplier that introduces floating-point errors for rulesets that depend on it. /// DO NOT USE THIS UNLESS 100% SURE. /// - public float BpmMultiplier { get; private set; } + public double BpmMultiplier { get; private set; } public LegacyDifficultyControlPoint(double beatLength) : this() { - BpmMultiplier = beatLength < 0 ? Math.Clamp((float)-beatLength, 10, 10000) / 100f : 1; + // Note: In stable, the division occurs on floats, but with compiler optimisations turned on actually seems to occur on doubles via some .NET black magic (possibly inlining?). + BpmMultiplier = beatLength < 0 ? Math.Clamp((float)-beatLength, 10, 10000) / 100.0 : 1; } public LegacyDifficultyControlPoint() From 2d3cacca11bc1d8de6c78cf8b6f1154f1e058050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 13 Jan 2021 00:58:53 +0100 Subject: [PATCH 03/10] Fix non-hosts crashing on load requested `onLoadRequested()` always released the `readyClickOperation` ongoing operation, without checking whether it actually needs to/should (it should only do so if the action initiating the operation was starting the game by the host). This would crash all other consumers, who already released the operation when their ready-up operation completed server side. To resolve, relax the constraint such that the operation can be ended multiple times in any order. At the end of the day the thing that matters is that the operation is done and the ready button is unblocked. --- .../OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs index e539b315e4..80991569dc 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerMatchSubScreen.cs @@ -241,8 +241,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer void endOperation() { - Debug.Assert(readyClickOperation != null); - readyClickOperation.Dispose(); + readyClickOperation?.Dispose(); readyClickOperation = null; } } @@ -255,9 +254,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer StartPlay(() => new MultiplayerPlayer(SelectedItem.Value, userIds)); - Debug.Assert(readyClickOperation != null); - - readyClickOperation.Dispose(); + readyClickOperation?.Dispose(); readyClickOperation = null; } From e8daea91d22e87e95d2deaf8caf70817c6277ebc Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 12 Jan 2021 18:13:05 +0300 Subject: [PATCH 04/10] Add online beatmap "explicit content" property --- osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs | 5 +++++ osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs index 06dee4d3f5..48f1f0ce68 100644 --- a/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetOnlineInfo.cs @@ -31,6 +31,11 @@ namespace osu.Game.Beatmaps /// public BeatmapSetOnlineStatus Status { get; set; } + /// + /// Whether or not this beatmap set has explicit content. + /// + public bool HasExplicitContent { get; set; } + /// /// Whether or not this beatmap set has a background video. /// diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 720d6bfff4..bd1800e9f7 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -42,6 +42,9 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"bpm")] private double bpm { get; set; } + [JsonProperty(@"nsfw")] + private bool hasExplicitContent { get; set; } + [JsonProperty(@"video")] private bool hasVideo { get; set; } @@ -94,6 +97,7 @@ namespace osu.Game.Online.API.Requests.Responses FavouriteCount = favouriteCount, BPM = bpm, Status = Status, + HasExplicitContent = hasExplicitContent, HasVideo = hasVideo, HasStoryboard = hasStoryboard, Submitted = submitted, From ee6baeb57e0d51e8d65a3c8c70e25701cc58ada8 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Tue, 12 Jan 2021 18:15:00 +0300 Subject: [PATCH 05/10] Add "explicit" marker pill --- .../BeatmapSet/ExplicitBeatmapPill.cs | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs diff --git a/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs b/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs new file mode 100644 index 0000000000..77528c65c3 --- /dev/null +++ b/osu.Game/Overlays/BeatmapSet/ExplicitBeatmapPill.cs @@ -0,0 +1,49 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Overlays.BeatmapSet +{ + public class ExplicitBeatmapPill : CompositeDrawable + { + public ExplicitBeatmapPill() + { + AutoSizeAxes = Axes.Both; + } + + [BackgroundDependencyLoader(true)] + private void load(OsuColour colours, OverlayColourProvider colourProvider) + { + InternalChild = new CircularContainer + { + Masking = true, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colourProvider?.Background5 ?? colours.Gray2, + }, + new OsuSpriteText + { + Margin = new MarginPadding { Horizontal = 10f, Vertical = 2f }, + Text = "EXPLICIT", + Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold), + // todo: this is --hsl-orange-2 from the new palette in https://github.com/ppy/osu-web/blob/8ceb46f/resources/assets/less/colors.less#L128-L151, + // should probably take the whole palette from there onto OsuColour for a nicer look in code. + Colour = Color4.FromHsl(new Vector4(45f / 360, 0.8f, 0.6f, 1f)), + } + } + }; + } + } +} From f6637eec36a460c5551e81d5b8776c12fad0caa9 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 13 Jan 2021 11:29:30 +0300 Subject: [PATCH 06/10] Add explicit pill to beatmap panels --- .../BeatmapListing/Panels/GridBeatmapPanel.cs | 29 +++++++++++++++---- .../BeatmapListing/Panels/ListBeatmapPanel.cs | 27 ++++++++++++++--- 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/BeatmapListing/Panels/GridBeatmapPanel.cs b/osu.Game/Overlays/BeatmapListing/Panels/GridBeatmapPanel.cs index 28c36e6c56..b7002a96e5 100644 --- a/osu.Game/Overlays/BeatmapListing/Panels/GridBeatmapPanel.cs +++ b/osu.Game/Overlays/BeatmapListing/Panels/GridBeatmapPanel.cs @@ -14,6 +14,7 @@ using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Overlays.BeatmapSet; using osuTK; using osuTK.Graphics; @@ -24,7 +25,7 @@ namespace osu.Game.Overlays.BeatmapListing.Panels private const float horizontal_padding = 10; private const float vertical_padding = 5; - private FillFlowContainer bottomPanel, statusContainer; + private FillFlowContainer bottomPanel, statusContainer, titleContainer; private PlayButton playButton; private Box progressBar; @@ -73,12 +74,20 @@ namespace osu.Game.Overlays.BeatmapListing.Panels AutoSizeAxes = Axes.Both, Padding = new MarginPadding { Left = horizontal_padding, Right = horizontal_padding }, Direction = FillDirection.Vertical, - Children = new[] + Children = new Drawable[] { - new OsuSpriteText + titleContainer = new FillFlowContainer { - Text = new LocalisedString((SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title)), - Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true) + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + new OsuSpriteText + { + Text = new LocalisedString((SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title)), + Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true) + }, + } }, new OsuSpriteText { @@ -194,6 +203,16 @@ namespace osu.Game.Overlays.BeatmapListing.Panels }, }); + if (SetInfo.OnlineInfo?.HasExplicitContent ?? false) + { + titleContainer.Add(new ExplicitBeatmapPill + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 10f, Top = 2f }, + }); + } + if (SetInfo.OnlineInfo?.HasVideo ?? false) { statusContainer.Add(new IconPill(FontAwesome.Solid.Film)); diff --git a/osu.Game/Overlays/BeatmapListing/Panels/ListBeatmapPanel.cs b/osu.Game/Overlays/BeatmapListing/Panels/ListBeatmapPanel.cs index 433ea37f06..69671ab75b 100644 --- a/osu.Game/Overlays/BeatmapListing/Panels/ListBeatmapPanel.cs +++ b/osu.Game/Overlays/BeatmapListing/Panels/ListBeatmapPanel.cs @@ -14,6 +14,7 @@ using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Overlays.BeatmapSet; using osuTK; using osuTK.Graphics; @@ -26,7 +27,7 @@ namespace osu.Game.Overlays.BeatmapListing.Panels private const float vertical_padding = 5; private const float height = 70; - private FillFlowContainer statusContainer; + private FillFlowContainer statusContainer, titleContainer; protected BeatmapPanelDownloadButton DownloadButton; private PlayButton playButton; private Box progressBar; @@ -98,10 +99,18 @@ namespace osu.Game.Overlays.BeatmapListing.Panels Direction = FillDirection.Vertical, Children = new Drawable[] { - new OsuSpriteText + titleContainer = new FillFlowContainer { - Text = new LocalisedString((SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title)), - Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true) + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new[] + { + new OsuSpriteText + { + Text = new LocalisedString((SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title)), + Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true) + }, + } }, new OsuSpriteText { @@ -208,6 +217,16 @@ namespace osu.Game.Overlays.BeatmapListing.Panels }, }); + if (SetInfo.OnlineInfo?.HasExplicitContent ?? false) + { + titleContainer.Add(new ExplicitBeatmapPill + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 10f, Top = 2f }, + }); + } + if (SetInfo.OnlineInfo?.HasVideo ?? false) { statusContainer.Add(new IconPill(FontAwesome.Solid.Film) { IconSize = new Vector2(20) }); From 78631323ba35174543cbb09d2c8fd4f545888077 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 13 Jan 2021 11:32:36 +0300 Subject: [PATCH 07/10] Add explicit pill to beatmap overlay --- osu.Game/Overlays/BeatmapSet/Header.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 321e496511..fbdee91d42 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -34,6 +34,7 @@ namespace osu.Game.Overlays.BeatmapSet private readonly Box coverGradient; private readonly OsuSpriteText title, artist; private readonly AuthorInfo author; + private readonly ExplicitBeatmapPill explicitPill; private readonly FillFlowContainer downloadButtonsContainer; private readonly BeatmapAvailability beatmapAvailability; private readonly BeatmapSetOnlineStatusPill onlineStatusPill; @@ -146,6 +147,13 @@ namespace osu.Game.Overlays.BeatmapSet Origin = Anchor.BottomLeft, Margin = new MarginPadding { Left = 3, Bottom = 4 }, // To better lineup with the font }, + explicitPill = new ExplicitBeatmapPill + { + Alpha = 0f, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Left = 10f, Top = 4 }, + } } }, artist = new OsuSpriteText @@ -253,6 +261,8 @@ namespace osu.Game.Overlays.BeatmapSet title.Text = setInfo.NewValue.Metadata.Title ?? string.Empty; artist.Text = setInfo.NewValue.Metadata.Artist ?? string.Empty; + explicitPill.Alpha = setInfo.NewValue.OnlineInfo.HasExplicitContent ? 1 : 0; + onlineStatusPill.FadeIn(500, Easing.OutQuint); onlineStatusPill.Status = setInfo.NewValue.OnlineInfo.Status; From 1502b07ea86d7673dbbffa2fc2ec83612ca8d81c Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 13 Jan 2021 11:33:00 +0300 Subject: [PATCH 08/10] Add explicit pill to playlist items --- .../OnlinePlay/DrawableRoomPlaylistItem.cs | 36 +++++++++++++++---- 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs index e3bce4029f..7987d715e3 100644 --- a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs +++ b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs @@ -23,6 +23,7 @@ using osu.Game.Online; using osu.Game.Online.Chat; using osu.Game.Online.Rooms; using osu.Game.Overlays.BeatmapListing.Panels; +using osu.Game.Overlays.BeatmapSet; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play.HUD; @@ -41,6 +42,7 @@ namespace osu.Game.Screens.OnlinePlay private Container difficultyIconContainer; private LinkFlowContainer beatmapText; private LinkFlowContainer authorText; + private ExplicitBeatmapPill explicitPill; private ModDisplay modDisplay; private readonly Bindable beatmap = new Bindable(); @@ -116,6 +118,9 @@ namespace osu.Game.Screens.OnlinePlay authorText.AddUserLink(Item.Beatmap.Value?.Metadata.Author); } + bool hasExplicitContent = Item.Beatmap.Value.BeatmapSet.OnlineInfo?.HasExplicitContent == true; + explicitPill.Alpha = hasExplicitContent ? 1 : 0; + modDisplay.Current.Value = requiredMods.ToArray(); } @@ -165,18 +170,37 @@ namespace osu.Game.Screens.OnlinePlay { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, - Spacing = new Vector2(15, 0), + Spacing = new Vector2(10f, 0), Children = new Drawable[] { - authorText = new LinkFlowContainer { AutoSizeAxes = Axes.Both }, - modDisplay = new ModDisplay + new FillFlowContainer + { + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10f, 0), + Children = new Drawable[] + { + authorText = new LinkFlowContainer { AutoSizeAxes = Axes.Both }, + explicitPill = new ExplicitBeatmapPill + { + Alpha = 0f, + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Margin = new MarginPadding { Top = 3f }, + } + }, + }, + new Container { Anchor = Anchor.CentreLeft, Origin = Anchor.CentreLeft, AutoSizeAxes = Axes.Both, - Scale = new Vector2(0.4f), - DisplayUnrankedText = false, - ExpansionMode = ExpansionMode.AlwaysExpanded + Child = modDisplay = new ModDisplay + { + Scale = new Vector2(0.4f), + DisplayUnrankedText = false, + ExpansionMode = ExpansionMode.AlwaysExpanded + } } } } From 7fd55efc434fb5522de44429cc27e27c32cd6969 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 13 Jan 2021 11:57:29 +0300 Subject: [PATCH 09/10] Add test cases for displaying explicit beatmaps --- .../Multiplayer/TestSceneDrawableRoomPlaylist.cs | 9 +++++++++ .../Visual/Online/TestSceneBeatmapSetOverlay.cs | 11 +++++++++++ osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs | 7 ++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs index 65c0cfd328..17d85d1120 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneDrawableRoomPlaylist.cs @@ -222,6 +222,15 @@ namespace osu.Game.Tests.Visual.Multiplayer AddAssert("download buttons shown", () => playlist.ChildrenOfType().All(d => d.IsPresent)); } + [Test] + public void TestExplicitBeatmapItem() + { + var beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo; + beatmap.BeatmapSet.OnlineInfo.HasExplicitContent = true; + + createPlaylist(beatmap); + } + private void moveToItem(int index, Vector2? offset = null) => AddStep($"move mouse to item {index}", () => InputManager.MoveMouseTo(playlist.ChildrenOfType>().ElementAt(index), offset)); diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs index c5d1fd6887..689321698a 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapSetOverlay.cs @@ -235,6 +235,17 @@ namespace osu.Game.Tests.Visual.Online AddAssert("left-most beatmap selected", () => overlay.Header.Picker.Difficulties.First().State == BeatmapPicker.DifficultySelectorState.Selected); } + [Test] + public void TestExplicitBeatmap() + { + AddStep("show explicit map", () => + { + var beatmapSet = CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet; + beatmapSet.OnlineInfo.HasExplicitContent = true; + overlay.ShowBeatmapSet(beatmapSet); + }); + } + [Test] public void TestHide() { diff --git a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs index 74ece5da05..fd5f306e07 100644 --- a/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs +++ b/osu.Game.Tests/Visual/Online/TestSceneDirectPanel.cs @@ -99,13 +99,16 @@ namespace osu.Game.Tests.Visual.Online [BackgroundDependencyLoader] private void load(RulesetStore rulesets) { - var normal = CreateWorkingBeatmap(Ruleset.Value).BeatmapSetInfo; + var normal = CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet; normal.OnlineInfo.HasVideo = true; normal.OnlineInfo.HasStoryboard = true; var undownloadable = getUndownloadableBeatmapSet(); var manyDifficulties = getManyDifficultiesBeatmapSet(rulesets); + var explicitMap = CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet; + explicitMap.OnlineInfo.HasExplicitContent = true; + Child = new BasicScrollContainer { RelativeSizeAxes = Axes.Both, @@ -121,9 +124,11 @@ namespace osu.Game.Tests.Visual.Online new GridBeatmapPanel(normal), new GridBeatmapPanel(undownloadable), new GridBeatmapPanel(manyDifficulties), + new GridBeatmapPanel(explicitMap), new ListBeatmapPanel(normal), new ListBeatmapPanel(undownloadable), new ListBeatmapPanel(manyDifficulties), + new ListBeatmapPanel(explicitMap) }, }, }; From f827c620813468f2c670f393c424b84e8b11f634 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Wed, 13 Jan 2021 11:58:55 +0300 Subject: [PATCH 10/10] Add empty online info to test beatmap This is for `BeatmapSetOverlay` to not eat a null reference trying to access `Beatmap.OnlineInfo`. --- osu.Game/Tests/Beatmaps/TestBeatmap.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Tests/Beatmaps/TestBeatmap.cs b/osu.Game/Tests/Beatmaps/TestBeatmap.cs index 035cb64099..fa6dc5647d 100644 --- a/osu.Game/Tests/Beatmaps/TestBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestBeatmap.cs @@ -32,6 +32,7 @@ namespace osu.Game.Tests.Beatmaps BeatmapInfo.BeatmapSet.Files = new List(); BeatmapInfo.BeatmapSet.Beatmaps = new List { BeatmapInfo }; BeatmapInfo.Length = 75000; + BeatmapInfo.OnlineInfo = new BeatmapOnlineInfo(); BeatmapInfo.BeatmapSet.OnlineInfo = new BeatmapSetOnlineInfo { Status = BeatmapSetOnlineStatus.Ranked,