From 94877117b9868e00ec8c95c9b482d92a25f7bc35 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Tue, 27 Jul 2021 18:22:47 +0200 Subject: [PATCH 01/16] Apply changes in-line with framework changes. --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 4 +++- osu.Game/Overlays/Rankings/Tables/RankingsTable.cs | 3 ++- osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs | 5 +++-- osu.Game/Screens/Edit/EditorTable.cs | 4 +++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index ddd1dfa6cd..22033f14cd 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -18,6 +18,8 @@ using osu.Game.Scoring; using osu.Game.Users.Drawables; using osuTK; using osuTK.Graphics; +using osu.Framework.Localisation; +using osu.Framework.Extensions.LocalisationExtensions; namespace osu.Game.Overlays.BeatmapSet.Scores { @@ -215,7 +217,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private class HeaderText : OsuSpriteText { - public HeaderText(string text) + public HeaderText(LocalisableString text) { Text = text.ToUpper(); Font = OsuFont.GetFont(size: 10, weight: FontWeight.Bold); diff --git a/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs b/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs index 585b5c22aa..0da48c6f88 100644 --- a/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs @@ -13,6 +13,7 @@ using osu.Framework.Extensions.IEnumerableExtensions; using osu.Game.Users; using osu.Game.Users.Drawables; using osuTK; +using osu.Framework.Localisation; namespace osu.Game.Overlays.Rankings.Tables { @@ -109,7 +110,7 @@ namespace osu.Game.Overlays.Rankings.Tables { private readonly bool isHighlighted; - public HeaderText(string text, bool isHighlighted) + public HeaderText(LocalisableString text, bool isHighlighted) { this.isHighlighted = isHighlighted; diff --git a/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs b/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs index a6969f483f..e3081491f4 100644 --- a/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs @@ -9,6 +9,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Users; using osu.Game.Scoring; +using osu.Framework.Localisation; namespace osu.Game.Overlays.Rankings.Tables { @@ -32,7 +33,7 @@ namespace osu.Game.Overlays.Rankings.Tables protected override Drawable CreateHeader(int index, TableColumn column) { var title = column?.Header ?? string.Empty; - return new UserTableHeaderText(title, HighlightedColumn == title, GradeColumns.Contains(title)); + return new UserTableHeaderText(title, HighlightedColumn == title, GradeColumns.Contains(title.ToString())); } protected sealed override Country GetCountry(UserStatistics item) => item.User.Country; @@ -66,7 +67,7 @@ namespace osu.Game.Overlays.Rankings.Tables private class UserTableHeaderText : HeaderText { - public UserTableHeaderText(string text, bool isHighlighted, bool isGrade) + public UserTableHeaderText(LocalisableString text, bool isHighlighted, bool isGrade) : base(text, isHighlighted) { Margin = new MarginPadding diff --git a/osu.Game/Screens/Edit/EditorTable.cs b/osu.Game/Screens/Edit/EditorTable.cs index 9578b96897..77c3a2f26c 100644 --- a/osu.Game/Screens/Edit/EditorTable.cs +++ b/osu.Game/Screens/Edit/EditorTable.cs @@ -2,10 +2,12 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; +using osu.Framework.Extensions.LocalisationExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; +using osu.Framework.Localisation; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; @@ -46,7 +48,7 @@ namespace osu.Game.Screens.Edit private class HeaderText : OsuSpriteText { - public HeaderText(string text) + public HeaderText(LocalisableString text) { Text = text.ToUpper(); Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold); From 239b38a0ab1776fa4d38bbe35dddb0ec9114f3d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 27 Jul 2021 21:42:34 +0200 Subject: [PATCH 02/16] Reduce implicit conversions by using `default` --- osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs | 2 +- osu.Game/Overlays/Rankings/Tables/RankingsTable.cs | 2 +- osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs | 2 +- osu.Game/Screens/Edit/EditorTable.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs index 22033f14cd..fee0e62315 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoreTable.cs @@ -213,7 +213,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores return content.ToArray(); } - protected override Drawable CreateHeader(int index, TableColumn column) => new HeaderText(column?.Header ?? string.Empty); + protected override Drawable CreateHeader(int index, TableColumn column) => new HeaderText(column?.Header ?? default); private class HeaderText : OsuSpriteText { diff --git a/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs b/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs index 0da48c6f88..f568aae59c 100644 --- a/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/RankingsTable.cs @@ -75,7 +75,7 @@ namespace osu.Game.Overlays.Rankings.Tables protected override Drawable CreateHeader(int index, TableColumn column) { - var title = column?.Header ?? string.Empty; + var title = column?.Header ?? default; return new HeaderText(title, title == HighlightedColumn); } diff --git a/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs b/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs index e3081491f4..56814244c0 100644 --- a/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs +++ b/osu.Game/Overlays/Rankings/Tables/UserBasedTable.cs @@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Rankings.Tables protected override Drawable CreateHeader(int index, TableColumn column) { - var title = column?.Header ?? string.Empty; + var title = column?.Header ?? default; return new UserTableHeaderText(title, HighlightedColumn == title, GradeColumns.Contains(title.ToString())); } diff --git a/osu.Game/Screens/Edit/EditorTable.cs b/osu.Game/Screens/Edit/EditorTable.cs index 77c3a2f26c..756339405c 100644 --- a/osu.Game/Screens/Edit/EditorTable.cs +++ b/osu.Game/Screens/Edit/EditorTable.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Edit }); } - protected override Drawable CreateHeader(int index, TableColumn column) => new HeaderText(column?.Header ?? string.Empty); + protected override Drawable CreateHeader(int index, TableColumn column) => new HeaderText(column?.Header ?? default); private class HeaderText : OsuSpriteText { From 58bbe9db7e3128b80a3fa694a5d6f27628e4c8d7 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Wed, 28 Jul 2021 18:21:08 +0800 Subject: [PATCH 03/16] Added muted mod --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 31 ++++--- osu.Game.Rulesets.Catch/Mods/CatchModMuted.cs | 11 +++ osu.Game.Rulesets.Mania/ManiaRuleset.cs | 21 +++-- osu.Game.Rulesets.Mania/Mods/ManiaModMuted.cs | 11 +++ osu.Game.Rulesets.Osu/Mods/OsuModMuted.cs | 12 +++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 37 ++++---- osu.Game.Rulesets.Taiko/Mods/TaikoModMuted.cs | 11 +++ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 31 ++++--- osu.Game/Overlays/MusicController.cs | 11 ++- osu.Game/Rulesets/Mods/ModMuted.cs | 93 +++++++++++++++++++ 10 files changed, 208 insertions(+), 61 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModMuted.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModMuted.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModMuted.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModMuted.cs create mode 100644 osu.Game/Rulesets/Mods/ModMuted.cs diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 76863acc78..c77caf0cef 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -1,30 +1,30 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Rulesets.Catch.Mods; -using osu.Game.Rulesets.Catch.UI; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.UI; +using System; using System.Collections.Generic; +using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; -using osu.Game.Rulesets.Catch.Replays; -using osu.Game.Rulesets.Replays.Types; +using osu.Game.Beatmaps; using osu.Game.Beatmaps.Legacy; +using osu.Game.Graphics; using osu.Game.Rulesets.Catch.Beatmaps; using osu.Game.Rulesets.Catch.Difficulty; -using osu.Game.Rulesets.Catch.Scoring; -using osu.Game.Rulesets.Difficulty; -using osu.Game.Rulesets.Scoring; -using osu.Game.Scoring; -using System; -using osu.Framework.Extensions.EnumExtensions; using osu.Game.Rulesets.Catch.Edit; +using osu.Game.Rulesets.Catch.Mods; +using osu.Game.Rulesets.Catch.Replays; +using osu.Game.Rulesets.Catch.Scoring; using osu.Game.Rulesets.Catch.Skinning.Legacy; +using osu.Game.Rulesets.Catch.UI; +using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Replays.Types; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; +using osu.Game.Scoring; using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch @@ -130,7 +130,8 @@ namespace osu.Game.Rulesets.Catch return new Mod[] { new MultiMod(new ModWindUp(), new ModWindDown()), - new CatchModFloatingFruits() + new CatchModFloatingFruits(), + new CatchModMuted(), }; default: diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModMuted.cs b/osu.Game.Rulesets.Catch/Mods/CatchModMuted.cs new file mode 100644 index 0000000000..4c73a6a21f --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModMuted.cs @@ -0,0 +1,11 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModMuted : ModMuted + { + } +} diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index fe736766d9..3615d7e660 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -2,22 +2,16 @@ // See the LICENCE file in the repository root for full licence text. using System; -using osu.Game.Beatmaps; -using osu.Game.Rulesets.Mania.Mods; -using osu.Game.Rulesets.Mania.UI; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.UI; using System.Collections.Generic; using System.Linq; using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; -using osu.Game.Graphics; -using osu.Game.Rulesets.Mania.Replays; -using osu.Game.Rulesets.Replays.Types; +using osu.Game.Beatmaps; using osu.Game.Beatmaps.Legacy; using osu.Game.Configuration; +using osu.Game.Graphics; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Difficulty; @@ -27,12 +21,18 @@ using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Configuration; using osu.Game.Rulesets.Mania.Difficulty; using osu.Game.Rulesets.Mania.Edit; +using osu.Game.Rulesets.Mania.Mods; +using osu.Game.Rulesets.Mania.Replays; using osu.Game.Rulesets.Mania.Scoring; using osu.Game.Rulesets.Mania.Skinning.Legacy; +using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.Scoring; -using osu.Game.Skinning; +using osu.Game.Rulesets.UI; using osu.Game.Scoring; using osu.Game.Screens.Ranking.Statistics; +using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania { @@ -253,7 +253,8 @@ namespace osu.Game.Rulesets.Mania case ModType.Fun: return new Mod[] { - new MultiMod(new ModWindUp(), new ModWindDown()) + new MultiMod(new ModWindUp(), new ModWindDown()), + new ManiaModMuted(), }; default: diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModMuted.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModMuted.cs new file mode 100644 index 0000000000..e0b98e491e --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModMuted.cs @@ -0,0 +1,11 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModMuted : ModMuted + { + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModMuted.cs b/osu.Game.Rulesets.Osu/Mods/OsuModMuted.cs new file mode 100644 index 0000000000..5e3ee37b61 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModMuted.cs @@ -0,0 +1,12 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Objects; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModMuted : ModMuted + { + } +} diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 5f37b0d040..30f56cdc7d 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -1,39 +1,39 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Rulesets.Osu.UI; -using osu.Game.Rulesets.UI; +using System; using System.Collections.Generic; +using System.Linq; +using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; -using osu.Game.Overlays.Settings; using osu.Framework.Input.Bindings; -using osu.Game.Rulesets.Osu.Edit; -using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Osu.Replays; -using osu.Game.Rulesets.Replays.Types; +using osu.Game.Beatmaps; using osu.Game.Beatmaps.Legacy; using osu.Game.Configuration; +using osu.Game.Graphics; +using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Difficulty; +using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.Osu.Difficulty; -using osu.Game.Rulesets.Osu.Scoring; -using osu.Game.Rulesets.Scoring; -using osu.Game.Scoring; -using osu.Game.Skinning; -using System; -using System.Linq; -using osu.Framework.Extensions.EnumExtensions; +using osu.Game.Rulesets.Osu.Edit; +using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.Replays; +using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Osu.Skinning.Legacy; using osu.Game.Rulesets.Osu.Statistics; +using osu.Game.Rulesets.Osu.UI; +using osu.Game.Rulesets.Replays.Types; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.UI; +using osu.Game.Scoring; using osu.Game.Screens.Ranking.Statistics; +using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu { @@ -188,6 +188,7 @@ namespace osu.Game.Rulesets.Osu new OsuModTraceable(), new OsuModBarrelRoll(), new OsuModApproachDifferent(), + new OsuModMuted(), }; case ModType.System: diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModMuted.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModMuted.cs new file mode 100644 index 0000000000..d6bd7c4ee8 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModMuted.cs @@ -0,0 +1,11 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Taiko.Objects; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModMuted : ModMuted + { + } +} diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index ab5fcf6336..428ae66a31 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -1,32 +1,32 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Taiko.Mods; -using osu.Game.Rulesets.Taiko.UI; -using osu.Game.Rulesets.UI; +using System; using System.Collections.Generic; +using System.Linq; +using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; -using osu.Game.Rulesets.Replays.Types; -using osu.Game.Rulesets.Taiko.Replays; +using osu.Game.Beatmaps; using osu.Game.Beatmaps.Legacy; +using osu.Game.Graphics; using osu.Game.Rulesets.Difficulty; +using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Beatmaps; using osu.Game.Rulesets.Taiko.Difficulty; -using osu.Game.Rulesets.Taiko.Scoring; -using osu.Game.Scoring; -using System; -using System.Linq; -using osu.Framework.Extensions.EnumExtensions; -using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Taiko.Edit; +using osu.Game.Rulesets.Taiko.Mods; using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.Replays; +using osu.Game.Rulesets.Taiko.Scoring; using osu.Game.Rulesets.Taiko.Skinning.Legacy; +using osu.Game.Rulesets.Taiko.UI; +using osu.Game.Rulesets.UI; +using osu.Game.Scoring; using osu.Game.Screens.Ranking.Statistics; using osu.Game.Skinning; @@ -149,7 +149,8 @@ namespace osu.Game.Rulesets.Taiko case ModType.Fun: return new Mod[] { - new MultiMod(new ModWindUp(), new ModWindDown()) + new MultiMod(new ModWindUp(), new ModWindDown()), + new TaikoModMuted(), }; default: diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index a15f80ca21..0325fa588f 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -12,8 +12,8 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; -using osu.Framework.Utils; using osu.Framework.Threading; +using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; @@ -419,15 +419,20 @@ namespace osu.Game.Overlays } /// - /// Resets the speed adjustments currently applied on and applies the mod adjustments if is true. + /// Resets the track adjustments currently applied on and applies the mod adjustments if is true. /// /// - /// Does not reset speed adjustments applied directly to the beatmap track. + /// Does not reset any adjustments applied directly to the beatmap track. /// public void ResetTrackAdjustments() { CurrentTrack.ResetSpeedAdjustments(); + // Adjustments other than speed should also be reset + // e.g. ModMuted may apply volume adjustments + CurrentTrack.RemoveAllAdjustments(AdjustableProperty.Balance); + CurrentTrack.RemoveAllAdjustments(AdjustableProperty.Volume); + if (allowRateAdjustments) { foreach (var mod in mods.Value.OfType()) diff --git a/osu.Game/Rulesets/Mods/ModMuted.cs b/osu.Game/Rulesets/Mods/ModMuted.cs new file mode 100644 index 0000000000..dff3982041 --- /dev/null +++ b/osu.Game/Rulesets/Mods/ModMuted.cs @@ -0,0 +1,93 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Track; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Game.Audio; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Configuration; +using osu.Game.Graphics.Containers; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.UI; +using osu.Game.Skinning; + +namespace osu.Game.Rulesets.Mods +{ + public abstract class ModMuted : Mod + { + public override string Name => "Muted"; + public override string Acronym => "MU"; + public override IconUsage? Icon => FontAwesome.Solid.VolumeMute; + public override string Description => "Who needs music in a rhythm game?"; + public override ModType Type => ModType.Fun; + public override double ScoreMultiplier => 1; + } + + public abstract class ModMuted : ModMuted, IApplicableToDrawableRuleset, IApplicableToTrack + where TObject : HitObject + { + private readonly BindableNumber volumeAdjust = new BindableDouble(); + + [SettingSource("Enable metronome", "Add a metronome to help you keep track of the rhythm.")] + public BindableBool EnableMetronome { get; } = new BindableBool + { + Default = true, + Value = true + }; + + public void ApplyToTrack(ITrack track) + { + track.AddAdjustment(AdjustableProperty.Volume, volumeAdjust); + } + + public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) + { + if (EnableMetronome.Value) + drawableRuleset.Overlays.Add(new MetronomeBeatContainer(drawableRuleset.Beatmap.HitObjects.First().StartTime)); + } + + public class MetronomeBeatContainer : BeatSyncedContainer + { + private readonly double firstHitTime; + + private PausableSkinnableSound sample; + + public MetronomeBeatContainer(double firstHitTime) + { + this.firstHitTime = firstHitTime; + AllowMistimedEventFiring = false; + Divisor = 1; + } + + [BackgroundDependencyLoader] + private void load() + { + InternalChildren = new Drawable[] + { + sample = new PausableSkinnableSound(new SampleInfo("Gameplay/catch-banana")) + }; + } + + protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) + { + base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes); + + if (!IsBeatSyncedWithTrack) return; + + int timeSignature = (int)timingPoint.TimeSignature; + + // play metronome from one measure before the first object. + if (BeatSyncClock.CurrentTime < firstHitTime - timingPoint.BeatLength * timeSignature) + return; + + sample.Frequency.Value = beatIndex % timeSignature == 0 ? 1 : 0.5f; + sample.Play(); + } + } + } +} From 22d83c75e3a612d77ab681c704aa3596c7d3834e Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Wed, 28 Jul 2021 18:32:38 +0800 Subject: [PATCH 04/16] Revert imports re-ordering Out of the scope of this PR --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 26 +++++++++--------- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 18 ++++++------- osu.Game.Rulesets.Osu/OsuRuleset.cs | 36 ++++++++++++------------- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 32 +++++++++++----------- osu.Game/Overlays/MusicController.cs | 2 +- 5 files changed, 57 insertions(+), 57 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index c77caf0cef..eafa1b9b9d 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -1,30 +1,30 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Rulesets.Catch.Mods; +using osu.Game.Rulesets.Catch.UI; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.UI; using System.Collections.Generic; -using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; -using osu.Game.Beatmaps; +using osu.Game.Rulesets.Catch.Replays; +using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; -using osu.Game.Graphics; using osu.Game.Rulesets.Catch.Beatmaps; using osu.Game.Rulesets.Catch.Difficulty; -using osu.Game.Rulesets.Catch.Edit; -using osu.Game.Rulesets.Catch.Mods; -using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Catch.Scoring; -using osu.Game.Rulesets.Catch.Skinning.Legacy; -using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Difficulty; -using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.UI; using osu.Game.Scoring; +using System; +using osu.Framework.Extensions.EnumExtensions; +using osu.Game.Rulesets.Catch.Edit; +using osu.Game.Rulesets.Catch.Skinning.Legacy; +using osu.Game.Rulesets.Edit; using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 3615d7e660..f4b6e10af4 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -2,16 +2,22 @@ // See the LICENCE file in the repository root for full licence text. using System; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mania.Mods; +using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.UI; using System.Collections.Generic; using System.Linq; using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; -using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Rulesets.Mania.Replays; +using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; using osu.Game.Configuration; -using osu.Game.Graphics; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Difficulty; @@ -21,18 +27,12 @@ using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Configuration; using osu.Game.Rulesets.Mania.Difficulty; using osu.Game.Rulesets.Mania.Edit; -using osu.Game.Rulesets.Mania.Mods; -using osu.Game.Rulesets.Mania.Replays; using osu.Game.Rulesets.Mania.Scoring; using osu.Game.Rulesets.Mania.Skinning.Legacy; -using osu.Game.Rulesets.Mania.UI; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.UI; +using osu.Game.Skinning; using osu.Game.Scoring; using osu.Game.Screens.Ranking.Statistics; -using osu.Game.Skinning; namespace osu.Game.Rulesets.Mania { diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 30f56cdc7d..21a49f9495 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -1,39 +1,39 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Rulesets.Osu.UI; +using osu.Game.Rulesets.UI; using System.Collections.Generic; -using System.Linq; -using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; +using osu.Game.Overlays.Settings; using osu.Framework.Input.Bindings; -using osu.Game.Beatmaps; +using osu.Game.Rulesets.Osu.Edit; +using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Osu.Replays; +using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; using osu.Game.Configuration; -using osu.Game.Graphics; -using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Difficulty; -using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Rulesets.Osu.Configuration; using osu.Game.Rulesets.Osu.Difficulty; -using osu.Game.Rulesets.Osu.Edit; -using osu.Game.Rulesets.Osu.Mods; -using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Osu.Scoring; +using osu.Game.Rulesets.Scoring; +using osu.Game.Scoring; +using osu.Game.Skinning; +using System; +using System.Linq; +using osu.Framework.Extensions.EnumExtensions; +using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Skinning.Legacy; using osu.Game.Rulesets.Osu.Statistics; -using osu.Game.Rulesets.Osu.UI; -using osu.Game.Rulesets.Replays.Types; -using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.UI; -using osu.Game.Scoring; using osu.Game.Screens.Ranking.Statistics; -using osu.Game.Skinning; namespace osu.Game.Rulesets.Osu { diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 428ae66a31..adc924ba38 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -1,32 +1,32 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Taiko.Mods; +using osu.Game.Rulesets.Taiko.UI; +using osu.Game.Rulesets.UI; using System.Collections.Generic; -using System.Linq; -using osu.Framework.Extensions.EnumExtensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; -using osu.Game.Beatmaps; -using osu.Game.Beatmaps.Legacy; -using osu.Game.Graphics; -using osu.Game.Rulesets.Difficulty; -using osu.Game.Rulesets.Edit; -using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Replays.Types; +using osu.Game.Rulesets.Taiko.Replays; +using osu.Game.Beatmaps.Legacy; +using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Taiko.Beatmaps; using osu.Game.Rulesets.Taiko.Difficulty; -using osu.Game.Rulesets.Taiko.Edit; -using osu.Game.Rulesets.Taiko.Mods; -using osu.Game.Rulesets.Taiko.Objects; -using osu.Game.Rulesets.Taiko.Replays; using osu.Game.Rulesets.Taiko.Scoring; -using osu.Game.Rulesets.Taiko.Skinning.Legacy; -using osu.Game.Rulesets.Taiko.UI; -using osu.Game.Rulesets.UI; using osu.Game.Scoring; +using System; +using System.Linq; +using osu.Framework.Extensions.EnumExtensions; +using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Taiko.Edit; +using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.Skinning.Legacy; using osu.Game.Screens.Ranking.Statistics; using osu.Game.Skinning; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 0325fa588f..3978d2aa6e 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -12,8 +12,8 @@ using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; -using osu.Framework.Threading; using osu.Framework.Utils; +using osu.Framework.Threading; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; From e89f33483dd796572fc89db8d267bb1a23d05c2a Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Wed, 28 Jul 2021 21:52:01 +0800 Subject: [PATCH 05/16] Code formatting fixes --- osu.Game.Rulesets.Catch/Mods/CatchModMuted.cs | 1 + osu.Game.Rulesets.Mania/Mods/ManiaModMuted.cs | 1 + osu.Game.Rulesets.Taiko/Mods/TaikoModMuted.cs | 1 + 3 files changed, 3 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModMuted.cs b/osu.Game.Rulesets.Catch/Mods/CatchModMuted.cs index 4c73a6a21f..6d2565440a 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModMuted.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModMuted.cs @@ -1,5 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. + using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Mods; diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModMuted.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModMuted.cs index e0b98e491e..33ebcf303a 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModMuted.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModMuted.cs @@ -1,5 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. + using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mods; diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModMuted.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModMuted.cs index d6bd7c4ee8..0f1e0b2885 100644 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoModMuted.cs +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModMuted.cs @@ -1,5 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. + using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Taiko.Objects; From fbd02dc8301446a380e479b9ed19a71ac116ee54 Mon Sep 17 00:00:00 2001 From: Lucas A Date: Wed, 28 Jul 2021 18:24:29 +0200 Subject: [PATCH 06/16] Update framework. --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 3a9fdfebab..1c180a6b39 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 4baaf89c67..2efcfeb278 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -36,7 +36,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 66cae06713..2630614c03 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -70,7 +70,7 @@ - + @@ -93,7 +93,7 @@ - + From 0620cd130e6427b3c468c03b8a4a0a19a1854b42 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Thu, 29 Jul 2021 14:41:47 +0800 Subject: [PATCH 07/16] Change mod description --- osu.Game/Rulesets/Mods/ModMuted.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModMuted.cs b/osu.Game/Rulesets/Mods/ModMuted.cs index dff3982041..aa2006cf73 100644 --- a/osu.Game/Rulesets/Mods/ModMuted.cs +++ b/osu.Game/Rulesets/Mods/ModMuted.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Mods public override string Name => "Muted"; public override string Acronym => "MU"; public override IconUsage? Icon => FontAwesome.Solid.VolumeMute; - public override string Description => "Who needs music in a rhythm game?"; + public override string Description => "Can you still feel the rhythm without music?"; public override ModType Type => ModType.Fun; public override double ScoreMultiplier => 1; } From 18e760ee91916bcca6071a51cdca628498dd8439 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Thu, 29 Jul 2021 14:52:18 +0800 Subject: [PATCH 08/16] Extract metronome from `OsuModTarget` --- osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs | 45 +--------------- .../Rulesets/Mods/MetronomeBeatContainer.cs | 53 +++++++++++++++++++ 2 files changed, 54 insertions(+), 44 deletions(-) create mode 100644 osu.Game/Rulesets/Mods/MetronomeBeatContainer.cs diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs index e21d1da009..576cc2da13 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs @@ -4,8 +4,6 @@ using System; using System.Collections.Generic; using System.Linq; -using osu.Framework.Allocation; -using osu.Framework.Audio.Track; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; @@ -16,7 +14,6 @@ using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Timing; using osu.Game.Configuration; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; using osu.Game.Overlays.Settings; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; @@ -29,7 +26,6 @@ using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.Osu.Utils; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; -using osu.Game.Skinning; using osuTK; using osuTK.Graphics; @@ -341,46 +337,7 @@ namespace osu.Game.Rulesets.Osu.Mods public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { - drawableRuleset.Overlays.Add(new TargetBeatContainer(drawableRuleset.Beatmap.HitObjects.First().StartTime)); - } - - public class TargetBeatContainer : BeatSyncedContainer - { - private readonly double firstHitTime; - - private PausableSkinnableSound sample; - - public TargetBeatContainer(double firstHitTime) - { - this.firstHitTime = firstHitTime; - AllowMistimedEventFiring = false; - Divisor = 1; - } - - [BackgroundDependencyLoader] - private void load() - { - InternalChildren = new Drawable[] - { - sample = new PausableSkinnableSound(new SampleInfo("Gameplay/catch-banana")) - }; - } - - protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) - { - base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes); - - if (!IsBeatSyncedWithTrack) return; - - int timeSignature = (int)timingPoint.TimeSignature; - - // play metronome from one measure before the first object. - if (BeatSyncClock.CurrentTime < firstHitTime - timingPoint.BeatLength * timeSignature) - return; - - sample.Frequency.Value = beatIndex % timeSignature == 0 ? 1 : 0.5f; - sample.Play(); - } + drawableRuleset.Overlays.Add(new MetronomeBeatContainer(drawableRuleset.Beatmap.HitObjects.First().StartTime)); } #endregion diff --git a/osu.Game/Rulesets/Mods/MetronomeBeatContainer.cs b/osu.Game/Rulesets/Mods/MetronomeBeatContainer.cs new file mode 100644 index 0000000000..c5bb2c918f --- /dev/null +++ b/osu.Game/Rulesets/Mods/MetronomeBeatContainer.cs @@ -0,0 +1,53 @@ +// 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.Audio.Track; +using osu.Framework.Graphics; +using osu.Game.Audio; +using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Graphics.Containers; +using osu.Game.Skinning; + +namespace osu.Game.Rulesets.Mods +{ + public class MetronomeBeatContainer : BeatSyncedContainer + { + private readonly double firstHitTime; + + private PausableSkinnableSound sample; + + /// Start time of the first hit object, used for providing a count down. + public MetronomeBeatContainer(double firstHitTime) + { + this.firstHitTime = firstHitTime; + AllowMistimedEventFiring = false; + Divisor = 1; + } + + [BackgroundDependencyLoader] + private void load() + { + InternalChildren = new Drawable[] + { + sample = new PausableSkinnableSound(new SampleInfo("Gameplay/catch-banana")) + }; + } + + protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) + { + base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes); + + if (!IsBeatSyncedWithTrack) return; + + int timeSignature = (int)timingPoint.TimeSignature; + + // play metronome from one measure before the first object. + if (BeatSyncClock.CurrentTime < firstHitTime - timingPoint.BeatLength * timeSignature) + return; + + sample.Frequency.Value = beatIndex % timeSignature == 0 ? 1 : 0.5f; + sample.Play(); + } + } +} From 0196141335b11d0f5b21d0bf700eb86e1024bd0f Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Thu, 29 Jul 2021 14:52:40 +0800 Subject: [PATCH 09/16] Remove unused constants --- osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs index 576cc2da13..615700e6b9 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs @@ -63,11 +63,6 @@ namespace osu.Game.Rulesets.Osu.Mods /// private const float distance_cap = 380f; - // The distances from the hit objects to the borders of the playfield they start to "turn around" and curve towards the middle. - // The closer the hit objects draw to the border, the sharper the turn - private const byte border_distance_x = 192; - private const byte border_distance_y = 144; - /// /// The extent of rotation towards playfield centre when a circle is near the edge /// From 935984d20016d19ee0de9e057a19ae0f3f137a44 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Thu, 29 Jul 2021 15:17:21 +0800 Subject: [PATCH 10/16] Rename `MetronomeBeatContainer` to `Metronome` --- osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs | 2 +- .../Rulesets/Mods/{MetronomeBeatContainer.cs => Metronome.cs} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename osu.Game/Rulesets/Mods/{MetronomeBeatContainer.cs => Metronome.cs} (93%) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs index 615700e6b9..210d5e0403 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs @@ -332,7 +332,7 @@ namespace osu.Game.Rulesets.Osu.Mods public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { - drawableRuleset.Overlays.Add(new MetronomeBeatContainer(drawableRuleset.Beatmap.HitObjects.First().StartTime)); + drawableRuleset.Overlays.Add(new Metronome(drawableRuleset.Beatmap.HitObjects.First().StartTime)); } #endregion diff --git a/osu.Game/Rulesets/Mods/MetronomeBeatContainer.cs b/osu.Game/Rulesets/Mods/Metronome.cs similarity index 93% rename from osu.Game/Rulesets/Mods/MetronomeBeatContainer.cs rename to osu.Game/Rulesets/Mods/Metronome.cs index c5bb2c918f..ee0a42b4bc 100644 --- a/osu.Game/Rulesets/Mods/MetronomeBeatContainer.cs +++ b/osu.Game/Rulesets/Mods/Metronome.cs @@ -11,14 +11,14 @@ using osu.Game.Skinning; namespace osu.Game.Rulesets.Mods { - public class MetronomeBeatContainer : BeatSyncedContainer + public class Metronome : BeatSyncedContainer { private readonly double firstHitTime; private PausableSkinnableSound sample; /// Start time of the first hit object, used for providing a count down. - public MetronomeBeatContainer(double firstHitTime) + public Metronome(double firstHitTime) { this.firstHitTime = firstHitTime; AllowMistimedEventFiring = false; From 89e8296eb1b17a42eae1f24422bf099a76a1ac37 Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Thu, 29 Jul 2021 15:39:26 +0800 Subject: [PATCH 11/16] Reset all types of adjustments in `MusicController`; Rename `AllowRateAdjustments` to `AllowTrackAdjustments` --- osu.Game/OsuGame.cs | 2 +- osu.Game/Overlays/MusicController.cs | 23 +++++++++++-------- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/IOsuScreen.cs | 4 ++-- osu.Game/Screens/Menu/MainMenu.cs | 2 +- .../Spectate/MultiSpectatorScreen.cs | 2 +- osu.Game/Screens/OsuScreen.cs | 2 +- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/StartupScreen.cs | 2 +- 9 files changed, 22 insertions(+), 19 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 8e32b2e6a7..3cfa2cc755 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1058,7 +1058,7 @@ namespace osu.Game OverlayActivationMode.BindTo(newOsuScreen.OverlayActivationMode); API.Activity.BindTo(newOsuScreen.Activity); - MusicController.AllowRateAdjustments = newOsuScreen.AllowRateAdjustments; + MusicController.AllowTrackAdjustments = newOsuScreen.AllowTrackAdjustments; if (newOsuScreen.HideOverlaysOnEnter) CloseAllOverlays(); diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index a15f80ca21..8fd50c3df2 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -400,35 +400,38 @@ namespace osu.Game.Overlays NextTrack(); } - private bool allowRateAdjustments; + private bool allowTrackAdjustments; /// - /// Whether mod rate adjustments are allowed to be applied. + /// Whether mod track adjustments are allowed to be applied. /// - public bool AllowRateAdjustments + public bool AllowTrackAdjustments { - get => allowRateAdjustments; + get => allowTrackAdjustments; set { - if (allowRateAdjustments == value) + if (allowTrackAdjustments == value) return; - allowRateAdjustments = value; + allowTrackAdjustments = value; ResetTrackAdjustments(); } } /// - /// Resets the speed adjustments currently applied on and applies the mod adjustments if is true. + /// Resets the adjustments currently applied on and applies the mod adjustments if is true. /// /// - /// Does not reset speed adjustments applied directly to the beatmap track. + /// Does not reset any adjustments applied directly to the beatmap track. /// public void ResetTrackAdjustments() { - CurrentTrack.ResetSpeedAdjustments(); + CurrentTrack.RemoveAllAdjustments(AdjustableProperty.Balance); + CurrentTrack.RemoveAllAdjustments(AdjustableProperty.Frequency); + CurrentTrack.RemoveAllAdjustments(AdjustableProperty.Tempo); + CurrentTrack.RemoveAllAdjustments(AdjustableProperty.Volume); - if (allowRateAdjustments) + if (allowTrackAdjustments) { foreach (var mod in mods.Value.OfType()) mod.ApplyToTrack(CurrentTrack); diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index b6dc97a7f6..61a3b0f5cc 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Edit public override bool DisallowExternalBeatmapRulesetChanges => true; - public override bool AllowRateAdjustments => false; + public override bool AllowTrackAdjustments => false; protected bool HasUnsavedChanges => lastSavedHash != changeHandler.CurrentStateHash; diff --git a/osu.Game/Screens/IOsuScreen.cs b/osu.Game/Screens/IOsuScreen.cs index 0434135547..17384c161c 100644 --- a/osu.Game/Screens/IOsuScreen.cs +++ b/osu.Game/Screens/IOsuScreen.cs @@ -59,9 +59,9 @@ namespace osu.Game.Screens Bindable Ruleset { get; } /// - /// Whether mod rate adjustments are allowed to be applied. + /// Whether mod track adjustments are allowed to be applied. /// - bool AllowRateAdjustments { get; } + bool AllowTrackAdjustments { get; } /// /// Invoked when the back button has been pressed to close any overlays before exiting this . diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index e53b46f391..1d0182a945 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Menu public override bool AllowExternalScreenChange => true; - public override bool AllowRateAdjustments => false; + public override bool AllowTrackAdjustments => false; private Screen songSelect; diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs index 2a2759e0dd..56ed7a9564 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate public override bool DisallowExternalBeatmapRulesetChanges => true; // We are managing our own adjustments. For now, this happens inside the Player instances themselves. - public override bool AllowRateAdjustments => false; + public override bool AllowTrackAdjustments => false; /// /// Whether all spectating players have finished loading. diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index c3b2612e79..e3fe14a585 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -81,7 +81,7 @@ namespace osu.Game.Screens public virtual float BackgroundParallaxAmount => 1; - public virtual bool AllowRateAdjustments => true; + public virtual bool AllowTrackAdjustments => true; public Bindable Beatmap { get; private set; } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 0e4d38660b..d76d44767a 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Play protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered; // We are managing our own adjustments (see OnEntering/OnExiting). - public override bool AllowRateAdjustments => false; + public override bool AllowTrackAdjustments => false; private readonly IBindable gameActive = new Bindable(true); diff --git a/osu.Game/Screens/StartupScreen.cs b/osu.Game/Screens/StartupScreen.cs index e5e134fd39..15f75d7cff 100644 --- a/osu.Game/Screens/StartupScreen.cs +++ b/osu.Game/Screens/StartupScreen.cs @@ -16,7 +16,7 @@ namespace osu.Game.Screens public override bool CursorVisible => false; - public override bool AllowRateAdjustments => false; + public override bool AllowTrackAdjustments => false; protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled; } From 888e8f1c8052c2abef891f60eecd18c079881eed Mon Sep 17 00:00:00 2001 From: Henry Lin Date: Thu, 29 Jul 2021 21:18:07 +0800 Subject: [PATCH 12/16] Use shared metronome class --- osu.Game/Rulesets/Mods/ModMuted.cs | 47 +----------------------------- 1 file changed, 1 insertion(+), 46 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModMuted.cs b/osu.Game/Rulesets/Mods/ModMuted.cs index aa2006cf73..9e69bc1386 100644 --- a/osu.Game/Rulesets/Mods/ModMuted.cs +++ b/osu.Game/Rulesets/Mods/ModMuted.cs @@ -2,19 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using System.Linq; -using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Track; using osu.Framework.Bindables; -using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; -using osu.Game.Audio; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Configuration; -using osu.Game.Graphics.Containers; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.UI; -using osu.Game.Skinning; namespace osu.Game.Rulesets.Mods { @@ -48,46 +42,7 @@ namespace osu.Game.Rulesets.Mods public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { if (EnableMetronome.Value) - drawableRuleset.Overlays.Add(new MetronomeBeatContainer(drawableRuleset.Beatmap.HitObjects.First().StartTime)); - } - - public class MetronomeBeatContainer : BeatSyncedContainer - { - private readonly double firstHitTime; - - private PausableSkinnableSound sample; - - public MetronomeBeatContainer(double firstHitTime) - { - this.firstHitTime = firstHitTime; - AllowMistimedEventFiring = false; - Divisor = 1; - } - - [BackgroundDependencyLoader] - private void load() - { - InternalChildren = new Drawable[] - { - sample = new PausableSkinnableSound(new SampleInfo("Gameplay/catch-banana")) - }; - } - - protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes) - { - base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes); - - if (!IsBeatSyncedWithTrack) return; - - int timeSignature = (int)timingPoint.TimeSignature; - - // play metronome from one measure before the first object. - if (BeatSyncClock.CurrentTime < firstHitTime - timingPoint.BeatLength * timeSignature) - return; - - sample.Frequency.Value = beatIndex % timeSignature == 0 ? 1 : 0.5f; - sample.Play(); - } + drawableRuleset.Overlays.Add(new Metronome(drawableRuleset.Beatmap.HitObjects.First().StartTime)); } } } From 5c5e33f4d744676baa7116aec7b576e950d61e41 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Jul 2021 01:53:08 +0900 Subject: [PATCH 13/16] Split out common logic for tournament game host tests --- .../NonVisual/CustomTourneyDirectoryTest.cs | 32 +++--------------- .../NonVisual/IPCLocationTest.cs | 28 ++-------------- .../NonVisual/TournamentHostTest.cs | 33 +++++++++++++++++++ 3 files changed, 41 insertions(+), 52 deletions(-) create mode 100644 osu.Game.Tournament.Tests/NonVisual/TournamentHostTest.cs diff --git a/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs b/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs index d2369056e1..fcc9f44f0c 100644 --- a/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs +++ b/osu.Game.Tournament.Tests/NonVisual/CustomTourneyDirectoryTest.cs @@ -1,21 +1,18 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.IO; -using System.Threading; -using System.Threading.Tasks; using NUnit.Framework; using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Platform; -using osu.Game.Tournament.Configuration; using osu.Game.Tests; +using osu.Game.Tournament.Configuration; namespace osu.Game.Tournament.Tests.NonVisual { [TestFixture] - public class CustomTourneyDirectoryTest + public class CustomTourneyDirectoryTest : TournamentHostTest { [Test] public void TestDefaultDirectory() @@ -24,7 +21,7 @@ namespace osu.Game.Tournament.Tests.NonVisual { try { - var osu = loadOsu(host); + var osu = LoadTournament(host); var storage = osu.Dependencies.Get(); Assert.That(storage.GetFullPath("."), Is.EqualTo(Path.Combine(host.Storage.GetFullPath("."), "tournaments", "default"))); @@ -54,7 +51,7 @@ namespace osu.Game.Tournament.Tests.NonVisual try { - var osu = loadOsu(host); + var osu = LoadTournament(host); storage = osu.Dependencies.Get(); @@ -111,7 +108,7 @@ namespace osu.Game.Tournament.Tests.NonVisual try { - var osu = loadOsu(host); + var osu = LoadTournament(host); var storage = osu.Dependencies.Get(); @@ -151,25 +148,6 @@ namespace osu.Game.Tournament.Tests.NonVisual } } - private TournamentGameBase loadOsu(GameHost host) - { - var osu = new TournamentGameBase(); - Task.Run(() => host.Run(osu)) - .ContinueWith(t => Assert.Fail($"Host threw exception {t.Exception}"), TaskContinuationOptions.OnlyOnFaulted); - waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time"); - return osu; - } - - private static void waitForOrAssert(Func result, string failureMessage, int timeout = 90000) - { - Task task = Task.Run(() => - { - while (!result()) Thread.Sleep(200); - }); - - Assert.IsTrue(task.Wait(timeout), failureMessage); - } - private string basePath(string testInstance) => Path.Combine(RuntimeInfo.StartupDirectory, "headless", testInstance); } } diff --git a/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs b/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs index e4eb5a36fb..eaa009c180 100644 --- a/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs +++ b/osu.Game.Tournament.Tests/NonVisual/IPCLocationTest.cs @@ -1,10 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System; using System.IO; -using System.Threading; -using System.Threading.Tasks; using NUnit.Framework; using osu.Framework; using osu.Framework.Allocation; @@ -15,7 +12,7 @@ using osu.Game.Tournament.IPC; namespace osu.Game.Tournament.Tests.NonVisual { [TestFixture] - public class IPCLocationTest + public class IPCLocationTest : TournamentHostTest { [Test] public void CheckIPCLocation() @@ -34,11 +31,11 @@ namespace osu.Game.Tournament.Tests.NonVisual try { - var osu = loadOsu(host); + var osu = LoadTournament(host); TournamentStorage storage = (TournamentStorage)osu.Dependencies.Get(); FileBasedIPC ipc = null; - waitForOrAssert(() => (ipc = osu.Dependencies.Get() as FileBasedIPC) != null, @"ipc could not be populated in a reasonable amount of time"); + WaitForOrAssert(() => (ipc = osu.Dependencies.Get() as FileBasedIPC) != null, @"ipc could not be populated in a reasonable amount of time"); Assert.True(ipc.SetIPCLocation(testStableInstallDirectory)); Assert.True(storage.AllTournaments.Exists("stable.json")); @@ -51,24 +48,5 @@ namespace osu.Game.Tournament.Tests.NonVisual } } } - - private TournamentGameBase loadOsu(GameHost host) - { - var osu = new TournamentGameBase(); - Task.Run(() => host.Run(osu)) - .ContinueWith(t => Assert.Fail($"Host threw exception {t.Exception}"), TaskContinuationOptions.OnlyOnFaulted); - waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time"); - return osu; - } - - private static void waitForOrAssert(Func result, string failureMessage, int timeout = 90000) - { - Task task = Task.Run(() => - { - while (!result()) Thread.Sleep(200); - }); - - Assert.IsTrue(task.Wait(timeout), failureMessage); - } } } diff --git a/osu.Game.Tournament.Tests/NonVisual/TournamentHostTest.cs b/osu.Game.Tournament.Tests/NonVisual/TournamentHostTest.cs new file mode 100644 index 0000000000..b14684200f --- /dev/null +++ b/osu.Game.Tournament.Tests/NonVisual/TournamentHostTest.cs @@ -0,0 +1,33 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Threading; +using System.Threading.Tasks; +using NUnit.Framework; +using osu.Framework.Platform; + +namespace osu.Game.Tournament.Tests.NonVisual +{ + public abstract class TournamentHostTest + { + public static TournamentGameBase LoadTournament(GameHost host, TournamentGameBase tournament = null) + { + tournament ??= new TournamentGameBase(); + Task.Run(() => host.Run(tournament)) + .ContinueWith(t => Assert.Fail($"Host threw exception {t.Exception}"), TaskContinuationOptions.OnlyOnFaulted); + WaitForOrAssert(() => tournament.IsLoaded, @"osu! failed to start in a reasonable amount of time"); + return tournament; + } + + public static void WaitForOrAssert(Func result, string failureMessage, int timeout = 90000) + { + Task task = Task.Run(() => + { + while (!result()) Thread.Sleep(200); + }); + + Assert.IsTrue(task.Wait(timeout), failureMessage); + } + } +} From 0b8ca667a94c5c5d962bbd66726e464deca21422 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Jul 2021 01:53:25 +0900 Subject: [PATCH 14/16] Add failing test coverage of loading with an unavailable ruleset --- .../NonVisual/DataLoadTest.cs | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 osu.Game.Tournament.Tests/NonVisual/DataLoadTest.cs diff --git a/osu.Game.Tournament.Tests/NonVisual/DataLoadTest.cs b/osu.Game.Tournament.Tests/NonVisual/DataLoadTest.cs new file mode 100644 index 0000000000..692cb3870c --- /dev/null +++ b/osu.Game.Tournament.Tests/NonVisual/DataLoadTest.cs @@ -0,0 +1,45 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.IO; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Platform; +using osu.Game.Rulesets; +using osu.Game.Tests; + +namespace osu.Game.Tournament.Tests.NonVisual +{ + public class DataLoadTest : TournamentHostTest + { + [Test] + public void TestUnavailableRuleset() + { + using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(TestUnavailableRuleset))) + { + try + { + var osu = new TestTournament(); + + LoadTournament(host, osu); + var storage = osu.Dependencies.Get(); + + Assert.That(storage.GetFullPath("."), Is.EqualTo(Path.Combine(host.Storage.GetFullPath("."), "tournaments", "default"))); + } + finally + { + host.Exit(); + } + } + } + + public class TestTournament : TournamentGameBase + { + [BackgroundDependencyLoader] + private void load() + { + Ruleset.Value = new RulesetInfo(); // not available + } + } + } +} From 46c72334fbd3d8427a92960cdffbc83d260439fb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Jul 2021 01:54:30 +0900 Subject: [PATCH 15/16] Fix stack overflow in ruleset change rejection logic --- osu.Game/OsuGameBase.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index a7fac24351..f2d575550a 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -479,7 +479,7 @@ namespace osu.Game if (r.NewValue?.Available != true) { // reject the change if the ruleset is not available. - Ruleset.Value = r.OldValue; + Ruleset.Value = r.OldValue?.Available == true ? r.OldValue : RulesetStore.AvailableRulesets.First(); return; } From 77b354bfba5ad6ecf4675a359a8a6b45359b16a9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 30 Jul 2021 02:12:03 +0900 Subject: [PATCH 16/16] Resolve ruleset from store after loading tournament ladder --- osu.Game.Tournament/TournamentGameBase.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs index 92eb7ac713..531da00faf 100644 --- a/osu.Game.Tournament/TournamentGameBase.cs +++ b/osu.Game.Tournament/TournamentGameBase.cs @@ -66,7 +66,9 @@ namespace osu.Game.Tournament } ladder ??= new LadderInfo(); - ladder.Ruleset.Value ??= RulesetStore.AvailableRulesets.First(); + + ladder.Ruleset.Value = RulesetStore.GetRuleset(ladder.Ruleset.Value?.ShortName) + ?? RulesetStore.AvailableRulesets.First(); bool addedInfo = false;