From 3b58f6a7e78d8244a6e60bf8b27078c84845fb3c Mon Sep 17 00:00:00 2001
From: smallketchup82 <69545310+smallketchup82@users.noreply.github.com>
Date: Thu, 21 Dec 2023 21:07:12 -0500
Subject: [PATCH 001/105] Implement difficulty statistics
---
global.json | 8 +-
.../Drawables/DifficultyIconTooltip.cs | 100 +++++++++++++++++-
2 files changed, 103 insertions(+), 5 deletions(-)
diff --git a/global.json b/global.json
index 5dcd5f425a..7835999220 100644
--- a/global.json
+++ b/global.json
@@ -1,7 +1,7 @@
{
"sdk": {
- "version": "6.0.100",
- "rollForward": "latestFeature"
+ "version": "6.0.0",
+ "rollForward": "latestFeature",
+ "allowPrerelease": true
}
-}
-
+}
\ No newline at end of file
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
index 3fa24bcc3e..7ea2c6a0a2 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
@@ -3,6 +3,7 @@
#nullable disable
+using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -19,6 +20,13 @@ namespace osu.Game.Beatmaps.Drawables
{
private OsuSpriteText difficultyName;
private StarRatingDisplay starRating;
+ private OsuSpriteText overallDifficulty;
+ private OsuSpriteText drainRate;
+ private OsuSpriteText circleSize;
+ private OsuSpriteText approachRate;
+ private OsuSpriteText BPM;
+ private OsuSpriteText maxCombo;
+ private OsuSpriteText length;
[BackgroundDependencyLoader]
private void load(OsuColour colours)
@@ -35,6 +43,7 @@ namespace osu.Game.Beatmaps.Drawables
Colour = colours.Gray3,
RelativeSizeAxes = Axes.Both
},
+ // Headers
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
@@ -55,6 +64,84 @@ namespace osu.Game.Beatmaps.Drawables
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
+ },
+ // Difficulty stats
+ new FillFlowContainer()
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(5),
+ Children = new Drawable[]
+ {
+ new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold),
+ },
+ overallDifficulty = new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Font = OsuFont.GetFont(size: 14),
+ },
+ drainRate = new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Font = OsuFont.GetFont(size: 14),
+ },
+ circleSize = new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Font = OsuFont.GetFont(size: 14),
+ },
+ approachRate = new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Font = OsuFont.GetFont(size: 14),
+ },
+ }
+ },
+ // Misc stats
+ new FillFlowContainer()
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(5),
+ Children = new Drawable[]
+ {
+ new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold),
+ },
+ length = new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Font = OsuFont.GetFont(size: 14),
+ },
+ BPM = new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Font = OsuFont.GetFont(size: 14),
+ },
+ maxCombo = new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Font = OsuFont.GetFont(size: 14),
+ },
+ }
}
}
}
@@ -68,10 +155,21 @@ namespace osu.Game.Beatmaps.Drawables
if (displayedContent != null)
starRating.Current.UnbindFrom(displayedContent.Difficulty);
+ // Header row
displayedContent = content;
-
starRating.Current.BindTarget = displayedContent.Difficulty;
difficultyName.Text = displayedContent.BeatmapInfo.DifficultyName;
+
+ // Difficulty row
+ overallDifficulty.Text = "OD: " + displayedContent.BeatmapInfo.Difficulty.OverallDifficulty.ToString("0.##");
+ drainRate.Text = "| HP: " + displayedContent.BeatmapInfo.Difficulty.DrainRate.ToString("0.##");
+ circleSize.Text = "| CS: " + displayedContent.BeatmapInfo.Difficulty.CircleSize.ToString("0.##");
+ approachRate.Text = "| AR: " + displayedContent.BeatmapInfo.Difficulty.ApproachRate.ToString("0.##");
+
+ // Misc row
+ length.Text = "Length: " + TimeSpan.FromMilliseconds(displayedContent.BeatmapInfo.Length).ToString("mm\\:ss");
+ BPM.Text = "| BPM: " + displayedContent.BeatmapInfo.BPM;
+ maxCombo.Text = "| Max Combo: " + displayedContent.BeatmapInfo.TotalObjectCount;
}
public void Move(Vector2 pos) => Position = pos;
From 803329c5d8aa3a73ef9a58875adb8255f241a0ec Mon Sep 17 00:00:00 2001
From: smallketchup82 <69545310+smallketchup82@users.noreply.github.com>
Date: Fri, 22 Dec 2023 15:58:41 -0500
Subject: [PATCH 002/105] rollback my accidental global.json change
---
global.json | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/global.json b/global.json
index 7835999220..d6c2c37f77 100644
--- a/global.json
+++ b/global.json
@@ -1,7 +1,6 @@
{
"sdk": {
- "version": "6.0.0",
- "rollForward": "latestFeature",
- "allowPrerelease": true
+ "version": "6.0.100",
+ "rollForward": "latestFeature"
}
}
\ No newline at end of file
From f7c1e66165b5415a3779961f852677fca073c3d5 Mon Sep 17 00:00:00 2001
From: smallketchup82 <69545310+smallketchup82@users.noreply.github.com>
Date: Fri, 22 Dec 2023 17:28:02 -0500
Subject: [PATCH 003/105] Make the difficulty stats change based on the
currently applied mods
---
osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 10 ++-
.../Drawables/DifficultyIconTooltip.cs | 61 ++++++++++++++-----
.../OnlinePlay/DrawableRoomPlaylistItem.cs | 2 +-
3 files changed, 55 insertions(+), 18 deletions(-)
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
index 1665ec52fa..44981003f2 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
@@ -14,6 +14,7 @@ using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Rulesets;
+using osu.Game.Rulesets.Mods;
using osuTK;
using osuTK.Graphics;
@@ -39,6 +40,8 @@ namespace osu.Game.Beatmaps.Drawables
private readonly IRulesetInfo ruleset;
+ private readonly Mod[]? mods;
+
private Drawable background = null!;
private readonly Container iconContainer;
@@ -58,11 +61,14 @@ namespace osu.Game.Beatmaps.Drawables
/// Creates a new . Will use provided beatmap's for initial value.
///
/// The beatmap to be displayed in the tooltip, and to be used for the initial star rating value.
+ /// The mods type beat
/// An optional ruleset to be used for the icon display, in place of the beatmap's ruleset.
- public DifficultyIcon(IBeatmapInfo beatmap, IRulesetInfo? ruleset = null)
+ public DifficultyIcon(IBeatmapInfo beatmap, IRulesetInfo? ruleset = null, Mod[]? mods = null)
: this(ruleset ?? beatmap.Ruleset)
{
this.beatmap = beatmap;
+ this.mods = mods;
+
Current.Value = new StarDifficulty(beatmap.StarRating, 0);
}
@@ -128,6 +134,6 @@ namespace osu.Game.Beatmaps.Drawables
GetCustomTooltip() => new DifficultyIconTooltip();
DifficultyIconTooltipContent IHasCustomTooltip.
- TooltipContent => (ShowTooltip && beatmap != null ? new DifficultyIconTooltipContent(beatmap, Current) : null)!;
+ TooltipContent => (ShowTooltip && beatmap != null ? new DifficultyIconTooltipContent(beatmap, Current, ruleset, mods) : null)!;
}
}
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
index 7ea2c6a0a2..0f5c94ac1d 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
@@ -4,6 +4,7 @@
#nullable disable
using System;
+using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -12,6 +13,8 @@ using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
+using osu.Game.Rulesets;
+using osu.Game.Rulesets.Mods;
using osuTK;
namespace osu.Game.Beatmaps.Drawables
@@ -24,7 +27,7 @@ namespace osu.Game.Beatmaps.Drawables
private OsuSpriteText drainRate;
private OsuSpriteText circleSize;
private OsuSpriteText approachRate;
- private OsuSpriteText BPM;
+ private OsuSpriteText bpm;
private OsuSpriteText maxCombo;
private OsuSpriteText length;
@@ -66,7 +69,7 @@ namespace osu.Game.Beatmaps.Drawables
Origin = Anchor.Centre,
},
// Difficulty stats
- new FillFlowContainer()
+ new FillFlowContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@@ -81,7 +84,7 @@ namespace osu.Game.Beatmaps.Drawables
Origin = Anchor.Centre,
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold),
},
- overallDifficulty = new OsuSpriteText
+ circleSize = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@@ -93,13 +96,13 @@ namespace osu.Game.Beatmaps.Drawables
Origin = Anchor.Centre,
Font = OsuFont.GetFont(size: 14),
},
- circleSize = new OsuSpriteText
+ approachRate = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Font = OsuFont.GetFont(size: 14),
},
- approachRate = new OsuSpriteText
+ overallDifficulty = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@@ -108,7 +111,7 @@ namespace osu.Game.Beatmaps.Drawables
}
},
// Misc stats
- new FillFlowContainer()
+ new FillFlowContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@@ -129,7 +132,7 @@ namespace osu.Game.Beatmaps.Drawables
Origin = Anchor.Centre,
Font = OsuFont.GetFont(size: 14),
},
- BPM = new OsuSpriteText
+ bpm = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@@ -155,20 +158,44 @@ namespace osu.Game.Beatmaps.Drawables
if (displayedContent != null)
starRating.Current.UnbindFrom(displayedContent.Difficulty);
- // Header row
displayedContent = content;
+
+ // Header row
starRating.Current.BindTarget = displayedContent.Difficulty;
difficultyName.Text = displayedContent.BeatmapInfo.DifficultyName;
+ double rate = 1;
+
+ if (displayedContent.Mods != null)
+ {
+ foreach (var mod in displayedContent.Mods.OfType())
+ rate = mod.ApplyToRate(0, rate);
+ }
+
+ double bpmAdjusted = displayedContent.BeatmapInfo.BPM * rate;
+
+ BeatmapDifficulty originalDifficulty = new BeatmapDifficulty(displayedContent.BeatmapInfo.Difficulty);
+
+ if (displayedContent.Mods != null)
+ {
+ foreach (var mod in displayedContent.Mods.OfType())
+ {
+ mod.ApplyToDifficulty(originalDifficulty);
+ }
+ }
+
+ Ruleset ruleset = displayedContent.Ruleset.CreateInstance();
+ BeatmapDifficulty adjustedDifficulty = ruleset.GetRateAdjustedDisplayDifficulty(originalDifficulty, rate);
+
// Difficulty row
- overallDifficulty.Text = "OD: " + displayedContent.BeatmapInfo.Difficulty.OverallDifficulty.ToString("0.##");
- drainRate.Text = "| HP: " + displayedContent.BeatmapInfo.Difficulty.DrainRate.ToString("0.##");
- circleSize.Text = "| CS: " + displayedContent.BeatmapInfo.Difficulty.CircleSize.ToString("0.##");
- approachRate.Text = "| AR: " + displayedContent.BeatmapInfo.Difficulty.ApproachRate.ToString("0.##");
+ circleSize.Text = "CS: " + adjustedDifficulty.CircleSize.ToString("0.##");
+ drainRate.Text = "| HP: " + adjustedDifficulty.DrainRate.ToString("0.##");
+ approachRate.Text = "| AR: " + adjustedDifficulty.ApproachRate.ToString("0.##");
+ overallDifficulty.Text = "| OD: " + adjustedDifficulty.OverallDifficulty.ToString("0.##");
// Misc row
- length.Text = "Length: " + TimeSpan.FromMilliseconds(displayedContent.BeatmapInfo.Length).ToString("mm\\:ss");
- BPM.Text = "| BPM: " + displayedContent.BeatmapInfo.BPM;
+ length.Text = "Length: " + TimeSpan.FromMilliseconds(displayedContent.BeatmapInfo.Length / rate).ToString("mm\\:ss");
+ bpm.Text = "| BPM: " + bpmAdjusted;
maxCombo.Text = "| Max Combo: " + displayedContent.BeatmapInfo.TotalObjectCount;
}
@@ -183,11 +210,15 @@ namespace osu.Game.Beatmaps.Drawables
{
public readonly IBeatmapInfo BeatmapInfo;
public readonly IBindable Difficulty;
+ public readonly IRulesetInfo Ruleset;
+ public readonly Mod[] Mods;
- public DifficultyIconTooltipContent(IBeatmapInfo beatmapInfo, IBindable difficulty)
+ public DifficultyIconTooltipContent(IBeatmapInfo beatmapInfo, IBindable difficulty, IRulesetInfo rulesetInfo, Mod[] mods)
{
BeatmapInfo = beatmapInfo;
Difficulty = difficulty;
+ Ruleset = rulesetInfo;
+ Mods = mods;
}
}
}
diff --git a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
index 8f405399a7..eb23ed6f8f 100644
--- a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
+++ b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
@@ -283,7 +283,7 @@ namespace osu.Game.Screens.OnlinePlay
}
if (beatmap != null)
- difficultyIconContainer.Child = new DifficultyIcon(beatmap, ruleset) { Size = new Vector2(icon_height) };
+ difficultyIconContainer.Child = new DifficultyIcon(beatmap, ruleset, requiredMods) { Size = new Vector2(icon_height) };
else
difficultyIconContainer.Clear();
From 1d4db3b7a95b894604a0717920fc2771fd7ef352 Mon Sep 17 00:00:00 2001
From: rushiiMachine <33725716+rushiiMachine@users.noreply.github.com>
Date: Tue, 26 Dec 2023 11:08:21 -0800
Subject: [PATCH 004/105] Fix `SkinEditorOverlay` freezing when `ReplayPlayer`
screen exits early
Originally when popping in, the ReplayPlayer was loaded first (if previous screen was MainMenu), and afterwards the SkinEditor component was loaded asynchronously. However, if the ReplayPlayer screen exits quickly (like in the event the beatmap has no objects), the skin editor component has not finished initializing (this is before it was even added to the component tree, so it's still not marked `Visible`), then the screen exiting will cause `OsuGame` to call SetTarget(newScreen) -> setTarget(...) which sees that the cached `skinEditor` is not visible yet, and hides/nulls the field. This is the point where LoadComponentAsync(editor, ...) finishes, and the callback sees that the cached skinEditor field is now different (null) than the one that was loaded, and never adds it to the component tree. This occurrence is unhandled and as such the SkinEditorOverlay never hides itself, consuming all input infinitely.
This PR changes the loading to start loading the ReplayPlayer *after* the SkinEditor has been loaded and added to the component tree.
Additionally, this lowers the exit delay for ReplayPlayer and changes the "no hit objects" notification to not be an error since it's a controlled exit.
---
osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs | 8 ++++----
osu.Game/Screens/Play/Player.cs | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs b/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs
index bedaf12c9b..880921ca64 100644
--- a/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs
+++ b/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs
@@ -100,9 +100,6 @@ namespace osu.Game.Overlays.SkinEditor
{
globallyDisableBeatmapSkinSetting();
- if (lastTargetScreen is MainMenu)
- PresentGameplay();
-
if (skinEditor != null)
{
skinEditor.Show();
@@ -122,6 +119,9 @@ namespace osu.Game.Overlays.SkinEditor
AddInternal(editor);
+ if (lastTargetScreen is MainMenu)
+ PresentGameplay();
+
Debug.Assert(lastTargetScreen != null);
SetTarget(lastTargetScreen);
@@ -316,7 +316,7 @@ namespace osu.Game.Overlays.SkinEditor
base.LoadComplete();
if (!LoadedBeatmapSuccessfully)
- Scheduler.AddDelayed(this.Exit, 3000);
+ Scheduler.AddDelayed(this.Exit, RESULTS_DISPLAY_DELAY);
}
protected override void Update()
diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs
index c960ac357f..08d77d60d8 100644
--- a/osu.Game/Screens/Play/Player.cs
+++ b/osu.Game/Screens/Play/Player.cs
@@ -547,7 +547,7 @@ namespace osu.Game.Screens.Play
if (playable.HitObjects.Count == 0)
{
- Logger.Log("Beatmap contains no hit objects!", level: LogLevel.Error);
+ Logger.Log("Beatmap contains no hit objects!", level: LogLevel.Important);
return null;
}
}
From 85a768d0c806d5c4579b762ae98e938eee135fe7 Mon Sep 17 00:00:00 2001
From: rushiiMachine <33725716+rushiiMachine@users.noreply.github.com>
Date: Tue, 26 Dec 2023 12:46:50 -0800
Subject: [PATCH 005/105] Don't reuse results delay const
---
osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs b/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs
index 880921ca64..10a032193f 100644
--- a/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs
+++ b/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs
@@ -316,7 +316,7 @@ namespace osu.Game.Overlays.SkinEditor
base.LoadComplete();
if (!LoadedBeatmapSuccessfully)
- Scheduler.AddDelayed(this.Exit, RESULTS_DISPLAY_DELAY);
+ Scheduler.AddDelayed(this.Exit, 1000);
}
protected override void Update()
From 0c8b551c6618668902ae1f92e0828f24fd1427f2 Mon Sep 17 00:00:00 2001
From: rushiiMachine <33725716+rushiiMachine@users.noreply.github.com>
Date: Wed, 27 Dec 2023 14:45:56 -0800
Subject: [PATCH 006/105] SkinEditor lifetime fix & show gameplay
If the SkinEditor was created already but not finished initializing, wait for it to initialize before handling a screen change, which could possibly null the skin editor. Additionally, in the case the skin editor is already loaded but hidden, make sure to show gameplay.
---
osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs b/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs
index 10a032193f..5f5323b584 100644
--- a/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs
+++ b/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs
@@ -103,6 +103,10 @@ namespace osu.Game.Overlays.SkinEditor
if (skinEditor != null)
{
skinEditor.Show();
+
+ if (lastTargetScreen is MainMenu)
+ PresentGameplay();
+
return;
}
@@ -252,7 +256,7 @@ namespace osu.Game.Overlays.SkinEditor
Debug.Assert(skinEditor != null);
- if (!target.IsLoaded)
+ if (!target.IsLoaded || !skinEditor.IsLoaded)
{
Scheduler.AddOnce(setTarget, target);
return;
From d2efa2e56a34a28a2656ca30885046aa33cd06f7 Mon Sep 17 00:00:00 2001
From: smallketchup82 <69545310+smallketchup82@users.noreply.github.com>
Date: Sun, 14 Jan 2024 15:47:50 -0500
Subject: [PATCH 007/105] peppy said he prefers the version without pipes so
ill remove the pipes
---
osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
index 0f5c94ac1d..a4ba2a27f6 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
@@ -189,14 +189,14 @@ namespace osu.Game.Beatmaps.Drawables
// Difficulty row
circleSize.Text = "CS: " + adjustedDifficulty.CircleSize.ToString("0.##");
- drainRate.Text = "| HP: " + adjustedDifficulty.DrainRate.ToString("0.##");
- approachRate.Text = "| AR: " + adjustedDifficulty.ApproachRate.ToString("0.##");
- overallDifficulty.Text = "| OD: " + adjustedDifficulty.OverallDifficulty.ToString("0.##");
+ drainRate.Text = " HP: " + adjustedDifficulty.DrainRate.ToString("0.##");
+ approachRate.Text = " AR: " + adjustedDifficulty.ApproachRate.ToString("0.##");
+ overallDifficulty.Text = " OD: " + adjustedDifficulty.OverallDifficulty.ToString("0.##");
// Misc row
length.Text = "Length: " + TimeSpan.FromMilliseconds(displayedContent.BeatmapInfo.Length / rate).ToString("mm\\:ss");
- bpm.Text = "| BPM: " + bpmAdjusted;
- maxCombo.Text = "| Max Combo: " + displayedContent.BeatmapInfo.TotalObjectCount;
+ bpm.Text = " BPM: " + bpmAdjusted;
+ maxCombo.Text = " Max Combo: " + displayedContent.BeatmapInfo.TotalObjectCount;
}
public void Move(Vector2 pos) => Position = pos;
From 0237c9c6d712ee07a9f877b589e80bcf53591045 Mon Sep 17 00:00:00 2001
From: smallketchup82 <69545310+smallketchup82@users.noreply.github.com>
Date: Sun, 14 Jan 2024 15:57:16 -0500
Subject: [PATCH 008/105] peppy said he prefers the version without pipes so
ill remove the pipes
---
global.json | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/global.json b/global.json
index d6c2c37f77..5dcd5f425a 100644
--- a/global.json
+++ b/global.json
@@ -3,4 +3,5 @@
"version": "6.0.100",
"rollForward": "latestFeature"
}
-}
\ No newline at end of file
+}
+
From b6422bc8bdb88a5b19b41992fb90bec6a966368d Mon Sep 17 00:00:00 2001
From: smallketchup82 <69545310+smallketchup82@users.noreply.github.com>
Date: Wed, 17 Jan 2024 09:07:17 -0500
Subject: [PATCH 009/105] Apply suggested changes
- Change difficultyicon mods parameter docstring to be more professional
- Add a parameter for controlling whether the difficulty statistics show or not. Defaults to false
- Round the BPM in the tooltip to make sure it displays correctly
---
osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 10 ++++--
.../Drawables/DifficultyIconTooltip.cs | 34 ++++++++++---------
.../OnlinePlay/DrawableRoomPlaylistItem.cs | 2 +-
3 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
index 44981003f2..9c2a435cb0 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
@@ -42,6 +42,8 @@ namespace osu.Game.Beatmaps.Drawables
private readonly Mod[]? mods;
+ private readonly bool showTooltip;
+
private Drawable background = null!;
private readonly Container iconContainer;
@@ -61,13 +63,15 @@ namespace osu.Game.Beatmaps.Drawables
/// Creates a new . Will use provided beatmap's for initial value.
///
/// The beatmap to be displayed in the tooltip, and to be used for the initial star rating value.
- /// The mods type beat
+ /// An array of mods to account for in the calculations
/// An optional ruleset to be used for the icon display, in place of the beatmap's ruleset.
- public DifficultyIcon(IBeatmapInfo beatmap, IRulesetInfo? ruleset = null, Mod[]? mods = null)
+ /// Whether to display a tooltip on hover. Defaults to false.
+ public DifficultyIcon(IBeatmapInfo beatmap, IRulesetInfo? ruleset = null, Mod[]? mods = null, bool showTooltip = false)
: this(ruleset ?? beatmap.Ruleset)
{
this.beatmap = beatmap;
this.mods = mods;
+ this.showTooltip = showTooltip;
Current.Value = new StarDifficulty(beatmap.StarRating, 0);
}
@@ -134,6 +138,6 @@ namespace osu.Game.Beatmaps.Drawables
GetCustomTooltip() => new DifficultyIconTooltip();
DifficultyIconTooltipContent IHasCustomTooltip.
- TooltipContent => (ShowTooltip && beatmap != null ? new DifficultyIconTooltipContent(beatmap, Current, ruleset, mods) : null)!;
+ TooltipContent => (ShowTooltip && beatmap != null ? new DifficultyIconTooltipContent(beatmap, Current, ruleset, mods, showTooltip) : null)!;
}
}
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
index a4ba2a27f6..c5e276e6b4 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
@@ -31,6 +31,9 @@ namespace osu.Game.Beatmaps.Drawables
private OsuSpriteText maxCombo;
private OsuSpriteText length;
+ private FillFlowContainer difficultyFillFlowContainer;
+ private FillFlowContainer miscFillFlowContainer;
+
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
@@ -69,21 +72,16 @@ namespace osu.Game.Beatmaps.Drawables
Origin = Anchor.Centre,
},
// Difficulty stats
- new FillFlowContainer
+ difficultyFillFlowContainer = new FillFlowContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
+ Alpha = 0,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5),
Children = new Drawable[]
{
- new OsuSpriteText
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold),
- },
circleSize = new OsuSpriteText
{
Anchor = Anchor.Centre,
@@ -111,21 +109,16 @@ namespace osu.Game.Beatmaps.Drawables
}
},
// Misc stats
- new FillFlowContainer
+ miscFillFlowContainer = new FillFlowContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
+ Alpha = 0,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Spacing = new Vector2(5),
Children = new Drawable[]
{
- new OsuSpriteText
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold),
- },
length = new OsuSpriteText
{
Anchor = Anchor.Centre,
@@ -164,6 +157,13 @@ namespace osu.Game.Beatmaps.Drawables
starRating.Current.BindTarget = displayedContent.Difficulty;
difficultyName.Text = displayedContent.BeatmapInfo.DifficultyName;
+ // Don't show difficulty stats if showTooltip is false
+ if (!displayedContent.ShowTooltip) return;
+
+ // Show the difficulty stats if showTooltip is true
+ difficultyFillFlowContainer.Show();
+ miscFillFlowContainer.Show();
+
double rate = 1;
if (displayedContent.Mods != null)
@@ -195,7 +195,7 @@ namespace osu.Game.Beatmaps.Drawables
// Misc row
length.Text = "Length: " + TimeSpan.FromMilliseconds(displayedContent.BeatmapInfo.Length / rate).ToString("mm\\:ss");
- bpm.Text = " BPM: " + bpmAdjusted;
+ bpm.Text = " BPM: " + Math.Round(bpmAdjusted, 0);
maxCombo.Text = " Max Combo: " + displayedContent.BeatmapInfo.TotalObjectCount;
}
@@ -212,13 +212,15 @@ namespace osu.Game.Beatmaps.Drawables
public readonly IBindable Difficulty;
public readonly IRulesetInfo Ruleset;
public readonly Mod[] Mods;
+ public readonly bool ShowTooltip;
- public DifficultyIconTooltipContent(IBeatmapInfo beatmapInfo, IBindable difficulty, IRulesetInfo rulesetInfo, Mod[] mods)
+ public DifficultyIconTooltipContent(IBeatmapInfo beatmapInfo, IBindable difficulty, IRulesetInfo rulesetInfo, Mod[] mods, bool showTooltip = false)
{
BeatmapInfo = beatmapInfo;
Difficulty = difficulty;
Ruleset = rulesetInfo;
Mods = mods;
+ ShowTooltip = showTooltip;
}
}
}
diff --git a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
index eb23ed6f8f..2a6387871f 100644
--- a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
+++ b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
@@ -283,7 +283,7 @@ namespace osu.Game.Screens.OnlinePlay
}
if (beatmap != null)
- difficultyIconContainer.Child = new DifficultyIcon(beatmap, ruleset, requiredMods) { Size = new Vector2(icon_height) };
+ difficultyIconContainer.Child = new DifficultyIcon(beatmap, ruleset, requiredMods, true) { Size = new Vector2(icon_height) };
else
difficultyIconContainer.Clear();
From 9a6541356eb32899ffc54bd1db2a151e3db5b42e Mon Sep 17 00:00:00 2001
From: smallketchup82 <69545310+smallketchup82@users.noreply.github.com>
Date: Wed, 17 Jan 2024 13:31:23 -0500
Subject: [PATCH 010/105] Refactor the extended tooltip variables to be more
descriptive
---
osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 10 +++++-----
osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs | 12 ++++++------
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
index 9c2a435cb0..7a9b2fe389 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
@@ -42,7 +42,7 @@ namespace osu.Game.Beatmaps.Drawables
private readonly Mod[]? mods;
- private readonly bool showTooltip;
+ private readonly bool showExtendedTooltip;
private Drawable background = null!;
@@ -65,13 +65,13 @@ namespace osu.Game.Beatmaps.Drawables
/// The beatmap to be displayed in the tooltip, and to be used for the initial star rating value.
/// An array of mods to account for in the calculations
/// An optional ruleset to be used for the icon display, in place of the beatmap's ruleset.
- /// Whether to display a tooltip on hover. Defaults to false.
- public DifficultyIcon(IBeatmapInfo beatmap, IRulesetInfo? ruleset = null, Mod[]? mods = null, bool showTooltip = false)
+ /// Whether to include the difficulty stats in the tooltip or not. Defaults to false
+ public DifficultyIcon(IBeatmapInfo beatmap, IRulesetInfo? ruleset = null, Mod[]? mods = null, bool showExtendedTooltip = false)
: this(ruleset ?? beatmap.Ruleset)
{
this.beatmap = beatmap;
this.mods = mods;
- this.showTooltip = showTooltip;
+ this.showExtendedTooltip = showExtendedTooltip;
Current.Value = new StarDifficulty(beatmap.StarRating, 0);
}
@@ -138,6 +138,6 @@ namespace osu.Game.Beatmaps.Drawables
GetCustomTooltip() => new DifficultyIconTooltip();
DifficultyIconTooltipContent IHasCustomTooltip.
- TooltipContent => (ShowTooltip && beatmap != null ? new DifficultyIconTooltipContent(beatmap, Current, ruleset, mods, showTooltip) : null)!;
+ TooltipContent => (ShowTooltip && beatmap != null ? new DifficultyIconTooltipContent(beatmap, Current, ruleset, mods, showExtendedTooltip) : null)!;
}
}
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
index c5e276e6b4..fae4100473 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
@@ -157,10 +157,10 @@ namespace osu.Game.Beatmaps.Drawables
starRating.Current.BindTarget = displayedContent.Difficulty;
difficultyName.Text = displayedContent.BeatmapInfo.DifficultyName;
- // Don't show difficulty stats if showTooltip is false
- if (!displayedContent.ShowTooltip) return;
+ // Don't show difficulty stats if showExtendedTooltip is false
+ if (!displayedContent.ShowExtendedTooltip) return;
- // Show the difficulty stats if showTooltip is true
+ // Show the difficulty stats if showExtendedTooltip is true
difficultyFillFlowContainer.Show();
miscFillFlowContainer.Show();
@@ -212,15 +212,15 @@ namespace osu.Game.Beatmaps.Drawables
public readonly IBindable Difficulty;
public readonly IRulesetInfo Ruleset;
public readonly Mod[] Mods;
- public readonly bool ShowTooltip;
+ public readonly bool ShowExtendedTooltip;
- public DifficultyIconTooltipContent(IBeatmapInfo beatmapInfo, IBindable difficulty, IRulesetInfo rulesetInfo, Mod[] mods, bool showTooltip = false)
+ public DifficultyIconTooltipContent(IBeatmapInfo beatmapInfo, IBindable difficulty, IRulesetInfo rulesetInfo, Mod[] mods, bool showExtendedTooltip = false)
{
BeatmapInfo = beatmapInfo;
Difficulty = difficulty;
Ruleset = rulesetInfo;
Mods = mods;
- ShowTooltip = showTooltip;
+ ShowExtendedTooltip = showExtendedTooltip;
}
}
}
From 060ea1d4fd82899991eae7b9cdd8468c18dc551c Mon Sep 17 00:00:00 2001
From: smallketchup82 <69545310+smallketchup82@users.noreply.github.com>
Date: Wed, 17 Jan 2024 14:04:13 -0500
Subject: [PATCH 011/105] Switch from using a constructor argument to using a
public field for ShowExtendedTooltip
---
osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 13 +++++++------
.../Screens/OnlinePlay/DrawableRoomPlaylistItem.cs | 8 +++++++-
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
index 7a9b2fe389..fc78d6f322 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
@@ -36,14 +36,17 @@ namespace osu.Game.Beatmaps.Drawables
///
public bool ShowTooltip { get; set; } = true;
+ ///
+ /// Whether to include the difficulty stats in the tooltip or not. Defaults to false. Has no effect if is false.
+ ///
+ public bool ShowExtendedTooltip { get; set; }
+
private readonly IBeatmapInfo? beatmap;
private readonly IRulesetInfo ruleset;
private readonly Mod[]? mods;
- private readonly bool showExtendedTooltip;
-
private Drawable background = null!;
private readonly Container iconContainer;
@@ -65,13 +68,11 @@ namespace osu.Game.Beatmaps.Drawables
/// The beatmap to be displayed in the tooltip, and to be used for the initial star rating value.
/// An array of mods to account for in the calculations
/// An optional ruleset to be used for the icon display, in place of the beatmap's ruleset.
- /// Whether to include the difficulty stats in the tooltip or not. Defaults to false
- public DifficultyIcon(IBeatmapInfo beatmap, IRulesetInfo? ruleset = null, Mod[]? mods = null, bool showExtendedTooltip = false)
+ public DifficultyIcon(IBeatmapInfo beatmap, IRulesetInfo? ruleset = null, Mod[]? mods = null)
: this(ruleset ?? beatmap.Ruleset)
{
this.beatmap = beatmap;
this.mods = mods;
- this.showExtendedTooltip = showExtendedTooltip;
Current.Value = new StarDifficulty(beatmap.StarRating, 0);
}
@@ -138,6 +139,6 @@ namespace osu.Game.Beatmaps.Drawables
GetCustomTooltip() => new DifficultyIconTooltip();
DifficultyIconTooltipContent IHasCustomTooltip.
- TooltipContent => (ShowTooltip && beatmap != null ? new DifficultyIconTooltipContent(beatmap, Current, ruleset, mods, showExtendedTooltip) : null)!;
+ TooltipContent => (ShowTooltip && beatmap != null ? new DifficultyIconTooltipContent(beatmap, Current, ruleset, mods, ShowExtendedTooltip) : null)!;
}
}
diff --git a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
index 2a6387871f..8cfdc2e0e2 100644
--- a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
+++ b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
@@ -283,7 +283,13 @@ namespace osu.Game.Screens.OnlinePlay
}
if (beatmap != null)
- difficultyIconContainer.Child = new DifficultyIcon(beatmap, ruleset, requiredMods, true) { Size = new Vector2(icon_height) };
+ {
+ difficultyIconContainer.Child = new DifficultyIcon(beatmap, ruleset, requiredMods)
+ {
+ Size = new Vector2(icon_height),
+ ShowExtendedTooltip = true
+ };
+ }
else
difficultyIconContainer.Clear();
From d80a5d44eedca57e8be969d771152edb4fe4b229 Mon Sep 17 00:00:00 2001
From: smallketchup82 <69545310+smallketchup82@users.noreply.github.com>
Date: Thu, 18 Jan 2024 03:17:37 -0500
Subject: [PATCH 012/105] Add tests for DifficultyIcon
---
.../Beatmaps/TestSceneDifficultyIcon.cs | 42 +++++++++++++++++++
1 file changed, 42 insertions(+)
create mode 100644 osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
new file mode 100644
index 0000000000..aa2543eea1
--- /dev/null
+++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
@@ -0,0 +1,42 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+#nullable disable
+
+using NUnit.Framework;
+using osu.Framework.Allocation;
+using osu.Framework.Audio;
+using osu.Framework.Platform;
+using osu.Game.Beatmaps.Drawables;
+using osu.Game.Rulesets;
+using osu.Game.Rulesets.Osu;
+using osu.Game.Tests.Beatmaps;
+
+namespace osu.Game.Tests.Visual.Beatmaps
+{
+ public partial class TestSceneDifficultyIcon : OsuTestScene
+ {
+ [Test]
+ public void createDifficultyIcon()
+ {
+ DifficultyIcon difficultyIcon = null;
+
+ AddStep("create difficulty icon", () =>
+ {
+ Child = difficultyIcon = new DifficultyIcon(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo, new OsuRuleset().RulesetInfo)
+ {
+ ShowTooltip = true,
+ ShowExtendedTooltip = true
+ };
+ });
+
+ AddStep("hide extended tooltip", () => difficultyIcon.ShowExtendedTooltip = false);
+
+ AddStep("hide tooltip", () => difficultyIcon.ShowTooltip = false);
+
+ AddStep("show tooltip", () => difficultyIcon.ShowTooltip = true);
+
+ AddStep("show extended tooltip", () => difficultyIcon.ShowExtendedTooltip = true);
+ }
+ }
+}
From 5c70c786b4581d91c5b2d069e04b9d774cf79351 Mon Sep 17 00:00:00 2001
From: smallketchup82 <69545310+smallketchup82@users.noreply.github.com>
Date: Thu, 18 Jan 2024 03:18:44 -0500
Subject: [PATCH 013/105] Fix extended tooltip content still being shown
despite ShowExtendedTooltip being false
---
osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
index fae4100473..fe23b49346 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
@@ -158,7 +158,12 @@ namespace osu.Game.Beatmaps.Drawables
difficultyName.Text = displayedContent.BeatmapInfo.DifficultyName;
// Don't show difficulty stats if showExtendedTooltip is false
- if (!displayedContent.ShowExtendedTooltip) return;
+ if (!displayedContent.ShowExtendedTooltip)
+ {
+ difficultyFillFlowContainer.Hide();
+ miscFillFlowContainer.Hide();
+ return;
+ }
// Show the difficulty stats if showExtendedTooltip is true
difficultyFillFlowContainer.Show();
From 87369f8a808b29e3da0bde82027a439e763532dc Mon Sep 17 00:00:00 2001
From: smallketchup82 <69545310+smallketchup82@users.noreply.github.com>
Date: Thu, 18 Jan 2024 11:16:03 -0500
Subject: [PATCH 014/105] Conform to code style & remove unused imports
---
osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
index aa2543eea1..79f9aec2e3 100644
--- a/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
+++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
@@ -4,11 +4,7 @@
#nullable disable
using NUnit.Framework;
-using osu.Framework.Allocation;
-using osu.Framework.Audio;
-using osu.Framework.Platform;
using osu.Game.Beatmaps.Drawables;
-using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu;
using osu.Game.Tests.Beatmaps;
@@ -17,7 +13,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
public partial class TestSceneDifficultyIcon : OsuTestScene
{
[Test]
- public void createDifficultyIcon()
+ public void CreateDifficultyIcon()
{
DifficultyIcon difficultyIcon = null;
From f12be60d8d33471fc8acb4ee54c369f4f4e928e8 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Mon, 22 Jan 2024 17:18:22 +0900
Subject: [PATCH 015/105] Make test actually test multiple icons
---
.../Beatmaps/TestSceneDifficultyIcon.cs | 39 +++++++++++++++++--
1 file changed, 35 insertions(+), 4 deletions(-)
diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
index 79f9aec2e3..80320c138b 100644
--- a/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
+++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
@@ -4,27 +4,58 @@
#nullable disable
using NUnit.Framework;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Utils;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Rulesets.Osu;
using osu.Game.Tests.Beatmaps;
+using osuTK;
namespace osu.Game.Tests.Visual.Beatmaps
{
public partial class TestSceneDifficultyIcon : OsuTestScene
{
+ private FillFlowContainer fill;
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ Child = fill = new FillFlowContainer
+ {
+ AutoSizeAxes = Axes.Y,
+ Width = 300,
+ Direction = FillDirection.Full,
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ };
+ }
+
[Test]
public void CreateDifficultyIcon()
{
DifficultyIcon difficultyIcon = null;
- AddStep("create difficulty icon", () =>
+ AddRepeatStep("create difficulty icon", () =>
{
- Child = difficultyIcon = new DifficultyIcon(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo, new OsuRuleset().RulesetInfo)
+ var rulesetInfo = new OsuRuleset().RulesetInfo;
+ var beatmapInfo = new TestBeatmap(rulesetInfo).BeatmapInfo;
+
+ beatmapInfo.Difficulty.ApproachRate = RNG.Next(0, 10);
+ beatmapInfo.Difficulty.CircleSize = RNG.Next(0, 10);
+ beatmapInfo.Difficulty.OverallDifficulty = RNG.Next(0, 10);
+ beatmapInfo.Difficulty.DrainRate = RNG.Next(0, 10);
+ beatmapInfo.StarRating = RNG.NextSingle(0, 10);
+ beatmapInfo.BPM = RNG.Next(60, 300);
+
+ fill.Add(difficultyIcon = new DifficultyIcon(beatmapInfo, rulesetInfo)
{
+ Scale = new Vector2(2),
ShowTooltip = true,
ShowExtendedTooltip = true
- };
- });
+ });
+ }, 10);
AddStep("hide extended tooltip", () => difficultyIcon.ShowExtendedTooltip = false);
From 2305a53a02b23185d83a9740ce876350adc711cc Mon Sep 17 00:00:00 2001
From: smallketchup82 <69545310+smallketchup82@users.noreply.github.com>
Date: Mon, 22 Jan 2024 08:59:37 -0500
Subject: [PATCH 016/105] Remove max combo reading & remove unnecessary commas
---
.../Drawables/DifficultyIconTooltip.cs | 26 +++++++------------
1 file changed, 9 insertions(+), 17 deletions(-)
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
index fe23b49346..7fe0080e89 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
@@ -28,7 +28,6 @@ namespace osu.Game.Beatmaps.Drawables
private OsuSpriteText circleSize;
private OsuSpriteText approachRate;
private OsuSpriteText bpm;
- private OsuSpriteText maxCombo;
private OsuSpriteText length;
private FillFlowContainer difficultyFillFlowContainer;
@@ -64,12 +63,12 @@ namespace osu.Game.Beatmaps.Drawables
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 16, weight: FontWeight.Bold),
+ Font = OsuFont.GetFont(size: 16, weight: FontWeight.Bold)
},
starRating = new StarRatingDisplay(default, StarRatingDisplaySize.Small)
{
Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
+ Origin = Anchor.Centre
},
// Difficulty stats
difficultyFillFlowContainer = new FillFlowContainer
@@ -86,26 +85,26 @@ namespace osu.Game.Beatmaps.Drawables
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14),
+ Font = OsuFont.GetFont(size: 14)
},
drainRate = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14),
+ Font = OsuFont.GetFont(size: 14)
},
approachRate = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14),
+ Font = OsuFont.GetFont(size: 14)
},
overallDifficulty = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14),
- },
+ Font = OsuFont.GetFont(size: 14)
+ }
}
},
// Misc stats
@@ -123,19 +122,13 @@ namespace osu.Game.Beatmaps.Drawables
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14),
+ Font = OsuFont.GetFont(size: 14)
},
bpm = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14),
- },
- maxCombo = new OsuSpriteText
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14),
+ Font = OsuFont.GetFont(size: 14)
},
}
}
@@ -201,7 +194,6 @@ namespace osu.Game.Beatmaps.Drawables
// Misc row
length.Text = "Length: " + TimeSpan.FromMilliseconds(displayedContent.BeatmapInfo.Length / rate).ToString("mm\\:ss");
bpm.Text = " BPM: " + Math.Round(bpmAdjusted, 0);
- maxCombo.Text = " Max Combo: " + displayedContent.BeatmapInfo.TotalObjectCount;
}
public void Move(Vector2 pos) => Position = pos;
From 64ba95bbd664964409224a8f589b473af7d6ca1e Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Thu, 25 Jan 2024 21:11:33 +0900
Subject: [PATCH 017/105] Remove pointless comments
---
osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs | 8 --------
1 file changed, 8 deletions(-)
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
index 7fe0080e89..6caaab1508 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
@@ -48,7 +48,6 @@ namespace osu.Game.Beatmaps.Drawables
Colour = colours.Gray3,
RelativeSizeAxes = Axes.Both
},
- // Headers
new FillFlowContainer
{
AutoSizeAxes = Axes.Both,
@@ -70,7 +69,6 @@ namespace osu.Game.Beatmaps.Drawables
Anchor = Anchor.Centre,
Origin = Anchor.Centre
},
- // Difficulty stats
difficultyFillFlowContainer = new FillFlowContainer
{
Anchor = Anchor.Centre,
@@ -107,7 +105,6 @@ namespace osu.Game.Beatmaps.Drawables
}
}
},
- // Misc stats
miscFillFlowContainer = new FillFlowContainer
{
Anchor = Anchor.Centre,
@@ -146,11 +143,9 @@ namespace osu.Game.Beatmaps.Drawables
displayedContent = content;
- // Header row
starRating.Current.BindTarget = displayedContent.Difficulty;
difficultyName.Text = displayedContent.BeatmapInfo.DifficultyName;
- // Don't show difficulty stats if showExtendedTooltip is false
if (!displayedContent.ShowExtendedTooltip)
{
difficultyFillFlowContainer.Hide();
@@ -158,7 +153,6 @@ namespace osu.Game.Beatmaps.Drawables
return;
}
- // Show the difficulty stats if showExtendedTooltip is true
difficultyFillFlowContainer.Show();
miscFillFlowContainer.Show();
@@ -185,13 +179,11 @@ namespace osu.Game.Beatmaps.Drawables
Ruleset ruleset = displayedContent.Ruleset.CreateInstance();
BeatmapDifficulty adjustedDifficulty = ruleset.GetRateAdjustedDisplayDifficulty(originalDifficulty, rate);
- // Difficulty row
circleSize.Text = "CS: " + adjustedDifficulty.CircleSize.ToString("0.##");
drainRate.Text = " HP: " + adjustedDifficulty.DrainRate.ToString("0.##");
approachRate.Text = " AR: " + adjustedDifficulty.ApproachRate.ToString("0.##");
overallDifficulty.Text = " OD: " + adjustedDifficulty.OverallDifficulty.ToString("0.##");
- // Misc row
length.Text = "Length: " + TimeSpan.FromMilliseconds(displayedContent.BeatmapInfo.Length / rate).ToString("mm\\:ss");
bpm.Text = " BPM: " + Math.Round(bpmAdjusted, 0);
}
From 3c18efed0530c362ae363c84f5a5321c7e60eb3e Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Thu, 25 Jan 2024 21:13:25 +0900
Subject: [PATCH 018/105] Remove transparency
---
osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
index 6caaab1508..fa07b150d5 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
@@ -44,7 +44,6 @@ namespace osu.Game.Beatmaps.Drawables
{
new Box
{
- Alpha = 0.9f,
Colour = colours.Gray3,
RelativeSizeAxes = Axes.Both
},
From aeac0a2a9d83c741b65c81e04ab445061d94324d Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Thu, 25 Jan 2024 21:16:12 +0900
Subject: [PATCH 019/105] Nullability
---
.../Drawables/DifficultyIconTooltip.cs | 38 +++++++++----------
1 file changed, 18 insertions(+), 20 deletions(-)
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
index fa07b150d5..803618f15e 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using System.Linq;
using osu.Framework.Allocation;
@@ -21,17 +19,17 @@ namespace osu.Game.Beatmaps.Drawables
{
internal partial class DifficultyIconTooltip : VisibilityContainer, ITooltip
{
- private OsuSpriteText difficultyName;
- private StarRatingDisplay starRating;
- private OsuSpriteText overallDifficulty;
- private OsuSpriteText drainRate;
- private OsuSpriteText circleSize;
- private OsuSpriteText approachRate;
- private OsuSpriteText bpm;
- private OsuSpriteText length;
+ private OsuSpriteText difficultyName = null!;
+ private StarRatingDisplay starRating = null!;
+ private OsuSpriteText overallDifficulty = null!;
+ private OsuSpriteText drainRate = null!;
+ private OsuSpriteText circleSize = null!;
+ private OsuSpriteText approachRate = null!;
+ private OsuSpriteText bpm = null!;
+ private OsuSpriteText length = null!;
- private FillFlowContainer difficultyFillFlowContainer;
- private FillFlowContainer miscFillFlowContainer;
+ private FillFlowContainer difficultyFillFlowContainer = null!;
+ private FillFlowContainer miscFillFlowContainer = null!;
[BackgroundDependencyLoader]
private void load(OsuColour colours)
@@ -133,7 +131,7 @@ namespace osu.Game.Beatmaps.Drawables
};
}
- private DifficultyIconTooltipContent displayedContent;
+ private DifficultyIconTooltipContent? displayedContent;
public void SetContent(DifficultyIconTooltipContent content)
{
@@ -178,12 +176,12 @@ namespace osu.Game.Beatmaps.Drawables
Ruleset ruleset = displayedContent.Ruleset.CreateInstance();
BeatmapDifficulty adjustedDifficulty = ruleset.GetRateAdjustedDisplayDifficulty(originalDifficulty, rate);
- circleSize.Text = "CS: " + adjustedDifficulty.CircleSize.ToString("0.##");
- drainRate.Text = " HP: " + adjustedDifficulty.DrainRate.ToString("0.##");
- approachRate.Text = " AR: " + adjustedDifficulty.ApproachRate.ToString("0.##");
- overallDifficulty.Text = " OD: " + adjustedDifficulty.OverallDifficulty.ToString("0.##");
+ circleSize.Text = @"CS: " + adjustedDifficulty.CircleSize.ToString(@"0.##");
+ drainRate.Text = @" HP: " + adjustedDifficulty.DrainRate.ToString(@"0.##");
+ approachRate.Text = @" AR: " + adjustedDifficulty.ApproachRate.ToString(@"0.##");
+ overallDifficulty.Text = @" OD: " + adjustedDifficulty.OverallDifficulty.ToString(@"0.##");
- length.Text = "Length: " + TimeSpan.FromMilliseconds(displayedContent.BeatmapInfo.Length / rate).ToString("mm\\:ss");
+ length.Text = "Length: " + TimeSpan.FromMilliseconds(displayedContent.BeatmapInfo.Length / rate).ToString(@"mm\:ss");
bpm.Text = " BPM: " + Math.Round(bpmAdjusted, 0);
}
@@ -199,10 +197,10 @@ namespace osu.Game.Beatmaps.Drawables
public readonly IBeatmapInfo BeatmapInfo;
public readonly IBindable Difficulty;
public readonly IRulesetInfo Ruleset;
- public readonly Mod[] Mods;
+ public readonly Mod[]? Mods;
public readonly bool ShowExtendedTooltip;
- public DifficultyIconTooltipContent(IBeatmapInfo beatmapInfo, IBindable difficulty, IRulesetInfo rulesetInfo, Mod[] mods, bool showExtendedTooltip = false)
+ public DifficultyIconTooltipContent(IBeatmapInfo beatmapInfo, IBindable difficulty, IRulesetInfo rulesetInfo, Mod[]? mods, bool showExtendedTooltip = false)
{
BeatmapInfo = beatmapInfo;
Difficulty = difficulty;
From 50300adef86222ed1554f512dafe857cf25d2cf3 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Thu, 25 Jan 2024 21:17:29 +0900
Subject: [PATCH 020/105] Tidy things up
---
.../Drawables/DifficultyIconTooltip.cs | 44 +++----------------
1 file changed, 6 insertions(+), 38 deletions(-)
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
index 803618f15e..71366de654 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
@@ -76,30 +76,10 @@ namespace osu.Game.Beatmaps.Drawables
Spacing = new Vector2(5),
Children = new Drawable[]
{
- circleSize = new OsuSpriteText
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14)
- },
- drainRate = new OsuSpriteText
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14)
- },
- approachRate = new OsuSpriteText
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14)
- },
- overallDifficulty = new OsuSpriteText
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14)
- }
+ circleSize = new OsuSpriteText { Font = OsuFont.GetFont(size: 14) },
+ drainRate = new OsuSpriteText { Font = OsuFont.GetFont(size: 14) },
+ approachRate = new OsuSpriteText { Font = OsuFont.GetFont(size: 14) },
+ overallDifficulty = new OsuSpriteText { Font = OsuFont.GetFont(size: 14) }
}
},
miscFillFlowContainer = new FillFlowContainer
@@ -112,18 +92,8 @@ namespace osu.Game.Beatmaps.Drawables
Spacing = new Vector2(5),
Children = new Drawable[]
{
- length = new OsuSpriteText
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14)
- },
- bpm = new OsuSpriteText
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Font = OsuFont.GetFont(size: 14)
- },
+ length = new OsuSpriteText { Font = OsuFont.GetFont(size: 14) },
+ bpm = new OsuSpriteText { Font = OsuFont.GetFont(size: 14) },
}
}
}
@@ -168,9 +138,7 @@ namespace osu.Game.Beatmaps.Drawables
if (displayedContent.Mods != null)
{
foreach (var mod in displayedContent.Mods.OfType())
- {
mod.ApplyToDifficulty(originalDifficulty);
- }
}
Ruleset ruleset = displayedContent.Ruleset.CreateInstance();
From 5d456c8d68fe61fa6fc97f8db235b0c6d429a55d Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Mon, 29 Jan 2024 04:55:21 +0300
Subject: [PATCH 021/105] Rework drawing of graded circles
---
.../Expanded/Accuracy/AccuracyCircle.cs | 87 +++++++++++--------
1 file changed, 52 insertions(+), 35 deletions(-)
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
index 0aff98df2b..8d32989110 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
@@ -169,46 +169,63 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
{
new CircularProgress
{
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.ForRank(ScoreRank.X),
- InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyX }
- },
- new CircularProgress
- {
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.ForRank(ScoreRank.S),
- InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyX - virtual_ss_percentage }
- },
- new CircularProgress
- {
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.ForRank(ScoreRank.A),
- InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyS }
- },
- new CircularProgress
- {
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.ForRank(ScoreRank.B),
- InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyA }
- },
- new CircularProgress
- {
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.ForRank(ScoreRank.C),
- InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyB }
- },
- new CircularProgress
- {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.ForRank(ScoreRank.D),
InnerRadius = RANK_CIRCLE_RADIUS,
Current = { Value = accuracyC }
},
+ new CircularProgress
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.ForRank(ScoreRank.C),
+ InnerRadius = RANK_CIRCLE_RADIUS,
+ Current = { Value = accuracyB - accuracyC },
+ Rotation = (float)accuracyC * 360
+ },
+ new CircularProgress
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.ForRank(ScoreRank.B),
+ InnerRadius = RANK_CIRCLE_RADIUS,
+ Current = { Value = accuracyA - accuracyB },
+ Rotation = (float)accuracyB * 360
+ },
+ new CircularProgress
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.ForRank(ScoreRank.A),
+ InnerRadius = RANK_CIRCLE_RADIUS,
+ Current = { Value = accuracyS - accuracyA },
+ Rotation = (float)accuracyA * 360
+ },
+ new CircularProgress
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.ForRank(ScoreRank.S),
+ InnerRadius = RANK_CIRCLE_RADIUS,
+ Current = { Value = accuracyX - accuracyS - virtual_ss_percentage },
+ Rotation = (float)accuracyS * 360
+ },
+ new CircularProgress
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.ForRank(ScoreRank.X),
+ InnerRadius = RANK_CIRCLE_RADIUS,
+ Current = { Value = 1f - (accuracyX - virtual_ss_percentage) },
+ Rotation = (float)(accuracyX - virtual_ss_percentage) * 360
+ },
new RankNotch((float)accuracyX),
new RankNotch((float)(accuracyX - virtual_ss_percentage)),
new RankNotch((float)accuracyS),
From 32b0e0b7380fcb54219fea66b4f46f2a83ece1e1 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Mon, 29 Jan 2024 05:05:18 +0300
Subject: [PATCH 022/105] Remove RankNotch
---
.../Expanded/Accuracy/AccuracyCircle.cs | 33 ++++++-------
.../Ranking/Expanded/Accuracy/RankNotch.cs | 49 -------------------
2 files changed, 14 insertions(+), 68 deletions(-)
delete mode 100644 osu.Game/Screens/Ranking/Expanded/Accuracy/RankNotch.cs
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
index 8d32989110..7bd586ebb7 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
@@ -76,9 +76,9 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
private const double virtual_ss_percentage = 0.01;
///
- /// The width of a in terms of accuracy.
+ /// The width of a solid "notch" in terms of accuracy that appears at the ends of the rank circles to add separation.
///
- public const double NOTCH_WIDTH_PERCENTAGE = 1.0 / 360;
+ public const float NOTCH_WIDTH_PERCENTAGE = 2f / 360;
///
/// The easing for the circle filling transforms.
@@ -174,7 +174,8 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.ForRank(ScoreRank.D),
InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyC }
+ Current = { Value = accuracyC - NOTCH_WIDTH_PERCENTAGE },
+ Rotation = NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
},
new CircularProgress
{
@@ -183,8 +184,8 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.ForRank(ScoreRank.C),
InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyB - accuracyC },
- Rotation = (float)accuracyC * 360
+ Current = { Value = accuracyB - accuracyC - NOTCH_WIDTH_PERCENTAGE },
+ Rotation = (float)accuracyC * 360 + NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
},
new CircularProgress
{
@@ -193,8 +194,8 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.ForRank(ScoreRank.B),
InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyA - accuracyB },
- Rotation = (float)accuracyB * 360
+ Current = { Value = accuracyA - accuracyB - NOTCH_WIDTH_PERCENTAGE },
+ Rotation = (float)accuracyB * 360 + NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
},
new CircularProgress
{
@@ -203,8 +204,8 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.ForRank(ScoreRank.A),
InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyS - accuracyA },
- Rotation = (float)accuracyA * 360
+ Current = { Value = accuracyS - accuracyA - NOTCH_WIDTH_PERCENTAGE },
+ Rotation = (float)accuracyA * 360 + NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
},
new CircularProgress
{
@@ -213,8 +214,8 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.ForRank(ScoreRank.S),
InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyX - accuracyS - virtual_ss_percentage },
- Rotation = (float)accuracyS * 360
+ Current = { Value = accuracyX - accuracyS - virtual_ss_percentage - NOTCH_WIDTH_PERCENTAGE },
+ Rotation = (float)accuracyS * 360 + NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
},
new CircularProgress
{
@@ -223,15 +224,9 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.ForRank(ScoreRank.X),
InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = 1f - (accuracyX - virtual_ss_percentage) },
- Rotation = (float)(accuracyX - virtual_ss_percentage) * 360
+ Current = { Value = 1f - (accuracyX - virtual_ss_percentage) - NOTCH_WIDTH_PERCENTAGE },
+ Rotation = (float)(accuracyX - virtual_ss_percentage) * 360 + NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
},
- new RankNotch((float)accuracyX),
- new RankNotch((float)(accuracyX - virtual_ss_percentage)),
- new RankNotch((float)accuracyS),
- new RankNotch((float)accuracyA),
- new RankNotch((float)accuracyB),
- new RankNotch((float)accuracyC),
new BufferedContainer
{
Name = "Graded circle mask",
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/RankNotch.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/RankNotch.cs
deleted file mode 100644
index 244acbe8b1..0000000000
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/RankNotch.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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 osuTK;
-
-namespace osu.Game.Screens.Ranking.Expanded.Accuracy
-{
- ///
- /// A solid "notch" of the that appears at the ends of the rank circles to add separation.
- ///
- public partial class RankNotch : CompositeDrawable
- {
- private readonly float position;
-
- public RankNotch(float position)
- {
- this.position = position;
-
- RelativeSizeAxes = Axes.Both;
- }
-
- [BackgroundDependencyLoader]
- private void load()
- {
- InternalChild = new Container
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Rotation = position * 360f,
- Child = new Box
- {
- Anchor = Anchor.TopCentre,
- Origin = Anchor.TopCentre,
- RelativeSizeAxes = Axes.Y,
- Height = AccuracyCircle.RANK_CIRCLE_RADIUS,
- Width = (float)AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 360f,
- Colour = OsuColour.Gray(0.3f),
- EdgeSmoothness = new Vector2(1f)
- }
- };
- }
- }
-}
From 5783838b07df8420916904ab307f91b23fb8a6ad Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Mon, 29 Jan 2024 05:14:24 +0300
Subject: [PATCH 023/105] Move graded circles into a separate class
---
.../Expanded/Accuracy/AccuracyCircle.cs | 105 ++--------------
.../Expanded/Accuracy/GradedCircles.cs | 113 ++++++++++++++++++
2 files changed, 120 insertions(+), 98 deletions(-)
create mode 100644 osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
index 7bd586ebb7..3141810894 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
@@ -20,7 +20,6 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Skinning;
-using osuTK;
using osuTK.Graphics;
namespace osu.Game.Screens.Ranking.Expanded.Accuracy
@@ -73,7 +72,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
///
/// SS is displayed as a 1% region, otherwise it would be invisible.
///
- private const double virtual_ss_percentage = 0.01;
+ public const double VIRTUAL_SS_PERCENTAGE = 0.01;
///
/// The width of a solid "notch" in terms of accuracy that appears at the ends of the rank circles to add separation.
@@ -88,7 +87,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
private readonly ScoreInfo score;
private CircularProgress accuracyCircle;
- private CircularProgress innerMask;
+ private GradedCircles gradedCircles;
private Container badges;
private RankText rankText;
@@ -157,96 +156,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
Colour = ColourInfo.GradientVertical(Color4Extensions.FromHex("#7CF6FF"), Color4Extensions.FromHex("#BAFFA9")),
InnerRadius = accuracy_circle_radius,
},
- new BufferedContainer
- {
- Name = "Graded circles",
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Size = new Vector2(0.8f),
- Padding = new MarginPadding(2),
- Children = new Drawable[]
- {
- new CircularProgress
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.ForRank(ScoreRank.D),
- InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyC - NOTCH_WIDTH_PERCENTAGE },
- Rotation = NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
- },
- new CircularProgress
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.ForRank(ScoreRank.C),
- InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyB - accuracyC - NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)accuracyC * 360 + NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
- },
- new CircularProgress
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.ForRank(ScoreRank.B),
- InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyA - accuracyB - NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)accuracyB * 360 + NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
- },
- new CircularProgress
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.ForRank(ScoreRank.A),
- InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyS - accuracyA - NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)accuracyA * 360 + NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
- },
- new CircularProgress
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.ForRank(ScoreRank.S),
- InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyX - accuracyS - virtual_ss_percentage - NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)accuracyS * 360 + NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
- },
- new CircularProgress
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.ForRank(ScoreRank.X),
- InnerRadius = RANK_CIRCLE_RADIUS,
- Current = { Value = 1f - (accuracyX - virtual_ss_percentage) - NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)(accuracyX - virtual_ss_percentage) * 360 + NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
- },
- new BufferedContainer
- {
- Name = "Graded circle mask",
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding(1),
- Blending = new BlendingParameters
- {
- Source = BlendingType.DstColor,
- Destination = BlendingType.OneMinusSrcColor,
- SourceAlpha = BlendingType.One,
- DestinationAlpha = BlendingType.SrcAlpha
- },
- Child = innerMask = new CircularProgress
- {
- RelativeSizeAxes = Axes.Both,
- InnerRadius = RANK_CIRCLE_RADIUS - 0.02f,
- }
- }
- }
- },
+ gradedCircles = new GradedCircles(accuracyC, accuracyB, accuracyA, accuracyS, accuracyX),
badges = new Container
{
Name = "Rank badges",
@@ -259,7 +169,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
new RankBadge(accuracyB, Interpolation.Lerp(accuracyB, accuracyA, 0.5), getRank(ScoreRank.B)),
// The S and A badges are moved down slightly to prevent collision with the SS badge.
new RankBadge(accuracyA, Interpolation.Lerp(accuracyA, accuracyS, 0.25), getRank(ScoreRank.A)),
- new RankBadge(accuracyS, Interpolation.Lerp(accuracyS, (accuracyX - virtual_ss_percentage), 0.25), getRank(ScoreRank.S)),
+ new RankBadge(accuracyS, Interpolation.Lerp(accuracyS, (accuracyX - VIRTUAL_SS_PERCENTAGE), 0.25), getRank(ScoreRank.S)),
new RankBadge(accuracyX, accuracyX, getRank(ScoreRank.X)),
}
},
@@ -301,8 +211,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
});
}
- using (BeginDelayedSequence(RANK_CIRCLE_TRANSFORM_DELAY))
- innerMask.FillTo(1f, RANK_CIRCLE_TRANSFORM_DURATION, ACCURACY_TRANSFORM_EASING);
+ gradedCircles.Transform();
using (BeginDelayedSequence(ACCURACY_TRANSFORM_DELAY))
{
@@ -331,7 +240,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
if (score.Rank == ScoreRank.X || score.Rank == ScoreRank.XH)
targetAccuracy = 1;
else
- targetAccuracy = Math.Min(accuracyX - virtual_ss_percentage - NOTCH_WIDTH_PERCENTAGE / 2, targetAccuracy);
+ targetAccuracy = Math.Min(accuracyX - VIRTUAL_SS_PERCENTAGE - NOTCH_WIDTH_PERCENTAGE / 2, targetAccuracy);
// The accuracy circle gauge visually fills up a bit too much.
// This wouldn't normally matter but we want it to align properly with the inner graded circle in the above cases.
@@ -368,7 +277,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
if (badge.Accuracy > score.Accuracy)
continue;
- using (BeginDelayedSequence(inverseEasing(ACCURACY_TRANSFORM_EASING, Math.Min(accuracyX - virtual_ss_percentage, badge.Accuracy) / targetAccuracy) * ACCURACY_TRANSFORM_DURATION))
+ using (BeginDelayedSequence(inverseEasing(ACCURACY_TRANSFORM_EASING, Math.Min(accuracyX - VIRTUAL_SS_PERCENTAGE, badge.Accuracy) / targetAccuracy) * ACCURACY_TRANSFORM_DURATION))
{
badge.Appear();
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
new file mode 100644
index 0000000000..51c4237528
--- /dev/null
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
@@ -0,0 +1,113 @@
+// 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.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.UserInterface;
+using osu.Game.Graphics;
+using osu.Game.Scoring;
+using osuTK;
+
+namespace osu.Game.Screens.Ranking.Expanded.Accuracy
+{
+ public partial class GradedCircles : BufferedContainer
+ {
+ private readonly CircularProgress innerMask;
+
+ public GradedCircles(double accuracyC, double accuracyB, double accuracyA, double accuracyS, double accuracyX)
+ {
+ Anchor = Anchor.Centre;
+ Origin = Anchor.Centre;
+ RelativeSizeAxes = Axes.Both;
+ Size = new Vector2(0.8f);
+ Padding = new MarginPadding(2);
+ Children = new Drawable[]
+ {
+ new CircularProgress
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.ForRank(ScoreRank.D),
+ InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
+ Current = { Value = accuracyC - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
+ Rotation = AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
+ },
+ new CircularProgress
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.ForRank(ScoreRank.C),
+ InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
+ Current = { Value = accuracyB - accuracyC - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
+ Rotation = (float)accuracyC * 360 + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
+ },
+ new CircularProgress
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.ForRank(ScoreRank.B),
+ InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
+ Current = { Value = accuracyA - accuracyB - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
+ Rotation = (float)accuracyB * 360 + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
+ },
+ new CircularProgress
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.ForRank(ScoreRank.A),
+ InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
+ Current = { Value = accuracyS - accuracyA - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
+ Rotation = (float)accuracyA * 360 + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
+ },
+ new CircularProgress
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.ForRank(ScoreRank.S),
+ InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
+ Current = { Value = accuracyX - accuracyS - AccuracyCircle.VIRTUAL_SS_PERCENTAGE - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
+ Rotation = (float)accuracyS * 360 + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
+ },
+ new CircularProgress
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Colour = OsuColour.ForRank(ScoreRank.X),
+ InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
+ Current = { Value = 1f - (accuracyX - AccuracyCircle.VIRTUAL_SS_PERCENTAGE) - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
+ Rotation = (float)(accuracyX - AccuracyCircle.VIRTUAL_SS_PERCENTAGE) * 360 + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
+ },
+ new BufferedContainer
+ {
+ Name = "Graded circle mask",
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding(1),
+ Blending = new BlendingParameters
+ {
+ Source = BlendingType.DstColor,
+ Destination = BlendingType.OneMinusSrcColor,
+ SourceAlpha = BlendingType.One,
+ DestinationAlpha = BlendingType.SrcAlpha
+ },
+ Child = innerMask = new CircularProgress
+ {
+ RelativeSizeAxes = Axes.Both,
+ InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS - 0.02f,
+ }
+ }
+ };
+ }
+
+ public void Transform()
+ {
+ using (BeginDelayedSequence(AccuracyCircle.RANK_CIRCLE_TRANSFORM_DELAY))
+ innerMask.FillTo(1f, AccuracyCircle.RANK_CIRCLE_TRANSFORM_DURATION, AccuracyCircle.ACCURACY_TRANSFORM_EASING);
+ }
+ }
+}
From 9c411ad48d81fa384619a6eb8c49c3e56f760fbc Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Mon, 29 Jan 2024 05:19:28 +0300
Subject: [PATCH 024/105] Simplify notch math
---
.../Ranking/Expanded/Accuracy/GradedCircles.cs | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
index 51c4237528..5241a4d983 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
@@ -31,7 +31,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
Colour = OsuColour.ForRank(ScoreRank.D),
InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
Current = { Value = accuracyC - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
- Rotation = AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
+ Rotation = AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 180
},
new CircularProgress
{
@@ -41,7 +41,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
Colour = OsuColour.ForRank(ScoreRank.C),
InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
Current = { Value = accuracyB - accuracyC - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)accuracyC * 360 + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
+ Rotation = (float)(accuracyC + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f) * 360
},
new CircularProgress
{
@@ -51,7 +51,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
Colour = OsuColour.ForRank(ScoreRank.B),
InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
Current = { Value = accuracyA - accuracyB - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)accuracyB * 360 + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
+ Rotation = (float)(accuracyB + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f) * 360
},
new CircularProgress
{
@@ -61,7 +61,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
Colour = OsuColour.ForRank(ScoreRank.A),
InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
Current = { Value = accuracyS - accuracyA - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)accuracyA * 360 + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
+ Rotation = (float)(accuracyA + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f) * 360
},
new CircularProgress
{
@@ -71,7 +71,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
Colour = OsuColour.ForRank(ScoreRank.S),
InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
Current = { Value = accuracyX - accuracyS - AccuracyCircle.VIRTUAL_SS_PERCENTAGE - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)accuracyS * 360 + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
+ Rotation = (float)(accuracyS + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f) * 360
},
new CircularProgress
{
@@ -81,7 +81,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
Colour = OsuColour.ForRank(ScoreRank.X),
InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
Current = { Value = 1f - (accuracyX - AccuracyCircle.VIRTUAL_SS_PERCENTAGE) - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)(accuracyX - AccuracyCircle.VIRTUAL_SS_PERCENTAGE) * 360 + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f * 360
+ Rotation = (float)(accuracyX - AccuracyCircle.VIRTUAL_SS_PERCENTAGE + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f) * 360
},
new BufferedContainer
{
From 809ca81b9ccba45aa1ea29fe4645805b8e32e2e7 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Mon, 29 Jan 2024 05:29:29 +0300
Subject: [PATCH 025/105] Add TestSceneGradedCircles
---
.../Visual/Ranking/TestSceneGradedCircles.cs | 44 +++++++++++++++++++
.../Expanded/Accuracy/GradedCircles.cs | 6 +++
2 files changed, 50 insertions(+)
create mode 100644 osu.Game.Tests/Visual/Ranking/TestSceneGradedCircles.cs
diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneGradedCircles.cs b/osu.Game.Tests/Visual/Ranking/TestSceneGradedCircles.cs
new file mode 100644
index 0000000000..87fbca5c44
--- /dev/null
+++ b/osu.Game.Tests/Visual/Ranking/TestSceneGradedCircles.cs
@@ -0,0 +1,44 @@
+// 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.Graphics.Containers;
+using osu.Framework.Graphics;
+using osu.Game.Rulesets.Osu;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Scoring;
+using osu.Game.Screens.Ranking.Expanded.Accuracy;
+using osuTK;
+
+namespace osu.Game.Tests.Visual.Ranking
+{
+ public partial class TestSceneGradedCircles : OsuTestScene
+ {
+ private readonly GradedCircles ring;
+
+ public TestSceneGradedCircles()
+ {
+ ScoreProcessor scoreProcessor = new OsuRuleset().CreateScoreProcessor();
+ double accuracyX = scoreProcessor.AccuracyCutoffFromRank(ScoreRank.X);
+ double accuracyS = scoreProcessor.AccuracyCutoffFromRank(ScoreRank.S);
+
+ double accuracyA = scoreProcessor.AccuracyCutoffFromRank(ScoreRank.A);
+ double accuracyB = scoreProcessor.AccuracyCutoffFromRank(ScoreRank.B);
+ double accuracyC = scoreProcessor.AccuracyCutoffFromRank(ScoreRank.C);
+
+ Add(new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Size = new Vector2(400),
+ Child = ring = new GradedCircles(accuracyC, accuracyB, accuracyA, accuracyS, accuracyX)
+ });
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ AddSliderStep("Progress", 0.0, 1.0, 1.0, p => ring.Progress = p);
+ }
+ }
+}
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
index 5241a4d983..2ce8c511e0 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
@@ -12,6 +12,12 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
{
public partial class GradedCircles : BufferedContainer
{
+ public double Progress
+ {
+ get => innerMask.Current.Value;
+ set => innerMask.Current.Value = value;
+ }
+
private readonly CircularProgress innerMask;
public GradedCircles(double accuracyC, double accuracyB, double accuracyA, double accuracyS, double accuracyX)
From 3987faa21cc80c39b42f465d1ef3f3046e235843 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Mon, 29 Jan 2024 06:13:52 +0300
Subject: [PATCH 026/105] Rework GradedCircles to not use BufferedContainer
---
.../Expanded/Accuracy/AccuracyCircle.cs | 5 +-
.../Expanded/Accuracy/GradedCircles.cs | 118 ++++++++----------
2 files changed, 52 insertions(+), 71 deletions(-)
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
index 3141810894..5b929554ff 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
@@ -77,7 +77,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
///
/// The width of a solid "notch" in terms of accuracy that appears at the ends of the rank circles to add separation.
///
- public const float NOTCH_WIDTH_PERCENTAGE = 2f / 360;
+ public const double NOTCH_WIDTH_PERCENTAGE = 2.0 / 360;
///
/// The easing for the circle filling transforms.
@@ -211,7 +211,8 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
});
}
- gradedCircles.Transform();
+ using (BeginDelayedSequence(RANK_CIRCLE_TRANSFORM_DELAY))
+ gradedCircles.TransformTo(nameof(GradedCircles.Progress), 1.0, RANK_CIRCLE_TRANSFORM_DURATION, ACCURACY_TRANSFORM_EASING);
using (BeginDelayedSequence(ACCURACY_TRANSFORM_DELAY))
{
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
index 2ce8c511e0..19c7a9b606 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
@@ -1,6 +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 osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
@@ -10,15 +11,31 @@ using osuTK;
namespace osu.Game.Screens.Ranking.Expanded.Accuracy
{
- public partial class GradedCircles : BufferedContainer
+ public partial class GradedCircles : CompositeDrawable
{
+ private double progress;
+
public double Progress
{
- get => innerMask.Current.Value;
- set => innerMask.Current.Value = value;
+ get => progress;
+ set
+ {
+ progress = value;
+ dProgress.RevealProgress = value;
+ cProgress.RevealProgress = value;
+ bProgress.RevealProgress = value;
+ aProgress.RevealProgress = value;
+ sProgress.RevealProgress = value;
+ xProgress.RevealProgress = value;
+ }
}
- private readonly CircularProgress innerMask;
+ private readonly GradedCircle dProgress;
+ private readonly GradedCircle cProgress;
+ private readonly GradedCircle bProgress;
+ private readonly GradedCircle aProgress;
+ private readonly GradedCircle sProgress;
+ private readonly GradedCircle xProgress;
public GradedCircles(double accuracyC, double accuracyB, double accuracyA, double accuracyS, double accuracyX)
{
@@ -27,93 +44,56 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
RelativeSizeAxes = Axes.Both;
Size = new Vector2(0.8f);
Padding = new MarginPadding(2);
- Children = new Drawable[]
+ InternalChildren = new Drawable[]
{
- new CircularProgress
+ dProgress = new GradedCircle(0.0, accuracyC)
{
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
Colour = OsuColour.ForRank(ScoreRank.D),
- InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyC - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
- Rotation = AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 180
},
- new CircularProgress
+ cProgress = new GradedCircle(accuracyC, accuracyB)
{
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
Colour = OsuColour.ForRank(ScoreRank.C),
- InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyB - accuracyC - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)(accuracyC + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f) * 360
},
- new CircularProgress
+ bProgress = new GradedCircle(accuracyB, accuracyA)
{
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
Colour = OsuColour.ForRank(ScoreRank.B),
- InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyA - accuracyB - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)(accuracyB + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f) * 360
},
- new CircularProgress
+ aProgress = new GradedCircle(accuracyA, accuracyS)
{
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
Colour = OsuColour.ForRank(ScoreRank.A),
- InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyS - accuracyA - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)(accuracyA + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f) * 360
},
- new CircularProgress
+ sProgress = new GradedCircle(accuracyS, accuracyX - AccuracyCircle.VIRTUAL_SS_PERCENTAGE)
{
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
Colour = OsuColour.ForRank(ScoreRank.S),
- InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
- Current = { Value = accuracyX - accuracyS - AccuracyCircle.VIRTUAL_SS_PERCENTAGE - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)(accuracyS + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f) * 360
},
- new CircularProgress
+ xProgress = new GradedCircle(accuracyX - AccuracyCircle.VIRTUAL_SS_PERCENTAGE, 1.0)
{
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Colour = OsuColour.ForRank(ScoreRank.X),
- InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS,
- Current = { Value = 1f - (accuracyX - AccuracyCircle.VIRTUAL_SS_PERCENTAGE) - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE },
- Rotation = (float)(accuracyX - AccuracyCircle.VIRTUAL_SS_PERCENTAGE + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5f) * 360
- },
- new BufferedContainer
- {
- Name = "Graded circle mask",
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding(1),
- Blending = new BlendingParameters
- {
- Source = BlendingType.DstColor,
- Destination = BlendingType.OneMinusSrcColor,
- SourceAlpha = BlendingType.One,
- DestinationAlpha = BlendingType.SrcAlpha
- },
- Child = innerMask = new CircularProgress
- {
- RelativeSizeAxes = Axes.Both,
- InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS - 0.02f,
- }
+ Colour = OsuColour.ForRank(ScoreRank.X)
}
};
}
- public void Transform()
+ private partial class GradedCircle : CircularProgress
{
- using (BeginDelayedSequence(AccuracyCircle.RANK_CIRCLE_TRANSFORM_DELAY))
- innerMask.FillTo(1f, AccuracyCircle.RANK_CIRCLE_TRANSFORM_DURATION, AccuracyCircle.ACCURACY_TRANSFORM_EASING);
+ public double RevealProgress
+ {
+ set => Current.Value = Math.Clamp(value, startProgress, endProgress) - startProgress;
+ }
+
+ private readonly double startProgress;
+ private readonly double endProgress;
+
+ public GradedCircle(double startProgress, double endProgress)
+ {
+ this.startProgress = startProgress + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5;
+ this.endProgress = endProgress - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5;
+
+ Anchor = Anchor.Centre;
+ Origin = Anchor.Centre;
+ RelativeSizeAxes = Axes.Both;
+ InnerRadius = AccuracyCircle.RANK_CIRCLE_RADIUS;
+ Rotation = (float)this.startProgress * 360;
+ }
}
}
}
From 0c0ba7abefe04e16f3d153964f7fe8f139ba2373 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Mon, 29 Jan 2024 06:28:38 +0300
Subject: [PATCH 027/105] Adjust values to visually match previous
---
osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs | 2 +-
osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
index 5b929554ff..8304e7a542 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
@@ -62,7 +62,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
///
/// Relative width of the rank circles.
///
- public const float RANK_CIRCLE_RADIUS = 0.06f;
+ public const float RANK_CIRCLE_RADIUS = 0.05f;
///
/// Relative width of the circle showing the accuracy.
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
index 19c7a9b606..efcb848530 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
@@ -43,7 +43,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
Origin = Anchor.Centre;
RelativeSizeAxes = Axes.Both;
Size = new Vector2(0.8f);
- Padding = new MarginPadding(2);
+ Padding = new MarginPadding(2.5f);
InternalChildren = new Drawable[]
{
dProgress = new GradedCircle(0.0, accuracyC)
From 7165511754ad437f035e87fdd96323d3c75e7a67 Mon Sep 17 00:00:00 2001
From: syscats
Date: Wed, 31 Jan 2024 15:49:31 +0100
Subject: [PATCH 028/105] Use ordinal sorting for artist string comparison
---
osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
index 6d2e938fb7..857f7efb8e 100644
--- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
+++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
@@ -67,7 +67,7 @@ namespace osu.Game.Screens.Select.Carousel
{
default:
case SortMode.Artist:
- comparison = string.Compare(BeatmapSet.Metadata.Artist, otherSet.BeatmapSet.Metadata.Artist, StringComparison.OrdinalIgnoreCase);
+ comparison = string.Compare(BeatmapSet.Metadata.Artist, otherSet.BeatmapSet.Metadata.Artist, StringComparison.Ordinal);
break;
case SortMode.Title:
From 0407b5d84ac0bc2d872ffc3bb173f622900ffd45 Mon Sep 17 00:00:00 2001
From: syscats
Date: Thu, 1 Feb 2024 14:03:59 +0100
Subject: [PATCH 029/105] use ordinal sorting on each method
---
osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
index 857f7efb8e..f7b715862a 100644
--- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
+++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
@@ -71,15 +71,15 @@ namespace osu.Game.Screens.Select.Carousel
break;
case SortMode.Title:
- comparison = string.Compare(BeatmapSet.Metadata.Title, otherSet.BeatmapSet.Metadata.Title, StringComparison.OrdinalIgnoreCase);
+ comparison = string.Compare(BeatmapSet.Metadata.Title, otherSet.BeatmapSet.Metadata.Title, StringComparison.Ordinal);
break;
case SortMode.Author:
- comparison = string.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username, StringComparison.OrdinalIgnoreCase);
+ comparison = string.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username, StringComparison.Ordinal);
break;
case SortMode.Source:
- comparison = string.Compare(BeatmapSet.Metadata.Source, otherSet.BeatmapSet.Metadata.Source, StringComparison.OrdinalIgnoreCase);
+ comparison = string.Compare(BeatmapSet.Metadata.Source, otherSet.BeatmapSet.Metadata.Source, StringComparison.Ordinal);
break;
case SortMode.DateAdded:
From 20504c55ef02b83ea9c575d3b435148a4eff8931 Mon Sep 17 00:00:00 2001
From: Loreos7
Date: Fri, 2 Feb 2024 15:32:55 +0300
Subject: [PATCH 030/105] localise storage error popup dialog
---
.../Localisation/StorageErrorDialogStrings.cs | 49 +++++++++++++++++++
osu.Game/Screens/Menu/StorageErrorDialog.cs | 17 ++++---
2 files changed, 58 insertions(+), 8 deletions(-)
create mode 100644 osu.Game/Localisation/StorageErrorDialogStrings.cs
diff --git a/osu.Game/Localisation/StorageErrorDialogStrings.cs b/osu.Game/Localisation/StorageErrorDialogStrings.cs
new file mode 100644
index 0000000000..6ad388dd1f
--- /dev/null
+++ b/osu.Game/Localisation/StorageErrorDialogStrings.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.Localisation;
+
+namespace osu.Game.Localisation
+{
+ public static class StorageErrorDialogStrings
+ {
+ private const string prefix = @"osu.Game.Resources.Localisation.StorageErrorDialog";
+
+ ///
+ /// "osu! storage error"
+ ///
+ public static LocalisableString StorageError => new TranslatableString(getKey(@"storage_error"), @"osu! storage error");
+
+ ///
+ /// "The specified osu! data location ("{0}") is not accessible. If it is on external storage, please reconnect the device and try again."
+ ///
+ public static LocalisableString LocationIsNotAccessible(string? loc) => new TranslatableString(getKey(@"location_is_not_accessible"), @"The specified osu! data location (""{0}"") is not accessible. If it is on external storage, please reconnect the device and try again.", loc);
+
+ ///
+ /// "The specified osu! data location ("{0}") is empty. If you have moved the files, please close osu! and move them back."
+ ///
+ public static LocalisableString LocationIsEmpty(string? loc2) => new TranslatableString(getKey(@"location_is_empty"), @"The specified osu! data location (""{0}"") is empty. If you have moved the files, please close osu! and move them back.", loc2);
+
+ ///
+ /// "Try again"
+ ///
+ public static LocalisableString TryAgain => new TranslatableString(getKey(@"try_again"), @"Try again");
+
+ ///
+ /// "Use default location until restart"
+ ///
+ public static LocalisableString UseDefaultLocation => new TranslatableString(getKey(@"use_default_location"), @"Use default location until restart");
+
+ ///
+ /// "Reset to default location"
+ ///
+ public static LocalisableString ResetToDefaultLocation => new TranslatableString(getKey(@"reset_to_default_location"), @"Reset to default location");
+
+ ///
+ /// "Start fresh at specified location"
+ ///
+ public static LocalisableString StartFresh => new TranslatableString(getKey(@"start_fresh"), @"Start fresh at specified location");
+
+ private static string getKey(string key) => $@"{prefix}:{key}";
+ }
+}
diff --git a/osu.Game/Screens/Menu/StorageErrorDialog.cs b/osu.Game/Screens/Menu/StorageErrorDialog.cs
index dd43289873..b48046d190 100644
--- a/osu.Game/Screens/Menu/StorageErrorDialog.cs
+++ b/osu.Game/Screens/Menu/StorageErrorDialog.cs
@@ -5,6 +5,7 @@ using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Sprites;
using osu.Game.IO;
+using osu.Game.Localisation;
using osu.Game.Overlays;
using osu.Game.Overlays.Dialog;
@@ -17,7 +18,7 @@ namespace osu.Game.Screens.Menu
public StorageErrorDialog(OsuStorage storage, OsuStorageError error)
{
- HeaderText = "osu! storage error";
+ HeaderText = StorageErrorDialogStrings.StorageError;
Icon = FontAwesome.Solid.ExclamationTriangle;
var buttons = new List();
@@ -25,13 +26,13 @@ namespace osu.Game.Screens.Menu
switch (error)
{
case OsuStorageError.NotAccessible:
- BodyText = $"The specified osu! data location (\"{storage.CustomStoragePath}\") is not accessible. If it is on external storage, please reconnect the device and try again.";
+ BodyText = StorageErrorDialogStrings.LocationIsNotAccessible(storage.CustomStoragePath);
buttons.AddRange(new PopupDialogButton[]
{
new PopupDialogCancelButton
{
- Text = "Try again",
+ Text = StorageErrorDialogStrings.TryAgain,
Action = () =>
{
if (!storage.TryChangeToCustomStorage(out var nextError))
@@ -40,29 +41,29 @@ namespace osu.Game.Screens.Menu
},
new PopupDialogCancelButton
{
- Text = "Use default location until restart",
+ Text = StorageErrorDialogStrings.UseDefaultLocation,
},
new PopupDialogOkButton
{
- Text = "Reset to default location",
+ Text = StorageErrorDialogStrings.ResetToDefaultLocation,
Action = storage.ResetCustomStoragePath
},
});
break;
case OsuStorageError.AccessibleButEmpty:
- BodyText = $"The specified osu! data location (\"{storage.CustomStoragePath}\") is empty. If you have moved the files, please close osu! and move them back.";
+ BodyText = StorageErrorDialogStrings.LocationIsEmpty(storage.CustomStoragePath);
// Todo: Provide the option to search for the files similar to migration.
buttons.AddRange(new PopupDialogButton[]
{
new PopupDialogCancelButton
{
- Text = "Start fresh at specified location"
+ Text = StorageErrorDialogStrings.StartFresh
},
new PopupDialogOkButton
{
- Text = "Reset to default location",
+ Text = StorageErrorDialogStrings.ResetToDefaultLocation,
Action = storage.ResetCustomStoragePath
},
});
From 397def9ceb543ca7e6d0ada77bfde9558dae286d Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Sun, 4 Feb 2024 02:58:15 +0300
Subject: [PATCH 031/105] Move layout specification outside the GradedCircles
class
---
.../Visual/Ranking/TestSceneGradedCircles.cs | 6 ++----
.../Ranking/Expanded/Accuracy/AccuracyCircle.cs | 14 +++++++++++++-
.../Ranking/Expanded/Accuracy/GradedCircles.cs | 6 ------
3 files changed, 15 insertions(+), 11 deletions(-)
diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneGradedCircles.cs b/osu.Game.Tests/Visual/Ranking/TestSceneGradedCircles.cs
index 87fbca5c44..116386b4b5 100644
--- a/osu.Game.Tests/Visual/Ranking/TestSceneGradedCircles.cs
+++ b/osu.Game.Tests/Visual/Ranking/TestSceneGradedCircles.cs
@@ -1,7 +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.Framework.Graphics.Containers;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Scoring;
@@ -25,12 +24,11 @@ namespace osu.Game.Tests.Visual.Ranking
double accuracyB = scoreProcessor.AccuracyCutoffFromRank(ScoreRank.B);
double accuracyC = scoreProcessor.AccuracyCutoffFromRank(ScoreRank.C);
- Add(new Container
+ Add(ring = new GradedCircles(accuracyC, accuracyB, accuracyA, accuracyS, accuracyX)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Size = new Vector2(400),
- Child = ring = new GradedCircles(accuracyC, accuracyB, accuracyA, accuracyS, accuracyX)
+ Size = new Vector2(400)
});
}
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
index 8304e7a542..8dc1a48f40 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
@@ -20,6 +20,7 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Skinning;
+using osuTK;
using osuTK.Graphics;
namespace osu.Game.Screens.Ranking.Expanded.Accuracy
@@ -156,7 +157,18 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
Colour = ColourInfo.GradientVertical(Color4Extensions.FromHex("#7CF6FF"), Color4Extensions.FromHex("#BAFFA9")),
InnerRadius = accuracy_circle_radius,
},
- gradedCircles = new GradedCircles(accuracyC, accuracyB, accuracyA, accuracyS, accuracyX),
+ new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Size = new Vector2(0.8f),
+ Padding = new MarginPadding(2.5f),
+ Child = gradedCircles = new GradedCircles(accuracyC, accuracyB, accuracyA, accuracyS, accuracyX)
+ {
+ RelativeSizeAxes = Axes.Both
+ }
+ },
badges = new Container
{
Name = "Rank badges",
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
index efcb848530..e60a24a310 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
@@ -7,7 +7,6 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Graphics;
using osu.Game.Scoring;
-using osuTK;
namespace osu.Game.Screens.Ranking.Expanded.Accuracy
{
@@ -39,11 +38,6 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
public GradedCircles(double accuracyC, double accuracyB, double accuracyA, double accuracyS, double accuracyX)
{
- Anchor = Anchor.Centre;
- Origin = Anchor.Centre;
- RelativeSizeAxes = Axes.Both;
- Size = new Vector2(0.8f);
- Padding = new MarginPadding(2.5f);
InternalChildren = new Drawable[]
{
dProgress = new GradedCircle(0.0, accuracyC)
From 4e5c9ddbfe6afad4713e9705cf4b28cd32cfd764 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Sun, 4 Feb 2024 03:02:39 +0300
Subject: [PATCH 032/105] Rename notch const to spacing
---
.../Ranking/Expanded/Accuracy/AccuracyCircle.cs | 12 ++++++------
.../Ranking/Expanded/Accuracy/GradedCircles.cs | 4 ++--
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
index 8dc1a48f40..7edfc00760 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
@@ -76,9 +76,9 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
public const double VIRTUAL_SS_PERCENTAGE = 0.01;
///
- /// The width of a solid "notch" in terms of accuracy that appears at the ends of the rank circles to add separation.
+ /// The width of spacing in terms of accuracy between the grade circles.
///
- public const double NOTCH_WIDTH_PERCENTAGE = 2.0 / 360;
+ public const double GRADE_SPACING_PERCENTAGE = 2.0 / 360;
///
/// The easing for the circle filling transforms.
@@ -241,10 +241,10 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
// to prevent ambiguity on what grade it's pointing at.
foreach (double p in notchPercentages)
{
- if (Precision.AlmostEquals(p, targetAccuracy, NOTCH_WIDTH_PERCENTAGE / 2))
+ if (Precision.AlmostEquals(p, targetAccuracy, GRADE_SPACING_PERCENTAGE / 2))
{
int tippingDirection = targetAccuracy - p >= 0 ? 1 : -1; // We "round up" here to match rank criteria
- targetAccuracy = p + tippingDirection * (NOTCH_WIDTH_PERCENTAGE / 2);
+ targetAccuracy = p + tippingDirection * (GRADE_SPACING_PERCENTAGE / 2);
break;
}
}
@@ -253,7 +253,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
if (score.Rank == ScoreRank.X || score.Rank == ScoreRank.XH)
targetAccuracy = 1;
else
- targetAccuracy = Math.Min(accuracyX - VIRTUAL_SS_PERCENTAGE - NOTCH_WIDTH_PERCENTAGE / 2, targetAccuracy);
+ targetAccuracy = Math.Min(accuracyX - VIRTUAL_SS_PERCENTAGE - GRADE_SPACING_PERCENTAGE / 2, targetAccuracy);
// The accuracy circle gauge visually fills up a bit too much.
// This wouldn't normally matter but we want it to align properly with the inner graded circle in the above cases.
@@ -349,7 +349,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
.FadeOut(800, Easing.Out);
accuracyCircle
- .FillTo(accuracyS - NOTCH_WIDTH_PERCENTAGE / 2 - visual_alignment_offset, 70, Easing.OutQuint);
+ .FillTo(accuracyS - GRADE_SPACING_PERCENTAGE / 2 - visual_alignment_offset, 70, Easing.OutQuint);
badges.Single(b => b.Rank == getRank(ScoreRank.S))
.FadeOut(70, Easing.OutQuint);
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
index e60a24a310..57b6d8e4ac 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
@@ -79,8 +79,8 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
public GradedCircle(double startProgress, double endProgress)
{
- this.startProgress = startProgress + AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5;
- this.endProgress = endProgress - AccuracyCircle.NOTCH_WIDTH_PERCENTAGE * 0.5;
+ this.startProgress = startProgress + AccuracyCircle.GRADE_SPACING_PERCENTAGE * 0.5;
+ this.endProgress = endProgress - AccuracyCircle.GRADE_SPACING_PERCENTAGE * 0.5;
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
From ff7cd67909d72c520ec2aabaf7ac96083d812cd3 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Tue, 6 Feb 2024 21:14:36 +0300
Subject: [PATCH 033/105] Move all the circles into their own container
---
.../Expanded/Accuracy/GradedCircles.cs | 66 +++++++++----------
1 file changed, 31 insertions(+), 35 deletions(-)
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
index 57b6d8e4ac..33b71c53a7 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/GradedCircles.cs
@@ -20,49 +20,45 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
set
{
progress = value;
- dProgress.RevealProgress = value;
- cProgress.RevealProgress = value;
- bProgress.RevealProgress = value;
- aProgress.RevealProgress = value;
- sProgress.RevealProgress = value;
- xProgress.RevealProgress = value;
+
+ foreach (var circle in circles)
+ circle.RevealProgress = value;
}
}
- private readonly GradedCircle dProgress;
- private readonly GradedCircle cProgress;
- private readonly GradedCircle bProgress;
- private readonly GradedCircle aProgress;
- private readonly GradedCircle sProgress;
- private readonly GradedCircle xProgress;
+ private readonly Container circles;
public GradedCircles(double accuracyC, double accuracyB, double accuracyA, double accuracyS, double accuracyX)
{
- InternalChildren = new Drawable[]
+ InternalChild = circles = new Container
{
- dProgress = new GradedCircle(0.0, accuracyC)
+ RelativeSizeAxes = Axes.Both,
+ Children = new[]
{
- Colour = OsuColour.ForRank(ScoreRank.D),
- },
- cProgress = new GradedCircle(accuracyC, accuracyB)
- {
- Colour = OsuColour.ForRank(ScoreRank.C),
- },
- bProgress = new GradedCircle(accuracyB, accuracyA)
- {
- Colour = OsuColour.ForRank(ScoreRank.B),
- },
- aProgress = new GradedCircle(accuracyA, accuracyS)
- {
- Colour = OsuColour.ForRank(ScoreRank.A),
- },
- sProgress = new GradedCircle(accuracyS, accuracyX - AccuracyCircle.VIRTUAL_SS_PERCENTAGE)
- {
- Colour = OsuColour.ForRank(ScoreRank.S),
- },
- xProgress = new GradedCircle(accuracyX - AccuracyCircle.VIRTUAL_SS_PERCENTAGE, 1.0)
- {
- Colour = OsuColour.ForRank(ScoreRank.X)
+ new GradedCircle(0.0, accuracyC)
+ {
+ Colour = OsuColour.ForRank(ScoreRank.D),
+ },
+ new GradedCircle(accuracyC, accuracyB)
+ {
+ Colour = OsuColour.ForRank(ScoreRank.C),
+ },
+ new GradedCircle(accuracyB, accuracyA)
+ {
+ Colour = OsuColour.ForRank(ScoreRank.B),
+ },
+ new GradedCircle(accuracyA, accuracyS)
+ {
+ Colour = OsuColour.ForRank(ScoreRank.A),
+ },
+ new GradedCircle(accuracyS, accuracyX - AccuracyCircle.VIRTUAL_SS_PERCENTAGE)
+ {
+ Colour = OsuColour.ForRank(ScoreRank.S),
+ },
+ new GradedCircle(accuracyX - AccuracyCircle.VIRTUAL_SS_PERCENTAGE, 1.0)
+ {
+ Colour = OsuColour.ForRank(ScoreRank.X)
+ }
}
};
}
From c500264306adceec5edbbab0baa40a7bc13c65c4 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Fri, 9 Feb 2024 23:20:31 +0300
Subject: [PATCH 034/105] Cache created judgement in HitObject
---
.../TestSceneCatchSkinConfiguration.cs | 2 +-
osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs | 2 +-
osu.Game.Rulesets.Catch/Objects/Banana.cs | 2 +-
osu.Game.Rulesets.Catch/Objects/BananaShower.cs | 2 +-
osu.Game.Rulesets.Catch/Objects/Droplet.cs | 2 +-
osu.Game.Rulesets.Catch/Objects/Fruit.cs | 2 +-
osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 2 +-
osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs | 2 +-
osu.Game.Rulesets.Mania/Objects/BarLine.cs | 2 +-
osu.Game.Rulesets.Mania/Objects/HoldNote.cs | 2 +-
osu.Game.Rulesets.Mania/Objects/HoldNoteBody.cs | 2 +-
osu.Game.Rulesets.Mania/Objects/Note.cs | 2 +-
osu.Game.Rulesets.Mania/Objects/TailNote.cs | 2 +-
.../TestSceneSpinnerRotation.cs | 2 +-
osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/HitCircle.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/Slider.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/SliderHeadCircle.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/SliderTick.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/Spinner.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs | 2 +-
.../TaikoHealthProcessorTest.cs | 8 ++++----
osu.Game.Rulesets.Taiko/Objects/BarLine.cs | 2 +-
osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 4 ++--
osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs | 2 +-
osu.Game.Rulesets.Taiko/Objects/IgnoreHit.cs | 2 +-
.../Objects/StrongNestedHitObject.cs | 2 +-
osu.Game.Rulesets.Taiko/Objects/Swell.cs | 2 +-
osu.Game.Rulesets.Taiko/Objects/SwellTick.cs | 2 +-
osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs | 2 +-
osu.Game/Beatmaps/IBeatmap.cs | 2 +-
osu.Game/Database/StandardisedScoreMigrationTools.cs | 2 +-
.../Difficulty/PerformanceBreakdownCalculator.cs | 4 ++--
.../Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 +-
osu.Game/Rulesets/Objects/HitObject.cs | 10 +++++++++-
osu.Game/Rulesets/Objects/Legacy/ConvertHitObject.cs | 2 +-
osu.Game/Rulesets/Scoring/JudgementProcessor.cs | 2 +-
.../Rulesets/Scoring/LegacyDrainingHealthProcessor.cs | 2 +-
41 files changed, 54 insertions(+), 46 deletions(-)
diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs
index e2fc31d869..0d7aa6af10 100644
--- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs
+++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs
@@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Catch.Tests
{
fruit.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
var drawableFruit = new DrawableFruit(fruit) { X = x };
- var judgement = fruit.CreateJudgement();
+ var judgement = fruit.Judgement;
catcher.OnNewResult(drawableFruit, new CatchJudgementResult(fruit, judgement)
{
Type = judgement.MaxResult
diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs
index f60ae29f77..b03fa00f76 100644
--- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs
+++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs
@@ -293,7 +293,7 @@ namespace osu.Game.Rulesets.Catch.Tests
private JudgementResult createResult(CatchHitObject hitObject)
{
- return new CatchJudgementResult(hitObject, hitObject.CreateJudgement())
+ return new CatchJudgementResult(hitObject, hitObject.Judgement)
{
Type = catcher.CanCatch(hitObject) ? HitResult.Great : HitResult.Miss
};
diff --git a/osu.Game.Rulesets.Catch/Objects/Banana.cs b/osu.Game.Rulesets.Catch/Objects/Banana.cs
index b80527f379..30bdb24b14 100644
--- a/osu.Game.Rulesets.Catch/Objects/Banana.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Banana.cs
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Catch.Objects
///
public int BananaIndex;
- public override Judgement CreateJudgement() => new CatchBananaJudgement();
+ protected override Judgement CreateJudgement() => new CatchBananaJudgement();
private static readonly IList default_banana_samples = new List { new BananaHitSampleInfo() }.AsReadOnly();
diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs
index 328cc2b52a..86c41fce90 100644
--- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs
+++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs
@@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Catch.Objects
{
public override bool LastInCombo => true;
- public override Judgement CreateJudgement() => new IgnoreJudgement();
+ protected override Judgement CreateJudgement() => new IgnoreJudgement();
protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
diff --git a/osu.Game.Rulesets.Catch/Objects/Droplet.cs b/osu.Game.Rulesets.Catch/Objects/Droplet.cs
index 9c1004a04b..107c6c3979 100644
--- a/osu.Game.Rulesets.Catch/Objects/Droplet.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Droplet.cs
@@ -8,6 +8,6 @@ namespace osu.Game.Rulesets.Catch.Objects
{
public class Droplet : PalpableCatchHitObject
{
- public override Judgement CreateJudgement() => new CatchDropletJudgement();
+ protected override Judgement CreateJudgement() => new CatchDropletJudgement();
}
}
diff --git a/osu.Game.Rulesets.Catch/Objects/Fruit.cs b/osu.Game.Rulesets.Catch/Objects/Fruit.cs
index 4818fe2cad..17270b803c 100644
--- a/osu.Game.Rulesets.Catch/Objects/Fruit.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Fruit.cs
@@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Catch.Objects
{
public class Fruit : PalpableCatchHitObject
{
- public override Judgement CreateJudgement() => new CatchJudgement();
+ protected override Judgement CreateJudgement() => new CatchJudgement();
public static FruitVisualRepresentation GetVisualRepresentation(int indexInBeatmap) => (FruitVisualRepresentation)(indexInBeatmap % 4);
}
diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
index 671291ef0e..49c24df5b9 100644
--- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
+++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
@@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.Objects
///
private const float base_scoring_distance = 100;
- public override Judgement CreateJudgement() => new IgnoreJudgement();
+ protected override Judgement CreateJudgement() => new IgnoreJudgement();
public int RepeatCount { get; set; }
diff --git a/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs
index 1bf160b5a6..ddcb92875f 100644
--- a/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs
+++ b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs
@@ -8,6 +8,6 @@ namespace osu.Game.Rulesets.Catch.Objects
{
public class TinyDroplet : Droplet
{
- public override Judgement CreateJudgement() => new CatchTinyDropletJudgement();
+ protected override Judgement CreateJudgement() => new CatchTinyDropletJudgement();
}
}
diff --git a/osu.Game.Rulesets.Mania/Objects/BarLine.cs b/osu.Game.Rulesets.Mania/Objects/BarLine.cs
index cf576239ed..742b5e4b0d 100644
--- a/osu.Game.Rulesets.Mania/Objects/BarLine.cs
+++ b/osu.Game.Rulesets.Mania/Objects/BarLine.cs
@@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Mania.Objects
set => major.Value = value;
}
- public override Judgement CreateJudgement() => new IgnoreJudgement();
+ protected override Judgement CreateJudgement() => new IgnoreJudgement();
}
}
diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
index 3f930a310b..4aac455bc5 100644
--- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
@@ -112,7 +112,7 @@ namespace osu.Game.Rulesets.Mania.Objects
});
}
- public override Judgement CreateJudgement() => new IgnoreJudgement();
+ protected override Judgement CreateJudgement() => new IgnoreJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNoteBody.cs b/osu.Game.Rulesets.Mania/Objects/HoldNoteBody.cs
index 47163d0d81..92b649c174 100644
--- a/osu.Game.Rulesets.Mania/Objects/HoldNoteBody.cs
+++ b/osu.Game.Rulesets.Mania/Objects/HoldNoteBody.cs
@@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Objects
///
public class HoldNoteBody : ManiaHitObject
{
- public override Judgement CreateJudgement() => new HoldNoteBodyJudgement();
+ protected override Judgement CreateJudgement() => new HoldNoteBodyJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
}
}
diff --git a/osu.Game.Rulesets.Mania/Objects/Note.cs b/osu.Game.Rulesets.Mania/Objects/Note.cs
index 0035960c63..b0f2991918 100644
--- a/osu.Game.Rulesets.Mania/Objects/Note.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Note.cs
@@ -11,6 +11,6 @@ namespace osu.Game.Rulesets.Mania.Objects
///
public class Note : ManiaHitObject
{
- public override Judgement CreateJudgement() => new ManiaJudgement();
+ protected override Judgement CreateJudgement() => new ManiaJudgement();
}
}
diff --git a/osu.Game.Rulesets.Mania/Objects/TailNote.cs b/osu.Game.Rulesets.Mania/Objects/TailNote.cs
index def32880f1..bddb4630cb 100644
--- a/osu.Game.Rulesets.Mania/Objects/TailNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/TailNote.cs
@@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Objects
///
public const double RELEASE_WINDOW_LENIENCE = 1.5;
- public override Judgement CreateJudgement() => new ManiaJudgement();
+ protected override Judgement CreateJudgement() => new ManiaJudgement();
public override double MaximumJudgementOffset => base.MaximumJudgementOffset * RELEASE_WINDOW_LENIENCE;
}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs
index 6706d20080..8d81fe3017 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs
@@ -134,7 +134,7 @@ namespace osu.Game.Rulesets.Osu.Tests
// multipled by 2 to nullify the score multiplier. (autoplay mod selected)
long totalScore = scoreProcessor.TotalScore.Value * 2;
- return totalScore == (int)(drawableSpinner.Result.TotalRotation / 360) * scoreProcessor.GetBaseScoreForResult(new SpinnerTick().CreateJudgement().MaxResult);
+ return totalScore == (int)(drawableSpinner.Result.TotalRotation / 360) * scoreProcessor.GetBaseScoreForResult(new SpinnerTick().Judgement.MaxResult);
});
addSeekStep(0);
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs
index 2c9292c58b..f07a1e930b 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs
@@ -79,7 +79,7 @@ namespace osu.Game.Rulesets.Osu.Mods
{
}
- public override Judgement CreateJudgement() => new OsuJudgement();
+ protected override Judgement CreateJudgement() => new OsuJudgement();
}
private partial class StrictTrackingDrawableSliderTail : DrawableSliderTail
diff --git a/osu.Game.Rulesets.Osu/Objects/HitCircle.cs b/osu.Game.Rulesets.Osu/Objects/HitCircle.cs
index d652db0fd4..6336482ccc 100644
--- a/osu.Game.Rulesets.Osu/Objects/HitCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/HitCircle.cs
@@ -8,6 +8,6 @@ namespace osu.Game.Rulesets.Osu.Objects
{
public class HitCircle : OsuHitObject
{
- public override Judgement CreateJudgement() => new OsuJudgement();
+ protected override Judgement CreateJudgement() => new OsuJudgement();
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs
index 506145568e..fc0248cbbd 100644
--- a/osu.Game.Rulesets.Osu/Objects/Slider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs
@@ -275,7 +275,7 @@ namespace osu.Game.Rulesets.Osu.Objects
TailSamples = this.GetNodeSamples(repeatCount + 1);
}
- public override Judgement CreateJudgement() => ClassicSliderBehaviour
+ protected override Judgement CreateJudgement() => ClassicSliderBehaviour
// Final combo is provided by the slider itself - see logic in `DrawableSlider.CheckForResult()`
? new OsuJudgement()
// Final combo is provided by the tail circle - see `SliderTailCircle`
diff --git a/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs b/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs
index 2d5a5b7727..8d60864f0b 100644
--- a/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs
@@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.Objects
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
- public override Judgement CreateJudgement() => new SliderEndJudgement();
+ protected override Judgement CreateJudgement() => new SliderEndJudgement();
public class SliderEndJudgement : OsuJudgement
{
diff --git a/osu.Game.Rulesets.Osu/Objects/SliderHeadCircle.cs b/osu.Game.Rulesets.Osu/Objects/SliderHeadCircle.cs
index 8305481788..4760135081 100644
--- a/osu.Game.Rulesets.Osu/Objects/SliderHeadCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/SliderHeadCircle.cs
@@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Osu.Objects
///
public bool ClassicSliderBehaviour;
- public override Judgement CreateJudgement() => ClassicSliderBehaviour ? new SliderTickJudgement() : base.CreateJudgement();
+ protected override Judgement CreateJudgement() => ClassicSliderBehaviour ? new SliderTickJudgement() : base.CreateJudgement();
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs b/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs
index ee2490439f..42d8d895e4 100644
--- a/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Objects
{
}
- public override Judgement CreateJudgement() => ClassicSliderBehaviour ? new LegacyTailJudgement() : new TailJudgement();
+ protected override Judgement CreateJudgement() => ClassicSliderBehaviour ? new LegacyTailJudgement() : new TailJudgement();
public class LegacyTailJudgement : OsuJudgement
{
diff --git a/osu.Game.Rulesets.Osu/Objects/SliderTick.cs b/osu.Game.Rulesets.Osu/Objects/SliderTick.cs
index 74ec4d6eb3..1d7ba2fbaf 100644
--- a/osu.Game.Rulesets.Osu/Objects/SliderTick.cs
+++ b/osu.Game.Rulesets.Osu/Objects/SliderTick.cs
@@ -32,6 +32,6 @@ namespace osu.Game.Rulesets.Osu.Objects
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
- public override Judgement CreateJudgement() => new SliderTickJudgement();
+ protected override Judgement CreateJudgement() => new SliderTickJudgement();
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Spinner.cs b/osu.Game.Rulesets.Osu/Objects/Spinner.cs
index e3dfe8e69a..9baa645b3c 100644
--- a/osu.Game.Rulesets.Osu/Objects/Spinner.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Spinner.cs
@@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.Osu.Objects
}
}
- public override Judgement CreateJudgement() => new OsuJudgement();
+ protected override Judgement CreateJudgement() => new OsuJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
diff --git a/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs b/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs
index 8d53100529..57db29ef0c 100644
--- a/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs
+++ b/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs
@@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Osu.Objects
{
public class SpinnerBonusTick : SpinnerTick
{
- public override Judgement CreateJudgement() => new OsuSpinnerBonusTickJudgement();
+ protected override Judgement CreateJudgement() => new OsuSpinnerBonusTickJudgement();
public class OsuSpinnerBonusTickJudgement : OsuSpinnerTickJudgement
{
diff --git a/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs b/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs
index 7989c9b7ff..cb59014909 100644
--- a/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs
+++ b/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Osu.Objects
///
public double SpinnerDuration { get; set; }
- public override Judgement CreateJudgement() => new OsuSpinnerTickJudgement();
+ protected override Judgement CreateJudgement() => new OsuSpinnerTickJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoHealthProcessorTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoHealthProcessorTest.cs
index f4a1e888c9..b28e870481 100644
--- a/osu.Game.Rulesets.Taiko.Tests/TaikoHealthProcessorTest.cs
+++ b/osu.Game.Rulesets.Taiko.Tests/TaikoHealthProcessorTest.cs
@@ -126,11 +126,11 @@ namespace osu.Game.Rulesets.Taiko.Tests
foreach (var nested in beatmap.HitObjects[0].NestedHitObjects)
{
- var nestedJudgement = nested.CreateJudgement();
+ var nestedJudgement = nested.Judgement;
healthProcessor.ApplyResult(new JudgementResult(nested, nestedJudgement) { Type = nestedJudgement.MaxResult });
}
- var judgement = beatmap.HitObjects[0].CreateJudgement();
+ var judgement = beatmap.HitObjects[0].Judgement;
healthProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], judgement) { Type = judgement.MaxResult });
Assert.Multiple(() =>
@@ -159,11 +159,11 @@ namespace osu.Game.Rulesets.Taiko.Tests
foreach (var nested in beatmap.HitObjects[0].NestedHitObjects)
{
- var nestedJudgement = nested.CreateJudgement();
+ var nestedJudgement = nested.Judgement;
healthProcessor.ApplyResult(new JudgementResult(nested, nestedJudgement) { Type = nestedJudgement.MaxResult });
}
- var judgement = beatmap.HitObjects[0].CreateJudgement();
+ var judgement = beatmap.HitObjects[0].Judgement;
healthProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], judgement) { Type = judgement.MaxResult });
Assert.Multiple(() =>
diff --git a/osu.Game.Rulesets.Taiko/Objects/BarLine.cs b/osu.Game.Rulesets.Taiko/Objects/BarLine.cs
index 46b3f13501..d87f8b3232 100644
--- a/osu.Game.Rulesets.Taiko/Objects/BarLine.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/BarLine.cs
@@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Taiko.Objects
set => major.Value = value;
}
- public override Judgement CreateJudgement() => new IgnoreJudgement();
+ protected override Judgement CreateJudgement() => new IgnoreJudgement();
}
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
index f3143de345..50cd722a3f 100644
--- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
@@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
}
}
- public override Judgement CreateJudgement() => new IgnoreJudgement();
+ protected override Judgement CreateJudgement() => new IgnoreJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
@@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
public class StrongNestedHit : StrongNestedHitObject
{
// The strong hit of the drum roll doesn't actually provide any score.
- public override Judgement CreateJudgement() => new IgnoreJudgement();
+ protected override Judgement CreateJudgement() => new IgnoreJudgement();
public StrongNestedHit(TaikoHitObject parent)
: base(parent)
diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs
index dc082ffd21..c1d4102042 100644
--- a/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs
@@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
Parent = parent;
}
- public override Judgement CreateJudgement() => new TaikoDrumRollTickJudgement();
+ protected override Judgement CreateJudgement() => new TaikoDrumRollTickJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
diff --git a/osu.Game.Rulesets.Taiko/Objects/IgnoreHit.cs b/osu.Game.Rulesets.Taiko/Objects/IgnoreHit.cs
index 302f940ef4..44cd700faf 100644
--- a/osu.Game.Rulesets.Taiko/Objects/IgnoreHit.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/IgnoreHit.cs
@@ -7,6 +7,6 @@ namespace osu.Game.Rulesets.Taiko.Objects
{
public class IgnoreHit : Hit
{
- public override Judgement CreateJudgement() => new IgnoreJudgement();
+ protected override Judgement CreateJudgement() => new IgnoreJudgement();
}
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/StrongNestedHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/StrongNestedHitObject.cs
index 14cbe338ed..227ab4ab52 100644
--- a/osu.Game.Rulesets.Taiko/Objects/StrongNestedHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/StrongNestedHitObject.cs
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
Parent = parent;
}
- public override Judgement CreateJudgement() => new TaikoStrongJudgement();
+ protected override Judgement CreateJudgement() => new TaikoStrongJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs
index a8db8df021..76d106f924 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs
@@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
}
}
- public override Judgement CreateJudgement() => new TaikoSwellJudgement();
+ protected override Judgement CreateJudgement() => new TaikoSwellJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs
index 41fb9cac7e..be1c1101de 100644
--- a/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs
@@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
{
public class SwellTick : TaikoHitObject
{
- public override Judgement CreateJudgement() => new IgnoreJudgement();
+ protected override Judgement CreateJudgement() => new IgnoreJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
index 1a1fde1990..697c23addf 100644
--- a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
@@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
///
public const float DEFAULT_SIZE = 0.475f;
- public override Judgement CreateJudgement() => new TaikoJudgement();
+ protected override Judgement CreateJudgement() => new TaikoJudgement();
protected override HitWindows CreateHitWindows() => new TaikoHitWindows();
}
diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs
index d97eb00d7e..b5bb6ccafc 100644
--- a/osu.Game/Beatmaps/IBeatmap.cs
+++ b/osu.Game/Beatmaps/IBeatmap.cs
@@ -94,7 +94,7 @@ namespace osu.Game.Beatmaps
static void addCombo(HitObject hitObject, ref int combo)
{
- if (hitObject.CreateJudgement().MaxResult.AffectsCombo())
+ if (hitObject.Judgement.MaxResult.AffectsCombo())
combo++;
foreach (var nested in hitObject.NestedHitObjects)
diff --git a/osu.Game/Database/StandardisedScoreMigrationTools.cs b/osu.Game/Database/StandardisedScoreMigrationTools.cs
index 403e73ab77..576d08f491 100644
--- a/osu.Game/Database/StandardisedScoreMigrationTools.cs
+++ b/osu.Game/Database/StandardisedScoreMigrationTools.cs
@@ -655,7 +655,7 @@ namespace osu.Game.Database
{
private readonly Judgement judgement;
- public override Judgement CreateJudgement() => judgement;
+ protected override Judgement CreateJudgement() => judgement;
public FakeHit(Judgement judgement)
{
diff --git a/osu.Game/Rulesets/Difficulty/PerformanceBreakdownCalculator.cs b/osu.Game/Rulesets/Difficulty/PerformanceBreakdownCalculator.cs
index 4563c264f7..946d83b14b 100644
--- a/osu.Game/Rulesets/Difficulty/PerformanceBreakdownCalculator.cs
+++ b/osu.Game/Rulesets/Difficulty/PerformanceBreakdownCalculator.cs
@@ -113,9 +113,9 @@ namespace osu.Game.Rulesets.Difficulty
private IEnumerable getPerfectHitResults(HitObject hitObject)
{
foreach (HitObject nested in hitObject.NestedHitObjects)
- yield return nested.CreateJudgement().MaxResult;
+ yield return nested.Judgement.MaxResult;
- yield return hitObject.CreateJudgement().MaxResult;
+ yield return hitObject.Judgement.MaxResult;
}
}
}
diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
index c9192ae3eb..16bd4b565c 100644
--- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
+++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
@@ -770,7 +770,7 @@ namespace osu.Game.Rulesets.Objects.Drawables
private void ensureEntryHasResult()
{
Debug.Assert(Entry != null);
- Entry.Result ??= CreateResult(HitObject.CreateJudgement())
+ Entry.Result ??= CreateResult(HitObject.Judgement)
?? throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}.");
}
diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs
index ef8bd08bf4..aed821332d 100644
--- a/osu.Game/Rulesets/Objects/HitObject.cs
+++ b/osu.Game/Rulesets/Objects/HitObject.cs
@@ -162,11 +162,19 @@ namespace osu.Game.Rulesets.Objects
protected void AddNested(HitObject hitObject) => nestedHitObjects.Add(hitObject);
+ ///
+ /// The that represents the scoring information for this .
+ ///
+ [JsonIgnore]
+ public Judgement Judgement => judgement ??= CreateJudgement();
+
+ private Judgement judgement;
+
///
/// Creates the that represents the scoring information for this .
///
[NotNull]
- public virtual Judgement CreateJudgement() => new Judgement();
+ protected virtual Judgement CreateJudgement() => new Judgement();
///
/// Creates the for this .
diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObject.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObject.cs
index bb36aab0b3..499953dab9 100644
--- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObject.cs
+++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObject.cs
@@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
public int ComboOffset { get; set; }
- public override Judgement CreateJudgement() => new IgnoreJudgement();
+ protected override Judgement CreateJudgement() => new IgnoreJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
}
diff --git a/osu.Game/Rulesets/Scoring/JudgementProcessor.cs b/osu.Game/Rulesets/Scoring/JudgementProcessor.cs
index e9f3bcb949..0e90330651 100644
--- a/osu.Game/Rulesets/Scoring/JudgementProcessor.cs
+++ b/osu.Game/Rulesets/Scoring/JudgementProcessor.cs
@@ -149,7 +149,7 @@ namespace osu.Game.Rulesets.Scoring
foreach (var obj in EnumerateHitObjects(beatmap))
{
- var judgement = obj.CreateJudgement();
+ var judgement = obj.Judgement;
var result = CreateResult(obj, judgement);
if (result == null)
diff --git a/osu.Game/Rulesets/Scoring/LegacyDrainingHealthProcessor.cs b/osu.Game/Rulesets/Scoring/LegacyDrainingHealthProcessor.cs
index ce2f7d5624..2bc3ea80ec 100644
--- a/osu.Game/Rulesets/Scoring/LegacyDrainingHealthProcessor.cs
+++ b/osu.Game/Rulesets/Scoring/LegacyDrainingHealthProcessor.cs
@@ -141,7 +141,7 @@ namespace osu.Game.Rulesets.Scoring
void increaseHp(HitObject hitObject)
{
- double amount = GetHealthIncreaseFor(hitObject, hitObject.CreateJudgement().MaxResult);
+ double amount = GetHealthIncreaseFor(hitObject, hitObject.Judgement.MaxResult);
currentHpUncapped += amount;
currentHp = Math.Max(0, Math.Min(1, currentHp + amount));
}
From c9c39ecb2f616b27b088bb455d5c122323127b10 Mon Sep 17 00:00:00 2001
From: Joseph Madamba
Date: Fri, 9 Feb 2024 15:15:27 -0800
Subject: [PATCH 035/105] Add `RankHighest` to `APIUser`
---
.../Visual/Online/TestSceneUserProfileOverlay.cs | 5 +++++
osu.Game/Online/API/Requests/Responses/APIUser.cs | 13 +++++++++++++
2 files changed, 18 insertions(+)
diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs
index bc8f75d4ce..020e020b10 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs
@@ -137,6 +137,11 @@ namespace osu.Game.Tests.Visual.Online
@"top_ranks",
@"medals"
},
+ RankHighest = new APIUser.UserRankHighest
+ {
+ Rank = 1,
+ UpdatedAt = DateTimeOffset.Now,
+ },
Statistics = new UserStatistics
{
IsRanked = true,
diff --git a/osu.Game/Online/API/Requests/Responses/APIUser.cs b/osu.Game/Online/API/Requests/Responses/APIUser.cs
index 56eec19fa1..4a31718f28 100644
--- a/osu.Game/Online/API/Requests/Responses/APIUser.cs
+++ b/osu.Game/Online/API/Requests/Responses/APIUser.cs
@@ -34,6 +34,19 @@ namespace osu.Game.Online.API.Requests.Responses
[JsonProperty(@"previous_usernames")]
public string[] PreviousUsernames;
+ [JsonProperty(@"rank_highest")]
+ [CanBeNull]
+ public UserRankHighest RankHighest;
+
+ public class UserRankHighest
+ {
+ [JsonProperty(@"rank")]
+ public int Rank;
+
+ [JsonProperty(@"updated_at")]
+ public DateTimeOffset UpdatedAt;
+ }
+
[JsonProperty(@"country_code")]
private string countryCodeString;
From 8d1d65a469c717f29115743ab231ce791930668d Mon Sep 17 00:00:00 2001
From: Joseph Madamba
Date: Fri, 9 Feb 2024 15:17:34 -0800
Subject: [PATCH 036/105] Add `ContentTooltipText` to `ProfileValueDisplay`
---
.../Header/Components/ProfileValueDisplay.cs | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
diff --git a/osu.Game/Overlays/Profile/Header/Components/ProfileValueDisplay.cs b/osu.Game/Overlays/Profile/Header/Components/ProfileValueDisplay.cs
index 4b1a0409a3..b2c23458b1 100644
--- a/osu.Game/Overlays/Profile/Header/Components/ProfileValueDisplay.cs
+++ b/osu.Game/Overlays/Profile/Header/Components/ProfileValueDisplay.cs
@@ -4,6 +4,7 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Cursor;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
@@ -13,7 +14,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
public partial class ProfileValueDisplay : CompositeDrawable
{
private readonly OsuSpriteText title;
- private readonly OsuSpriteText content;
+ private readonly ContentText content;
public LocalisableString Title
{
@@ -25,6 +26,11 @@ namespace osu.Game.Overlays.Profile.Header.Components
set => content.Text = value;
}
+ public LocalisableString ContentTooltipText
+ {
+ set => content.TooltipText = value;
+ }
+
public ProfileValueDisplay(bool big = false, int minimumWidth = 60)
{
AutoSizeAxes = Axes.Both;
@@ -38,9 +44,9 @@ namespace osu.Game.Overlays.Profile.Header.Components
{
Font = OsuFont.GetFont(size: 12)
},
- content = new OsuSpriteText
+ content = new ContentText
{
- Font = OsuFont.GetFont(size: big ? 30 : 20, weight: FontWeight.Light)
+ Font = OsuFont.GetFont(size: big ? 30 : 20, weight: FontWeight.Light),
},
new Container // Add a minimum size to the FillFlowContainer
{
@@ -56,5 +62,10 @@ namespace osu.Game.Overlays.Profile.Header.Components
title.Colour = colourProvider.Content1;
content.Colour = colourProvider.Content2;
}
+
+ private partial class ContentText : OsuSpriteText, IHasTooltip
+ {
+ public LocalisableString TooltipText { get; set; }
+ }
}
}
From ae89b89928af680dc921cfc4880241aa787e44ce Mon Sep 17 00:00:00 2001
From: Joseph Madamba
Date: Fri, 9 Feb 2024 15:33:49 -0800
Subject: [PATCH 037/105] Centralise global rank display logic to new class
---
.../Header/Components/GlobalRankDisplay.cs | 32 +++++++++++++++++++
.../Profile/Header/Components/MainDetails.cs | 9 ++----
osu.Game/Users/UserRankPanel.cs | 6 ++--
3 files changed, 37 insertions(+), 10 deletions(-)
create mode 100644 osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs
diff --git a/osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs b/osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs
new file mode 100644
index 0000000000..290b052e27
--- /dev/null
+++ b/osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs
@@ -0,0 +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.Framework.Bindables;
+using osu.Framework.Extensions.LocalisationExtensions;
+using osu.Framework.Localisation;
+using osu.Game.Resources.Localisation.Web;
+using osu.Game.Users;
+
+namespace osu.Game.Overlays.Profile.Header.Components
+{
+ public partial class GlobalRankDisplay : ProfileValueDisplay
+ {
+ public readonly Bindable UserStatistics = new Bindable();
+
+ public GlobalRankDisplay()
+ : base(true)
+ {
+ Title = UsersStrings.ShowRankGlobalSimple;
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ UserStatistics.BindValueChanged(s =>
+ {
+ Content = s.NewValue?.GlobalRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-";
+ }, true);
+ }
+ }
+}
diff --git a/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs b/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs
index b89973c5e5..2aea897451 100644
--- a/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs
+++ b/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs
@@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
private readonly Dictionary scoreRankInfos = new Dictionary();
private ProfileValueDisplay medalInfo = null!;
private ProfileValueDisplay ppInfo = null!;
- private ProfileValueDisplay detailGlobalRank = null!;
+ private GlobalRankDisplay detailGlobalRank = null!;
private ProfileValueDisplay detailCountryRank = null!;
private RankGraph rankGraph = null!;
@@ -52,10 +52,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
Spacing = new Vector2(20),
Children = new Drawable[]
{
- detailGlobalRank = new ProfileValueDisplay(true)
- {
- Title = UsersStrings.ShowRankGlobalSimple,
- },
+ detailGlobalRank = new GlobalRankDisplay(),
detailCountryRank = new ProfileValueDisplay(true)
{
Title = UsersStrings.ShowRankCountrySimple,
@@ -142,7 +139,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
foreach (var scoreRankInfo in scoreRankInfos)
scoreRankInfo.Value.RankCount = user?.Statistics?.GradesCount[scoreRankInfo.Key] ?? 0;
- detailGlobalRank.Content = user?.Statistics?.GlobalRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-";
+ detailGlobalRank.UserStatistics.Value = user?.Statistics;
detailCountryRank.Content = user?.Statistics?.CountryRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-";
rankGraph.Statistics.Value = user?.Statistics;
diff --git a/osu.Game/Users/UserRankPanel.cs b/osu.Game/Users/UserRankPanel.cs
index 84ff3114fc..ba9ef1eee4 100644
--- a/osu.Game/Users/UserRankPanel.cs
+++ b/osu.Game/Users/UserRankPanel.cs
@@ -27,7 +27,6 @@ namespace osu.Game.Users
[Resolved]
private IAPIProvider api { get; set; } = null!;
- private ProfileValueDisplay globalRankDisplay = null!;
private ProfileValueDisplay countryRankDisplay = null!;
private readonly IBindable statistics = new Bindable();
@@ -47,7 +46,6 @@ namespace osu.Game.Users
statistics.BindTo(api.Statistics);
statistics.BindValueChanged(stats =>
{
- globalRankDisplay.Content = stats.NewValue?.GlobalRank?.ToLocalisableString("\\##,##0") ?? "-";
countryRankDisplay.Content = stats.NewValue?.CountryRank?.ToLocalisableString("\\##,##0") ?? "-";
}, true);
}
@@ -163,9 +161,9 @@ namespace osu.Game.Users
{
new Drawable[]
{
- globalRankDisplay = new ProfileValueDisplay(true)
+ new GlobalRankDisplay
{
- Title = UsersStrings.ShowRankGlobalSimple,
+ UserStatistics = { BindTarget = statistics },
},
countryRankDisplay = new ProfileValueDisplay(true)
{
From ffd0d9bb3994f7471746921f63a3594efc16c49d Mon Sep 17 00:00:00 2001
From: Joseph Madamba
Date: Fri, 9 Feb 2024 15:36:15 -0800
Subject: [PATCH 038/105] Add highest rank tooltip to global rank display
---
.../Profile/Header/Components/GlobalRankDisplay.cs | 12 ++++++++++++
.../Profile/Header/Components/MainDetails.cs | 1 +
osu.Game/Users/UserRankPanel.cs | 6 ++++++
3 files changed, 19 insertions(+)
diff --git a/osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs b/osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs
index 290b052e27..dcd4129b45 100644
--- a/osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs
+++ b/osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs
@@ -4,6 +4,7 @@
using osu.Framework.Bindables;
using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Localisation;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Resources.Localisation.Web;
using osu.Game.Users;
@@ -12,6 +13,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
public partial class GlobalRankDisplay : ProfileValueDisplay
{
public readonly Bindable UserStatistics = new Bindable();
+ public readonly Bindable User = new Bindable();
public GlobalRankDisplay()
: base(true)
@@ -27,6 +29,16 @@ namespace osu.Game.Overlays.Profile.Header.Components
{
Content = s.NewValue?.GlobalRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-";
}, true);
+
+ // needed as statistics doesn't populate User
+ User.BindValueChanged(u =>
+ {
+ var rankHighest = u.NewValue?.RankHighest;
+
+ ContentTooltipText = rankHighest != null
+ ? UsersStrings.ShowRankHighest(rankHighest.Rank.ToLocalisableString("\\##,##0"), rankHighest.UpdatedAt.ToLocalisableString(@"d MMM yyyy"))
+ : string.Empty;
+ }, true);
}
}
}
diff --git a/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs b/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs
index 2aea897451..ffdf8edc21 100644
--- a/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs
+++ b/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs
@@ -140,6 +140,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
scoreRankInfo.Value.RankCount = user?.Statistics?.GradesCount[scoreRankInfo.Key] ?? 0;
detailGlobalRank.UserStatistics.Value = user?.Statistics;
+ detailGlobalRank.User.Value = user;
detailCountryRank.Content = user?.Statistics?.CountryRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-";
rankGraph.Statistics.Value = user?.Statistics;
diff --git a/osu.Game/Users/UserRankPanel.cs b/osu.Game/Users/UserRankPanel.cs
index ba9ef1eee4..4a00583094 100644
--- a/osu.Game/Users/UserRankPanel.cs
+++ b/osu.Game/Users/UserRankPanel.cs
@@ -30,6 +30,7 @@ namespace osu.Game.Users
private ProfileValueDisplay countryRankDisplay = null!;
private readonly IBindable statistics = new Bindable();
+ private readonly IBindable user = new Bindable();
public UserRankPanel(APIUser user)
: base(user)
@@ -48,6 +49,8 @@ namespace osu.Game.Users
{
countryRankDisplay.Content = stats.NewValue?.CountryRank?.ToLocalisableString("\\##,##0") ?? "-";
}, true);
+
+ user.BindTo(api.LocalUser!);
}
protected override Drawable CreateLayout()
@@ -164,6 +167,9 @@ namespace osu.Game.Users
new GlobalRankDisplay
{
UserStatistics = { BindTarget = statistics },
+ // TODO: make highest rank update, as api.LocalUser doesn't update
+ // maybe move to statistics in api, so `SoloStatisticsWatcher` can update the value
+ User = { BindTarget = user },
},
countryRankDisplay = new ProfileValueDisplay(true)
{
From 7b0b39dbaa515e5d2455de0da7e9884d222fc601 Mon Sep 17 00:00:00 2001
From: Joseph Madamba
Date: Fri, 9 Feb 2024 15:46:14 -0800
Subject: [PATCH 039/105] Fix total play time tooltip area including label
---
.../Profile/Header/Components/TotalPlayTime.cs | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/osu.Game/Overlays/Profile/Header/Components/TotalPlayTime.cs b/osu.Game/Overlays/Profile/Header/Components/TotalPlayTime.cs
index 08ca59d89b..a3c22d61d2 100644
--- a/osu.Game/Overlays/Profile/Header/Components/TotalPlayTime.cs
+++ b/osu.Game/Overlays/Profile/Header/Components/TotalPlayTime.cs
@@ -5,25 +5,19 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Cursor;
-using osu.Framework.Localisation;
using osu.Game.Resources.Localisation.Web;
namespace osu.Game.Overlays.Profile.Header.Components
{
- public partial class TotalPlayTime : CompositeDrawable, IHasTooltip
+ public partial class TotalPlayTime : CompositeDrawable
{
public readonly Bindable User = new Bindable();
- public LocalisableString TooltipText { get; set; }
-
private ProfileValueDisplay info = null!;
public TotalPlayTime()
{
AutoSizeAxes = Axes.Both;
-
- TooltipText = "0 hours";
}
[BackgroundDependencyLoader]
@@ -32,6 +26,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
InternalChild = info = new ProfileValueDisplay(minimumWidth: 140)
{
Title = UsersStrings.ShowStatsPlayTime,
+ ContentTooltipText = "0 hours",
};
User.BindValueChanged(updateTime, true);
@@ -40,7 +35,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
private void updateTime(ValueChangedEvent user)
{
int? playTime = user.NewValue?.User.Statistics?.PlayTime;
- TooltipText = (playTime ?? 0) / 3600 + " hours";
+ info.ContentTooltipText = (playTime ?? 0) / 3600 + " hours";
info.Content = formatTime(playTime);
}
From 5fa54c8c6355aeb85df2daa905d4c02d66995132 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Sat, 10 Feb 2024 14:16:45 +0300
Subject: [PATCH 040/105] Fix remaining use cases
---
.../Objects/EmptyFreeformHitObject.cs | 2 +-
.../Objects/PippidonHitObject.cs | 2 +-
.../Objects/EmptyScrollingHitObject.cs | 2 +-
.../Objects/PippidonHitObject.cs | 2 +-
.../Gameplay/TestSceneDrainingHealthProcessor.cs | 2 +-
.../Gameplay/TestSceneDrawableHitObject.cs | 2 +-
.../Gameplay/TestSceneScoreProcessor.cs | 14 +++++++-------
.../Rulesets/Scoring/ScoreProcessorTest.cs | 15 ++++++---------
8 files changed, 19 insertions(+), 22 deletions(-)
diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/EmptyFreeformHitObject.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/EmptyFreeformHitObject.cs
index 9cd18d2d9f..e166d09f84 100644
--- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/EmptyFreeformHitObject.cs
+++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/EmptyFreeformHitObject.cs
@@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.EmptyFreeform.Objects
{
public class EmptyFreeformHitObject : HitObject, IHasPosition
{
- public override Judgement CreateJudgement() => new Judgement();
+ protected override Judgement CreateJudgement() => new Judgement();
public Vector2 Position { get; set; }
diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs
index 0c22554e82..748e6d3b53 100644
--- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs
+++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs
@@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Pippidon.Objects
{
public class PippidonHitObject : HitObject, IHasPosition
{
- public override Judgement CreateJudgement() => new Judgement();
+ protected override Judgement CreateJudgement() => new Judgement();
public Vector2 Position { get; set; }
diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/EmptyScrollingHitObject.cs b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/EmptyScrollingHitObject.cs
index 9b469be496..4564bd1e09 100644
--- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/EmptyScrollingHitObject.cs
+++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/EmptyScrollingHitObject.cs
@@ -8,6 +8,6 @@ namespace osu.Game.Rulesets.EmptyScrolling.Objects
{
public class EmptyScrollingHitObject : HitObject
{
- public override Judgement CreateJudgement() => new Judgement();
+ protected override Judgement CreateJudgement() => new Judgement();
}
}
diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs
index 9dd135479f..ed16bce9f6 100644
--- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs
+++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs
@@ -13,6 +13,6 @@ namespace osu.Game.Rulesets.Pippidon.Objects
///
public int Lane;
- public override Judgement CreateJudgement() => new Judgement();
+ protected override Judgement CreateJudgement() => new Judgement();
}
}
diff --git a/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs b/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs
index 584a9e09c0..f0f93f59b5 100644
--- a/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs
+++ b/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs
@@ -358,7 +358,7 @@ namespace osu.Game.Tests.Gameplay
this.maxResult = maxResult;
}
- public override Judgement CreateJudgement() => new TestJudgement(maxResult);
+ protected override Judgement CreateJudgement() => new TestJudgement(maxResult);
protected override HitWindows CreateHitWindows() => new HitWindows();
private class TestJudgement : Judgement
diff --git a/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs b/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs
index 73177e36e1..22643feebb 100644
--- a/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs
+++ b/osu.Game.Tests/Gameplay/TestSceneDrawableHitObject.cs
@@ -175,7 +175,7 @@ namespace osu.Game.Tests.Gameplay
var hitObject = new HitObject { StartTime = Time.Current };
lifetimeEntry = new HitObjectLifetimeEntry(hitObject)
{
- Result = new JudgementResult(hitObject, hitObject.CreateJudgement())
+ Result = new JudgementResult(hitObject, hitObject.Judgement)
{
Type = HitResult.Great
}
diff --git a/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs b/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs
index 1a644ad600..a428979015 100644
--- a/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs
+++ b/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs
@@ -129,10 +129,10 @@ namespace osu.Game.Tests.Gameplay
var scoreProcessor = new ScoreProcessor(new OsuRuleset());
scoreProcessor.ApplyBeatmap(beatmap);
- scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], beatmap.HitObjects[0].CreateJudgement()) { Type = HitResult.Ok });
- scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[1], beatmap.HitObjects[1].CreateJudgement()) { Type = HitResult.LargeTickHit });
- scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[2], beatmap.HitObjects[2].CreateJudgement()) { Type = HitResult.SmallTickMiss });
- scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[3], beatmap.HitObjects[3].CreateJudgement()) { Type = HitResult.SmallBonus });
+ scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], beatmap.HitObjects[0].Judgement) { Type = HitResult.Ok });
+ scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[1], beatmap.HitObjects[1].Judgement) { Type = HitResult.LargeTickHit });
+ scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[2], beatmap.HitObjects[2].Judgement) { Type = HitResult.SmallTickMiss });
+ scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[3], beatmap.HitObjects[3].Judgement) { Type = HitResult.SmallBonus });
var score = new ScoreInfo { Ruleset = new OsuRuleset().RulesetInfo };
scoreProcessor.FailScore(score);
@@ -169,8 +169,8 @@ namespace osu.Game.Tests.Gameplay
Assert.That(scoreProcessor.MinimumAccuracy.Value, Is.EqualTo(0));
Assert.That(scoreProcessor.MaximumAccuracy.Value, Is.EqualTo(1));
- scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], beatmap.HitObjects[0].CreateJudgement()) { Type = HitResult.Ok });
- scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[1], beatmap.HitObjects[1].CreateJudgement()) { Type = HitResult.Great });
+ scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], beatmap.HitObjects[0].Judgement) { Type = HitResult.Ok });
+ scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[1], beatmap.HitObjects[1].Judgement) { Type = HitResult.Great });
Assert.That(scoreProcessor.Accuracy.Value, Is.EqualTo((double)(100 + 300) / (2 * 300)).Within(Precision.DOUBLE_EPSILON));
Assert.That(scoreProcessor.MinimumAccuracy.Value, Is.EqualTo((double)(100 + 300) / (4 * 300)).Within(Precision.DOUBLE_EPSILON));
@@ -196,7 +196,7 @@ namespace osu.Game.Tests.Gameplay
this.maxResult = maxResult;
}
- public override Judgement CreateJudgement() => new TestJudgement(maxResult);
+ protected override Judgement CreateJudgement() => new TestJudgement(maxResult);
}
}
}
diff --git a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs
index a3f91fffba..ea43a65825 100644
--- a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs
+++ b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs
@@ -112,7 +112,7 @@ namespace osu.Game.Tests.Rulesets.Scoring
for (int i = 0; i < 4; i++)
{
- var judgementResult = new JudgementResult(fourObjectBeatmap.HitObjects[i], fourObjectBeatmap.HitObjects[i].CreateJudgement())
+ var judgementResult = new JudgementResult(fourObjectBeatmap.HitObjects[i], fourObjectBeatmap.HitObjects[i].Judgement)
{
Type = i == 2 ? minResult : hitResult
};
@@ -141,7 +141,7 @@ namespace osu.Game.Tests.Rulesets.Scoring
for (int i = 0; i < object_count; ++i)
{
- var judgementResult = new JudgementResult(largeBeatmap.HitObjects[i], largeBeatmap.HitObjects[i].CreateJudgement())
+ var judgementResult = new JudgementResult(largeBeatmap.HitObjects[i], largeBeatmap.HitObjects[i].Judgement)
{
Type = HitResult.Great
};
@@ -325,11 +325,11 @@ namespace osu.Game.Tests.Rulesets.Scoring
scoreProcessor = new TestScoreProcessor();
scoreProcessor.ApplyBeatmap(beatmap);
- scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], beatmap.HitObjects[0].CreateJudgement()) { Type = HitResult.Great });
+ scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], beatmap.HitObjects[0].Judgement) { Type = HitResult.Great });
Assert.That(scoreProcessor.Combo.Value, Is.EqualTo(1));
Assert.That(scoreProcessor.Accuracy.Value, Is.EqualTo(1));
- scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[1], beatmap.HitObjects[1].CreateJudgement()) { Type = HitResult.ComboBreak });
+ scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[1], beatmap.HitObjects[1].Judgement) { Type = HitResult.ComboBreak });
Assert.That(scoreProcessor.Combo.Value, Is.EqualTo(0));
Assert.That(scoreProcessor.Accuracy.Value, Is.EqualTo(1));
}
@@ -350,7 +350,7 @@ namespace osu.Game.Tests.Rulesets.Scoring
for (int i = 0; i < beatmap.HitObjects.Count; i++)
{
- scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[i], beatmap.HitObjects[i].CreateJudgement())
+ scoreProcessor.ApplyResult(new JudgementResult(beatmap.HitObjects[i], beatmap.HitObjects[i].Judgement)
{
Type = i == 0 ? HitResult.Miss : HitResult.Great
});
@@ -441,10 +441,7 @@ namespace osu.Game.Tests.Rulesets.Scoring
private readonly HitResult maxResult;
private readonly HitResult? minResult;
- public override Judgement CreateJudgement()
- {
- return new TestJudgement(maxResult, minResult);
- }
+ protected override Judgement CreateJudgement() => new TestJudgement(maxResult, minResult);
public TestHitObject(HitResult maxResult, HitResult? minResult = null)
{
From a03835bf1c472a477dc992b7c2d05357e1b07da4 Mon Sep 17 00:00:00 2001
From: Joseph Madamba
Date: Wed, 14 Feb 2024 20:13:27 -0800
Subject: [PATCH 041/105] Improve comments
---
.../Overlays/Profile/Header/Components/GlobalRankDisplay.cs | 2 +-
osu.Game/Users/UserRankPanel.cs | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs b/osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs
index dcd4129b45..d32f56ab1b 100644
--- a/osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs
+++ b/osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs
@@ -30,7 +30,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
Content = s.NewValue?.GlobalRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-";
}, true);
- // needed as statistics doesn't populate User
+ // needed as `UserStatistics` doesn't populate `User`
User.BindValueChanged(u =>
{
var rankHighest = u.NewValue?.RankHighest;
diff --git a/osu.Game/Users/UserRankPanel.cs b/osu.Game/Users/UserRankPanel.cs
index 4a00583094..0b8a5166e6 100644
--- a/osu.Game/Users/UserRankPanel.cs
+++ b/osu.Game/Users/UserRankPanel.cs
@@ -167,8 +167,8 @@ namespace osu.Game.Users
new GlobalRankDisplay
{
UserStatistics = { BindTarget = statistics },
- // TODO: make highest rank update, as api.LocalUser doesn't update
- // maybe move to statistics in api, so `SoloStatisticsWatcher` can update the value
+ // TODO: make highest rank update, as `api.LocalUser` doesn't update
+ // maybe move to `UserStatistics` in api, so `SoloStatisticsWatcher` can update the value
User = { BindTarget = user },
},
countryRankDisplay = new ProfileValueDisplay(true)
From 95e745c6fbabce01dda192e567546185bfe62e9f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Thu, 15 Feb 2024 10:16:06 +0100
Subject: [PATCH 042/105] Use better messaging for selected submission failure
reasons
These have been cropping up rather often lately, mostly courtesy of
linux users, but not only:
https://github.com/ppy/osu/issues/26840
https://github.com/ppy/osu/issues/27008
https://github.com/ppy/osu/discussions/26962
so this is a proposal for slightly improved messaging for such cases to
hopefully get users on the right track.
The original error is still logged to network log, so there's no
information loss.
---
osu.Game/Screens/Play/SubmittingPlayer.cs | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/osu.Game/Screens/Play/SubmittingPlayer.cs b/osu.Game/Screens/Play/SubmittingPlayer.cs
index c45d46e993..c759710aba 100644
--- a/osu.Game/Screens/Play/SubmittingPlayer.cs
+++ b/osu.Game/Screens/Play/SubmittingPlayer.cs
@@ -140,7 +140,13 @@ namespace osu.Game.Screens.Play
{
switch (exception.Message)
{
- case "expired token":
+ case @"missing token header":
+ case @"invalid client hash":
+ case @"invalid verification hash":
+ Logger.Log("You are not able to submit a score. Please ensure that you are using the latest version of the official game releases.", level: LogLevel.Important);
+ break;
+
+ case @"expired token":
Logger.Log("Score submission failed because your system clock is set incorrectly. Please check your system time, date and timezone.", level: LogLevel.Important);
break;
From 898d5ce88bd4d249f98b8fe7cc6dd5e7cdd635d4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Thu, 15 Feb 2024 10:40:40 +0100
Subject: [PATCH 043/105] Show selected submission failure messages even in
solo
Previously, if a `SubmittingPlayer` instance deemed it okay to proceed
with gameplay despite submission failure, it would silently log all
errors and proceed, but the score would still not be submitted. This
feels a bit anti-user in the cases wherein something is genuinely wrong
with either the client or web, so things like token verification
failures or API failures are now shown as notifications to give the user
an indication that something went wrong at all.
Selected cases (non-user-playable mod, logged out, beatmap is not
online) are still logged silently because those are either known and
expected, or someone is messing with things.
---
osu.Game/Screens/Play/SoloPlayer.cs | 2 +-
osu.Game/Screens/Play/SubmittingPlayer.cs | 33 ++++++++++++-----------
osu.Game/Tests/Visual/TestPlayer.cs | 2 +-
3 files changed, 20 insertions(+), 17 deletions(-)
diff --git a/osu.Game/Screens/Play/SoloPlayer.cs b/osu.Game/Screens/Play/SoloPlayer.cs
index f7ae3eb62b..f4cf2da364 100644
--- a/osu.Game/Screens/Play/SoloPlayer.cs
+++ b/osu.Game/Screens/Play/SoloPlayer.cs
@@ -52,7 +52,7 @@ namespace osu.Game.Screens.Play
Scores = { BindTarget = LeaderboardScores }
};
- protected override bool HandleTokenRetrievalFailure(Exception exception) => false;
+ protected override bool ShouldExitOnTokenRetrievalFailure(Exception exception) => false;
protected override Task ImportScore(Score score)
{
diff --git a/osu.Game/Screens/Play/SubmittingPlayer.cs b/osu.Game/Screens/Play/SubmittingPlayer.cs
index c759710aba..0873f60791 100644
--- a/osu.Game/Screens/Play/SubmittingPlayer.cs
+++ b/osu.Game/Screens/Play/SubmittingPlayer.cs
@@ -118,7 +118,7 @@ namespace osu.Game.Screens.Play
token = r.ID;
tcs.SetResult(true);
};
- req.Failure += handleTokenFailure;
+ req.Failure += ex => handleTokenFailure(ex, displayNotification: true);
api.Queue(req);
@@ -128,14 +128,20 @@ namespace osu.Game.Screens.Play
return true;
- void handleTokenFailure(Exception exception)
+ void handleTokenFailure(Exception exception, bool displayNotification = false)
{
tcs.SetResult(false);
- if (HandleTokenRetrievalFailure(exception))
+ bool shouldExit = ShouldExitOnTokenRetrievalFailure(exception);
+
+ if (displayNotification || shouldExit)
{
+ string whatWillHappen = shouldExit
+ ? "You are not able to submit a score."
+ : "The following score will not be submitted.";
+
if (string.IsNullOrEmpty(exception.Message))
- Logger.Error(exception, "Failed to retrieve a score submission token.");
+ Logger.Error(exception, $"{whatWillHappen} Failed to retrieve a score submission token.");
else
{
switch (exception.Message)
@@ -143,31 +149,28 @@ namespace osu.Game.Screens.Play
case @"missing token header":
case @"invalid client hash":
case @"invalid verification hash":
- Logger.Log("You are not able to submit a score. Please ensure that you are using the latest version of the official game releases.", level: LogLevel.Important);
+ Logger.Log($"{whatWillHappen} Please ensure that you are using the latest version of the official game releases.", level: LogLevel.Important);
break;
case @"expired token":
- Logger.Log("Score submission failed because your system clock is set incorrectly. Please check your system time, date and timezone.", level: LogLevel.Important);
+ Logger.Log($"{whatWillHappen} Your system clock is set incorrectly. Please check your system time, date and timezone.", level: LogLevel.Important);
break;
default:
- Logger.Log($"You are not able to submit a score: {exception.Message}", level: LogLevel.Important);
+ Logger.Log($"{whatWillHappen} {exception.Message}", level: LogLevel.Important);
break;
}
}
+ }
+ if (shouldExit)
+ {
Schedule(() =>
{
ValidForResume = false;
this.Exit();
});
}
- else
- {
- // Gameplay is allowed to continue, but we still should keep track of the error.
- // In the future, this should be visible to the user in some way.
- Logger.Log($"Score submission token retrieval failed ({exception.Message})");
- }
}
}
@@ -176,7 +179,7 @@ namespace osu.Game.Screens.Play
///
/// The error causing the failure.
/// Whether gameplay should be immediately exited as a result. Returning false allows the gameplay session to continue. Defaults to true.
- protected virtual bool HandleTokenRetrievalFailure(Exception exception) => true;
+ protected virtual bool ShouldExitOnTokenRetrievalFailure(Exception exception) => true;
protected override async Task PrepareScoreForResultsAsync(Score score)
{
@@ -237,7 +240,7 @@ namespace osu.Game.Screens.Play
///
/// Construct a request to be used for retrieval of the score token.
- /// Can return null, at which point will be fired.
+ /// Can return null, at which point will be fired.
///
[CanBeNull]
protected abstract APIRequest CreateTokenRequest();
diff --git a/osu.Game/Tests/Visual/TestPlayer.cs b/osu.Game/Tests/Visual/TestPlayer.cs
index d9cae6b03b..579a1934e0 100644
--- a/osu.Game/Tests/Visual/TestPlayer.cs
+++ b/osu.Game/Tests/Visual/TestPlayer.cs
@@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual
PauseOnFocusLost = pauseOnFocusLost;
}
- protected override bool HandleTokenRetrievalFailure(Exception exception) => false;
+ protected override bool ShouldExitOnTokenRetrievalFailure(Exception exception) => false;
protected override APIRequest CreateTokenRequest()
{
From 0fff9d49378ce8acc9aa0e612b6215ed831eea9b Mon Sep 17 00:00:00 2001
From: Dan Balasescu
Date: Fri, 16 Feb 2024 19:17:41 +0900
Subject: [PATCH 044/105] Add non-whitespace search term for mods
---
osu.Game/Overlays/Mods/ModPanel.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/osu.Game/Overlays/Mods/ModPanel.cs b/osu.Game/Overlays/Mods/ModPanel.cs
index f294b1892d..2d8d01d8c8 100644
--- a/osu.Game/Overlays/Mods/ModPanel.cs
+++ b/osu.Game/Overlays/Mods/ModPanel.cs
@@ -80,6 +80,7 @@ namespace osu.Game.Overlays.Mods
public override IEnumerable FilterTerms => new[]
{
Mod.Name,
+ Mod.Name.Replace(" ", string.Empty),
Mod.Acronym,
Mod.Description
};
From 171270d99c21f1f620150cd119489bf40e8fa80c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Fri, 16 Feb 2024 12:58:13 +0100
Subject: [PATCH 045/105] Fix missing RPC method mapping
Thanks, signalr.
---
osu.Game/Online/Metadata/OnlineMetadataClient.cs | 1 +
1 file changed, 1 insertion(+)
diff --git a/osu.Game/Online/Metadata/OnlineMetadataClient.cs b/osu.Game/Online/Metadata/OnlineMetadataClient.cs
index c42c3378b7..19c32166da 100644
--- a/osu.Game/Online/Metadata/OnlineMetadataClient.cs
+++ b/osu.Game/Online/Metadata/OnlineMetadataClient.cs
@@ -58,6 +58,7 @@ namespace osu.Game.Online.Metadata
// https://github.com/dotnet/aspnetcore/issues/15198
connection.On(nameof(IMetadataClient.BeatmapSetsUpdated), ((IMetadataClient)this).BeatmapSetsUpdated);
connection.On(nameof(IMetadataClient.UserPresenceUpdated), ((IMetadataClient)this).UserPresenceUpdated);
+ connection.On(nameof(IStatefulUserHubClient.DisconnectRequested), ((IMetadataClient)this).DisconnectRequested);
};
IsConnected.BindTo(connector.IsConnected);
From 9fa60b169e6bc887b64236775fece8ecc936356c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Fri, 16 Feb 2024 12:58:50 +0100
Subject: [PATCH 046/105] Actually disconnect from metadata hub when requested
to
Nothing in this override, on in the base implementation, would actually
attempt to disconnect.
---
osu.Game/Online/Metadata/OnlineMetadataClient.cs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/osu.Game/Online/Metadata/OnlineMetadataClient.cs b/osu.Game/Online/Metadata/OnlineMetadataClient.cs
index 19c32166da..ea8ef60124 100644
--- a/osu.Game/Online/Metadata/OnlineMetadataClient.cs
+++ b/osu.Game/Online/Metadata/OnlineMetadataClient.cs
@@ -233,6 +233,8 @@ namespace osu.Game.Online.Metadata
{
await base.DisconnectRequested().ConfigureAwait(false);
await EndWatchingUserPresence().ConfigureAwait(false);
+ if (connector != null)
+ await connector.Disconnect().ConfigureAwait(false);
}
protected override void Dispose(bool isDisposing)
From b4aa24703239da3b5e81fe834b06fe661662dbfd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Fri, 16 Feb 2024 12:59:22 +0100
Subject: [PATCH 047/105] Do not attempt to stop watching user presence when
requested to disconnect
First of all, this sort of cleanup isn't really the client's
responsibility, and secondly, at the point the client received this
request to disconnect, *none of its requests will be honored anymore*
(currently the only scenario of this if another client has connected
- the server-side concurrency filter will reject this request).
When disconnection is requested, the only valid thing to do with respect
to talking to the server is to stop doing it.
This will be moved server-side in a follow-up change, although I'm not
even strictly sure that's required - I'd like to think signalr would
know to clean up a disconnecting client from all groups they were in.
---
osu.Game/Online/Metadata/OnlineMetadataClient.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/osu.Game/Online/Metadata/OnlineMetadataClient.cs b/osu.Game/Online/Metadata/OnlineMetadataClient.cs
index ea8ef60124..3805d12688 100644
--- a/osu.Game/Online/Metadata/OnlineMetadataClient.cs
+++ b/osu.Game/Online/Metadata/OnlineMetadataClient.cs
@@ -232,7 +232,6 @@ namespace osu.Game.Online.Metadata
public override async Task DisconnectRequested()
{
await base.DisconnectRequested().ConfigureAwait(false);
- await EndWatchingUserPresence().ConfigureAwait(false);
if (connector != null)
await connector.Disconnect().ConfigureAwait(false);
}
From 1049be7d724565ba61da9f18ddb825366affd723 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Fri, 16 Feb 2024 13:06:58 +0100
Subject: [PATCH 048/105] Add extended xmldoc to `DisconnectRequested()`
Just expounds on what the previous commit message said.
---
osu.Game/Online/IStatefulUserHubClient.cs | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/osu.Game/Online/IStatefulUserHubClient.cs b/osu.Game/Online/IStatefulUserHubClient.cs
index 86105dd629..e931e3c862 100644
--- a/osu.Game/Online/IStatefulUserHubClient.cs
+++ b/osu.Game/Online/IStatefulUserHubClient.cs
@@ -13,6 +13,18 @@ namespace osu.Game.Online
///
public interface IStatefulUserHubClient
{
+ ///
+ /// Invoked when the server requests a client to disconnect.
+ ///
+ ///
+ /// When this request is received, the client must presume any and all further requests to the server
+ /// will either fail or be ignored.
+ /// This method is ONLY to be used for the purposes of:
+ ///
+ /// - actually physically disconnecting from the server,
+ /// - cleaning up / setting up any and all required local client state.
+ ///
+ ///
Task DisconnectRequested();
}
}
From 060b01eee8d30d996858515829568feb827cc8b4 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Fri, 16 Feb 2024 20:24:02 +0300
Subject: [PATCH 049/105] Make CreateJudgement public again and add remarks
---
.../Objects/EmptyFreeformHitObject.cs | 2 +-
.../osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs | 2 +-
.../Objects/EmptyScrollingHitObject.cs | 2 +-
.../osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs | 2 +-
osu.Game.Rulesets.Catch/Objects/Banana.cs | 2 +-
osu.Game.Rulesets.Catch/Objects/BananaShower.cs | 2 +-
osu.Game.Rulesets.Catch/Objects/Droplet.cs | 2 +-
osu.Game.Rulesets.Catch/Objects/Fruit.cs | 2 +-
osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 2 +-
osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs | 2 +-
osu.Game.Rulesets.Mania/Objects/BarLine.cs | 2 +-
osu.Game.Rulesets.Mania/Objects/HoldNote.cs | 2 +-
osu.Game.Rulesets.Mania/Objects/HoldNoteBody.cs | 2 +-
osu.Game.Rulesets.Mania/Objects/Note.cs | 2 +-
osu.Game.Rulesets.Mania/Objects/TailNote.cs | 2 +-
osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/HitCircle.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/Slider.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/SliderHeadCircle.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/SliderTick.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/Spinner.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs | 2 +-
osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs | 2 +-
osu.Game.Rulesets.Taiko/Objects/BarLine.cs | 2 +-
osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs | 4 ++--
osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs | 2 +-
osu.Game.Rulesets.Taiko/Objects/IgnoreHit.cs | 2 +-
osu.Game.Rulesets.Taiko/Objects/StrongNestedHitObject.cs | 2 +-
osu.Game.Rulesets.Taiko/Objects/Swell.cs | 2 +-
osu.Game.Rulesets.Taiko/Objects/SwellTick.cs | 2 +-
osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs | 2 +-
osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs | 2 +-
osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs | 2 +-
osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs | 2 +-
osu.Game/Database/StandardisedScoreMigrationTools.cs | 2 +-
osu.Game/Rulesets/Objects/HitObject.cs | 6 +++++-
osu.Game/Rulesets/Objects/Legacy/ConvertHitObject.cs | 2 +-
39 files changed, 44 insertions(+), 40 deletions(-)
diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/EmptyFreeformHitObject.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/EmptyFreeformHitObject.cs
index e166d09f84..9cd18d2d9f 100644
--- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/EmptyFreeformHitObject.cs
+++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/Objects/EmptyFreeformHitObject.cs
@@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.EmptyFreeform.Objects
{
public class EmptyFreeformHitObject : HitObject, IHasPosition
{
- protected override Judgement CreateJudgement() => new Judgement();
+ public override Judgement CreateJudgement() => new Judgement();
public Vector2 Position { get; set; }
diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs
index 748e6d3b53..0c22554e82 100644
--- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs
+++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs
@@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Pippidon.Objects
{
public class PippidonHitObject : HitObject, IHasPosition
{
- protected override Judgement CreateJudgement() => new Judgement();
+ public override Judgement CreateJudgement() => new Judgement();
public Vector2 Position { get; set; }
diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/EmptyScrollingHitObject.cs b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/EmptyScrollingHitObject.cs
index 4564bd1e09..9b469be496 100644
--- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/EmptyScrollingHitObject.cs
+++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/Objects/EmptyScrollingHitObject.cs
@@ -8,6 +8,6 @@ namespace osu.Game.Rulesets.EmptyScrolling.Objects
{
public class EmptyScrollingHitObject : HitObject
{
- protected override Judgement CreateJudgement() => new Judgement();
+ public override Judgement CreateJudgement() => new Judgement();
}
}
diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs
index ed16bce9f6..9dd135479f 100644
--- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs
+++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/Objects/PippidonHitObject.cs
@@ -13,6 +13,6 @@ namespace osu.Game.Rulesets.Pippidon.Objects
///
public int Lane;
- protected override Judgement CreateJudgement() => new Judgement();
+ public override Judgement CreateJudgement() => new Judgement();
}
}
diff --git a/osu.Game.Rulesets.Catch/Objects/Banana.cs b/osu.Game.Rulesets.Catch/Objects/Banana.cs
index 30bdb24b14..b80527f379 100644
--- a/osu.Game.Rulesets.Catch/Objects/Banana.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Banana.cs
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Catch.Objects
///
public int BananaIndex;
- protected override Judgement CreateJudgement() => new CatchBananaJudgement();
+ public override Judgement CreateJudgement() => new CatchBananaJudgement();
private static readonly IList default_banana_samples = new List { new BananaHitSampleInfo() }.AsReadOnly();
diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs
index 86c41fce90..328cc2b52a 100644
--- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs
+++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs
@@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Catch.Objects
{
public override bool LastInCombo => true;
- protected override Judgement CreateJudgement() => new IgnoreJudgement();
+ public override Judgement CreateJudgement() => new IgnoreJudgement();
protected override void CreateNestedHitObjects(CancellationToken cancellationToken)
{
diff --git a/osu.Game.Rulesets.Catch/Objects/Droplet.cs b/osu.Game.Rulesets.Catch/Objects/Droplet.cs
index 107c6c3979..9c1004a04b 100644
--- a/osu.Game.Rulesets.Catch/Objects/Droplet.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Droplet.cs
@@ -8,6 +8,6 @@ namespace osu.Game.Rulesets.Catch.Objects
{
public class Droplet : PalpableCatchHitObject
{
- protected override Judgement CreateJudgement() => new CatchDropletJudgement();
+ public override Judgement CreateJudgement() => new CatchDropletJudgement();
}
}
diff --git a/osu.Game.Rulesets.Catch/Objects/Fruit.cs b/osu.Game.Rulesets.Catch/Objects/Fruit.cs
index 17270b803c..4818fe2cad 100644
--- a/osu.Game.Rulesets.Catch/Objects/Fruit.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Fruit.cs
@@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Catch.Objects
{
public class Fruit : PalpableCatchHitObject
{
- protected override Judgement CreateJudgement() => new CatchJudgement();
+ public override Judgement CreateJudgement() => new CatchJudgement();
public static FruitVisualRepresentation GetVisualRepresentation(int indexInBeatmap) => (FruitVisualRepresentation)(indexInBeatmap % 4);
}
diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
index 49c24df5b9..671291ef0e 100644
--- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
+++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
@@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.Objects
///
private const float base_scoring_distance = 100;
- protected override Judgement CreateJudgement() => new IgnoreJudgement();
+ public override Judgement CreateJudgement() => new IgnoreJudgement();
public int RepeatCount { get; set; }
diff --git a/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs
index ddcb92875f..1bf160b5a6 100644
--- a/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs
+++ b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs
@@ -8,6 +8,6 @@ namespace osu.Game.Rulesets.Catch.Objects
{
public class TinyDroplet : Droplet
{
- protected override Judgement CreateJudgement() => new CatchTinyDropletJudgement();
+ public override Judgement CreateJudgement() => new CatchTinyDropletJudgement();
}
}
diff --git a/osu.Game.Rulesets.Mania/Objects/BarLine.cs b/osu.Game.Rulesets.Mania/Objects/BarLine.cs
index 742b5e4b0d..cf576239ed 100644
--- a/osu.Game.Rulesets.Mania/Objects/BarLine.cs
+++ b/osu.Game.Rulesets.Mania/Objects/BarLine.cs
@@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Mania.Objects
set => major.Value = value;
}
- protected override Judgement CreateJudgement() => new IgnoreJudgement();
+ public override Judgement CreateJudgement() => new IgnoreJudgement();
}
}
diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
index 4aac455bc5..3f930a310b 100644
--- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
@@ -112,7 +112,7 @@ namespace osu.Game.Rulesets.Mania.Objects
});
}
- protected override Judgement CreateJudgement() => new IgnoreJudgement();
+ public override Judgement CreateJudgement() => new IgnoreJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNoteBody.cs b/osu.Game.Rulesets.Mania/Objects/HoldNoteBody.cs
index 92b649c174..47163d0d81 100644
--- a/osu.Game.Rulesets.Mania/Objects/HoldNoteBody.cs
+++ b/osu.Game.Rulesets.Mania/Objects/HoldNoteBody.cs
@@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Objects
///
public class HoldNoteBody : ManiaHitObject
{
- protected override Judgement CreateJudgement() => new HoldNoteBodyJudgement();
+ public override Judgement CreateJudgement() => new HoldNoteBodyJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
}
}
diff --git a/osu.Game.Rulesets.Mania/Objects/Note.cs b/osu.Game.Rulesets.Mania/Objects/Note.cs
index b0f2991918..0035960c63 100644
--- a/osu.Game.Rulesets.Mania/Objects/Note.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Note.cs
@@ -11,6 +11,6 @@ namespace osu.Game.Rulesets.Mania.Objects
///
public class Note : ManiaHitObject
{
- protected override Judgement CreateJudgement() => new ManiaJudgement();
+ public override Judgement CreateJudgement() => new ManiaJudgement();
}
}
diff --git a/osu.Game.Rulesets.Mania/Objects/TailNote.cs b/osu.Game.Rulesets.Mania/Objects/TailNote.cs
index bddb4630cb..def32880f1 100644
--- a/osu.Game.Rulesets.Mania/Objects/TailNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/TailNote.cs
@@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Objects
///
public const double RELEASE_WINDOW_LENIENCE = 1.5;
- protected override Judgement CreateJudgement() => new ManiaJudgement();
+ public override Judgement CreateJudgement() => new ManiaJudgement();
public override double MaximumJudgementOffset => base.MaximumJudgementOffset * RELEASE_WINDOW_LENIENCE;
}
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs
index f07a1e930b..2c9292c58b 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs
@@ -79,7 +79,7 @@ namespace osu.Game.Rulesets.Osu.Mods
{
}
- protected override Judgement CreateJudgement() => new OsuJudgement();
+ public override Judgement CreateJudgement() => new OsuJudgement();
}
private partial class StrictTrackingDrawableSliderTail : DrawableSliderTail
diff --git a/osu.Game.Rulesets.Osu/Objects/HitCircle.cs b/osu.Game.Rulesets.Osu/Objects/HitCircle.cs
index 6336482ccc..d652db0fd4 100644
--- a/osu.Game.Rulesets.Osu/Objects/HitCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/HitCircle.cs
@@ -8,6 +8,6 @@ namespace osu.Game.Rulesets.Osu.Objects
{
public class HitCircle : OsuHitObject
{
- protected override Judgement CreateJudgement() => new OsuJudgement();
+ public override Judgement CreateJudgement() => new OsuJudgement();
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs
index fc0248cbbd..506145568e 100644
--- a/osu.Game.Rulesets.Osu/Objects/Slider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs
@@ -275,7 +275,7 @@ namespace osu.Game.Rulesets.Osu.Objects
TailSamples = this.GetNodeSamples(repeatCount + 1);
}
- protected override Judgement CreateJudgement() => ClassicSliderBehaviour
+ public override Judgement CreateJudgement() => ClassicSliderBehaviour
// Final combo is provided by the slider itself - see logic in `DrawableSlider.CheckForResult()`
? new OsuJudgement()
// Final combo is provided by the tail circle - see `SliderTailCircle`
diff --git a/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs b/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs
index 8d60864f0b..2d5a5b7727 100644
--- a/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/SliderEndCircle.cs
@@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.Objects
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
- protected override Judgement CreateJudgement() => new SliderEndJudgement();
+ public override Judgement CreateJudgement() => new SliderEndJudgement();
public class SliderEndJudgement : OsuJudgement
{
diff --git a/osu.Game.Rulesets.Osu/Objects/SliderHeadCircle.cs b/osu.Game.Rulesets.Osu/Objects/SliderHeadCircle.cs
index 4760135081..8305481788 100644
--- a/osu.Game.Rulesets.Osu/Objects/SliderHeadCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/SliderHeadCircle.cs
@@ -14,6 +14,6 @@ namespace osu.Game.Rulesets.Osu.Objects
///
public bool ClassicSliderBehaviour;
- protected override Judgement CreateJudgement() => ClassicSliderBehaviour ? new SliderTickJudgement() : base.CreateJudgement();
+ public override Judgement CreateJudgement() => ClassicSliderBehaviour ? new SliderTickJudgement() : base.CreateJudgement();
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs b/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs
index 42d8d895e4..ee2490439f 100644
--- a/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Objects
{
}
- protected override Judgement CreateJudgement() => ClassicSliderBehaviour ? new LegacyTailJudgement() : new TailJudgement();
+ public override Judgement CreateJudgement() => ClassicSliderBehaviour ? new LegacyTailJudgement() : new TailJudgement();
public class LegacyTailJudgement : OsuJudgement
{
diff --git a/osu.Game.Rulesets.Osu/Objects/SliderTick.cs b/osu.Game.Rulesets.Osu/Objects/SliderTick.cs
index 1d7ba2fbaf..74ec4d6eb3 100644
--- a/osu.Game.Rulesets.Osu/Objects/SliderTick.cs
+++ b/osu.Game.Rulesets.Osu/Objects/SliderTick.cs
@@ -32,6 +32,6 @@ namespace osu.Game.Rulesets.Osu.Objects
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
- protected override Judgement CreateJudgement() => new SliderTickJudgement();
+ public override Judgement CreateJudgement() => new SliderTickJudgement();
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Spinner.cs b/osu.Game.Rulesets.Osu/Objects/Spinner.cs
index 9baa645b3c..e3dfe8e69a 100644
--- a/osu.Game.Rulesets.Osu/Objects/Spinner.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Spinner.cs
@@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.Osu.Objects
}
}
- protected override Judgement CreateJudgement() => new OsuJudgement();
+ public override Judgement CreateJudgement() => new OsuJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
diff --git a/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs b/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs
index 57db29ef0c..8d53100529 100644
--- a/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs
+++ b/osu.Game.Rulesets.Osu/Objects/SpinnerBonusTick.cs
@@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Osu.Objects
{
public class SpinnerBonusTick : SpinnerTick
{
- protected override Judgement CreateJudgement() => new OsuSpinnerBonusTickJudgement();
+ public override Judgement CreateJudgement() => new OsuSpinnerBonusTickJudgement();
public class OsuSpinnerBonusTickJudgement : OsuSpinnerTickJudgement
{
diff --git a/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs b/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs
index cb59014909..7989c9b7ff 100644
--- a/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs
+++ b/osu.Game.Rulesets.Osu/Objects/SpinnerTick.cs
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Osu.Objects
///
public double SpinnerDuration { get; set; }
- protected override Judgement CreateJudgement() => new OsuSpinnerTickJudgement();
+ public override Judgement CreateJudgement() => new OsuSpinnerTickJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
diff --git a/osu.Game.Rulesets.Taiko/Objects/BarLine.cs b/osu.Game.Rulesets.Taiko/Objects/BarLine.cs
index d87f8b3232..46b3f13501 100644
--- a/osu.Game.Rulesets.Taiko/Objects/BarLine.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/BarLine.cs
@@ -19,6 +19,6 @@ namespace osu.Game.Rulesets.Taiko.Objects
set => major.Value = value;
}
- protected override Judgement CreateJudgement() => new IgnoreJudgement();
+ public override Judgement CreateJudgement() => new IgnoreJudgement();
}
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
index 50cd722a3f..f3143de345 100644
--- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
@@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
}
}
- protected override Judgement CreateJudgement() => new IgnoreJudgement();
+ public override Judgement CreateJudgement() => new IgnoreJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
@@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
public class StrongNestedHit : StrongNestedHitObject
{
// The strong hit of the drum roll doesn't actually provide any score.
- protected override Judgement CreateJudgement() => new IgnoreJudgement();
+ public override Judgement CreateJudgement() => new IgnoreJudgement();
public StrongNestedHit(TaikoHitObject parent)
: base(parent)
diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs
index c1d4102042..dc082ffd21 100644
--- a/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/DrumRollTick.cs
@@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
Parent = parent;
}
- protected override Judgement CreateJudgement() => new TaikoDrumRollTickJudgement();
+ public override Judgement CreateJudgement() => new TaikoDrumRollTickJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
diff --git a/osu.Game.Rulesets.Taiko/Objects/IgnoreHit.cs b/osu.Game.Rulesets.Taiko/Objects/IgnoreHit.cs
index 44cd700faf..302f940ef4 100644
--- a/osu.Game.Rulesets.Taiko/Objects/IgnoreHit.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/IgnoreHit.cs
@@ -7,6 +7,6 @@ namespace osu.Game.Rulesets.Taiko.Objects
{
public class IgnoreHit : Hit
{
- protected override Judgement CreateJudgement() => new IgnoreJudgement();
+ public override Judgement CreateJudgement() => new IgnoreJudgement();
}
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/StrongNestedHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/StrongNestedHitObject.cs
index 227ab4ab52..14cbe338ed 100644
--- a/osu.Game.Rulesets.Taiko/Objects/StrongNestedHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/StrongNestedHitObject.cs
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
Parent = parent;
}
- protected override Judgement CreateJudgement() => new TaikoStrongJudgement();
+ public override Judgement CreateJudgement() => new TaikoStrongJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs
index 76d106f924..a8db8df021 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs
@@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
}
}
- protected override Judgement CreateJudgement() => new TaikoSwellJudgement();
+ public override Judgement CreateJudgement() => new TaikoSwellJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs
index be1c1101de..41fb9cac7e 100644
--- a/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs
@@ -8,7 +8,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
{
public class SwellTick : TaikoHitObject
{
- protected override Judgement CreateJudgement() => new IgnoreJudgement();
+ public override Judgement CreateJudgement() => new IgnoreJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
index 697c23addf..1a1fde1990 100644
--- a/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/TaikoHitObject.cs
@@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
///
public const float DEFAULT_SIZE = 0.475f;
- protected override Judgement CreateJudgement() => new TaikoJudgement();
+ public override Judgement CreateJudgement() => new TaikoJudgement();
protected override HitWindows CreateHitWindows() => new TaikoHitWindows();
}
diff --git a/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs b/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs
index f0f93f59b5..584a9e09c0 100644
--- a/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs
+++ b/osu.Game.Tests/Gameplay/TestSceneDrainingHealthProcessor.cs
@@ -358,7 +358,7 @@ namespace osu.Game.Tests.Gameplay
this.maxResult = maxResult;
}
- protected override Judgement CreateJudgement() => new TestJudgement(maxResult);
+ public override Judgement CreateJudgement() => new TestJudgement(maxResult);
protected override HitWindows CreateHitWindows() => new HitWindows();
private class TestJudgement : Judgement
diff --git a/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs b/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs
index a428979015..8ec18377f4 100644
--- a/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs
+++ b/osu.Game.Tests/Gameplay/TestSceneScoreProcessor.cs
@@ -196,7 +196,7 @@ namespace osu.Game.Tests.Gameplay
this.maxResult = maxResult;
}
- protected override Judgement CreateJudgement() => new TestJudgement(maxResult);
+ public override Judgement CreateJudgement() => new TestJudgement(maxResult);
}
}
}
diff --git a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs
index ea43a65825..1647fbee42 100644
--- a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs
+++ b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs
@@ -441,7 +441,7 @@ namespace osu.Game.Tests.Rulesets.Scoring
private readonly HitResult maxResult;
private readonly HitResult? minResult;
- protected override Judgement CreateJudgement() => new TestJudgement(maxResult, minResult);
+ public override Judgement CreateJudgement() => new TestJudgement(maxResult, minResult);
public TestHitObject(HitResult maxResult, HitResult? minResult = null)
{
diff --git a/osu.Game/Database/StandardisedScoreMigrationTools.cs b/osu.Game/Database/StandardisedScoreMigrationTools.cs
index 576d08f491..403e73ab77 100644
--- a/osu.Game/Database/StandardisedScoreMigrationTools.cs
+++ b/osu.Game/Database/StandardisedScoreMigrationTools.cs
@@ -655,7 +655,7 @@ namespace osu.Game.Database
{
private readonly Judgement judgement;
- protected override Judgement CreateJudgement() => judgement;
+ public override Judgement CreateJudgement() => judgement;
public FakeHit(Judgement judgement)
{
diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs
index aed821332d..317dd35fef 100644
--- a/osu.Game/Rulesets/Objects/HitObject.cs
+++ b/osu.Game/Rulesets/Objects/HitObject.cs
@@ -173,8 +173,12 @@ namespace osu.Game.Rulesets.Objects
///
/// Creates the that represents the scoring information for this .
///
+ ///
+ /// Use to avoid unnecessary allocations.
+ /// This method has been left public for compatibility reasons and eventually will be made protected.
+ ///
[NotNull]
- protected virtual Judgement CreateJudgement() => new Judgement();
+ public virtual Judgement CreateJudgement() => new Judgement();
///
/// Creates the for this .
diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObject.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObject.cs
index 499953dab9..bb36aab0b3 100644
--- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObject.cs
+++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObject.cs
@@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
public int ComboOffset { get; set; }
- protected override Judgement CreateJudgement() => new IgnoreJudgement();
+ public override Judgement CreateJudgement() => new IgnoreJudgement();
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
}
From b0f334c39e4ac1c3b587fa31b7c7759cfa5ec281 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Sat, 17 Feb 2024 00:45:30 +0300
Subject: [PATCH 050/105] Fix DrawableLinkCompiler allocations
---
osu.Game/Online/Chat/DrawableLinkCompiler.cs | 32 ++++++++++++++++----
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/osu.Game/Online/Chat/DrawableLinkCompiler.cs b/osu.Game/Online/Chat/DrawableLinkCompiler.cs
index 883a2496f7..fa107a0e43 100644
--- a/osu.Game/Online/Chat/DrawableLinkCompiler.cs
+++ b/osu.Game/Online/Chat/DrawableLinkCompiler.cs
@@ -4,9 +4,11 @@
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
+using osu.Framework.Extensions.ListExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
+using osu.Framework.Lists;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
@@ -23,12 +25,21 @@ namespace osu.Game.Online.Chat
///
/// Each word part of a chat link (split for word-wrap support).
///
- public readonly List Parts;
+ public readonly SlimReadOnlyListWrapper Parts;
[Resolved]
private OverlayColourProvider? overlayColourProvider { get; set; }
- public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Parts.Any(d => d.ReceivePositionalInputAt(screenSpacePos));
+ public override bool ReceivePositionalInputAt(Vector2 screenSpacePos)
+ {
+ foreach (var part in Parts)
+ {
+ if (part.ReceivePositionalInputAt(screenSpacePos))
+ return true;
+ }
+
+ return false;
+ }
protected override HoverSounds CreateHoverSounds(HoverSampleSet sampleSet) => new LinkHoverSounds(sampleSet, Parts);
@@ -39,7 +50,7 @@ namespace osu.Game.Online.Chat
public DrawableLinkCompiler(IEnumerable parts)
{
- Parts = parts.ToList();
+ Parts = parts.ToList().AsSlimReadOnly();
}
[BackgroundDependencyLoader]
@@ -52,15 +63,24 @@ namespace osu.Game.Online.Chat
private partial class LinkHoverSounds : HoverClickSounds
{
- private readonly List parts;
+ private readonly SlimReadOnlyListWrapper parts;
- public LinkHoverSounds(HoverSampleSet sampleSet, List parts)
+ public LinkHoverSounds(HoverSampleSet sampleSet, SlimReadOnlyListWrapper parts)
: base(sampleSet)
{
this.parts = parts;
}
- public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => parts.Any(d => d.ReceivePositionalInputAt(screenSpacePos));
+ public override bool ReceivePositionalInputAt(Vector2 screenSpacePos)
+ {
+ foreach (var part in parts)
+ {
+ if (part.ReceivePositionalInputAt(screenSpacePos))
+ return true;
+ }
+
+ return false;
+ }
}
}
}
From 22f5a66c029bed6b135cbb3c99b63363e4248ecd Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Sat, 17 Feb 2024 15:46:38 +0300
Subject: [PATCH 051/105] Reduce allocations during beatmap selection
---
.../Preprocessing/OsuDifficultyHitObject.cs | 8 ++++-
osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 8 +++--
osu.Game.Rulesets.Osu/Objects/Slider.cs | 36 +++++++++++++++----
osu.Game/Rulesets/Objects/SliderPath.cs | 15 ++++----
osu.Game/Screens/Select/BeatmapCarousel.cs | 19 ++++++++--
5 files changed, 67 insertions(+), 19 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs
index 488d1e2e9f..0e537632b1 100644
--- a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs
+++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs
@@ -232,7 +232,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
IList nestedObjects = slider.NestedHitObjects;
- SliderTick? lastRealTick = slider.NestedHitObjects.OfType().LastOrDefault();
+ SliderTick? lastRealTick = null;
+
+ foreach (var hitobject in slider.NestedHitObjects)
+ {
+ if (hitobject is SliderTick tick)
+ lastRealTick = tick;
+ }
if (lastRealTick?.StartTime > trackingEndTime)
{
diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs
index 74631400ca..6c77d9189c 100644
--- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs
+++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System;
-using System.Linq;
using osu.Framework.Bindables;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
@@ -149,8 +148,11 @@ namespace osu.Game.Rulesets.Osu.Objects
{
StackHeightBindable.BindValueChanged(height =>
{
- foreach (var nested in NestedHitObjects.OfType())
- nested.StackHeight = height.NewValue;
+ foreach (var nested in NestedHitObjects)
+ {
+ if (nested is OsuHitObject osuHitObject)
+ osuHitObject.StackHeight = height.NewValue;
+ }
});
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs
index 506145568e..8a87e17089 100644
--- a/osu.Game.Rulesets.Osu/Objects/Slider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs
@@ -252,18 +252,42 @@ namespace osu.Game.Rulesets.Osu.Objects
protected void UpdateNestedSamples()
{
- var firstSample = Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL)
- ?? Samples.FirstOrDefault(); // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933)
+ HitSampleInfo firstSample = null;
+
+ for (int i = 0; i < Samples.Count; i++)
+ {
+ // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933)
+ if (i == 0)
+ {
+ firstSample = Samples[i];
+ continue;
+ }
+
+ if (Samples[i].Name != HitSampleInfo.HIT_NORMAL)
+ continue;
+
+ firstSample = Samples[i];
+ break;
+ }
+
var sampleList = new List();
if (firstSample != null)
sampleList.Add(firstSample.With("slidertick"));
- foreach (var tick in NestedHitObjects.OfType())
- tick.Samples = sampleList;
+ foreach (var nested in NestedHitObjects)
+ {
+ switch (nested)
+ {
+ case SliderTick tick:
+ tick.Samples = sampleList;
+ break;
- foreach (var repeat in NestedHitObjects.OfType())
- repeat.Samples = this.GetNodeSamples(repeat.RepeatIndex + 1);
+ case SliderRepeat repeat:
+ repeat.Samples = this.GetNodeSamples(repeat.RepeatIndex + 1);
+ break;
+ }
+ }
if (HeadCircle != null)
HeadCircle.Samples = this.GetNodeSamples(0);
diff --git a/osu.Game/Rulesets/Objects/SliderPath.cs b/osu.Game/Rulesets/Objects/SliderPath.cs
index dc71608132..f33a07f082 100644
--- a/osu.Game/Rulesets/Objects/SliderPath.cs
+++ b/osu.Game/Rulesets/Objects/SliderPath.cs
@@ -61,16 +61,17 @@ namespace osu.Game.Rulesets.Objects
case NotifyCollectionChangedAction.Add:
Debug.Assert(args.NewItems != null);
- foreach (var c in args.NewItems.Cast())
- c.Changed += invalidate;
+ foreach (object? newItem in args.NewItems)
+ ((PathControlPoint)newItem).Changed += invalidate;
+
break;
case NotifyCollectionChangedAction.Reset:
case NotifyCollectionChangedAction.Remove:
Debug.Assert(args.OldItems != null);
- foreach (var c in args.OldItems.Cast())
- c.Changed -= invalidate;
+ foreach (object? oldItem in args.OldItems)
+ ((PathControlPoint)oldItem).Changed -= invalidate;
break;
}
@@ -269,10 +270,10 @@ namespace osu.Game.Rulesets.Objects
{
List subPath = calculateSubPath(segmentVertices, segmentType);
// Skip the first vertex if it is the same as the last vertex from the previous segment
- int skipFirst = calculatedPath.Count > 0 && subPath.Count > 0 && calculatedPath.Last() == subPath[0] ? 1 : 0;
+ bool skipFirst = calculatedPath.Count > 0 && subPath.Count > 0 && calculatedPath.Last() == subPath[0];
- foreach (Vector2 t in subPath.Skip(skipFirst))
- calculatedPath.Add(t);
+ for (int j = skipFirst ? 1 : 0; j < subPath.Count; j++)
+ calculatedPath.Add(subPath[j]);
}
if (i > 0)
diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs
index 70ecde3858..ae0f397d52 100644
--- a/osu.Game/Screens/Select/BeatmapCarousel.cs
+++ b/osu.Game/Screens/Select/BeatmapCarousel.cs
@@ -510,12 +510,27 @@ namespace osu.Game.Screens.Select
if (beatmapInfo?.Hidden != false)
return false;
- foreach (CarouselBeatmapSet set in beatmapSets)
+ foreach (var carouselItem in root.Items)
{
+ if (carouselItem is not CarouselBeatmapSet set)
+ continue;
+
if (!bypassFilters && set.Filtered.Value)
continue;
- var item = set.Beatmaps.FirstOrDefault(p => p.BeatmapInfo.Equals(beatmapInfo));
+ CarouselBeatmap? item = null;
+
+ foreach (var setCarouselItem in set.Items)
+ {
+ if (setCarouselItem is not CarouselBeatmap setCarouselBeatmap)
+ continue;
+
+ if (!setCarouselBeatmap.BeatmapInfo.Equals(beatmapInfo))
+ continue;
+
+ item = setCarouselBeatmap;
+ break;
+ }
if (item == null)
// The beatmap that needs to be selected doesn't exist in this set
From 62a7e315bf669fea52ea2bb153995f08f16e9661 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Sun, 18 Feb 2024 03:11:29 +0800
Subject: [PATCH 052/105] Update framework
---
osu.Android.props | 2 +-
osu.Game/osu.Game.csproj | 2 +-
osu.iOS.props | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/osu.Android.props b/osu.Android.props
index f61ff79b9f..85171cc0fa 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -10,7 +10,7 @@
true
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 506bebfd47..f23debd38f 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -23,6 +23,6 @@
iossimulator-x64
-
+
From 0714a4fc1e23a4a3e7672ff7a075fe86d6878194 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Sun, 18 Feb 2024 03:18:50 +0800
Subject: [PATCH 053/105] Revert sample lookup logic that was not allocating
anything
---
osu.Game.Rulesets.Osu/Objects/Slider.cs | 19 ++-----------------
1 file changed, 2 insertions(+), 17 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs
index 8a87e17089..900f42d96b 100644
--- a/osu.Game.Rulesets.Osu/Objects/Slider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs
@@ -252,23 +252,8 @@ namespace osu.Game.Rulesets.Osu.Objects
protected void UpdateNestedSamples()
{
- HitSampleInfo firstSample = null;
-
- for (int i = 0; i < Samples.Count; i++)
- {
- // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933)
- if (i == 0)
- {
- firstSample = Samples[i];
- continue;
- }
-
- if (Samples[i].Name != HitSampleInfo.HIT_NORMAL)
- continue;
-
- firstSample = Samples[i];
- break;
- }
+ var firstSample = Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL)
+ ?? Samples.FirstOrDefault(); // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933)
var sampleList = new List();
From 0df6e8f5950aaeac17ff1fefee6fb80b3f73d4f3 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Sun, 18 Feb 2024 03:22:10 +0800
Subject: [PATCH 054/105] Remove list allocations in `UpdateNestedSamples`
---
osu.Game.Rulesets.Osu/Objects/Slider.cs | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs
index 900f42d96b..79bf91bcae 100644
--- a/osu.Game.Rulesets.Osu/Objects/Slider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs
@@ -252,20 +252,16 @@ namespace osu.Game.Rulesets.Osu.Objects
protected void UpdateNestedSamples()
{
- var firstSample = Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL)
- ?? Samples.FirstOrDefault(); // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933)
-
- var sampleList = new List();
-
- if (firstSample != null)
- sampleList.Add(firstSample.With("slidertick"));
+ // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933)
+ HitSampleInfo tickSample = (Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL) ?? Samples.First()).With("slidertick");
foreach (var nested in NestedHitObjects)
{
switch (nested)
{
case SliderTick tick:
- tick.Samples = sampleList;
+ tick.SamplesBindable.Clear();
+ tick.SamplesBindable.Add(tickSample);
break;
case SliderRepeat repeat:
From dd82de473a1b42ad77d871ad7faeea6b5f1c718c Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Sat, 17 Feb 2024 22:42:47 +0300
Subject: [PATCH 055/105] Revert BeatmapCarousel changes
---
osu.Game/Screens/Select/BeatmapCarousel.cs | 19 ++-----------------
1 file changed, 2 insertions(+), 17 deletions(-)
diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs
index ae0f397d52..70ecde3858 100644
--- a/osu.Game/Screens/Select/BeatmapCarousel.cs
+++ b/osu.Game/Screens/Select/BeatmapCarousel.cs
@@ -510,27 +510,12 @@ namespace osu.Game.Screens.Select
if (beatmapInfo?.Hidden != false)
return false;
- foreach (var carouselItem in root.Items)
+ foreach (CarouselBeatmapSet set in beatmapSets)
{
- if (carouselItem is not CarouselBeatmapSet set)
- continue;
-
if (!bypassFilters && set.Filtered.Value)
continue;
- CarouselBeatmap? item = null;
-
- foreach (var setCarouselItem in set.Items)
- {
- if (setCarouselItem is not CarouselBeatmap setCarouselBeatmap)
- continue;
-
- if (!setCarouselBeatmap.BeatmapInfo.Equals(beatmapInfo))
- continue;
-
- item = setCarouselBeatmap;
- break;
- }
+ var item = set.Beatmaps.FirstOrDefault(p => p.BeatmapInfo.Equals(beatmapInfo));
if (item == null)
// The beatmap that needs to be selected doesn't exist in this set
From 572f693eec361a69d83dedc317fa9608bd816099 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Sat, 17 Feb 2024 23:28:35 +0300
Subject: [PATCH 056/105] Fix failing tests related to slider ticks
---
osu.Game.Rulesets.Osu/Objects/Slider.cs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs
index 79bf91bcae..203e829180 100644
--- a/osu.Game.Rulesets.Osu/Objects/Slider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs
@@ -253,7 +253,7 @@ namespace osu.Game.Rulesets.Osu.Objects
protected void UpdateNestedSamples()
{
// TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933)
- HitSampleInfo tickSample = (Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL) ?? Samples.First()).With("slidertick");
+ HitSampleInfo tickSample = (Samples.FirstOrDefault(s => s.Name == HitSampleInfo.HIT_NORMAL) ?? Samples.FirstOrDefault())?.With("slidertick");
foreach (var nested in NestedHitObjects)
{
@@ -261,7 +261,9 @@ namespace osu.Game.Rulesets.Osu.Objects
{
case SliderTick tick:
tick.SamplesBindable.Clear();
- tick.SamplesBindable.Add(tickSample);
+
+ if (tickSample != null)
+ tick.SamplesBindable.Add(tickSample);
break;
case SliderRepeat repeat:
From 414e55c90e33d492988914f992f0684284209145 Mon Sep 17 00:00:00 2001
From: Salman Ahmed
Date: Sun, 18 Feb 2024 01:38:50 +0300
Subject: [PATCH 057/105] Add visual test case
---
.../Visual/Online/TestSceneDrawableComment.cs | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/osu.Game.Tests/Visual/Online/TestSceneDrawableComment.cs b/osu.Game.Tests/Visual/Online/TestSceneDrawableComment.cs
index 6f09e4c1f6..5cdf79160c 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneDrawableComment.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneDrawableComment.cs
@@ -81,16 +81,17 @@ namespace osu.Game.Tests.Visual.Online
},
// Taken from https://github.com/ppy/osu/issues/13993#issuecomment-885994077
+ new[] { "Problematic", @"My tablet doesn't work :( It's a Huion 420 and it's apparently incompatible with OpenTablet Driver. The warning I get is: ""DeviceInUseException: Device is currently in use by another kernel module. To fix this issue, please follow the instructions from https://github.com/OpenTabletDriver/OpenTabletDriver/wiki/Linux-FAQ#arg umentoutofrangeexception-value-0-15"" and it repeats 4 times on the notification before logging subsequent warnings. Checking the logs, it looks for other Huion tablets before sending the notification (e.g. ""2021-07-23 03:52:33 [verbose]: Detect: Searching for tablet 'Huion WH1409 V2' 20 2021-07-23 03:52:33 [error]: DeviceInUseException: Device is currently in use by another kernel module. To fix this issue, please follow the instructions from https://github.com/OpenTabletDriver/OpenTabletDriver/wiki/Linux-FAQ#arg umentoutofrangeexception-value-0-15"") I use an Arch based installation of Linux and the tablet runs perfectly with Digimend kernel driver, with area configuration, pen pressure, etc. On osu!lazer the cursor disappears until I set it to ""Borderless"" instead of ""Fullscreen"" and even after it shows up, it goes to the bottom left corner as soon as a map starts. I have honestly 0 idea of whats going on at this point.", },
new[]
{
- "Problematic", @"My tablet doesn't work :(
-It's a Huion 420 and it's apparently incompatible with OpenTablet Driver. The warning I get is: ""DeviceInUseException: Device is currently in use by another kernel module. To fix this issue, please follow the instructions from https://github.com/OpenTabletDriver/OpenTabletDriver/wiki/Linux-FAQ#arg umentoutofrangeexception-value-0-15"" and it repeats 4 times on the notification before logging subsequent warnings.
-Checking the logs, it looks for other Huion tablets before sending the notification (e.g.
- ""2021-07-23 03:52:33 [verbose]: Detect: Searching for tablet 'Huion WH1409 V2'
- 20 2021-07-23 03:52:33 [error]: DeviceInUseException: Device is currently in use by another kernel module. To fix this issue, please follow the instructions from https://github.com/OpenTabletDriver/OpenTabletDriver/wiki/Linux-FAQ#arg umentoutofrangeexception-value-0-15"")
-I use an Arch based installation of Linux and the tablet runs perfectly with Digimend kernel driver, with area configuration, pen pressure, etc. On osu!lazer the cursor disappears until I set it to ""Borderless"" instead of ""Fullscreen"" and even after it shows up, it goes to the bottom left corner as soon as a map starts.
-I have honestly 0 idea of whats going on at this point."
- }
+ "Code Block", @"User not found! ;_;
+
+There are a few possible reasons for this:
+
+ They may have changed their username.
+ The account may be temporarily unavailable due to security or abuse issues.
+ You may have made a typo!"
+ },
};
}
}
From 91675e097033c249cf7b6947e1023ee2c719ef5f Mon Sep 17 00:00:00 2001
From: Salman Ahmed
Date: Sun, 18 Feb 2024 02:00:55 +0300
Subject: [PATCH 058/105] Update markdown code block implementation in line
with framework changes
---
...suMarkdownFencedCodeBlock.cs => OsuMarkdownCodeBlock.cs} | 6 +++---
.../Graphics/Containers/Markdown/OsuMarkdownContainer.cs | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
rename osu.Game/Graphics/Containers/Markdown/{OsuMarkdownFencedCodeBlock.cs => OsuMarkdownCodeBlock.cs} (87%)
diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownFencedCodeBlock.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownCodeBlock.cs
similarity index 87%
rename from osu.Game/Graphics/Containers/Markdown/OsuMarkdownFencedCodeBlock.cs
rename to osu.Game/Graphics/Containers/Markdown/OsuMarkdownCodeBlock.cs
index 7d84d368ad..27802f4c0e 100644
--- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownFencedCodeBlock.cs
+++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownCodeBlock.cs
@@ -10,11 +10,11 @@ using osu.Game.Overlays;
namespace osu.Game.Graphics.Containers.Markdown
{
- public partial class OsuMarkdownFencedCodeBlock : MarkdownFencedCodeBlock
+ public partial class OsuMarkdownCodeBlock : MarkdownCodeBlock
{
// TODO : change to monospace font for this component
- public OsuMarkdownFencedCodeBlock(FencedCodeBlock fencedCodeBlock)
- : base(fencedCodeBlock)
+ public OsuMarkdownCodeBlock(CodeBlock codeBlock)
+ : base(codeBlock)
{
}
diff --git a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs
index b4031752db..d465e53432 100644
--- a/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs
+++ b/osu.Game/Graphics/Containers/Markdown/OsuMarkdownContainer.cs
@@ -67,7 +67,7 @@ namespace osu.Game.Graphics.Containers.Markdown
protected override MarkdownHeading CreateHeading(HeadingBlock headingBlock) => new OsuMarkdownHeading(headingBlock);
- protected override MarkdownFencedCodeBlock CreateFencedCodeBlock(FencedCodeBlock fencedCodeBlock) => new OsuMarkdownFencedCodeBlock(fencedCodeBlock);
+ protected override MarkdownCodeBlock CreateCodeBlock(CodeBlock codeBlock) => new OsuMarkdownCodeBlock(codeBlock);
protected override MarkdownSeparator CreateSeparator(ThematicBreakBlock thematicBlock) => new OsuMarkdownSeparator();
From 9655e8c48af03283ee323ee0d35fd6f354454119 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Sun, 18 Feb 2024 17:54:29 +0800
Subject: [PATCH 059/105] Adjust xmldoc slightly
---
osu.Game/Rulesets/Objects/HitObject.cs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs
index 317dd35fef..04bdc35941 100644
--- a/osu.Game/Rulesets/Objects/HitObject.cs
+++ b/osu.Game/Rulesets/Objects/HitObject.cs
@@ -171,11 +171,10 @@ namespace osu.Game.Rulesets.Objects
private Judgement judgement;
///
- /// Creates the that represents the scoring information for this .
+ /// Should be overridden to create a that represents the scoring information for this .
///
///
- /// Use to avoid unnecessary allocations.
- /// This method has been left public for compatibility reasons and eventually will be made protected.
+ /// For read access, use to avoid unnecessary allocations.
///
[NotNull]
public virtual Judgement CreateJudgement() => new Judgement();
From 415a65bf59cdce4b8fab7d836fe3cdc4f7a2a168 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Sat, 17 Feb 2024 19:00:30 +0800
Subject: [PATCH 060/105] Add failing tests for beatmap inconsistencies
---
.../Navigation/TestSceneScreenNavigation.cs | 63 +++++++++++++++++++
osu.Game/Tests/Visual/OsuGameTestScene.cs | 4 +-
2 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
index 8ff4fd5ecf..7e42d4781d 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
@@ -4,6 +4,7 @@
#nullable disable
using System;
+using System.IO;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
@@ -18,6 +19,7 @@ using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Collections;
using osu.Game.Configuration;
+using osu.Game.Extensions;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
@@ -221,6 +223,67 @@ namespace osu.Game.Tests.Visual.Navigation
AddAssert("Overlay was shown", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible);
}
+ [Test]
+ public void TestAttemptPlayBeatmapWrongHashFails()
+ {
+ Screens.Select.SongSelect songSelect = null;
+
+ AddStep("import beatmap", () => BeatmapImportHelper.LoadQuickOszIntoOsu(Game).GetResultSafely());
+ PushAndConfirm(() => songSelect = new TestPlaySongSelect());
+ AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
+
+ AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
+
+ AddStep("change beatmap files", () =>
+ {
+ foreach (var file in Game.Beatmap.Value.BeatmapSetInfo.Files.Where(f => Path.GetExtension(f.Filename) == ".osu"))
+ {
+ using (var stream = Game.Storage.GetStream(Path.Combine("files", file.File.GetStoragePath()), FileAccess.ReadWrite))
+ stream.WriteByte(0);
+ }
+ });
+
+ AddStep("invalidate cache", () =>
+ {
+ ((IWorkingBeatmapCache)Game.BeatmapManager).Invalidate(Game.Beatmap.Value.BeatmapSetInfo);
+ });
+
+ AddStep("select next difficulty", () => InputManager.Key(Key.Down));
+ AddStep("press enter", () => InputManager.Key(Key.Enter));
+
+ AddUntilStep("wait for player loader", () => Game.ScreenStack.CurrentScreen is PlayerLoader);
+ AddUntilStep("wait for song select", () => songSelect.IsCurrentScreen());
+ }
+
+ [Test]
+ public void TestAttemptPlayBeatmapMissingFails()
+ {
+ Screens.Select.SongSelect songSelect = null;
+
+ AddStep("import beatmap", () => BeatmapImportHelper.LoadQuickOszIntoOsu(Game).GetResultSafely());
+ PushAndConfirm(() => songSelect = new TestPlaySongSelect());
+ AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded);
+
+ AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
+
+ AddStep("delete beatmap files", () =>
+ {
+ foreach (var file in Game.Beatmap.Value.BeatmapSetInfo.Files.Where(f => Path.GetExtension(f.Filename) == ".osu"))
+ Game.Storage.Delete(Path.Combine("files", file.File.GetStoragePath()));
+ });
+
+ AddStep("invalidate cache", () =>
+ {
+ ((IWorkingBeatmapCache)Game.BeatmapManager).Invalidate(Game.Beatmap.Value.BeatmapSetInfo);
+ });
+
+ AddStep("select next difficulty", () => InputManager.Key(Key.Down));
+ AddStep("press enter", () => InputManager.Key(Key.Enter));
+
+ AddUntilStep("wait for player loader", () => Game.ScreenStack.CurrentScreen is PlayerLoader);
+ AddUntilStep("wait for song select", () => songSelect.IsCurrentScreen());
+ }
+
[Test]
public void TestRetryCountIncrements()
{
diff --git a/osu.Game/Tests/Visual/OsuGameTestScene.cs b/osu.Game/Tests/Visual/OsuGameTestScene.cs
index 6069fe4fb0..b86273b4a3 100644
--- a/osu.Game/Tests/Visual/OsuGameTestScene.cs
+++ b/osu.Game/Tests/Visual/OsuGameTestScene.cs
@@ -153,6 +153,8 @@ namespace osu.Game.Tests.Visual
public new Bindable> SelectedMods => base.SelectedMods;
+ public new Storage Storage => base.Storage;
+
public new SpectatorClient SpectatorClient => base.SpectatorClient;
// if we don't apply these changes, when running under nUnit the version that gets populated is that of nUnit.
@@ -166,7 +168,7 @@ namespace osu.Game.Tests.Visual
public TestOsuGame(Storage storage, IAPIProvider api, string[] args = null)
: base(args)
{
- Storage = storage;
+ base.Storage = storage;
API = api;
}
From 882f11bf79d0ce405fb865cd0a7a1d552f540513 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Sun, 18 Feb 2024 23:19:57 +0800
Subject: [PATCH 061/105] Fix logo tracking container being off by one frame
This was especially visible at the main menu when running in single thread mode.
---
osu.Game/Graphics/Containers/LogoTrackingContainer.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs
index 08eae25951..57f87b588a 100644
--- a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs
+++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs
@@ -82,9 +82,9 @@ namespace osu.Game.Graphics.Containers
absolutePos.Y / Logo.Parent!.RelativeToAbsoluteFactor.Y);
}
- protected override void Update()
+ protected override void UpdateAfterChildren()
{
- base.Update();
+ base.UpdateAfterChildren();
if (Logo == null)
return;
From 6b6a6aea54fadf4dd5b811629fd075fe1b7f5c34 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Sun, 18 Feb 2024 23:35:26 +0800
Subject: [PATCH 062/105] Apply NRT to `LogoTrackingContainer`
---
.../Visual/UserInterface/TestSceneLogoTrackingContainer.cs | 2 +-
osu.Game/Graphics/Containers/LogoTrackingContainer.cs | 6 ++----
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs
index 57ea4ee58e..8d5c961265 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLogoTrackingContainer.cs
@@ -282,7 +282,7 @@ namespace osu.Game.Tests.Visual.UserInterface
///
/// Check that the logo is tracking the position of the facade, with an acceptable precision lenience.
///
- public bool IsLogoTracking => Precision.AlmostEquals(Logo.Position, ComputeLogoTrackingPosition());
+ public bool IsLogoTracking => Precision.AlmostEquals(Logo!.Position, ComputeLogoTrackingPosition());
}
}
}
diff --git a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs
index 57f87b588a..13c672cbd6 100644
--- a/osu.Game/Graphics/Containers/LogoTrackingContainer.cs
+++ b/osu.Game/Graphics/Containers/LogoTrackingContainer.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -19,7 +17,7 @@ namespace osu.Game.Graphics.Containers
{
public Facade LogoFacade => facade;
- protected OsuLogo Logo { get; private set; }
+ protected OsuLogo? Logo { get; private set; }
private readonly InternalFacade facade = new InternalFacade();
@@ -76,7 +74,7 @@ namespace osu.Game.Graphics.Containers
/// Will only be correct if the logo's are set to Axes.Both
protected Vector2 ComputeLogoTrackingPosition()
{
- var absolutePos = Logo.Parent!.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre);
+ var absolutePos = Logo!.Parent!.ToLocalSpace(LogoFacade.ScreenSpaceDrawQuad.Centre);
return new Vector2(absolutePos.X / Logo.Parent!.RelativeToAbsoluteFactor.X,
absolutePos.Y / Logo.Parent!.RelativeToAbsoluteFactor.Y);
From 998d8206668ba1733d7f7d6ff1afacde219f8a3a Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Mon, 19 Feb 2024 00:21:54 +0800
Subject: [PATCH 063/105] Ensure audio filters can't be attached before load
(or post-disposal)
Will probably fix https://github.com/ppy/osu/issues/27225?
---
osu.Game/Audio/Effects/AudioFilter.cs | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/osu.Game/Audio/Effects/AudioFilter.cs b/osu.Game/Audio/Effects/AudioFilter.cs
index 682ca4ca7b..c8673372d7 100644
--- a/osu.Game/Audio/Effects/AudioFilter.cs
+++ b/osu.Game/Audio/Effects/AudioFilter.cs
@@ -4,6 +4,7 @@
using System.Diagnostics;
using ManagedBass.Fx;
using osu.Framework.Audio.Mixing;
+using osu.Framework.Caching;
using osu.Framework.Graphics;
namespace osu.Game.Audio.Effects
@@ -22,6 +23,8 @@ namespace osu.Game.Audio.Effects
private bool isAttached;
+ private readonly Cached filterApplication = new Cached();
+
private int cutoff;
///
@@ -36,7 +39,7 @@ namespace osu.Game.Audio.Effects
return;
cutoff = value;
- updateFilter(cutoff);
+ filterApplication.Invalidate();
}
}
@@ -61,6 +64,17 @@ namespace osu.Game.Audio.Effects
Cutoff = getInitialCutoff(type);
}
+ protected override void Update()
+ {
+ base.Update();
+
+ if (!filterApplication.IsValid)
+ {
+ updateFilter(cutoff);
+ filterApplication.Validate();
+ }
+ }
+
private int getInitialCutoff(BQFType type)
{
switch (type)
From 3059ddf3b2638a0c6c3c1520fd1e93b32c1dc24d Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Mon, 19 Feb 2024 01:08:40 +0300
Subject: [PATCH 064/105] Fix allocations in SliderInputManager
---
osu.Game.Rulesets.Osu/OsuInputManager.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/OsuInputManager.cs b/osu.Game.Rulesets.Osu/OsuInputManager.cs
index e472de1dfe..ceac1989a6 100644
--- a/osu.Game.Rulesets.Osu/OsuInputManager.cs
+++ b/osu.Game.Rulesets.Osu/OsuInputManager.cs
@@ -1,13 +1,13 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
+using osu.Framework.Lists;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Osu.UI;
@@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu
{
public partial class OsuInputManager : RulesetInputManager
{
- public IEnumerable PressedActions => KeyBindingContainer.PressedActions;
+ public SlimReadOnlyListWrapper PressedActions => KeyBindingContainer.PressedActions;
///
/// Whether gameplay input buttons should be allowed.
From 5a448ce02f5c65a40a57b4a3f51641d907a92de9 Mon Sep 17 00:00:00 2001
From: maromalo
Date: Sun, 18 Feb 2024 19:59:56 -0300
Subject: [PATCH 065/105] Turn BPMDisplay to RollingCounter
---
osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs b/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs
index b9e4896b21..1db02b7cf2 100644
--- a/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs
+++ b/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs
@@ -1,6 +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.Collections.Generic;
using System.Linq;
using System.Threading;
@@ -168,7 +169,7 @@ namespace osu.Game.Overlays.Mods
foreach (var mod in mods.Value.OfType())
rate = mod.ApplyToRate(0, rate);
- bpmDisplay.Current.Value = BeatmapInfo.Value.BPM * rate;
+ bpmDisplay.Current.Value = (int)Math.Round(Math.Round(BeatmapInfo.Value.BPM) * rate);
BeatmapDifficulty originalDifficulty = new BeatmapDifficulty(BeatmapInfo.Value.Difficulty);
@@ -194,11 +195,11 @@ namespace osu.Game.Overlays.Mods
RightContent.FadeTo(Collapsed.Value && !IsHovered ? 0 : 1, transition_duration, Easing.OutQuint);
}
- private partial class BPMDisplay : RollingCounter
+ private partial class BPMDisplay : RollingCounter
{
protected override double RollingDuration => 250;
- protected override LocalisableString FormatCount(double count) => count.ToLocalisableString("0 BPM");
+ protected override LocalisableString FormatCount(int count) => count.ToLocalisableString("0 BPM");
protected override OsuSpriteText CreateSpriteText() => new OsuSpriteText
{
From 444ac5ed4d312fc0914b79888c8a2d00f414a728 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Mon, 19 Feb 2024 09:34:52 +0100
Subject: [PATCH 066/105] Add failing test coverage
---
.../TestSceneSkinEditorNavigation.cs | 20 +++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs
index 57f1b2fbe9..9c180d43da 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorNavigation.cs
@@ -9,6 +9,7 @@ using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.UserInterface;
+using osu.Framework.Input;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Framework.Threading;
@@ -301,6 +302,25 @@ namespace osu.Game.Tests.Visual.Navigation
switchToGameplayScene();
}
+ [Test]
+ public void TestRulesetInputDisabledWhenSkinEditorOpen()
+ {
+ advanceToSongSelect();
+ openSkinEditor();
+
+ AddStep("import beatmap", () => BeatmapImportHelper.LoadQuickOszIntoOsu(Game).WaitSafely());
+ AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
+
+ switchToGameplayScene();
+ AddUntilStep("nested input disabled", () => ((Player)Game.ScreenStack.CurrentScreen).ChildrenOfType().All(manager => !manager.UseParentInput));
+
+ toggleSkinEditor();
+ AddUntilStep("nested input enabled", () => ((Player)Game.ScreenStack.CurrentScreen).ChildrenOfType().Any(manager => manager.UseParentInput));
+
+ toggleSkinEditor();
+ AddUntilStep("nested input disabled", () => ((Player)Game.ScreenStack.CurrentScreen).ChildrenOfType().All(manager => !manager.UseParentInput));
+ }
+
private void advanceToSongSelect()
{
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
From 7f82f103171223518fe34341f07dd07ab4be6c8f Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Sat, 17 Feb 2024 19:00:43 +0800
Subject: [PATCH 067/105] Fix beatmap potentially loading in a bad state
Over-caching could mean that a beatmap could load and cause a late
crash. Let's catch it early to avoid such a crash occurring.
---
osu.Game/Beatmaps/WorkingBeatmapCache.cs | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/osu.Game/Beatmaps/WorkingBeatmapCache.cs b/osu.Game/Beatmaps/WorkingBeatmapCache.cs
index 74a85cde7c..8af74d11d8 100644
--- a/osu.Game/Beatmaps/WorkingBeatmapCache.cs
+++ b/osu.Game/Beatmaps/WorkingBeatmapCache.cs
@@ -9,6 +9,7 @@ using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Audio;
using osu.Framework.Audio.Track;
+using osu.Framework.Extensions;
using osu.Framework.Graphics.Rendering;
using osu.Framework.Graphics.Rendering.Dummy;
using osu.Framework.Graphics.Textures;
@@ -143,8 +144,6 @@ namespace osu.Game.Beatmaps
{
string fileStorePath = BeatmapSetInfo.GetPathForFile(BeatmapInfo.Path);
- // TODO: check validity of file
-
var stream = GetStream(fileStorePath);
if (stream == null)
@@ -153,6 +152,12 @@ namespace osu.Game.Beatmaps
return null;
}
+ if (stream.ComputeMD5Hash() != BeatmapInfo.MD5Hash)
+ {
+ Logger.Log($"Beatmap failed to load (file {BeatmapInfo.Path} does not have the expected hash).", level: LogLevel.Error);
+ return null;
+ }
+
using (var reader = new LineBufferedReader(stream))
return Decoder.GetDecoder(reader).Decode(reader);
}
From 1ca566c6b0001dace3e3a3911c51f66cbf8536fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Mon, 19 Feb 2024 09:45:03 +0100
Subject: [PATCH 068/105] Disable nested input managers on edited screen when
skin editor is open
---
.../Overlays/SkinEditor/SkinEditorOverlay.cs | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs b/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs
index 40cd31934f..93e2f92a1c 100644
--- a/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs
+++ b/osu.Game/Overlays/SkinEditor/SkinEditorOverlay.cs
@@ -10,9 +10,11 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Primitives;
+using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Framework.Screens;
+using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Graphics.Containers;
@@ -66,6 +68,7 @@ namespace osu.Game.Overlays.SkinEditor
private IBindable beatmap { get; set; } = null!;
private OsuScreen? lastTargetScreen;
+ private InvokeOnDisposal? nestedInputManagerDisable;
private Vector2 lastDrawSize;
@@ -105,6 +108,7 @@ namespace osu.Game.Overlays.SkinEditor
if (skinEditor != null)
{
+ disableNestedInputManagers();
skinEditor.Show();
return;
}
@@ -132,6 +136,8 @@ namespace osu.Game.Overlays.SkinEditor
{
skinEditor?.Save(false);
skinEditor?.Hide();
+ nestedInputManagerDisable?.Dispose();
+ nestedInputManagerDisable = null;
globallyReenableBeatmapSkinSetting();
}
@@ -243,6 +249,9 @@ namespace osu.Game.Overlays.SkinEditor
///
public void SetTarget(OsuScreen screen)
{
+ nestedInputManagerDisable?.Dispose();
+ nestedInputManagerDisable = null;
+
lastTargetScreen = screen;
if (skinEditor == null) return;
@@ -271,6 +280,7 @@ namespace osu.Game.Overlays.SkinEditor
{
skinEditor.Save(false);
skinEditor.UpdateTargetScreen(target);
+ disableNestedInputManagers();
}
else
{
@@ -280,6 +290,21 @@ namespace osu.Game.Overlays.SkinEditor
}
}
+ private void disableNestedInputManagers()
+ {
+ if (lastTargetScreen == null)
+ return;
+
+ var nestedInputManagers = lastTargetScreen.ChildrenOfType().Where(manager => manager.UseParentInput).ToArray();
+ foreach (var inputManager in nestedInputManagers)
+ inputManager.UseParentInput = false;
+ nestedInputManagerDisable = new InvokeOnDisposal(() =>
+ {
+ foreach (var inputManager in nestedInputManagers)
+ inputManager.UseParentInput = true;
+ });
+ }
+
private readonly Bindable beatmapSkins = new Bindable();
private LeasedBindable? leasedBeatmapSkins;
From ec26ab51d18d5e4e46ee30782ebc388461c4073f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Mon, 19 Feb 2024 13:56:21 +0100
Subject: [PATCH 069/105] Use different wording
---
osu.Game/Screens/Play/SubmittingPlayer.cs | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/osu.Game/Screens/Play/SubmittingPlayer.cs b/osu.Game/Screens/Play/SubmittingPlayer.cs
index 0873f60791..ecb507f382 100644
--- a/osu.Game/Screens/Play/SubmittingPlayer.cs
+++ b/osu.Game/Screens/Play/SubmittingPlayer.cs
@@ -137,11 +137,11 @@ namespace osu.Game.Screens.Play
if (displayNotification || shouldExit)
{
string whatWillHappen = shouldExit
- ? "You are not able to submit a score."
- : "The following score will not be submitted.";
+ ? "Play in this state is not permitted."
+ : "Your score will not be submitted.";
if (string.IsNullOrEmpty(exception.Message))
- Logger.Error(exception, $"{whatWillHappen} Failed to retrieve a score submission token.");
+ Logger.Error(exception, $"Failed to retrieve a score submission token.\n\n{whatWillHappen}");
else
{
switch (exception.Message)
@@ -149,11 +149,11 @@ namespace osu.Game.Screens.Play
case @"missing token header":
case @"invalid client hash":
case @"invalid verification hash":
- Logger.Log($"{whatWillHappen} Please ensure that you are using the latest version of the official game releases.", level: LogLevel.Important);
+ Logger.Log($"Please ensure that you are using the latest version of the official game releases.\n\n{whatWillHappen}", level: LogLevel.Important);
break;
case @"expired token":
- Logger.Log($"{whatWillHappen} Your system clock is set incorrectly. Please check your system time, date and timezone.", level: LogLevel.Important);
+ Logger.Log($"Your system clock is set incorrectly. Please check your system time, date and timezone.\n\n{whatWillHappen}", level: LogLevel.Important);
break;
default:
From 012d6b7fe1058696e92eaf3c2eee589da50e4f3c Mon Sep 17 00:00:00 2001
From: Mike Will
Date: Sun, 18 Feb 2024 22:16:54 -0500
Subject: [PATCH 070/105] Change `userBeatmapOffsetClock` to a
`FramedOffsetClock`
Assuming that the global audio offset is set perfectly, such that
any audio latency is fully accounted for, if a specific beatmap
still sounds out of sync, that would no longer be a latency issue.
Instead, it would indicate a misalignment between the beatmap's
track and time codes, the correction for which should be a
virtual-time offset, not a real-time offset.
---
osu.Game/Beatmaps/FramedBeatmapClock.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/osu.Game/Beatmaps/FramedBeatmapClock.cs b/osu.Game/Beatmaps/FramedBeatmapClock.cs
index d0ffbdd459..49dff96ff1 100644
--- a/osu.Game/Beatmaps/FramedBeatmapClock.cs
+++ b/osu.Game/Beatmaps/FramedBeatmapClock.cs
@@ -29,7 +29,7 @@ namespace osu.Game.Beatmaps
private readonly OffsetCorrectionClock? userGlobalOffsetClock;
private readonly OffsetCorrectionClock? platformOffsetClock;
- private readonly OffsetCorrectionClock? userBeatmapOffsetClock;
+ private readonly FramedOffsetClock? userBeatmapOffsetClock;
private readonly IFrameBasedClock finalClockSource;
@@ -70,7 +70,7 @@ namespace osu.Game.Beatmaps
userGlobalOffsetClock = new OffsetCorrectionClock(platformOffsetClock);
// User per-beatmap offset will be applied to this final clock.
- finalClockSource = userBeatmapOffsetClock = new OffsetCorrectionClock(userGlobalOffsetClock);
+ finalClockSource = userBeatmapOffsetClock = new FramedOffsetClock(userGlobalOffsetClock);
}
else
{
@@ -122,7 +122,7 @@ namespace osu.Game.Beatmaps
Debug.Assert(userBeatmapOffsetClock != null);
Debug.Assert(platformOffsetClock != null);
- return userGlobalOffsetClock.RateAdjustedOffset + userBeatmapOffsetClock.RateAdjustedOffset + platformOffsetClock.RateAdjustedOffset;
+ return userGlobalOffsetClock.RateAdjustedOffset + userBeatmapOffsetClock.Offset + platformOffsetClock.RateAdjustedOffset;
}
}
From 29900353d924e2dd2efc54f98df5b1fdd8bcd38b Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Mon, 19 Feb 2024 20:26:15 +0300
Subject: [PATCH 071/105] Reduce allocations in SliderSelectionBlueprint
---
.../Sliders/SliderSelectionBlueprint.cs | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs
index e421d497e7..4d2b980c23 100644
--- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs
@@ -416,8 +416,22 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
DrawableObject.SliderBody?.ToScreenSpace(DrawableObject.SliderBody.PathEndOffset) ?? BodyPiece.ToScreenSpace(BodyPiece.PathEndLocation)
};
- public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) =>
- BodyPiece.ReceivePositionalInputAt(screenSpacePos) || ControlPointVisualiser?.Pieces.Any(p => p.ReceivePositionalInputAt(screenSpacePos)) == true;
+ public override bool ReceivePositionalInputAt(Vector2 screenSpacePos)
+ {
+ if (BodyPiece.ReceivePositionalInputAt(screenSpacePos))
+ return true;
+
+ if (ControlPointVisualiser == null)
+ return false;
+
+ foreach (var p in ControlPointVisualiser.Pieces)
+ {
+ if (p.ReceivePositionalInputAt(screenSpacePos))
+ return true;
+ }
+
+ return false;
+ }
protected virtual SliderCircleOverlay CreateCircleOverlay(Slider slider, SliderPosition position) => new SliderCircleOverlay(slider, position);
}
From c7586403112e4616d12817e0dd3d52e7d8dea487 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Mon, 19 Feb 2024 20:49:56 +0300
Subject: [PATCH 072/105] Reduce allocations in ComposerDistanceSnapProvider
---
.../Edit/ComposerDistanceSnapProvider.cs | 27 ++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/osu.Game/Rulesets/Edit/ComposerDistanceSnapProvider.cs b/osu.Game/Rulesets/Edit/ComposerDistanceSnapProvider.cs
index b3ca59a5b0..b2f38662cc 100644
--- a/osu.Game/Rulesets/Edit/ComposerDistanceSnapProvider.cs
+++ b/osu.Game/Rulesets/Edit/ComposerDistanceSnapProvider.cs
@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions;
@@ -124,12 +123,34 @@ namespace osu.Game.Rulesets.Edit
private (HitObject before, HitObject after)? getObjectsOnEitherSideOfCurrentTime()
{
- HitObject? lastBefore = playfield.HitObjectContainer.AliveObjects.LastOrDefault(h => h.HitObject.StartTime < editorClock.CurrentTime)?.HitObject;
+ HitObject? lastBefore = null;
+
+ foreach (var entry in playfield.HitObjectContainer.AliveEntries)
+ {
+ double objTime = entry.Value.HitObject.StartTime;
+
+ if (objTime >= editorClock.CurrentTime)
+ continue;
+
+ if (objTime > lastBefore?.StartTime)
+ lastBefore = entry.Value.HitObject;
+ }
if (lastBefore == null)
return null;
- HitObject? firstAfter = playfield.HitObjectContainer.AliveObjects.FirstOrDefault(h => h.HitObject.StartTime >= editorClock.CurrentTime)?.HitObject;
+ HitObject? firstAfter = null;
+
+ foreach (var entry in playfield.HitObjectContainer.AliveEntries)
+ {
+ double objTime = entry.Value.HitObject.StartTime;
+
+ if (objTime < editorClock.CurrentTime)
+ continue;
+
+ if (objTime < firstAfter?.StartTime)
+ firstAfter = entry.Value.HitObject;
+ }
if (firstAfter == null)
return null;
From 3791ab30c44acaaa312f4180c4a82263d2b1aa7c Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Mon, 19 Feb 2024 20:55:43 +0300
Subject: [PATCH 073/105] Reduce allocations in HitCircleOverlapMarker
---
.../HitCircles/Components/HitCircleOverlapMarker.cs | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs
index 3cba0610a1..fe335a048d 100644
--- a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs
@@ -78,9 +78,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components
Scale = new Vector2(hitObject.Scale);
- if (hitObject is IHasComboInformation combo)
- ring.BorderColour = combo.GetComboColour(skin);
-
double editorTime = editorClock.CurrentTime;
double hitObjectTime = hitObject.StartTime;
bool hasReachedObject = editorTime >= hitObjectTime;
@@ -92,6 +89,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components
ring.Scale = new Vector2(1 + 0.1f * ringScale);
content.Alpha = 0.9f * (1 - alpha);
+
+ // TODO: should only update colour on skin/combo/object change.
+ if (hitObject is IHasComboInformation combo && content.Alpha > 0)
+ ring.BorderColour = combo.GetComboColour(skin);
}
else
content.Alpha = 0;
From 2ff8667dd2e433fd7abb832cc8bb91def14c44d1 Mon Sep 17 00:00:00 2001
From: Joseph Madamba
Date: Mon, 19 Feb 2024 12:11:12 -0800
Subject: [PATCH 074/105] Revert "Centralise global rank display logic to new
class"
Also don't show on `LoginOverlay` usage for now.
---
.../Header/Components/GlobalRankDisplay.cs | 44 -------------------
.../Profile/Header/Components/MainDetails.cs | 17 +++++--
osu.Game/Users/UserRankPanel.cs | 13 +++---
3 files changed, 19 insertions(+), 55 deletions(-)
delete mode 100644 osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs
diff --git a/osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs b/osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs
deleted file mode 100644
index d32f56ab1b..0000000000
--- a/osu.Game/Overlays/Profile/Header/Components/GlobalRankDisplay.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-// 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.Bindables;
-using osu.Framework.Extensions.LocalisationExtensions;
-using osu.Framework.Localisation;
-using osu.Game.Online.API.Requests.Responses;
-using osu.Game.Resources.Localisation.Web;
-using osu.Game.Users;
-
-namespace osu.Game.Overlays.Profile.Header.Components
-{
- public partial class GlobalRankDisplay : ProfileValueDisplay
- {
- public readonly Bindable UserStatistics = new Bindable();
- public readonly Bindable User = new Bindable();
-
- public GlobalRankDisplay()
- : base(true)
- {
- Title = UsersStrings.ShowRankGlobalSimple;
- }
-
- protected override void LoadComplete()
- {
- base.LoadComplete();
-
- UserStatistics.BindValueChanged(s =>
- {
- Content = s.NewValue?.GlobalRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-";
- }, true);
-
- // needed as `UserStatistics` doesn't populate `User`
- User.BindValueChanged(u =>
- {
- var rankHighest = u.NewValue?.RankHighest;
-
- ContentTooltipText = rankHighest != null
- ? UsersStrings.ShowRankHighest(rankHighest.Rank.ToLocalisableString("\\##,##0"), rankHighest.UpdatedAt.ToLocalisableString(@"d MMM yyyy"))
- : string.Empty;
- }, true);
- }
- }
-}
diff --git a/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs b/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs
index ffdf8edc21..2505c1bc8c 100644
--- a/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs
+++ b/osu.Game/Overlays/Profile/Header/Components/MainDetails.cs
@@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Profile.Header.Components
private readonly Dictionary scoreRankInfos = new Dictionary();
private ProfileValueDisplay medalInfo = null!;
private ProfileValueDisplay ppInfo = null!;
- private GlobalRankDisplay detailGlobalRank = null!;
+ private ProfileValueDisplay detailGlobalRank = null!;
private ProfileValueDisplay detailCountryRank = null!;
private RankGraph rankGraph = null!;
@@ -52,7 +52,10 @@ namespace osu.Game.Overlays.Profile.Header.Components
Spacing = new Vector2(20),
Children = new Drawable[]
{
- detailGlobalRank = new GlobalRankDisplay(),
+ detailGlobalRank = new ProfileValueDisplay(true)
+ {
+ Title = UsersStrings.ShowRankGlobalSimple,
+ },
detailCountryRank = new ProfileValueDisplay(true)
{
Title = UsersStrings.ShowRankCountrySimple,
@@ -139,8 +142,14 @@ namespace osu.Game.Overlays.Profile.Header.Components
foreach (var scoreRankInfo in scoreRankInfos)
scoreRankInfo.Value.RankCount = user?.Statistics?.GradesCount[scoreRankInfo.Key] ?? 0;
- detailGlobalRank.UserStatistics.Value = user?.Statistics;
- detailGlobalRank.User.Value = user;
+ detailGlobalRank.Content = user?.Statistics?.GlobalRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-";
+
+ var rankHighest = user?.RankHighest;
+
+ detailGlobalRank.ContentTooltipText = rankHighest != null
+ ? UsersStrings.ShowRankHighest(rankHighest.Rank.ToLocalisableString("\\##,##0"), rankHighest.UpdatedAt.ToLocalisableString(@"d MMM yyyy"))
+ : string.Empty;
+
detailCountryRank.Content = user?.Statistics?.CountryRank?.ToLocalisableString("\\##,##0") ?? (LocalisableString)"-";
rankGraph.Statistics.Value = user?.Statistics;
diff --git a/osu.Game/Users/UserRankPanel.cs b/osu.Game/Users/UserRankPanel.cs
index 0b8a5166e6..b440261a4c 100644
--- a/osu.Game/Users/UserRankPanel.cs
+++ b/osu.Game/Users/UserRankPanel.cs
@@ -27,10 +27,10 @@ namespace osu.Game.Users
[Resolved]
private IAPIProvider api { get; set; } = null!;
+ private ProfileValueDisplay globalRankDisplay = null!;
private ProfileValueDisplay countryRankDisplay = null!;
private readonly IBindable statistics = new Bindable();
- private readonly IBindable user = new Bindable();
public UserRankPanel(APIUser user)
: base(user)
@@ -47,10 +47,9 @@ namespace osu.Game.Users
statistics.BindTo(api.Statistics);
statistics.BindValueChanged(stats =>
{
+ globalRankDisplay.Content = stats.NewValue?.GlobalRank?.ToLocalisableString("\\##,##0") ?? "-";
countryRankDisplay.Content = stats.NewValue?.CountryRank?.ToLocalisableString("\\##,##0") ?? "-";
}, true);
-
- user.BindTo(api.LocalUser!);
}
protected override Drawable CreateLayout()
@@ -164,12 +163,12 @@ namespace osu.Game.Users
{
new Drawable[]
{
- new GlobalRankDisplay
+ globalRankDisplay = new ProfileValueDisplay(true)
{
- UserStatistics = { BindTarget = statistics },
- // TODO: make highest rank update, as `api.LocalUser` doesn't update
+ Title = UsersStrings.ShowRankGlobalSimple,
+ // TODO: implement highest rank tooltip
+ // `RankHighest` resides in `APIUser`, but `api.LocalUser` doesn't update
// maybe move to `UserStatistics` in api, so `SoloStatisticsWatcher` can update the value
- User = { BindTarget = user },
},
countryRankDisplay = new ProfileValueDisplay(true)
{
From 40d6e8ce85cbd516a75510299c230d4048fd5b25 Mon Sep 17 00:00:00 2001
From: Dan Balasescu
Date: Tue, 20 Feb 2024 15:13:22 +0900
Subject: [PATCH 075/105] Remove legacy OpenGL renderer option, it's now just
OpenGL
---
.../Sections/Graphics/RendererSettings.cs | 17 +++++------------
1 file changed, 5 insertions(+), 12 deletions(-)
diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs
index fc5dd34971..a8b127d522 100644
--- a/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/Graphics/RendererSettings.cs
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
-using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Configuration;
using osu.Framework.Extensions;
@@ -28,15 +27,16 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
var renderer = config.GetBindable(FrameworkSetting.Renderer);
automaticRendererInUse = renderer.Value == RendererType.Automatic;
- SettingsEnumDropdown rendererDropdown;
-
Children = new Drawable[]
{
- rendererDropdown = new RendererSettingsDropdown
+ new RendererSettingsDropdown
{
LabelText = GraphicsSettingsStrings.Renderer,
Current = renderer,
- Items = host.GetPreferredRenderersForCurrentPlatform().Order().Where(t => t != RendererType.Vulkan),
+ Items = host.GetPreferredRenderersForCurrentPlatform().Order()
+#pragma warning disable CS0612 // Type or member is obsolete
+ .Where(t => t != RendererType.Vulkan && t != RendererType.OpenGLLegacy),
+#pragma warning restore CS0612 // Type or member is obsolete
Keywords = new[] { @"compatibility", @"directx" },
},
// TODO: this needs to be a custom dropdown at some point
@@ -79,13 +79,6 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
}));
}
});
-
- // TODO: remove this once we support SDL+android.
- if (RuntimeInfo.OS == RuntimeInfo.Platform.Android)
- {
- rendererDropdown.Items = new[] { RendererType.Automatic, RendererType.OpenGLLegacy };
- rendererDropdown.SetNoticeText("New renderer support for android is coming soon!", true);
- }
}
private partial class RendererSettingsDropdown : SettingsEnumDropdown
From e9aca9226a43285bded225e75465b41045965938 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Tue, 20 Feb 2024 19:10:03 +0300
Subject: [PATCH 076/105] Reduce allocations in ManiaPlayfield.TotalColumns
---
osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
index 0d36f51943..b3420c49f3 100644
--- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
@@ -7,7 +7,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using System;
using System.Collections.Generic;
-using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Primitives;
using osu.Game.Rulesets.Mania.Beatmaps;
@@ -149,7 +148,18 @@ namespace osu.Game.Rulesets.Mania.UI
///
/// Retrieves the total amount of columns across all stages in this playfield.
///
- public int TotalColumns => stages.Sum(s => s.Columns.Length);
+ public int TotalColumns
+ {
+ get
+ {
+ int sum = 0;
+
+ foreach (var stage in stages)
+ sum += stage.Columns.Length;
+
+ return sum;
+ }
+ }
private Stage getStageByColumn(int column)
{
From 6678c4783bc338287b6465f65cf7a8bb3ee2d288 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Tue, 20 Feb 2024 19:31:28 +0300
Subject: [PATCH 077/105] Fix PlaybackControl string allocations
---
osu.Game/Screens/Edit/Components/PlaybackControl.cs | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/osu.Game/Screens/Edit/Components/PlaybackControl.cs b/osu.Game/Screens/Edit/Components/PlaybackControl.cs
index 431336aa60..a5ed0d680f 100644
--- a/osu.Game/Screens/Edit/Components/PlaybackControl.cs
+++ b/osu.Game/Screens/Edit/Components/PlaybackControl.cs
@@ -97,11 +97,14 @@ namespace osu.Game.Screens.Edit.Components
editorClock.Start();
}
+ private static readonly IconUsage play_icon = FontAwesome.Regular.PlayCircle;
+ private static readonly IconUsage pause_icon = FontAwesome.Regular.PauseCircle;
+
protected override void Update()
{
base.Update();
- playButton.Icon = editorClock.IsRunning ? FontAwesome.Regular.PauseCircle : FontAwesome.Regular.PlayCircle;
+ playButton.Icon = editorClock.IsRunning ? pause_icon : play_icon;
}
private partial class PlaybackTabControl : OsuTabControl
From 871bdb9cf7919088f0344cf9c9f6ca37b204b622 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Tue, 20 Feb 2024 19:38:57 +0300
Subject: [PATCH 078/105] Reduce string allocations in TimeInfoContainer
---
.../Edit/Components/TimeInfoContainer.cs | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs b/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs
index 9c51258f17..4747828bca 100644
--- a/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs
+++ b/osu.Game/Screens/Edit/Components/TimeInfoContainer.cs
@@ -47,11 +47,26 @@ namespace osu.Game.Screens.Edit.Components
};
}
+ private double? lastTime;
+ private double? lastBPM;
+
protected override void Update()
{
base.Update();
- trackTimer.Text = editorClock.CurrentTime.ToEditorFormattedString();
- bpm.Text = @$"{editorBeatmap.ControlPointInfo.TimingPointAt(editorClock.CurrentTime).BPM:0} BPM";
+
+ if (lastTime != editorClock.CurrentTime)
+ {
+ lastTime = editorClock.CurrentTime;
+ trackTimer.Text = editorClock.CurrentTime.ToEditorFormattedString();
+ }
+
+ double newBPM = editorBeatmap.ControlPointInfo.TimingPointAt(editorClock.CurrentTime).BPM;
+
+ if (lastBPM != newBPM)
+ {
+ lastBPM = newBPM;
+ bpm.Text = @$"{newBPM:0} BPM";
+ }
}
}
}
From b92cff9a8ed370c59fca69dba9b9cb9923efa737 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Tue, 20 Feb 2024 20:29:35 +0300
Subject: [PATCH 079/105] Reduce allocations in ManiaSelectionBlueprint
---
.../Blueprints/ManiaSelectionBlueprint.cs | 29 ++++++++++++++-----
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs
index 1ae65dd8c0..c645ddd98d 100644
--- a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
+using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Mania.Objects;
@@ -17,9 +18,6 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
[Resolved]
private Playfield playfield { get; set; } = null!;
- [Resolved]
- private IScrollingInfo scrollingInfo { get; set; } = null!;
-
protected ScrollingHitObjectContainer HitObjectContainer => ((ManiaPlayfield)playfield).GetColumn(HitObject.Column).HitObjectContainer;
protected ManiaSelectionBlueprint(T hitObject)
@@ -28,14 +26,31 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
RelativeSizeAxes = Axes.None;
}
- protected override void Update()
- {
- base.Update();
+ private readonly IBindable directionBindable = new Bindable();
- var anchor = scrollingInfo.Direction.Value == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre;
+ [BackgroundDependencyLoader]
+ private void load(IScrollingInfo scrollingInfo)
+ {
+ directionBindable.BindTo(scrollingInfo.Direction);
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+ directionBindable.BindValueChanged(onDirectionChanged, true);
+ }
+
+ private void onDirectionChanged(ValueChangedEvent direction)
+ {
+ var anchor = direction.NewValue == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre;
Anchor = Origin = anchor;
foreach (var child in InternalChildren)
child.Anchor = child.Origin = anchor;
+ }
+
+ protected override void Update()
+ {
+ base.Update();
Position = Parent!.ToLocalSpace(HitObjectContainer.ScreenSpacePositionAtTime(HitObject.StartTime)) - AnchorPosition;
Width = HitObjectContainer.DrawWidth;
From 2543a48ac83a2983b76da3bfe5d63f55ad3b1544 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Tue, 20 Feb 2024 23:18:37 +0300
Subject: [PATCH 080/105] Apply padding to GridContainers directly
---
.../Chat/ChannelList/ChannelListItem.cs | 56 ++++----
.../Profile/Header/DetailHeaderContainer.cs | 63 ++++-----
osu.Game/Screens/Edit/BottomBar.cs | 46 +++----
.../Compose/Components/BeatDivisorControl.cs | 89 +++++-------
.../Screens/Edit/EditorScreenWithTimeline.cs | 35 ++---
.../Screens/Edit/Timing/TapTimingControl.cs | 35 ++---
osu.Game/Screens/Edit/Verify/VerifyScreen.cs | 24 ++--
.../Components/MatchBeatmapDetailArea.cs | 52 ++++---
.../Lounge/Components/PillContainer.cs | 30 ++--
.../Playlists/PlaylistsRoomSubScreen.cs | 42 +++---
.../ContractedPanelMiddleContent.cs | 50 ++++---
osu.Game/Screens/Select/BeatmapDetails.cs | 129 +++++++++---------
12 files changed, 292 insertions(+), 359 deletions(-)
diff --git a/osu.Game/Overlays/Chat/ChannelList/ChannelListItem.cs b/osu.Game/Overlays/Chat/ChannelList/ChannelListItem.cs
index 21b6147113..87b1f4ef01 100644
--- a/osu.Game/Overlays/Chat/ChannelList/ChannelListItem.cs
+++ b/osu.Game/Overlays/Chat/ChannelList/ChannelListItem.cs
@@ -66,41 +66,37 @@ namespace osu.Game.Overlays.Chat.ChannelList
Colour = colourProvider.Background4,
Alpha = 0f,
},
- new Container
+ new GridContainer
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = 18, Right = 10 },
- Child = new GridContainer
+ ColumnDimensions = new[]
{
- RelativeSizeAxes = Axes.Both,
- ColumnDimensions = new[]
- {
- new Dimension(GridSizeMode.AutoSize),
- new Dimension(),
- new Dimension(GridSizeMode.AutoSize),
- new Dimension(GridSizeMode.AutoSize),
- },
- Content = new[]
- {
- new Drawable?[]
- {
- createIcon(),
- text = new TruncatingSpriteText
- {
- Anchor = Anchor.CentreLeft,
- Origin = Anchor.CentreLeft,
- Text = Channel.Name,
- Font = OsuFont.Torus.With(size: 17, weight: FontWeight.SemiBold),
- Colour = colourProvider.Light3,
- Margin = new MarginPadding { Bottom = 2 },
- RelativeSizeAxes = Axes.X,
- },
- createMentionPill(),
- close = createCloseButton(),
- }
- },
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension(),
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension(GridSizeMode.AutoSize),
},
- },
+ Content = new[]
+ {
+ new Drawable?[]
+ {
+ createIcon(),
+ text = new TruncatingSpriteText
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ Text = Channel.Name,
+ Font = OsuFont.Torus.With(size: 17, weight: FontWeight.SemiBold),
+ Colour = colourProvider.Light3,
+ Margin = new MarginPadding { Bottom = 2 },
+ RelativeSizeAxes = Axes.X,
+ },
+ createMentionPill(),
+ close = createCloseButton(),
+ }
+ }
+ }
};
Action = () => OnRequestSelect?.Invoke(Channel);
diff --git a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs
index 1f35f39b49..118bf9171e 100644
--- a/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/DetailHeaderContainer.cs
@@ -26,47 +26,42 @@ namespace osu.Game.Overlays.Profile.Header
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background5,
},
- new Container
+ new GridContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Horizontal = WaveOverlayContainer.HORIZONTAL_PADDING, Vertical = 10 },
- Child = new GridContainer
+ RowDimensions = new[]
{
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- RowDimensions = new[]
+ new Dimension(GridSizeMode.AutoSize),
+ },
+ ColumnDimensions = new[]
+ {
+ new Dimension(),
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension(GridSizeMode.AutoSize),
+ },
+ Content = new[]
+ {
+ new Drawable[]
{
- new Dimension(GridSizeMode.AutoSize),
- },
- ColumnDimensions = new[]
- {
- new Dimension(),
- new Dimension(GridSizeMode.AutoSize),
- new Dimension(GridSizeMode.AutoSize),
- },
- Content = new[]
- {
- new Drawable[]
+ new MainDetails
{
- new MainDetails
- {
- RelativeSizeAxes = Axes.X,
- User = { BindTarget = User }
- },
- new Box
- {
- RelativeSizeAxes = Axes.Y,
- Width = 2,
- Colour = colourProvider.Background6,
- Margin = new MarginPadding { Horizontal = 15 }
- },
- new ExtendedDetails
- {
- Anchor = Anchor.CentreLeft,
- Origin = Anchor.CentreLeft,
- User = { BindTarget = User }
- }
+ RelativeSizeAxes = Axes.X,
+ User = { BindTarget = User }
+ },
+ new Box
+ {
+ RelativeSizeAxes = Axes.Y,
+ Width = 2,
+ Colour = colourProvider.Background6,
+ Margin = new MarginPadding { Horizontal = 15 }
+ },
+ new ExtendedDetails
+ {
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ User = { BindTarget = User }
}
}
}
diff --git a/osu.Game/Screens/Edit/BottomBar.cs b/osu.Game/Screens/Edit/BottomBar.cs
index aa3c4ba0d0..bc7dfaab88 100644
--- a/osu.Game/Screens/Edit/BottomBar.cs
+++ b/osu.Game/Screens/Edit/BottomBar.cs
@@ -47,35 +47,31 @@ namespace osu.Game.Screens.Edit
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background4,
},
- new Container
+ new GridContainer
{
RelativeSizeAxes = Axes.Both,
- Child = new GridContainer
+ ColumnDimensions = new[]
{
- RelativeSizeAxes = Axes.Both,
- ColumnDimensions = new[]
- {
- new Dimension(GridSizeMode.Absolute, 170),
- new Dimension(),
- new Dimension(GridSizeMode.Absolute, 220),
- new Dimension(GridSizeMode.Absolute, HitObjectComposer.TOOLBOX_CONTRACTED_SIZE_RIGHT),
- },
- Content = new[]
- {
- new Drawable[]
- {
- new TimeInfoContainer { RelativeSizeAxes = Axes.Both },
- new SummaryTimeline { RelativeSizeAxes = Axes.Both },
- new PlaybackControl { RelativeSizeAxes = Axes.Both },
- TestGameplayButton = new TestGameplayButton
- {
- RelativeSizeAxes = Axes.Both,
- Size = new Vector2(1),
- Action = editor.TestGameplay,
- }
- },
- }
+ new Dimension(GridSizeMode.Absolute, 170),
+ new Dimension(),
+ new Dimension(GridSizeMode.Absolute, 220),
+ new Dimension(GridSizeMode.Absolute, HitObjectComposer.TOOLBOX_CONTRACTED_SIZE_RIGHT),
},
+ Content = new[]
+ {
+ new Drawable[]
+ {
+ new TimeInfoContainer { RelativeSizeAxes = Axes.Both },
+ new SummaryTimeline { RelativeSizeAxes = Axes.Both },
+ new PlaybackControl { RelativeSizeAxes = Axes.Both },
+ TestGameplayButton = new TestGameplayButton
+ {
+ RelativeSizeAxes = Axes.Both,
+ Size = new Vector2(1),
+ Action = editor.TestGameplay,
+ }
+ },
+ }
}
};
}
diff --git a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs
index da1a37d57f..40b97d2137 100644
--- a/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/BeatDivisorControl.cs
@@ -86,35 +86,31 @@ namespace osu.Game.Screens.Edit.Compose.Components
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background3
},
- new Container
+ new GridContainer
{
RelativeSizeAxes = Axes.Both,
- Child = new GridContainer
+ Content = new[]
{
- RelativeSizeAxes = Axes.Both,
- Content = new[]
+ new Drawable[]
{
- new Drawable[]
+ new ChevronButton
{
- new ChevronButton
- {
- Icon = FontAwesome.Solid.ChevronLeft,
- Action = beatDivisor.SelectPrevious
- },
- new DivisorDisplay { BeatDivisor = { BindTarget = beatDivisor } },
- new ChevronButton
- {
- Icon = FontAwesome.Solid.ChevronRight,
- Action = beatDivisor.SelectNext
- }
+ Icon = FontAwesome.Solid.ChevronLeft,
+ Action = beatDivisor.SelectPrevious
},
+ new DivisorDisplay { BeatDivisor = { BindTarget = beatDivisor } },
+ new ChevronButton
+ {
+ Icon = FontAwesome.Solid.ChevronRight,
+ Action = beatDivisor.SelectNext
+ }
},
- ColumnDimensions = new[]
- {
- new Dimension(GridSizeMode.Absolute, 20),
- new Dimension(),
- new Dimension(GridSizeMode.Absolute, 20)
- }
+ },
+ ColumnDimensions = new[]
+ {
+ new Dimension(GridSizeMode.Absolute, 20),
+ new Dimension(),
+ new Dimension(GridSizeMode.Absolute, 20)
}
}
}
@@ -122,42 +118,31 @@ namespace osu.Game.Screens.Edit.Compose.Components
},
new Drawable[]
{
- new Container
+ new GridContainer
{
RelativeSizeAxes = Axes.Both,
- Children = new Drawable[]
+ Content = new[]
{
- new Container
+ new Drawable[]
{
- RelativeSizeAxes = Axes.Both,
- Child = new GridContainer
+ new ChevronButton
{
- RelativeSizeAxes = Axes.Both,
- Content = new[]
- {
- new Drawable[]
- {
- new ChevronButton
- {
- Icon = FontAwesome.Solid.ChevronLeft,
- Action = () => cycleDivisorType(-1)
- },
- new DivisorTypeText { BeatDivisor = { BindTarget = beatDivisor } },
- new ChevronButton
- {
- Icon = FontAwesome.Solid.ChevronRight,
- Action = () => cycleDivisorType(1)
- }
- },
- },
- ColumnDimensions = new[]
- {
- new Dimension(GridSizeMode.Absolute, 20),
- new Dimension(),
- new Dimension(GridSizeMode.Absolute, 20)
- }
+ Icon = FontAwesome.Solid.ChevronLeft,
+ Action = () => cycleDivisorType(-1)
+ },
+ new DivisorTypeText { BeatDivisor = { BindTarget = beatDivisor } },
+ new ChevronButton
+ {
+ Icon = FontAwesome.Solid.ChevronRight,
+ Action = () => cycleDivisorType(1)
}
- }
+ },
+ },
+ ColumnDimensions = new[]
+ {
+ new Dimension(GridSizeMode.Absolute, 20),
+ new Dimension(),
+ new Dimension(GridSizeMode.Absolute, 20)
}
}
},
diff --git a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs
index 575a66d421..2b97d363f1 100644
--- a/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs
+++ b/osu.Game/Screens/Edit/EditorScreenWithTimeline.cs
@@ -57,37 +57,32 @@ namespace osu.Game.Screens.Edit
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background4
},
- new Container
+ new GridContainer
{
Name = "Timeline content",
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Horizontal = PADDING, Top = PADDING },
- Child = new GridContainer
+ Content = new[]
{
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Content = new[]
+ new Drawable[]
{
- new Drawable[]
+ TimelineContent = new Container
{
- TimelineContent = new Container
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- },
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
},
},
- RowDimensions = new[]
- {
- new Dimension(GridSizeMode.AutoSize),
- },
- ColumnDimensions = new[]
- {
- new Dimension(),
- new Dimension(GridSizeMode.Absolute, 90),
- }
},
+ RowDimensions = new[]
+ {
+ new Dimension(GridSizeMode.AutoSize),
+ },
+ ColumnDimensions = new[]
+ {
+ new Dimension(),
+ new Dimension(GridSizeMode.Absolute, 90),
+ }
}
}
},
diff --git a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs
index bb7a3b8be3..8cdbd97ecb 100644
--- a/osu.Game/Screens/Edit/Timing/TapTimingControl.cs
+++ b/osu.Game/Screens/Edit/Timing/TapTimingControl.cs
@@ -65,35 +65,28 @@ namespace osu.Game.Screens.Edit.Timing
{
new Drawable[]
{
- new Container
+ new GridContainer
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(padding),
- Children = new Drawable[]
+ ColumnDimensions = new[]
{
- new GridContainer
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension()
+ },
+ Content = new[]
+ {
+ new Drawable[]
{
- RelativeSizeAxes = Axes.Both,
- ColumnDimensions = new[]
+ metronome = new MetronomeDisplay
{
- new Dimension(GridSizeMode.AutoSize),
- new Dimension()
- },
- Content = new[]
- {
- new Drawable[]
- {
- metronome = new MetronomeDisplay
- {
- Anchor = Anchor.CentreLeft,
- Origin = Anchor.CentreLeft,
- },
- new WaveformComparisonDisplay()
- }
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
},
+ new WaveformComparisonDisplay()
}
- }
- },
+ },
+ }
},
new Drawable[]
{
diff --git a/osu.Game/Screens/Edit/Verify/VerifyScreen.cs b/osu.Game/Screens/Edit/Verify/VerifyScreen.cs
index b6e0450e23..fe508860e0 100644
--- a/osu.Game/Screens/Edit/Verify/VerifyScreen.cs
+++ b/osu.Game/Screens/Edit/Verify/VerifyScreen.cs
@@ -34,25 +34,21 @@ namespace osu.Game.Screens.Edit.Verify
InterpretedDifficulty.Default = StarDifficulty.GetDifficultyRating(EditorBeatmap.BeatmapInfo.StarRating);
InterpretedDifficulty.SetDefault();
- Child = new Container
+ Child = new GridContainer
{
RelativeSizeAxes = Axes.Both,
- Child = new GridContainer
+ ColumnDimensions = new[]
{
- RelativeSizeAxes = Axes.Both,
- ColumnDimensions = new[]
+ new Dimension(),
+ new Dimension(GridSizeMode.Absolute, 250),
+ },
+ Content = new[]
+ {
+ new Drawable[]
{
- new Dimension(),
- new Dimension(GridSizeMode.Absolute, 250),
+ IssueList = new IssueList(),
+ new IssueSettings(),
},
- Content = new[]
- {
- new Drawable[]
- {
- IssueList = new IssueList(),
- new IssueSettings(),
- },
- }
}
};
}
diff --git a/osu.Game/Screens/OnlinePlay/Components/MatchBeatmapDetailArea.cs b/osu.Game/Screens/OnlinePlay/Components/MatchBeatmapDetailArea.cs
index dec91d8a37..b0ede8d9b5 100644
--- a/osu.Game/Screens/OnlinePlay/Components/MatchBeatmapDetailArea.cs
+++ b/osu.Game/Screens/OnlinePlay/Components/MatchBeatmapDetailArea.cs
@@ -26,48 +26,44 @@ namespace osu.Game.Screens.OnlinePlay.Components
[Resolved(typeof(Room))]
protected BindableList Playlist { get; private set; }
- private readonly Drawable playlistArea;
+ private readonly GridContainer playlistArea;
private readonly DrawableRoomPlaylist playlist;
public MatchBeatmapDetailArea()
{
- Add(playlistArea = new Container
+ Add(playlistArea = new GridContainer
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Vertical = 10 },
- Child = new GridContainer
+ Content = new[]
{
- RelativeSizeAxes = Axes.Both,
- Content = new[]
+ new Drawable[]
{
- new Drawable[]
+ new Container
{
- new Container
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Bottom = 10 },
+ Child = playlist = new PlaylistsRoomSettingsPlaylist
{
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding { Bottom = 10 },
- Child = playlist = new PlaylistsRoomSettingsPlaylist
- {
- RelativeSizeAxes = Axes.Both
- }
+ RelativeSizeAxes = Axes.Both
}
- },
- new Drawable[]
- {
- new RoundedButton
- {
- Text = "Add new playlist entry",
- RelativeSizeAxes = Axes.Both,
- Size = Vector2.One,
- Action = () => CreateNewItem?.Invoke()
- }
- },
+ }
},
- RowDimensions = new[]
+ new Drawable[]
{
- new Dimension(),
- new Dimension(GridSizeMode.Absolute, 50),
- }
+ new RoundedButton
+ {
+ Text = "Add new playlist entry",
+ RelativeSizeAxes = Axes.Both,
+ Size = Vector2.One,
+ Action = () => CreateNewItem?.Invoke()
+ }
+ },
+ },
+ RowDimensions = new[]
+ {
+ new Dimension(),
+ new Dimension(GridSizeMode.Absolute, 50),
}
});
}
diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/PillContainer.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/PillContainer.cs
index b473ea82c6..5f77742588 100644
--- a/osu.Game/Screens/OnlinePlay/Lounge/Components/PillContainer.cs
+++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/PillContainer.cs
@@ -40,35 +40,31 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
Colour = Color4.Black,
Alpha = 0.5f
},
- new Container
+ new GridContainer
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
AutoSizeAxes = Axes.Both,
Padding = new MarginPadding { Horizontal = padding },
- Child = new GridContainer
+ ColumnDimensions = new[]
{
- AutoSizeAxes = Axes.Both,
- ColumnDimensions = new[]
+ new Dimension(GridSizeMode.AutoSize, minSize: 80 - 2 * padding)
+ },
+ Content = new[]
+ {
+ new[]
{
- new Dimension(GridSizeMode.AutoSize, minSize: 80 - 2 * padding)
- },
- Content = new[]
- {
- new[]
+ new Container
{
- new Container
+ AutoSizeAxes = Axes.Both,
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Padding = new MarginPadding { Bottom = 2 },
+ Child = content = new Container
{
AutoSizeAxes = Axes.Both,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Padding = new MarginPadding { Bottom = 2 },
- Child = content = new Container
- {
- AutoSizeAxes = Axes.Both,
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- }
}
}
}
diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs
index cf5a8e1985..2460f78c96 100644
--- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs
+++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsRoomSubScreen.cs
@@ -95,38 +95,34 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
new Drawable[]
{
// Playlist items column
- new Container
+ new GridContainer
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Right = 5 },
- Child = new GridContainer
+ Content = new[]
{
- RelativeSizeAxes = Axes.Both,
- Content = new[]
+ new Drawable[] { new OverlinedPlaylistHeader(), },
+ new Drawable[]
{
- new Drawable[] { new OverlinedPlaylistHeader(), },
- new Drawable[]
+ new DrawableRoomPlaylist
{
- new DrawableRoomPlaylist
+ RelativeSizeAxes = Axes.Both,
+ Items = { BindTarget = Room.Playlist },
+ SelectedItem = { BindTarget = SelectedItem },
+ AllowSelection = true,
+ AllowShowingResults = true,
+ RequestResults = item =>
{
- RelativeSizeAxes = Axes.Both,
- Items = { BindTarget = Room.Playlist },
- SelectedItem = { BindTarget = SelectedItem },
- AllowSelection = true,
- AllowShowingResults = true,
- RequestResults = item =>
- {
- Debug.Assert(RoomId.Value != null);
- ParentScreen?.Push(new PlaylistsResultsScreen(null, RoomId.Value.Value, item, false));
- }
+ Debug.Assert(RoomId.Value != null);
+ ParentScreen?.Push(new PlaylistsResultsScreen(null, RoomId.Value.Value, item, false));
}
- },
+ }
},
- RowDimensions = new[]
- {
- new Dimension(GridSizeMode.AutoSize),
- new Dimension(),
- }
+ },
+ RowDimensions = new[]
+ {
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension(),
}
},
// Spacer
diff --git a/osu.Game/Screens/Ranking/Contracted/ContractedPanelMiddleContent.cs b/osu.Game/Screens/Ranking/Contracted/ContractedPanelMiddleContent.cs
index 195cd03e9b..cfb6465e62 100644
--- a/osu.Game/Screens/Ranking/Contracted/ContractedPanelMiddleContent.cs
+++ b/osu.Game/Screens/Ranking/Contracted/ContractedPanelMiddleContent.cs
@@ -150,44 +150,40 @@ namespace osu.Game.Screens.Ranking.Contracted
},
new Drawable[]
{
- new Container
+ new GridContainer
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Vertical = 5 },
- Child = new GridContainer
+ Content = new[]
{
- RelativeSizeAxes = Axes.Both,
- Content = new[]
+ new Drawable[]
{
- new Drawable[]
+ new OsuSpriteText
{
- new OsuSpriteText
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Current = scoreManager.GetBindableTotalScoreString(score),
+ Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, fixedWidth: true),
+ Spacing = new Vector2(-1, 0)
+ },
+ },
+ new Drawable[]
+ {
+ new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Top = 2 },
+ Child = new DrawableRank(score.Rank)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Current = scoreManager.GetBindableTotalScoreString(score),
- Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, fixedWidth: true),
- Spacing = new Vector2(-1, 0)
- },
- },
- new Drawable[]
- {
- new Container
- {
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding { Top = 2 },
- Child = new DrawableRank(score.Rank)
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- }
}
- },
+ }
},
- RowDimensions = new[]
- {
- new Dimension(GridSizeMode.AutoSize),
- }
+ },
+ RowDimensions = new[]
+ {
+ new Dimension(GridSizeMode.AutoSize),
}
}
},
diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs
index dec2c1c1de..2bb60716ff 100644
--- a/osu.Game/Screens/Select/BeatmapDetails.cs
+++ b/osu.Game/Screens/Select/BeatmapDetails.cs
@@ -75,99 +75,92 @@ namespace osu.Game.Screens.Select
RelativeSizeAxes = Axes.Both,
Colour = Colour4.Black.Opacity(0.3f),
},
- new Container
+ new GridContainer
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Horizontal = spacing },
- Children = new Drawable[]
+ RowDimensions = new[]
{
- new GridContainer
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension()
+ },
+ Content = new[]
+ {
+ new Drawable[]
{
- RelativeSizeAxes = Axes.Both,
- RowDimensions = new[]
+ new FillFlowContainer
{
- new Dimension(GridSizeMode.AutoSize),
- new Dimension()
- },
- Content = new[]
- {
- new Drawable[]
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ Direction = FillDirection.Horizontal,
+ Children = new Drawable[]
{
new FillFlowContainer
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
- Direction = FillDirection.Horizontal,
- Children = new Drawable[]
+ Width = 0.5f,
+ Spacing = new Vector2(spacing),
+ Padding = new MarginPadding { Right = spacing / 2 },
+ Children = new[]
{
- new FillFlowContainer
+ new DetailBox().WithChild(new OnlineViewContainer(string.Empty)
{
RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- Width = 0.5f,
- Spacing = new Vector2(spacing),
- Padding = new MarginPadding { Right = spacing / 2 },
- Children = new[]
+ Height = 134,
+ Padding = new MarginPadding { Horizontal = spacing, Top = spacing },
+ Child = ratingsDisplay = new UserRatings
{
- new DetailBox().WithChild(new OnlineViewContainer(string.Empty)
- {
- RelativeSizeAxes = Axes.X,
- Height = 134,
- Padding = new MarginPadding { Horizontal = spacing, Top = spacing },
- Child = ratingsDisplay = new UserRatings
- {
- RelativeSizeAxes = Axes.Both,
- },
- }),
+ RelativeSizeAxes = Axes.Both,
},
- },
- new OsuScrollContainer
+ }),
+ },
+ },
+ new OsuScrollContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ Height = 250,
+ Width = 0.5f,
+ ScrollbarVisible = false,
+ Padding = new MarginPadding { Left = spacing / 2 },
+ Child = new FillFlowContainer
+ {
+ RelativeSizeAxes = Axes.X,
+ AutoSizeAxes = Axes.Y,
+ LayoutDuration = transition_duration,
+ LayoutEasing = Easing.OutQuad,
+ Children = new[]
{
- RelativeSizeAxes = Axes.X,
- Height = 250,
- Width = 0.5f,
- ScrollbarVisible = false,
- Padding = new MarginPadding { Left = spacing / 2 },
- Child = new FillFlowContainer
- {
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- LayoutDuration = transition_duration,
- LayoutEasing = Easing.OutQuad,
- Children = new[]
- {
- description = new MetadataSectionDescription(query => songSelect?.Search(query)),
- source = new MetadataSectionSource(query => songSelect?.Search(query)),
- tags = new MetadataSectionTags(query => songSelect?.Search(query)),
- },
- },
+ description = new MetadataSectionDescription(query => songSelect?.Search(query)),
+ source = new MetadataSectionSource(query => songSelect?.Search(query)),
+ tags = new MetadataSectionTags(query => songSelect?.Search(query)),
},
},
},
},
- new Drawable[]
+ },
+ },
+ new Drawable[]
+ {
+ failRetryContainer = new OnlineViewContainer("Sign in to view more details")
+ {
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
{
- failRetryContainer = new OnlineViewContainer("Sign in to view more details")
+ new OsuSpriteText
+ {
+ Text = BeatmapsetsStrings.ShowInfoPointsOfFailure,
+ Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 14),
+ },
+ failRetryGraph = new FailRetryGraph
{
RelativeSizeAxes = Axes.Both,
- Children = new Drawable[]
- {
- new OsuSpriteText
- {
- Text = BeatmapsetsStrings.ShowInfoPointsOfFailure,
- Font = OsuFont.GetFont(weight: FontWeight.Bold, size: 14),
- },
- failRetryGraph = new FailRetryGraph
- {
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding { Top = 14 + spacing / 2 },
- },
- },
+ Padding = new MarginPadding { Top = 14 + spacing / 2 },
},
- }
- }
- },
- },
+ },
+ },
+ }
+ }
},
loading = new LoadingLayer(true)
};
From 86e3b597b42e79eafdb6ea0722277b6a9882485b Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Wed, 21 Feb 2024 13:18:51 +0800
Subject: [PATCH 081/105] Fix `LegacyApproachCircle` incorrectly applying
scaling factor
---
.../Skinning/Legacy/LegacyApproachCircle.cs | 5 -----
1 file changed, 5 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs
index 0bdea0cab1..8ff85090ca 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs
@@ -8,7 +8,6 @@ using osu.Framework.Graphics.Sprites;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Skinning;
-using osuTK;
using osuTK.Graphics;
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
@@ -26,10 +25,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
var texture = skin.GetTexture(@"approachcircle");
Debug.Assert(texture != null);
Texture = texture.WithMaximumSize(OsuHitObject.OBJECT_DIMENSIONS * 2);
-
- // account for the sprite being used for the default approach circle being taken from stable,
- // when hitcircles have 5px padding on each size. this should be removed if we update the sprite.
- Scale = new Vector2(128 / 118f);
}
protected override void LoadComplete()
From a11a83ac480f86f9420ee2f78abb01a2912b858d Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Wed, 21 Feb 2024 13:44:04 +0800
Subject: [PATCH 082/105] Improve comment regarding scale adjust of approach
circles
---
.../Skinning/Default/DefaultApproachCircle.cs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs
index 272f4b5658..3a4c454bf1 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs
@@ -25,8 +25,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
{
Texture = textures.Get(@"Gameplay/osu/approachcircle").WithMaximumSize(OsuHitObject.OBJECT_DIMENSIONS * 2);
- // account for the sprite being used for the default approach circle being taken from stable,
- // when hitcircles have 5px padding on each size. this should be removed if we update the sprite.
+ // In triangles and argon skins, we expanded hitcircles to take up the full 128 px which are clickable,
+ // but still use the old approach circle sprite. To make it feel correct (ie. disappear as it collides
+ // with the hitcircle, *not when it overlaps the border*) we need to expand it slightly.
Scale = new Vector2(128 / 118f);
}
From a137fa548080cf6c5ff5b6d79b427cf23a677d2b Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Wed, 21 Feb 2024 15:43:53 +0800
Subject: [PATCH 083/105] Fix classic skin follow circles animating from
incorrect starting point
---
osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyFollowCircle.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyFollowCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyFollowCircle.cs
index fa2bb9b2ad..4a8b737206 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyFollowCircle.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyFollowCircle.cs
@@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
// Note that the scale adjust here is 2 instead of DrawableSliderBall.FOLLOW_AREA to match legacy behaviour.
// This means the actual tracking area for gameplay purposes is larger than the sprite (but skins may be accounting for this).
- this.ScaleTo(0.5f).ScaleTo(2f, Math.Min(180f, remainingTime), Easing.Out)
+ this.ScaleTo(1f).ScaleTo(2f, Math.Min(180f, remainingTime), Easing.Out)
.FadeTo(0).FadeTo(1f, Math.Min(60f, remainingTime));
}
From 259be976e870db1fcc6f64f1382a23be02919ad1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Wed, 21 Feb 2024 11:42:34 +0100
Subject: [PATCH 084/105] Adjust test to fail
---
.../SongSelect/TestSceneBeatmapCarousel.cs | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs
index aa4c879468..de2ae3708f 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestSceneBeatmapCarousel.cs
@@ -629,7 +629,8 @@ namespace osu.Game.Tests.Visual.SongSelect
{
var sets = new List();
- const string zzz_string = "zzzzz";
+ const string zzz_lowercase = "zzzzz";
+ const string zzz_uppercase = "ZZZZZ";
AddStep("Populuate beatmap sets", () =>
{
@@ -640,10 +641,16 @@ namespace osu.Game.Tests.Visual.SongSelect
var set = TestResources.CreateTestBeatmapSetInfo();
if (i == 4)
- set.Beatmaps.ForEach(b => b.Metadata.Artist = zzz_string);
+ set.Beatmaps.ForEach(b => b.Metadata.Artist = zzz_uppercase);
+
+ if (i == 8)
+ set.Beatmaps.ForEach(b => b.Metadata.Artist = zzz_lowercase);
+
+ if (i == 12)
+ set.Beatmaps.ForEach(b => b.Metadata.Author.Username = zzz_uppercase);
if (i == 16)
- set.Beatmaps.ForEach(b => b.Metadata.Author.Username = zzz_string);
+ set.Beatmaps.ForEach(b => b.Metadata.Author.Username = zzz_lowercase);
sets.Add(set);
}
@@ -652,9 +659,11 @@ namespace osu.Game.Tests.Visual.SongSelect
loadBeatmaps(sets);
AddStep("Sort by author", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Author }, false));
- AddAssert($"Check {zzz_string} is at bottom", () => carousel.BeatmapSets.Last().Metadata.Author.Username == zzz_string);
+ AddAssert($"Check {zzz_uppercase} is last", () => carousel.BeatmapSets.Last().Metadata.Author.Username == zzz_uppercase);
+ AddAssert($"Check {zzz_lowercase} is second last", () => carousel.BeatmapSets.SkipLast(1).Last().Metadata.Author.Username == zzz_lowercase);
AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false));
- AddAssert($"Check {zzz_string} is at bottom", () => carousel.BeatmapSets.Last().Metadata.Artist == zzz_string);
+ AddAssert($"Check {zzz_uppercase} is last", () => carousel.BeatmapSets.Last().Metadata.Artist == zzz_uppercase);
+ AddAssert($"Check {zzz_lowercase} is second last", () => carousel.BeatmapSets.SkipLast(1).Last().Metadata.Artist == zzz_lowercase);
}
///
From 59235d6c50a796469bb29440745eec9e13d0e926 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Wed, 21 Feb 2024 12:07:18 +0100
Subject: [PATCH 085/105] Implement custom comparer for expected carousel sort
behaviour
Co-authored-by: Salman Ahmed
---
.../Utils/OrdinalSortByCaseStringComparer.cs | 49 +++++++++++++++++++
1 file changed, 49 insertions(+)
create mode 100644 osu.Game/Utils/OrdinalSortByCaseStringComparer.cs
diff --git a/osu.Game/Utils/OrdinalSortByCaseStringComparer.cs b/osu.Game/Utils/OrdinalSortByCaseStringComparer.cs
new file mode 100644
index 0000000000..99d73f644f
--- /dev/null
+++ b/osu.Game/Utils/OrdinalSortByCaseStringComparer.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 System;
+using System.Collections.Generic;
+
+namespace osu.Game.Utils
+{
+ ///
+ /// This string comparer is something of a cross-over between and .
+ /// is used first, but is used as a tie-breaker.
+ ///
+ ///
+ /// This comparer's behaviour somewhat emulates ,
+ /// but non-ordinal comparers - both culture-aware and culture-invariant - have huge performance overheads due to i18n factors (up to 5x slower).
+ ///
+ ///
+ /// Given the following strings to sort: [A, B, C, D, a, b, c, d, A] and a stable sorting algorithm:
+ ///
+ /// -
+ /// would return [A, A, B, C, D, a, b, c, d].
+ /// This is undesirable as letters are interleaved.
+ ///
+ /// -
+ /// would return [A, a, A, B, b, C, c, D, d].
+ /// Different letters are not interleaved, but because case is ignored, the As are left in arbitrary order.
+ ///
+ ///
+ /// -
+ /// would return [a, A, A, b, B, c, C, d, D], which is the expected behaviour.
+ ///
+ ///
+ public class OrdinalSortByCaseStringComparer : IComparer
+ {
+ public static readonly OrdinalSortByCaseStringComparer INSTANCE = new OrdinalSortByCaseStringComparer();
+
+ private OrdinalSortByCaseStringComparer()
+ {
+ }
+
+ public int Compare(string? a, string? b)
+ {
+ int result = StringComparer.OrdinalIgnoreCase.Compare(a, b);
+ if (result == 0)
+ result = -StringComparer.Ordinal.Compare(a, b); // negative to place lowercase letters before uppercase.
+ return result;
+ }
+ }
+}
From 04a2ac3df332fda91ae41c2ee9bc5e1300a60d36 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Wed, 21 Feb 2024 12:07:28 +0100
Subject: [PATCH 086/105] Add benchmarking for custom string comparer
---
.../BenchmarkStringComparison.cs | 48 +++++++++++++++++++
1 file changed, 48 insertions(+)
create mode 100644 osu.Game.Benchmarks/BenchmarkStringComparison.cs
diff --git a/osu.Game.Benchmarks/BenchmarkStringComparison.cs b/osu.Game.Benchmarks/BenchmarkStringComparison.cs
new file mode 100644
index 0000000000..78e4130abe
--- /dev/null
+++ b/osu.Game.Benchmarks/BenchmarkStringComparison.cs
@@ -0,0 +1,48 @@
+// 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.Collections.Generic;
+using BenchmarkDotNet.Attributes;
+using osu.Game.Utils;
+
+namespace osu.Game.Benchmarks
+{
+ public class BenchmarkStringComparison
+ {
+ private string[] strings = null!;
+
+ [GlobalSetup]
+ public void GlobalSetUp()
+ {
+ strings = new string[10000];
+
+ for (int i = 0; i < strings.Length; ++i)
+ strings[i] = Guid.NewGuid().ToString();
+
+ for (int i = 0; i < strings.Length; ++i)
+ {
+ if (i % 2 == 0)
+ strings[i] = strings[i].ToUpperInvariant();
+ }
+ }
+
+ [Benchmark]
+ public void OrdinalIgnoreCase() => compare(StringComparer.OrdinalIgnoreCase);
+
+ [Benchmark]
+ public void OrdinalSortByCase() => compare(OrdinalSortByCaseStringComparer.INSTANCE);
+
+ [Benchmark]
+ public void InvariantCulture() => compare(StringComparer.InvariantCulture);
+
+ private void compare(IComparer comparer)
+ {
+ for (int i = 0; i < strings.Length; ++i)
+ {
+ for (int j = i + 1; j < strings.Length; ++j)
+ _ = comparer.Compare(strings[i], strings[j]);
+ }
+ }
+ }
+}
From 929858226ad208e29746f1b22b80399623f07d52 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Wed, 21 Feb 2024 12:09:37 +0100
Subject: [PATCH 087/105] Use custom comparer in beatmap carousel for expected
sort behaviour
---
osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
index 6c41bc3805..bf0d7dcbde 100644
--- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
+++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
@@ -7,6 +7,7 @@ using System.Linq;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Game.Beatmaps;
using osu.Game.Screens.Select.Filter;
+using osu.Game.Utils;
namespace osu.Game.Screens.Select.Carousel
{
@@ -67,19 +68,19 @@ namespace osu.Game.Screens.Select.Carousel
{
default:
case SortMode.Artist:
- comparison = string.Compare(BeatmapSet.Metadata.Artist, otherSet.BeatmapSet.Metadata.Artist, StringComparison.Ordinal);
+ comparison = OrdinalSortByCaseStringComparer.INSTANCE.Compare(BeatmapSet.Metadata.Artist, otherSet.BeatmapSet.Metadata.Artist);
break;
case SortMode.Title:
- comparison = string.Compare(BeatmapSet.Metadata.Title, otherSet.BeatmapSet.Metadata.Title, StringComparison.Ordinal);
+ comparison = OrdinalSortByCaseStringComparer.INSTANCE.Compare(BeatmapSet.Metadata.Title, otherSet.BeatmapSet.Metadata.Title);
break;
case SortMode.Author:
- comparison = string.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username, StringComparison.Ordinal);
+ comparison = OrdinalSortByCaseStringComparer.INSTANCE.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username);
break;
case SortMode.Source:
- comparison = string.Compare(BeatmapSet.Metadata.Source, otherSet.BeatmapSet.Metadata.Source, StringComparison.Ordinal);
+ comparison = OrdinalSortByCaseStringComparer.INSTANCE.Compare(BeatmapSet.Metadata.Source, otherSet.BeatmapSet.Metadata.Source);
break;
case SortMode.DateAdded:
From fb593470d553c68b77e7ec129c47cfd9a21097d0 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Wed, 21 Feb 2024 21:02:20 +0800
Subject: [PATCH 088/105] Use `DEFAULT` instead of `INSTANCE` or static field
Matches other similar comparers.
---
osu.Game.Benchmarks/BenchmarkStringComparison.cs | 2 +-
osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs | 8 ++++----
osu.Game/Utils/OrdinalSortByCaseStringComparer.cs | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/osu.Game.Benchmarks/BenchmarkStringComparison.cs b/osu.Game.Benchmarks/BenchmarkStringComparison.cs
index 78e4130abe..d40b92db5f 100644
--- a/osu.Game.Benchmarks/BenchmarkStringComparison.cs
+++ b/osu.Game.Benchmarks/BenchmarkStringComparison.cs
@@ -31,7 +31,7 @@ namespace osu.Game.Benchmarks
public void OrdinalIgnoreCase() => compare(StringComparer.OrdinalIgnoreCase);
[Benchmark]
- public void OrdinalSortByCase() => compare(OrdinalSortByCaseStringComparer.INSTANCE);
+ public void OrdinalSortByCase() => compare(OrdinalSortByCaseStringComparer.DEFAULT);
[Benchmark]
public void InvariantCulture() => compare(StringComparer.InvariantCulture);
diff --git a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
index bf0d7dcbde..43c9c621e8 100644
--- a/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
+++ b/osu.Game/Screens/Select/Carousel/CarouselBeatmapSet.cs
@@ -68,19 +68,19 @@ namespace osu.Game.Screens.Select.Carousel
{
default:
case SortMode.Artist:
- comparison = OrdinalSortByCaseStringComparer.INSTANCE.Compare(BeatmapSet.Metadata.Artist, otherSet.BeatmapSet.Metadata.Artist);
+ comparison = OrdinalSortByCaseStringComparer.DEFAULT.Compare(BeatmapSet.Metadata.Artist, otherSet.BeatmapSet.Metadata.Artist);
break;
case SortMode.Title:
- comparison = OrdinalSortByCaseStringComparer.INSTANCE.Compare(BeatmapSet.Metadata.Title, otherSet.BeatmapSet.Metadata.Title);
+ comparison = OrdinalSortByCaseStringComparer.DEFAULT.Compare(BeatmapSet.Metadata.Title, otherSet.BeatmapSet.Metadata.Title);
break;
case SortMode.Author:
- comparison = OrdinalSortByCaseStringComparer.INSTANCE.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username);
+ comparison = OrdinalSortByCaseStringComparer.DEFAULT.Compare(BeatmapSet.Metadata.Author.Username, otherSet.BeatmapSet.Metadata.Author.Username);
break;
case SortMode.Source:
- comparison = OrdinalSortByCaseStringComparer.INSTANCE.Compare(BeatmapSet.Metadata.Source, otherSet.BeatmapSet.Metadata.Source);
+ comparison = OrdinalSortByCaseStringComparer.DEFAULT.Compare(BeatmapSet.Metadata.Source, otherSet.BeatmapSet.Metadata.Source);
break;
case SortMode.DateAdded:
diff --git a/osu.Game/Utils/OrdinalSortByCaseStringComparer.cs b/osu.Game/Utils/OrdinalSortByCaseStringComparer.cs
index 99d73f644f..6c1532eef5 100644
--- a/osu.Game/Utils/OrdinalSortByCaseStringComparer.cs
+++ b/osu.Game/Utils/OrdinalSortByCaseStringComparer.cs
@@ -32,7 +32,7 @@ namespace osu.Game.Utils
///
public class OrdinalSortByCaseStringComparer : IComparer
{
- public static readonly OrdinalSortByCaseStringComparer INSTANCE = new OrdinalSortByCaseStringComparer();
+ public static readonly OrdinalSortByCaseStringComparer DEFAULT = new OrdinalSortByCaseStringComparer();
private OrdinalSortByCaseStringComparer()
{
From 6d32cfb7ee7c466a6a8b673ea6b9cac3c66d6ffd Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Wed, 21 Feb 2024 21:39:33 +0800
Subject: [PATCH 089/105] Update framework
---
osu.Android.props | 2 +-
osu.Game/osu.Game.csproj | 2 +-
osu.iOS.props | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/osu.Android.props b/osu.Android.props
index 85171cc0fa..30037c868c 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -10,7 +10,7 @@
true
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index f23debd38f..463a726856 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -23,6 +23,6 @@
iossimulator-x64
-
+
From 805f0b6a296aa2507d97fdeec1f14fe78e8c8854 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Wed, 21 Feb 2024 14:55:10 +0100
Subject: [PATCH 090/105] Remove unused using directive
---
osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
index 25fe8170b1..5bf7c0326a 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuTouchInput.cs
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System.Diagnostics;
-using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
From 4cefa8bb8d256228266d204449610f443c6c37d6 Mon Sep 17 00:00:00 2001
From: Andrei Zavatski
Date: Wed, 21 Feb 2024 22:47:49 +0300
Subject: [PATCH 091/105] Reduce allocations in TimelineBlueprintContainer
---
.../Components/Timeline/TimelineBlueprintContainer.cs | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs
index b60e04afc1..6ebd1961a2 100644
--- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimelineBlueprintContainer.cs
@@ -116,6 +116,8 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
updateStacking();
}
+ private readonly Stack currentConcurrentObjects = new Stack();
+
private void updateStacking()
{
// because only blueprints of objects which are alive (via pooling) are displayed in the timeline, it's feasible to do this every-update.
@@ -125,10 +127,12 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
// after the stack gets this tall, we can presume there is space underneath to draw subsequent blueprints.
const int stack_reset_count = 3;
- Stack currentConcurrentObjects = new Stack();
+ currentConcurrentObjects.Clear();
- foreach (var b in SelectionBlueprints.Reverse())
+ for (int i = SelectionBlueprints.Count - 1; i >= 0; i--)
{
+ var b = SelectionBlueprints[i];
+
// remove objects from the stack as long as their end time is in the past.
while (currentConcurrentObjects.TryPeek(out HitObject hitObject))
{
From d01421b951bc308583caa0c687f0715ab55f34de Mon Sep 17 00:00:00 2001
From: Boudewijn Popkema
Date: Wed, 21 Feb 2024 23:15:37 +0100
Subject: [PATCH 092/105] clear remembered username when checkbox is unticked
---
osu.Game/Overlays/Login/LoginForm.cs | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/osu.Game/Overlays/Login/LoginForm.cs b/osu.Game/Overlays/Login/LoginForm.cs
index 80dfca93d2..a77baa3186 100644
--- a/osu.Game/Overlays/Login/LoginForm.cs
+++ b/osu.Game/Overlays/Login/LoginForm.cs
@@ -13,11 +13,11 @@ using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Localisation;
using osu.Game.Online.API;
using osu.Game.Overlays.Settings;
using osu.Game.Resources.Localisation.Web;
using osuTK;
-using osu.Game.Localisation;
namespace osu.Game.Overlays.Login
{
@@ -26,6 +26,7 @@ namespace osu.Game.Overlays.Login
private TextBox username = null!;
private TextBox password = null!;
private ShakeContainer shakeSignIn = null!;
+ private SettingsCheckbox rememberUsername = null!;
[Resolved]
private IAPIProvider api { get; set; } = null!;
@@ -82,7 +83,7 @@ namespace osu.Game.Overlays.Login
},
},
},
- new SettingsCheckbox
+ rememberUsername = new SettingsCheckbox
{
LabelText = LoginPanelStrings.RememberUsername,
Current = config.GetBindable(OsuSetting.SaveUsername),
@@ -130,6 +131,7 @@ namespace osu.Game.Overlays.Login
forgottenPasswordLink.AddLink(LayoutStrings.PopupLoginLoginForgot, $"{api.WebsiteRootUrl}/home/password-reset");
password.OnCommit += (_, _) => performLogin();
+ rememberUsername.SettingChanged += () => onRememberUsernameChanged(config);
if (api.LastLoginError?.Message is string error)
{
@@ -146,6 +148,12 @@ namespace osu.Game.Overlays.Login
shakeSignIn.Shake();
}
+ private void onRememberUsernameChanged(OsuConfigManager config)
+ {
+ if (rememberUsername.Current.Value == false)
+ config.SetValue(OsuSetting.Username, string.Empty);
+ }
+
protected override bool OnClick(ClickEvent e) => true;
protected override void OnFocus(FocusEvent e)
From 2831ff60e1a361874f0285f1db74be7fa621300a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Thu, 22 Feb 2024 09:39:49 +0100
Subject: [PATCH 093/105] Add test coverage
---
.../Visual/Menus/TestSceneLoginOverlay.cs | 36 +++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/osu.Game.Tests/Visual/Menus/TestSceneLoginOverlay.cs b/osu.Game.Tests/Visual/Menus/TestSceneLoginOverlay.cs
index 5fc075ed99..e603f72bb8 100644
--- a/osu.Game.Tests/Visual/Menus/TestSceneLoginOverlay.cs
+++ b/osu.Game.Tests/Visual/Menus/TestSceneLoginOverlay.cs
@@ -8,11 +8,13 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
+using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Overlays;
using osu.Game.Overlays.Login;
+using osu.Game.Overlays.Settings;
using osu.Game.Users.Drawables;
using osuTK.Input;
@@ -25,6 +27,9 @@ namespace osu.Game.Tests.Visual.Menus
private LoginOverlay loginOverlay = null!;
+ [Resolved]
+ private OsuConfigManager configManager { get; set; } = null!;
+
[BackgroundDependencyLoader]
private void load()
{
@@ -156,5 +161,36 @@ namespace osu.Game.Tests.Visual.Menus
});
AddAssert("login overlay is hidden", () => loginOverlay.State.Value == Visibility.Hidden);
}
+
+ [Test]
+ public void TestUncheckingRememberUsernameClearsIt()
+ {
+ AddStep("logout", () => API.Logout());
+ AddStep("set username", () => configManager.SetValue(OsuSetting.Username, "test_user"));
+ AddStep("set remember password", () => configManager.SetValue(OsuSetting.SavePassword, true));
+ AddStep("uncheck remember username", () =>
+ {
+ InputManager.MoveMouseTo(loginOverlay.ChildrenOfType().First());
+ InputManager.Click(MouseButton.Left);
+ });
+ AddAssert("remember username off", () => configManager.Get(OsuSetting.SaveUsername), () => Is.False);
+ AddAssert("remember password off", () => configManager.Get(OsuSetting.SavePassword), () => Is.False);
+ AddAssert("username cleared", () => configManager.Get(OsuSetting.Username), () => Is.Empty);
+ }
+
+ [Test]
+ public void TestUncheckingRememberPasswordClearsToken()
+ {
+ AddStep("logout", () => API.Logout());
+ AddStep("set token", () => configManager.SetValue(OsuSetting.Token, "test_token"));
+ AddStep("set remember password", () => configManager.SetValue(OsuSetting.SavePassword, true));
+ AddStep("uncheck remember token", () =>
+ {
+ InputManager.MoveMouseTo(loginOverlay.ChildrenOfType().Last());
+ InputManager.Click(MouseButton.Left);
+ });
+ AddAssert("remember password off", () => configManager.Get(OsuSetting.SavePassword), () => Is.False);
+ AddAssert("token cleared", () => configManager.Get(OsuSetting.Token), () => Is.Empty);
+ }
}
}
From a1046f0a865641e5b7ffea225d3ad32b45ae4177 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Thu, 22 Feb 2024 09:40:27 +0100
Subject: [PATCH 094/105] Revert "clear remembered username when checkbox is
unticked"
This reverts commit d01421b951bc308583caa0c687f0715ab55f34de.
---
osu.Game/Overlays/Login/LoginForm.cs | 12 ++----------
1 file changed, 2 insertions(+), 10 deletions(-)
diff --git a/osu.Game/Overlays/Login/LoginForm.cs b/osu.Game/Overlays/Login/LoginForm.cs
index a77baa3186..80dfca93d2 100644
--- a/osu.Game/Overlays/Login/LoginForm.cs
+++ b/osu.Game/Overlays/Login/LoginForm.cs
@@ -13,11 +13,11 @@ using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
-using osu.Game.Localisation;
using osu.Game.Online.API;
using osu.Game.Overlays.Settings;
using osu.Game.Resources.Localisation.Web;
using osuTK;
+using osu.Game.Localisation;
namespace osu.Game.Overlays.Login
{
@@ -26,7 +26,6 @@ namespace osu.Game.Overlays.Login
private TextBox username = null!;
private TextBox password = null!;
private ShakeContainer shakeSignIn = null!;
- private SettingsCheckbox rememberUsername = null!;
[Resolved]
private IAPIProvider api { get; set; } = null!;
@@ -83,7 +82,7 @@ namespace osu.Game.Overlays.Login
},
},
},
- rememberUsername = new SettingsCheckbox
+ new SettingsCheckbox
{
LabelText = LoginPanelStrings.RememberUsername,
Current = config.GetBindable(OsuSetting.SaveUsername),
@@ -131,7 +130,6 @@ namespace osu.Game.Overlays.Login
forgottenPasswordLink.AddLink(LayoutStrings.PopupLoginLoginForgot, $"{api.WebsiteRootUrl}/home/password-reset");
password.OnCommit += (_, _) => performLogin();
- rememberUsername.SettingChanged += () => onRememberUsernameChanged(config);
if (api.LastLoginError?.Message is string error)
{
@@ -148,12 +146,6 @@ namespace osu.Game.Overlays.Login
shakeSignIn.Shake();
}
- private void onRememberUsernameChanged(OsuConfigManager config)
- {
- if (rememberUsername.Current.Value == false)
- config.SetValue(OsuSetting.Username, string.Empty);
- }
-
protected override bool OnClick(ClickEvent e) => true;
protected override void OnFocus(FocusEvent e)
From 01f6ab0336a630a588b0938576660a02150bdeb7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Thu, 22 Feb 2024 09:44:59 +0100
Subject: [PATCH 095/105] Use more correct implementation
---
osu.Game/Configuration/OsuConfigManager.cs | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs
index 6b2cb4ee74..a71460ded7 100644
--- a/osu.Game/Configuration/OsuConfigManager.cs
+++ b/osu.Game/Configuration/OsuConfigManager.cs
@@ -77,12 +77,19 @@ namespace osu.Game.Configuration
SetDefault(OsuSetting.SavePassword, false).ValueChanged += enabled =>
{
- if (enabled.NewValue) SetValue(OsuSetting.SaveUsername, true);
+ if (enabled.NewValue)
+ SetValue(OsuSetting.SaveUsername, true);
+ else
+ GetBindable(OsuSetting.Token).SetDefault();
};
SetDefault(OsuSetting.SaveUsername, true).ValueChanged += enabled =>
{
- if (!enabled.NewValue) SetValue(OsuSetting.SavePassword, false);
+ if (!enabled.NewValue)
+ {
+ GetBindable(OsuSetting.Username).SetDefault();
+ SetValue(OsuSetting.SavePassword, false);
+ }
};
SetDefault(OsuSetting.ExternalLinkWarning, true);
From 81a9908c60012bde9ee9135c254ab2b891be5ecc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Thu, 22 Feb 2024 10:27:37 +0100
Subject: [PATCH 096/105] Extract common helper for BPM rounding
---
osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs | 4 ++--
osu.Game/Screens/Select/BeatmapInfoWedge.cs | 7 ++++---
osu.Game/Utils/FormatUtils.cs | 10 ++++++++++
3 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs b/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs
index 1db02b7cf2..2f0b39bfbd 100644
--- a/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs
+++ b/osu.Game/Overlays/Mods/BeatmapAttributesDisplay.cs
@@ -1,7 +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 System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
@@ -20,6 +19,7 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
+using osu.Game.Utils;
using osuTK;
namespace osu.Game.Overlays.Mods
@@ -169,7 +169,7 @@ namespace osu.Game.Overlays.Mods
foreach (var mod in mods.Value.OfType())
rate = mod.ApplyToRate(0, rate);
- bpmDisplay.Current.Value = (int)Math.Round(Math.Round(BeatmapInfo.Value.BPM) * rate);
+ bpmDisplay.Current.Value = FormatUtils.RoundBPM(BeatmapInfo.Value.BPM, rate);
BeatmapDifficulty originalDifficulty = new BeatmapDifficulty(BeatmapInfo.Value.Difficulty);
diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs
index c69cd6ead6..3cab4b67b6 100644
--- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs
+++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs
@@ -31,6 +31,7 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using osu.Game.Graphics.Containers;
using osu.Game.Resources.Localisation.Web;
+using osu.Game.Utils;
namespace osu.Game.Screens.Select
{
@@ -405,9 +406,9 @@ namespace osu.Game.Screens.Select
foreach (var mod in mods.Value.OfType())
rate = mod.ApplyToRate(0, rate);
- int bpmMax = (int)Math.Round(Math.Round(beatmap.ControlPointInfo.BPMMaximum) * rate);
- int bpmMin = (int)Math.Round(Math.Round(beatmap.ControlPointInfo.BPMMinimum) * rate);
- int mostCommonBPM = (int)Math.Round(Math.Round(60000 / beatmap.GetMostCommonBeatLength()) * rate);
+ int bpmMax = FormatUtils.RoundBPM(beatmap.ControlPointInfo.BPMMaximum, rate);
+ int bpmMin = FormatUtils.RoundBPM(beatmap.ControlPointInfo.BPMMinimum, rate);
+ int mostCommonBPM = FormatUtils.RoundBPM(60000 / beatmap.GetMostCommonBeatLength(), rate);
string labelText = bpmMin == bpmMax
? $"{bpmMin}"
diff --git a/osu.Game/Utils/FormatUtils.cs b/osu.Game/Utils/FormatUtils.cs
index 799dc75ca9..cccad3711c 100644
--- a/osu.Game/Utils/FormatUtils.cs
+++ b/osu.Game/Utils/FormatUtils.cs
@@ -49,5 +49,15 @@ namespace osu.Game.Utils
return precision;
}
+
+ ///
+ /// Applies rounding to the given BPM value.
+ ///
+ ///
+ /// Double-rounding is applied intentionally (see https://github.com/ppy/osu/pull/18345#issue-1243311382 for rationale).
+ ///
+ /// The base BPM to round.
+ /// Rate adjustment, if applicable.
+ public static int RoundBPM(double baseBpm, double rate = 1) => (int)Math.Round(Math.Round(baseBpm) * rate);
}
}
From 84fdcd24ef17194422a3aab9f3d6653955cda3d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Thu, 22 Feb 2024 10:56:50 +0100
Subject: [PATCH 097/105] Remove description from mod search terms
Closes https://github.com/ppy/osu/issues/27111.
---
osu.Game/Overlays/Mods/ModPanel.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/osu.Game/Overlays/Mods/ModPanel.cs b/osu.Game/Overlays/Mods/ModPanel.cs
index 2d8d01d8c8..cf173b0d6a 100644
--- a/osu.Game/Overlays/Mods/ModPanel.cs
+++ b/osu.Game/Overlays/Mods/ModPanel.cs
@@ -77,12 +77,11 @@ namespace osu.Game.Overlays.Mods
///
public bool Visible => modState.Visible;
- public override IEnumerable FilterTerms => new[]
+ public override IEnumerable FilterTerms => new LocalisableString[]
{
Mod.Name,
Mod.Name.Replace(" ", string.Empty),
Mod.Acronym,
- Mod.Description
};
public override bool MatchingFilter
From b08fcbd4e953af0051bf9560eba57006763ded43 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Thu, 22 Feb 2024 10:56:13 +0100
Subject: [PATCH 098/105] Adjust tests to new behaviour
---
.../Visual/UserInterface/TestSceneModSelectOverlay.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs
index 99a5897dff..b26e126249 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs
@@ -788,7 +788,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddAssert("all columns visible", () => this.ChildrenOfType().All(col => col.IsPresent));
AddStep("set search", () => modSelectOverlay.SearchTerm = "HD");
- AddAssert("one column visible", () => this.ChildrenOfType().Count(col => col.IsPresent) == 1);
+ AddAssert("two columns visible", () => this.ChildrenOfType().Count(col => col.IsPresent) == 2);
AddStep("filter out everything", () => modSelectOverlay.SearchTerm = "Some long search term with no matches");
AddAssert("no columns visible", () => this.ChildrenOfType().All(col => !col.IsPresent));
@@ -812,7 +812,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddAssert("all columns visible", () => this.ChildrenOfType().All(col => col.IsPresent));
AddStep("set search", () => modSelectOverlay.SearchTerm = "fail");
- AddAssert("one column visible", () => this.ChildrenOfType().Count(col => col.IsPresent) == 2);
+ AddAssert("one column visible", () => this.ChildrenOfType().Count(col => col.IsPresent) == 1);
AddStep("hide", () => modSelectOverlay.Hide());
AddStep("show", () => modSelectOverlay.Show());
From 47db317df84862a68947c20e71dcfe87c552830f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Thu, 22 Feb 2024 11:45:57 +0100
Subject: [PATCH 099/105] Enable NRT in `TestSceneDifficultyIcon`
---
osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
index 80320c138b..e544177d50 100644
--- a/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
+++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -16,7 +14,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
{
public partial class TestSceneDifficultyIcon : OsuTestScene
{
- private FillFlowContainer fill;
+ private FillFlowContainer fill = null!;
protected override void LoadComplete()
{
@@ -35,7 +33,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
[Test]
public void CreateDifficultyIcon()
{
- DifficultyIcon difficultyIcon = null;
+ DifficultyIcon difficultyIcon = null!;
AddRepeatStep("create difficulty icon", () =>
{
From d06c67ad8f921b02990b954256c95c22c5e70f22 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Thu, 22 Feb 2024 11:57:40 +0100
Subject: [PATCH 100/105] Substitute two jank interdependent bool flags for
single tri-state enums
---
.../Beatmaps/TestSceneDifficultyIcon.cs | 12 ++------
osu.Game/Beatmaps/Drawables/DifficultyIcon.cs | 29 ++++++++++++++-----
.../Drawables/DifficultyIconTooltip.cs | 11 ++++---
osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 2 +-
.../OnlinePlay/DrawableRoomPlaylistItem.cs | 2 +-
.../Carousel/DrawableCarouselBeatmap.cs | 2 +-
6 files changed, 34 insertions(+), 24 deletions(-)
diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
index e544177d50..6a226c2b8c 100644
--- a/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
+++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
@@ -50,18 +50,12 @@ namespace osu.Game.Tests.Visual.Beatmaps
fill.Add(difficultyIcon = new DifficultyIcon(beatmapInfo, rulesetInfo)
{
Scale = new Vector2(2),
- ShowTooltip = true,
- ShowExtendedTooltip = true
});
}, 10);
- AddStep("hide extended tooltip", () => difficultyIcon.ShowExtendedTooltip = false);
-
- AddStep("hide tooltip", () => difficultyIcon.ShowTooltip = false);
-
- AddStep("show tooltip", () => difficultyIcon.ShowTooltip = true);
-
- AddStep("show extended tooltip", () => difficultyIcon.ShowExtendedTooltip = true);
+ AddStep("no tooltip", () => difficultyIcon.TooltipType = DifficultyIconTooltipType.None);
+ AddStep("basic tooltip", () => difficultyIcon.TooltipType = DifficultyIconTooltipType.StarRating);
+ AddStep("extended tooltip", () => difficultyIcon.TooltipType = DifficultyIconTooltipType.Extended);
}
}
}
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
index 73073a8286..2e7f894d12 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIcon.cs
@@ -32,14 +32,9 @@ namespace osu.Game.Beatmaps.Drawables
}
///
- /// Whether to display a tooltip on hover. Only works if a beatmap was provided at construction time.
+ /// Which type of tooltip to show. Only works if a beatmap was provided at construction time.
///
- public bool ShowTooltip { get; set; } = true;
-
- ///
- /// Whether to include the difficulty stats in the tooltip or not. Defaults to false. Has no effect if is false.
- ///
- public bool ShowExtendedTooltip { get; set; }
+ public DifficultyIconTooltipType TooltipType { get; set; } = DifficultyIconTooltipType.StarRating;
private readonly IBeatmapInfo? beatmap;
@@ -138,6 +133,24 @@ namespace osu.Game.Beatmaps.Drawables
GetCustomTooltip() => new DifficultyIconTooltip();
DifficultyIconTooltipContent IHasCustomTooltip.
- TooltipContent => (ShowTooltip && beatmap != null ? new DifficultyIconTooltipContent(beatmap, Current, ruleset, mods, ShowExtendedTooltip) : null)!;
+ TooltipContent => (TooltipType != DifficultyIconTooltipType.None && beatmap != null ? new DifficultyIconTooltipContent(beatmap, Current, ruleset, mods, TooltipType) : null)!;
+ }
+
+ public enum DifficultyIconTooltipType
+ {
+ ///
+ /// No tooltip.
+ ///
+ None,
+
+ ///
+ /// Star rating only.
+ ///
+ StarRating,
+
+ ///
+ /// Star rating, OD, HP, CS, AR, length, BPM, and max combo.
+ ///
+ Extended,
}
}
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
index 71366de654..952f71332f 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
@@ -113,7 +113,7 @@ namespace osu.Game.Beatmaps.Drawables
starRating.Current.BindTarget = displayedContent.Difficulty;
difficultyName.Text = displayedContent.BeatmapInfo.DifficultyName;
- if (!displayedContent.ShowExtendedTooltip)
+ if (displayedContent.TooltipType == DifficultyIconTooltipType.StarRating)
{
difficultyFillFlowContainer.Hide();
miscFillFlowContainer.Hide();
@@ -166,15 +166,18 @@ namespace osu.Game.Beatmaps.Drawables
public readonly IBindable Difficulty;
public readonly IRulesetInfo Ruleset;
public readonly Mod[]? Mods;
- public readonly bool ShowExtendedTooltip;
+ public readonly DifficultyIconTooltipType TooltipType;
- public DifficultyIconTooltipContent(IBeatmapInfo beatmapInfo, IBindable difficulty, IRulesetInfo rulesetInfo, Mod[]? mods, bool showExtendedTooltip = false)
+ public DifficultyIconTooltipContent(IBeatmapInfo beatmapInfo, IBindable difficulty, IRulesetInfo rulesetInfo, Mod[]? mods, DifficultyIconTooltipType tooltipType)
{
+ if (tooltipType == DifficultyIconTooltipType.None)
+ throw new ArgumentOutOfRangeException(nameof(tooltipType), tooltipType, "Cannot instantiate a tooltip without a type");
+
BeatmapInfo = beatmapInfo;
Difficulty = difficulty;
Ruleset = rulesetInfo;
Mods = mods;
- ShowExtendedTooltip = showExtendedTooltip;
+ TooltipType = tooltipType;
}
}
}
diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs
index 1f38e2ed6c..5f021803b0 100644
--- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs
+++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs
@@ -297,7 +297,7 @@ namespace osu.Game.Overlays.BeatmapSet
},
icon = new DifficultyIcon(beatmapInfo, ruleset)
{
- ShowTooltip = false,
+ TooltipType = DifficultyIconTooltipType.None,
Current = { Value = new StarDifficulty(beatmapInfo.StarRating, 0) },
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
diff --git a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
index 44e91c6975..1b8e2d8be6 100644
--- a/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
+++ b/osu.Game/Screens/OnlinePlay/DrawableRoomPlaylistItem.cs
@@ -285,7 +285,7 @@ namespace osu.Game.Screens.OnlinePlay
difficultyIconContainer.Child = new DifficultyIcon(beatmap, ruleset, requiredMods)
{
Size = new Vector2(icon_height),
- ShowExtendedTooltip = true
+ TooltipType = DifficultyIconTooltipType.Extended,
};
}
else
diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs
index baf0a14062..01e58d4ab2 100644
--- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs
+++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmap.cs
@@ -122,7 +122,7 @@ namespace osu.Game.Screens.Select.Carousel
{
difficultyIcon = new DifficultyIcon(beatmapInfo)
{
- ShowTooltip = false,
+ TooltipType = DifficultyIconTooltipType.None,
Scale = new Vector2(1.8f),
},
new FillFlowContainer
From 37400643605426647eb80097401002828ff0d7ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Thu, 22 Feb 2024 11:59:55 +0100
Subject: [PATCH 101/105] Fix test scene not properly setting tooltip type on
all icons
---
.../Visual/Beatmaps/TestSceneDifficultyIcon.cs | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
index 6a226c2b8c..fb6bebe50d 100644
--- a/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
+++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneDifficultyIcon.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
+using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Utils;
@@ -14,13 +15,13 @@ namespace osu.Game.Tests.Visual.Beatmaps
{
public partial class TestSceneDifficultyIcon : OsuTestScene
{
- private FillFlowContainer fill = null!;
+ private FillFlowContainer fill = null!;
protected override void LoadComplete()
{
base.LoadComplete();
- Child = fill = new FillFlowContainer
+ Child = fill = new FillFlowContainer
{
AutoSizeAxes = Axes.Y,
Width = 300,
@@ -33,8 +34,6 @@ namespace osu.Game.Tests.Visual.Beatmaps
[Test]
public void CreateDifficultyIcon()
{
- DifficultyIcon difficultyIcon = null!;
-
AddRepeatStep("create difficulty icon", () =>
{
var rulesetInfo = new OsuRuleset().RulesetInfo;
@@ -47,15 +46,15 @@ namespace osu.Game.Tests.Visual.Beatmaps
beatmapInfo.StarRating = RNG.NextSingle(0, 10);
beatmapInfo.BPM = RNG.Next(60, 300);
- fill.Add(difficultyIcon = new DifficultyIcon(beatmapInfo, rulesetInfo)
+ fill.Add(new DifficultyIcon(beatmapInfo, rulesetInfo)
{
Scale = new Vector2(2),
});
}, 10);
- AddStep("no tooltip", () => difficultyIcon.TooltipType = DifficultyIconTooltipType.None);
- AddStep("basic tooltip", () => difficultyIcon.TooltipType = DifficultyIconTooltipType.StarRating);
- AddStep("extended tooltip", () => difficultyIcon.TooltipType = DifficultyIconTooltipType.Extended);
+ AddStep("no tooltip", () => fill.ForEach(icon => icon.TooltipType = DifficultyIconTooltipType.None));
+ AddStep("basic tooltip", () => fill.ForEach(icon => icon.TooltipType = DifficultyIconTooltipType.StarRating));
+ AddStep("extended tooltip", () => fill.ForEach(icon => icon.TooltipType = DifficultyIconTooltipType.Extended));
}
}
}
From 7861125e7ac1dcd48c06f5ab005870b5c111c31c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Thu, 22 Feb 2024 12:11:49 +0100
Subject: [PATCH 102/105] Swap AR and OD on tooltips
Matches everything else.
---
osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
index 952f71332f..1f3dcfee8c 100644
--- a/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
+++ b/osu.Game/Beatmaps/Drawables/DifficultyIconTooltip.cs
@@ -78,8 +78,8 @@ namespace osu.Game.Beatmaps.Drawables
{
circleSize = new OsuSpriteText { Font = OsuFont.GetFont(size: 14) },
drainRate = new OsuSpriteText { Font = OsuFont.GetFont(size: 14) },
+ overallDifficulty = new OsuSpriteText { Font = OsuFont.GetFont(size: 14) },
approachRate = new OsuSpriteText { Font = OsuFont.GetFont(size: 14) },
- overallDifficulty = new OsuSpriteText { Font = OsuFont.GetFont(size: 14) }
}
},
miscFillFlowContainer = new FillFlowContainer
From bbf3f6b56ca29f367b40fb5cc5414aab349820c2 Mon Sep 17 00:00:00 2001
From: Salman Ahmed
Date: Thu, 22 Feb 2024 16:31:13 +0300
Subject: [PATCH 103/105] Fix old-style legacy spinner fade in not matching
stable
---
.../Skinning/Legacy/LegacyOldStyleSpinner.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs
index c57487cf75..c75983f3d2 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs
@@ -92,8 +92,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt))
this.FadeOut();
- using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimeFadeIn / 2))
- this.FadeInFromZero(spinner.TimeFadeIn / 2);
+ using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimeFadeIn))
+ this.FadeInFromZero(spinner.TimeFadeIn);
}
protected override void Update()
From 99bbbf810bfcdbe2d1ee8fea5cecbc86e46ce667 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Thu, 22 Feb 2024 16:58:21 +0100
Subject: [PATCH 104/105] Update github actions to resolve most node
deprecation warnings
As is github tradition, workflows started yelling about running on a
node version that was getting sunset, so here we go again.
Relevant bumps:
- https://github.com/actions/checkout/releases/tag/v4.0.0
- https://github.com/actions/setup-dotnet/releases/tag/v4.0.0
- https://github.com/actions/cache/releases/tag/v4.0.0
- https://github.com/actions/setup-java/releases/tag/v4.0.0
- https://github.com/peter-evans/create-pull-request/releases/tag/v6.0.0
- https://github.com/dorny/test-reporter/releases/tag/v1.8.0
Notably, `actions/upload-artifact` is _not_ bumped to v4, although it
should be to resolve the node deprecation warnings, because it has more
breaking changes and bumping would break `dorny/test-reporter`
(see https://github.com/dorny/test-reporter/issues/363).
---
.github/workflows/ci.yml | 20 +++++++++----------
.github/workflows/diffcalc.yml | 2 +-
.github/workflows/report-nunit.yml | 2 +-
.github/workflows/sentry-release.yml | 2 +-
.../workflows/update-web-mod-definitions.yml | 10 +++++-----
5 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index de902df93f..1ea4654563 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -13,10 +13,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Install .NET 8.0.x
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: "8.0.x"
@@ -27,7 +27,7 @@ jobs:
run: dotnet restore osu.Desktop.slnf
- name: Restore inspectcode cache
- uses: actions/cache@v3
+ uses: actions/cache@v4
with:
path: ${{ github.workspace }}/inspectcode
key: inspectcode-${{ hashFiles('.config/dotnet-tools.json', '.github/workflows/ci.yml', 'osu.sln*', 'osu*.slnf', '.editorconfig', '.globalconfig', 'CodeAnalysis/*', '**/*.csproj', '**/*.props') }}
@@ -70,10 +70,10 @@ jobs:
timeout-minutes: 60
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Install .NET 8.0.x
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: "8.0.x"
@@ -99,16 +99,16 @@ jobs:
timeout-minutes: 60
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Setup JDK 11
- uses: actions/setup-java@v3
+ uses: actions/setup-java@v4
with:
distribution: microsoft
java-version: 11
- name: Install .NET 8.0.x
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: "8.0.x"
@@ -126,10 +126,10 @@ jobs:
timeout-minutes: 60
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
- name: Install .NET 8.0.x
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: "8.0.x"
diff --git a/.github/workflows/diffcalc.yml b/.github/workflows/diffcalc.yml
index 5f16e09040..7a2dcecb9c 100644
--- a/.github/workflows/diffcalc.yml
+++ b/.github/workflows/diffcalc.yml
@@ -140,7 +140,7 @@ jobs:
GOOGLE_CREDS_FILE: ${{ steps.set-outputs.outputs.GOOGLE_CREDS_FILE }}
steps:
- name: Checkout diffcalc-sheet-generator
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
path: ${{ env.EXECUTION_ID }}
repository: 'smoogipoo/diffcalc-sheet-generator'
diff --git a/.github/workflows/report-nunit.yml b/.github/workflows/report-nunit.yml
index 99e39f6f56..c44f46d70a 100644
--- a/.github/workflows/report-nunit.yml
+++ b/.github/workflows/report-nunit.yml
@@ -28,7 +28,7 @@ jobs:
timeout-minutes: 5
steps:
- name: Annotate CI run with test results
- uses: dorny/test-reporter@v1.6.0
+ uses: dorny/test-reporter@v1.8.0
with:
artifact: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}}
name: Test Results (${{matrix.os.prettyname}}, ${{matrix.threadingMode}})
diff --git a/.github/workflows/sentry-release.yml b/.github/workflows/sentry-release.yml
index ff4165c414..be104d0fd3 100644
--- a/.github/workflows/sentry-release.yml
+++ b/.github/workflows/sentry-release.yml
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
fetch-depth: 0
diff --git a/.github/workflows/update-web-mod-definitions.yml b/.github/workflows/update-web-mod-definitions.yml
index 5827a6cdbf..b19f03ad7d 100644
--- a/.github/workflows/update-web-mod-definitions.yml
+++ b/.github/workflows/update-web-mod-definitions.yml
@@ -13,23 +13,23 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Install .NET 8.0.x
- uses: actions/setup-dotnet@v3
+ uses: actions/setup-dotnet@v4
with:
dotnet-version: "8.0.x"
- name: Checkout ppy/osu
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
path: osu
- name: Checkout ppy/osu-tools
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
repository: ppy/osu-tools
path: osu-tools
- name: Checkout ppy/osu-web
- uses: actions/checkout@v3
+ uses: actions/checkout@v4
with:
repository: ppy/osu-web
path: osu-web
@@ -43,7 +43,7 @@ jobs:
working-directory: ./osu-tools
- name: Create pull request with changes
- uses: peter-evans/create-pull-request@v5
+ uses: peter-evans/create-pull-request@v6
with:
title: Update mod definitions
body: "This PR has been auto-generated to update the mod definitions to match ppy/osu@${{ github.ref_name }}."
From e1ceb8a5fa9abb9512c5e1639ae1132b64a9d272 Mon Sep 17 00:00:00 2001
From: SupDos <6813986+SupDos@users.noreply.github.com>
Date: Thu, 22 Feb 2024 18:54:28 +0100
Subject: [PATCH 105/105] Add missing .olz association to iOS
---
osu.iOS/Info.plist | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/osu.iOS/Info.plist b/osu.iOS/Info.plist
index cf51fe995b..1330e29bc1 100644
--- a/osu.iOS/Info.plist
+++ b/osu.iOS/Info.plist
@@ -102,6 +102,19 @@
osz
+
+ UTTypeConformsTo
+
+ sh.ppy.osu.items
+
+ UTTypeIdentifier
+ sh.ppy.osu.olz
+ UTTypeTagSpecification
+
+ public.filename-extension
+ olz
+
+
CFBundleDocumentTypes