From dc75d55f72af11bdf81b081dad8f5e84be3ed2e2 Mon Sep 17 00:00:00 2001
From: Gabe Livengood <47010459+ggliv@users.noreply.github.com>
Date: Wed, 8 Jun 2022 14:02:15 -0400
Subject: [PATCH 01/41] allow modfailcondition to arbitrarily trigger fail
---
osu.Game/Rulesets/Mods/ModFailCondition.cs | 19 +++++++++++++++++++
osu.Game/Rulesets/Scoring/HealthProcessor.cs | 14 ++++++++++----
2 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/osu.Game/Rulesets/Mods/ModFailCondition.cs b/osu.Game/Rulesets/Mods/ModFailCondition.cs
index 4425ece513..1aab0ab880 100644
--- a/osu.Game/Rulesets/Mods/ModFailCondition.cs
+++ b/osu.Game/Rulesets/Mods/ModFailCondition.cs
@@ -19,12 +19,31 @@ namespace osu.Game.Rulesets.Mods
public virtual bool PerformFail() => true;
public virtual bool RestartOnFail => Restart.Value;
+ private HealthProcessor healthProcessorInternal;
public void ApplyToHealthProcessor(HealthProcessor healthProcessor)
{
+ healthProcessorInternal = healthProcessor;
healthProcessor.FailConditions += FailCondition;
}
+ ///
+ /// Immediately triggers a failure on the loaded .
+ ///
+ protected void TriggerArbitraryFailure() => healthProcessorInternal.TriggerFailure();
+
+ ///
+ /// Determines whether should trigger a failure. Called every time a
+ /// judgement is applied to .
+ ///
+ /// The loaded .
+ /// The latest .
+ /// Whether the fail condition has been met.
+ ///
+ /// This method should only be used to trigger failures based on .
+ /// Using outside values to evaluate failure may introduce event ordering discrepancies, use
+ /// an with instead.
+ ///
protected abstract bool FailCondition(HealthProcessor healthProcessor, JudgementResult result);
}
}
diff --git a/osu.Game/Rulesets/Scoring/HealthProcessor.cs b/osu.Game/Rulesets/Scoring/HealthProcessor.cs
index 0f51560476..4f5ff95477 100644
--- a/osu.Game/Rulesets/Scoring/HealthProcessor.cs
+++ b/osu.Game/Rulesets/Scoring/HealthProcessor.cs
@@ -33,6 +33,15 @@ namespace osu.Game.Rulesets.Scoring
///
public bool HasFailed { get; private set; }
+ ///
+ /// Immediately triggers a failure for this HealthProcessor.
+ ///
+ public void TriggerFailure()
+ {
+ if (Failed?.Invoke() != false)
+ HasFailed = true;
+ }
+
protected override void ApplyResultInternal(JudgementResult result)
{
result.HealthAtJudgement = Health.Value;
@@ -44,10 +53,7 @@ namespace osu.Game.Rulesets.Scoring
Health.Value += GetHealthIncreaseFor(result);
if (meetsAnyFailCondition(result))
- {
- if (Failed?.Invoke() != false)
- HasFailed = true;
- }
+ TriggerFailure();
}
protected override void RevertResultInternal(JudgementResult result)
From 21c5499da16eb88f12d6f5bee8d28b1557559b2f Mon Sep 17 00:00:00 2001
From: Gabe Livengood <47010459+ggliv@users.noreply.github.com>
Date: Fri, 10 Jun 2022 13:11:17 -0400
Subject: [PATCH 02/41] remove arbitrary from method name
---
osu.Game/Rulesets/Mods/ModFailCondition.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/osu.Game/Rulesets/Mods/ModFailCondition.cs b/osu.Game/Rulesets/Mods/ModFailCondition.cs
index 1aab0ab880..9500734408 100644
--- a/osu.Game/Rulesets/Mods/ModFailCondition.cs
+++ b/osu.Game/Rulesets/Mods/ModFailCondition.cs
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mods
///
/// Immediately triggers a failure on the loaded .
///
- protected void TriggerArbitraryFailure() => healthProcessorInternal.TriggerFailure();
+ protected void TriggerFailure() => healthProcessorInternal.TriggerFailure();
///
/// Determines whether should trigger a failure. Called every time a
@@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mods
///
/// This method should only be used to trigger failures based on .
/// Using outside values to evaluate failure may introduce event ordering discrepancies, use
- /// an with instead.
+ /// an with instead.
///
protected abstract bool FailCondition(HealthProcessor healthProcessor, JudgementResult result);
}
From 6e64a8f55ef5838a5d58625668138fb3c85e34db Mon Sep 17 00:00:00 2001
From: Gabe Livengood <47010459+ggliv@users.noreply.github.com>
Date: Fri, 10 Jun 2022 13:13:35 -0400
Subject: [PATCH 03/41] use event to trigger failure
---
osu.Game/Rulesets/Mods/ModFailCondition.cs | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/osu.Game/Rulesets/Mods/ModFailCondition.cs b/osu.Game/Rulesets/Mods/ModFailCondition.cs
index 9500734408..63cebc9747 100644
--- a/osu.Game/Rulesets/Mods/ModFailCondition.cs
+++ b/osu.Game/Rulesets/Mods/ModFailCondition.cs
@@ -19,18 +19,18 @@ namespace osu.Game.Rulesets.Mods
public virtual bool PerformFail() => true;
public virtual bool RestartOnFail => Restart.Value;
- private HealthProcessor healthProcessorInternal;
+ private event Action failureTriggered;
public void ApplyToHealthProcessor(HealthProcessor healthProcessor)
{
- healthProcessorInternal = healthProcessor;
+ failureTriggered = healthProcessor.TriggerFailure;
healthProcessor.FailConditions += FailCondition;
}
///
/// Immediately triggers a failure on the loaded .
///
- protected void TriggerFailure() => healthProcessorInternal.TriggerFailure();
+ protected void TriggerFailure() => failureTriggered?.Invoke();
///
/// Determines whether should trigger a failure. Called every time a
From 74e7cc205601bc4edb9d88e12afb8c63f8e967d2 Mon Sep 17 00:00:00 2001
From: tsrk
Date: Wed, 15 Feb 2023 22:18:02 +0000
Subject: [PATCH 04/41] feat: implement new design of key counter
---
.../Visual/Gameplay/TestSceneKeyCounter.cs | 39 +++++++---
osu.Game/Screens/Play/ArgonKeyCounter.cs | 76 +++++++++++++++++++
.../Screens/Play/ArgonKeyCounterDisplay.cs | 42 ++++++++++
3 files changed, 147 insertions(+), 10 deletions(-)
create mode 100644 osu.Game/Screens/Play/ArgonKeyCounter.cs
create mode 100644 osu.Game/Screens/Play/ArgonKeyCounterDisplay.cs
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
index 975a5c9465..41add82245 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
@@ -8,6 +8,7 @@ using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Utils;
using osu.Game.Screens.Play;
+using osuTK;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Gameplay
@@ -18,24 +19,44 @@ namespace osu.Game.Tests.Visual.Gameplay
public TestSceneKeyCounter()
{
DefaultKeyCounter testCounter;
+ KeyCounterDisplay kc;
+ KeyCounterDisplay argonKc;
- KeyCounterDisplay kc = new DefaultKeyCounterDisplay
+ Children = new Drawable[]
{
- Origin = Anchor.Centre,
- Anchor = Anchor.Centre,
- Children = new[]
+ kc = new DefaultKeyCounterDisplay
{
- testCounter = new DefaultKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
- new DefaultKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
- new DefaultKeyCounter(new KeyCounterMouseTrigger(MouseButton.Left)),
- new DefaultKeyCounter(new KeyCounterMouseTrigger(MouseButton.Right)),
+ Origin = Anchor.Centre,
+ Anchor = Anchor.Centre,
+ Position = new Vector2(0, -50),
+ Children = new[]
+ {
+ testCounter = new DefaultKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
+ new DefaultKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
+ new DefaultKeyCounter(new KeyCounterMouseTrigger(MouseButton.Left)),
+ new DefaultKeyCounter(new KeyCounterMouseTrigger(MouseButton.Right)),
+ },
},
+ argonKc = new ArgonKeyCounterDisplay
+ {
+ Origin = Anchor.Centre,
+ Anchor = Anchor.Centre,
+ Position = new Vector2(0, 50),
+ Children = new[]
+ {
+ new ArgonKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
+ new ArgonKeyCounter(new KeyCounterKeyboardTrigger(Key.X)),
+ new ArgonKeyCounter(new KeyCounterMouseTrigger(MouseButton.Left)),
+ new ArgonKeyCounter(new KeyCounterMouseTrigger(MouseButton.Right)),
+ },
+ }
};
AddStep("Add random", () =>
{
Key key = (Key)((int)Key.A + RNG.Next(26));
kc.Add(kc.CreateKeyCounter(new KeyCounterKeyboardTrigger(key)));
+ argonKc.Add(argonKc.CreateKeyCounter(new KeyCounterKeyboardTrigger(key)));
});
Key testKey = ((KeyCounterKeyboardTrigger)kc.Children.First().Trigger).Key;
@@ -52,8 +73,6 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("Disable counting", () => testCounter.IsCounting = false);
addPressKeyStep();
AddAssert($"Check {testKey} count has not changed", () => testCounter.CountPresses == 2);
-
- Add(kc);
}
}
}
diff --git a/osu.Game/Screens/Play/ArgonKeyCounter.cs b/osu.Game/Screens/Play/ArgonKeyCounter.cs
new file mode 100644
index 0000000000..a275a7e017
--- /dev/null
+++ b/osu.Game/Screens/Play/ArgonKeyCounter.cs
@@ -0,0 +1,76 @@
+// 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.Shapes;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
+using osuTK;
+
+namespace osu.Game.Screens.Play
+{
+ public partial class ArgonKeyCounter : KeyCounter
+ {
+ private Circle inputIndicator = null!;
+ private OsuSpriteText countText = null!;
+
+ // These values were taken from Figma
+ private const float line_height = 3;
+ private const float name_font_size = 10;
+ private const float count_font_size = 14;
+
+ // Make things look bigger without using Scale
+ private const float scale_factor = 1.5f;
+
+ public ArgonKeyCounter(InputTrigger trigger)
+ : base(trigger)
+ {
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(OsuColour colours)
+ {
+ Children = new Drawable[]
+ {
+ inputIndicator = new Circle
+ {
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ RelativeSizeAxes = Axes.X,
+ Height = line_height * scale_factor,
+ Alpha = 0.5f
+ },
+ new OsuSpriteText
+ {
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomLeft,
+ Position = new Vector2(0, -13) * scale_factor,
+ Font = OsuFont.Torus.With(size: name_font_size * scale_factor, weight: FontWeight.Bold),
+ Colour = colours.Blue0,
+ Text = Name
+ },
+ countText = new OsuSpriteText
+ {
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.BottomLeft,
+ Font = OsuFont.Torus.With(size: count_font_size * scale_factor, weight: FontWeight.Bold),
+ Text = "0"
+ },
+ };
+
+ // Values from Figma didn't match visually
+ // So these were just eyeballed
+ Height = 30 * scale_factor;
+ Width = 35 * scale_factor;
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ IsLit.BindValueChanged(e => inputIndicator.Alpha = e.NewValue ? 1 : 0.5f, true);
+ PressesCount.BindValueChanged(e => countText.Text = e.NewValue.ToString(@"#,0"), true);
+ }
+ }
+}
diff --git a/osu.Game/Screens/Play/ArgonKeyCounterDisplay.cs b/osu.Game/Screens/Play/ArgonKeyCounterDisplay.cs
new file mode 100644
index 0000000000..da34a64a4c
--- /dev/null
+++ b/osu.Game/Screens/Play/ArgonKeyCounterDisplay.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.
+
+using System.Collections.Generic;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osuTK;
+
+namespace osu.Game.Screens.Play
+{
+ public partial class ArgonKeyCounterDisplay : KeyCounterDisplay
+ {
+ private const int duration = 100;
+
+ public new IReadOnlyList Children
+ {
+ get => (IReadOnlyList)base.Children;
+ set => base.Children = value;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ KeyFlow.Direction = FillDirection.Horizontal;
+ KeyFlow.AutoSizeAxes = Axes.Both;
+ KeyFlow.Spacing = new Vector2(2);
+
+ InternalChildren = new[]
+ {
+ KeyFlow
+ };
+ }
+
+ protected override bool CheckType(KeyCounter key) => key is ArgonKeyCounter;
+
+ protected override void UpdateVisibility()
+ => KeyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration);
+
+ public override KeyCounter CreateKeyCounter(KeyCounter.InputTrigger trigger) => new ArgonKeyCounter(trigger);
+ }
+}
From 9f4b1f0f242a95ab2df2e77e2f2670ae5f846364 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Thu, 20 Apr 2023 14:30:01 +0900
Subject: [PATCH 05/41] Always round editor rotation to integer values
---
.../Edit/Compose/Components/SelectionBoxRotationHandle.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs
index 305f5bf3c4..c2a3f12efd 100644
--- a/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/SelectionBoxRotationHandle.cs
@@ -118,7 +118,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
{
float oldRotation = cumulativeRotation.Value ?? 0;
- float newRotation = shouldSnap ? snap(rawCumulativeRotation, snap_step) : rawCumulativeRotation;
+ float newRotation = shouldSnap ? snap(rawCumulativeRotation, snap_step) : MathF.Round(rawCumulativeRotation);
newRotation = (newRotation - 180) % 360 + 180;
cumulativeRotation.Value = newRotation;
From b62de5514c532a3c2df5ef4c311eb5b273578050 Mon Sep 17 00:00:00 2001
From: Haspamelodica
Date: Fri, 21 Apr 2023 02:10:24 +0200
Subject: [PATCH 06/41] Fixed video importing bug #23259
---
osu.Game/Beatmaps/BeatmapManager.cs | 2 +-
osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +-
osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +-
osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs | 2 +-
osu.Game/OsuGameBase.cs | 2 +-
5 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs
index cab49b7d69..6af6a25579 100644
--- a/osu.Game/Beatmaps/BeatmapManager.cs
+++ b/osu.Game/Beatmaps/BeatmapManager.cs
@@ -368,7 +368,7 @@ namespace osu.Game.Beatmaps
// user requested abort
return;
- var video = b.Files.FirstOrDefault(f => OsuGameBase.VIDEO_EXTENSIONS.Any(ex => f.Filename.EndsWith(ex, StringComparison.Ordinal)));
+ var video = b.Files.FirstOrDefault(f => OsuGameBase.VIDEO_EXTENSIONS.Any(ex => f.Filename.EndsWith(ex, StringComparison.OrdinalIgnoreCase)));
if (video != null)
{
diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs
index a9bdd21b64..0e3a62e8fa 100644
--- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs
+++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs
@@ -369,7 +369,7 @@ namespace osu.Game.Beatmaps.Formats
// Some very old beatmaps had incorrect type specifications for their backgrounds (ie. using 1 for VIDEO
// instead of 0 for BACKGROUND). To handle this gracefully, check the file extension against known supported
// video extensions and handle similar to a background if it doesn't match.
- if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(filename)))
+ if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(filename).ToUpperInvariant()))
{
beatmap.BeatmapInfo.Metadata.BackgroundFile = filename;
}
diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
index f8308fe431..2eb496a798 100644
--- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
+++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
@@ -114,7 +114,7 @@ namespace osu.Game.Beatmaps.Formats
//
// This avoids potential weird crashes when ffmpeg attempts to parse an image file as a video
// (see https://github.com/ppy/osu/issues/22829#issuecomment-1465552451).
- if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(path)))
+ if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(path).ToUpperInvariant()))
break;
storyboard.GetLayer("Video").Add(new StoryboardVideo(path, offset));
diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs b/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs
index 37e15c6127..825b1a5636 100644
--- a/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs
+++ b/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs
@@ -70,7 +70,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
{
get
{
- if (OsuGameBase.VIDEO_EXTENSIONS.Contains(File.Extension))
+ if (OsuGameBase.VIDEO_EXTENSIONS.Contains(File.Extension.ToUpperInvariant()))
return FontAwesome.Regular.FileVideo;
switch (File.Extension)
diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs
index 34e31b0d61..2ab6c24af7 100644
--- a/osu.Game/OsuGameBase.cs
+++ b/osu.Game/OsuGameBase.cs
@@ -71,7 +71,7 @@ namespace osu.Game
[Cached(typeof(OsuGameBase))]
public partial class OsuGameBase : Framework.Game, ICanAcceptFiles, IBeatSyncProvider
{
- public static readonly string[] VIDEO_EXTENSIONS = { ".mp4", ".mov", ".avi", ".flv", ".mpg", ".wmv", ".m4v" };
+ public static readonly string[] VIDEO_EXTENSIONS = { ".MP4", ".MOV", ".AVI", ".FLV", ".MPG", ".WMV", ".M4V" };
public const string OSU_PROTOCOL = "osu://";
From e90660c1a48c7eb46447348756ca2b976ca1bbf6 Mon Sep 17 00:00:00 2001
From: Haspamelodica
Date: Fri, 21 Apr 2023 02:35:28 +0200
Subject: [PATCH 07/41] Switched to lowercase
---
osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +-
osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs | 2 +-
osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs | 2 +-
osu.Game/OsuGameBase.cs | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs
index 0e3a62e8fa..ef1dbc0488 100644
--- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs
+++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs
@@ -369,7 +369,7 @@ namespace osu.Game.Beatmaps.Formats
// Some very old beatmaps had incorrect type specifications for their backgrounds (ie. using 1 for VIDEO
// instead of 0 for BACKGROUND). To handle this gracefully, check the file extension against known supported
// video extensions and handle similar to a background if it doesn't match.
- if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(filename).ToUpperInvariant()))
+ if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(filename).ToLowerInvariant()))
{
beatmap.BeatmapInfo.Metadata.BackgroundFile = filename;
}
diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
index 2eb496a798..df5d3edb55 100644
--- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
+++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs
@@ -114,7 +114,7 @@ namespace osu.Game.Beatmaps.Formats
//
// This avoids potential weird crashes when ffmpeg attempts to parse an image file as a video
// (see https://github.com/ppy/osu/issues/22829#issuecomment-1465552451).
- if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(path).ToUpperInvariant()))
+ if (!OsuGameBase.VIDEO_EXTENSIONS.Contains(Path.GetExtension(path).ToLowerInvariant()))
break;
storyboard.GetLayer("Video").Add(new StoryboardVideo(path, offset));
diff --git a/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs b/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs
index 825b1a5636..7097102335 100644
--- a/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs
+++ b/osu.Game/Graphics/UserInterfaceV2/OsuFileSelector.cs
@@ -70,7 +70,7 @@ namespace osu.Game.Graphics.UserInterfaceV2
{
get
{
- if (OsuGameBase.VIDEO_EXTENSIONS.Contains(File.Extension.ToUpperInvariant()))
+ if (OsuGameBase.VIDEO_EXTENSIONS.Contains(File.Extension.ToLowerInvariant()))
return FontAwesome.Regular.FileVideo;
switch (File.Extension)
diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs
index 2ab6c24af7..34e31b0d61 100644
--- a/osu.Game/OsuGameBase.cs
+++ b/osu.Game/OsuGameBase.cs
@@ -71,7 +71,7 @@ namespace osu.Game
[Cached(typeof(OsuGameBase))]
public partial class OsuGameBase : Framework.Game, ICanAcceptFiles, IBeatSyncProvider
{
- public static readonly string[] VIDEO_EXTENSIONS = { ".MP4", ".MOV", ".AVI", ".FLV", ".MPG", ".WMV", ".M4V" };
+ public static readonly string[] VIDEO_EXTENSIONS = { ".mp4", ".mov", ".avi", ".flv", ".mpg", ".wmv", ".m4v" };
public const string OSU_PROTOCOL = "osu://";
From e9fb836e9ccfbd6690ffcf5c6974e2d125a5fb80 Mon Sep 17 00:00:00 2001
From: Haspamelodica
Date: Fri, 21 Apr 2023 03:24:11 +0200
Subject: [PATCH 08/41] Added tests for video backgrounds
---
.../Formats/LegacyBeatmapDecoderTest.cs | 31 +++++++++++++++
.../Formats/LegacyStoryboardDecoderTest.cs | 38 ++++++++++++++++++-
.../video-with-lowercase-extension.osb | 5 +++
.../video-with-uppercase-extension.osb | 5 +++
4 files changed, 77 insertions(+), 2 deletions(-)
create mode 100644 osu.Game.Tests/Resources/video-with-lowercase-extension.osb
create mode 100644 osu.Game.Tests/Resources/video-with-uppercase-extension.osb
diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
index 518981980b..5979f6785e 100644
--- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
+++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
@@ -21,6 +21,7 @@ using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Beatmaps;
using osu.Game.Skinning;
+using osu.Game.Storyboards;
using osu.Game.Tests.Resources;
using osuTK;
using osuTK.Graphics;
@@ -160,6 +161,36 @@ namespace osu.Game.Tests.Beatmaps.Formats
}
}
+ [Test]
+ public void TestDecodeVideoWithLowercaseExtension()
+ {
+ var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
+
+ using (var resStream = TestResources.OpenResource("video-with-lowercase-extension.osb"))
+ using (var stream = new LineBufferedReader(resStream))
+ {
+ var beatmap = decoder.Decode(stream);
+ var metadata = beatmap.Metadata;
+
+ Assert.AreEqual("BG.jpg", metadata.BackgroundFile);
+ }
+ }
+
+ [Test]
+ public void TestDecodeVideoWithUppercaseExtension()
+ {
+ var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
+
+ using (var resStream = TestResources.OpenResource("video-with-uppercase-extension.osb"))
+ using (var stream = new LineBufferedReader(resStream))
+ {
+ var beatmap = decoder.Decode(stream);
+ var metadata = beatmap.Metadata;
+
+ Assert.AreEqual("BG.jpg", metadata.BackgroundFile);
+ }
+ }
+
[Test]
public void TestDecodeImageSpecifiedAsVideo()
{
diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs
index 3a776ac225..1bfe134610 100644
--- a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs
+++ b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs
@@ -169,6 +169,40 @@ namespace osu.Game.Tests.Beatmaps.Formats
}
}
+ [Test]
+ public void TestDecodeVideoWithLowercaseExtension()
+ {
+ var decoder = new LegacyStoryboardDecoder();
+
+ using (var resStream = TestResources.OpenResource("video-with-lowercase-extension.osb"))
+ using (var stream = new LineBufferedReader(resStream))
+ {
+ var storyboard = decoder.Decode(stream);
+
+ StoryboardLayer video = storyboard.Layers.Single(l => l.Name == "Video");
+ Assert.That(video.Elements.Count, Is.EqualTo(1));
+
+ Assert.AreEqual("Video.avi", ((StoryboardVideo)video.Elements[0]).Path);
+ }
+ }
+
+ [Test]
+ public void TestDecodeVideoWithUppercaseExtension()
+ {
+ var decoder = new LegacyStoryboardDecoder();
+
+ using (var resStream = TestResources.OpenResource("video-with-uppercase-extension.osb"))
+ using (var stream = new LineBufferedReader(resStream))
+ {
+ var storyboard = decoder.Decode(stream);
+
+ StoryboardLayer video = storyboard.Layers.Single(l => l.Name == "Video");
+ Assert.That(video.Elements.Count, Is.EqualTo(1));
+
+ Assert.AreEqual("Video.AVI", ((StoryboardVideo)video.Elements[0]).Path);
+ }
+ }
+
[Test]
public void TestDecodeImageSpecifiedAsVideo()
{
@@ -179,8 +213,8 @@ namespace osu.Game.Tests.Beatmaps.Formats
{
var storyboard = decoder.Decode(stream);
- StoryboardLayer foreground = storyboard.Layers.Single(l => l.Name == "Video");
- Assert.That(foreground.Elements.Count, Is.Zero);
+ StoryboardLayer video = storyboard.Layers.Single(l => l.Name == "Video");
+ Assert.That(video.Elements.Count, Is.Zero);
}
}
diff --git a/osu.Game.Tests/Resources/video-with-lowercase-extension.osb b/osu.Game.Tests/Resources/video-with-lowercase-extension.osb
new file mode 100644
index 0000000000..eec09722ed
--- /dev/null
+++ b/osu.Game.Tests/Resources/video-with-lowercase-extension.osb
@@ -0,0 +1,5 @@
+osu file format v14
+
+[Events]
+0,0,"BG.jpg",0,0
+Video,0,"Video.avi",0,0
diff --git a/osu.Game.Tests/Resources/video-with-uppercase-extension.osb b/osu.Game.Tests/Resources/video-with-uppercase-extension.osb
new file mode 100644
index 0000000000..3834a547f2
--- /dev/null
+++ b/osu.Game.Tests/Resources/video-with-uppercase-extension.osb
@@ -0,0 +1,5 @@
+osu file format v14
+
+[Events]
+0,0,"BG.jpg",0,0
+Video,0,"Video.AVI",0,0
From 3166f88c17a291724f03b2bb53ca96413864a443 Mon Sep 17 00:00:00 2001
From: Haspamelodica
Date: Fri, 21 Apr 2023 10:11:47 +0200
Subject: [PATCH 09/41] Removed unneccessary using directive
---
osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
index 5979f6785e..d898650b66 100644
--- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
+++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
@@ -21,7 +21,6 @@ using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Beatmaps;
using osu.Game.Skinning;
-using osu.Game.Storyboards;
using osu.Game.Tests.Resources;
using osuTK;
using osuTK.Graphics;
From 847b63066b9e08255026c3c530ebb5acab9ab5a4 Mon Sep 17 00:00:00 2001
From: Terochi
Date: Fri, 21 Apr 2023 21:46:03 +0200
Subject: [PATCH 10/41] fix
---
osu.Game.Rulesets.Catch/UI/Catcher.cs | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs
index ab754e51f7..7787dd80c1 100644
--- a/osu.Game.Rulesets.Catch/UI/Catcher.cs
+++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs
@@ -418,10 +418,13 @@ namespace osu.Game.Rulesets.Catch.UI
private void clearPlate(DroppedObjectAnimation animation)
{
- var droppedObjects = caughtObjectContainer.Children.Select(getDroppedObject).ToArray();
+ var caughtObjects = caughtObjectContainer.Children.ToArray();
caughtObjectContainer.Clear(false);
+ //use the already returned PoolableDrawables for new objects
+ var droppedObjects = caughtObjects.Select(getDroppedObject).ToArray();
+
droppedObjectTarget.AddRange(droppedObjects);
foreach (var droppedObject in droppedObjects)
@@ -430,13 +433,11 @@ namespace osu.Game.Rulesets.Catch.UI
private void removeFromPlate(CaughtObject caughtObject, DroppedObjectAnimation animation)
{
- var droppedObject = getDroppedObject(caughtObject);
-
caughtObjectContainer.Remove(caughtObject, false);
- droppedObjectTarget.Add(droppedObject);
+ droppedObjectTarget.Add(getDroppedObject(caughtObject));
- applyDropAnimation(droppedObject, animation);
+ applyDropAnimation(caughtObject, animation);
}
private void applyDropAnimation(Drawable d, DroppedObjectAnimation animation)
@@ -456,6 +457,8 @@ namespace osu.Game.Rulesets.Catch.UI
break;
}
+ //define lifetime start for dropped objects to be disposed correctly when rewinding replay
+ d.LifetimeStart = Clock.CurrentTime;
d.Expire();
}
From bb1ed387ef29958bcc8f8006cebfad2ead9dc8c8 Mon Sep 17 00:00:00 2001
From: Terochi
Date: Sat, 22 Apr 2023 10:54:50 +0200
Subject: [PATCH 11/41] fixed missed bit and comments
---
osu.Game.Rulesets.Catch/UI/Catcher.cs | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs
index 7787dd80c1..f77dab56c8 100644
--- a/osu.Game.Rulesets.Catch/UI/Catcher.cs
+++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs
@@ -422,7 +422,7 @@ namespace osu.Game.Rulesets.Catch.UI
caughtObjectContainer.Clear(false);
- //use the already returned PoolableDrawables for new objects
+ // Use the already returned PoolableDrawables for new objects
var droppedObjects = caughtObjects.Select(getDroppedObject).ToArray();
droppedObjectTarget.AddRange(droppedObjects);
@@ -435,9 +435,11 @@ namespace osu.Game.Rulesets.Catch.UI
{
caughtObjectContainer.Remove(caughtObject, false);
- droppedObjectTarget.Add(getDroppedObject(caughtObject));
+ var droppedObject = getDroppedObject(caughtObject);
- applyDropAnimation(caughtObject, animation);
+ droppedObjectTarget.Add(droppedObject);
+
+ applyDropAnimation(droppedObject, animation);
}
private void applyDropAnimation(Drawable d, DroppedObjectAnimation animation)
@@ -457,7 +459,7 @@ namespace osu.Game.Rulesets.Catch.UI
break;
}
- //define lifetime start for dropped objects to be disposed correctly when rewinding replay
+ // Define lifetime start for dropped objects to be disposed correctly when rewinding replay
d.LifetimeStart = Clock.CurrentTime;
d.Expire();
}
From 3919400be2c0d2dddc287ca8bda36677dfb029fe Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Tue, 25 Apr 2023 14:28:56 +0900
Subject: [PATCH 12/41] Apply NRT to some storyboard classes
---
osu.Game/Storyboards/StoryboardAnimation.cs | 2 --
osu.Game/Storyboards/StoryboardSprite.cs | 13 +++++--------
2 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/osu.Game/Storyboards/StoryboardAnimation.cs b/osu.Game/Storyboards/StoryboardAnimation.cs
index 16deac8e9e..1a4b6bb923 100644
--- a/osu.Game/Storyboards/StoryboardAnimation.cs
+++ b/osu.Game/Storyboards/StoryboardAnimation.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 osuTK;
using osu.Framework.Graphics;
using osu.Game.Storyboards.Drawables;
diff --git a/osu.Game/Storyboards/StoryboardSprite.cs b/osu.Game/Storyboards/StoryboardSprite.cs
index 5b7b194be7..0c28d7bce1 100644
--- a/osu.Game/Storyboards/StoryboardSprite.cs
+++ b/osu.Game/Storyboards/StoryboardSprite.cs
@@ -1,12 +1,9 @@
// 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.Collections.Generic;
using System.Linq;
-using JetBrains.Annotations;
using osu.Framework.Graphics;
using osu.Game.Storyboards.Drawables;
using osuTK;
@@ -114,7 +111,7 @@ namespace osu.Game.Storyboards
public virtual Drawable CreateDrawable()
=> new DrawableStoryboardSprite(this);
- public void ApplyTransforms(Drawable drawable, IEnumerable> triggeredGroups = null)
+ public void ApplyTransforms(Drawable drawable, IEnumerable>? triggeredGroups = null)
{
// For performance reasons, we need to apply the commands in order by start time. Not doing so will cause many functions to be interleaved, resulting in O(n^2) complexity.
// To achieve this, commands are "generated" as pairs of (command, initFunc, transformFunc) and batched into a contiguous list
@@ -156,7 +153,7 @@ namespace osu.Game.Storyboards
foreach (var command in commands)
{
- DrawablePropertyInitializer initFunc = null;
+ DrawablePropertyInitializer? initFunc = null;
if (!initialized)
{
@@ -169,7 +166,7 @@ namespace osu.Game.Storyboards
}
}
- private IEnumerable.TypedCommand> getCommands(CommandTimelineSelector timelineSelector, IEnumerable> triggeredGroups)
+ private IEnumerable.TypedCommand> getCommands(CommandTimelineSelector timelineSelector, IEnumerable>? triggeredGroups)
{
var commands = TimelineGroup.GetCommands(timelineSelector);
foreach (var loop in loops)
@@ -198,11 +195,11 @@ namespace osu.Game.Storyboards
{
public double StartTime => command.StartTime;
- private readonly DrawablePropertyInitializer initializeProperty;
+ private readonly DrawablePropertyInitializer? initializeProperty;
private readonly DrawableTransformer transform;
private readonly CommandTimeline.TypedCommand command;
- public GeneratedCommand([NotNull] CommandTimeline.TypedCommand command, [CanBeNull] DrawablePropertyInitializer initializeProperty, [NotNull] DrawableTransformer transform)
+ public GeneratedCommand(CommandTimeline.TypedCommand command, DrawablePropertyInitializer? initializeProperty, DrawableTransformer transform)
{
this.command = command;
this.initializeProperty = initializeProperty;
From dce0c5fac815b4334a921b81989baf2d06e3c57c Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Tue, 25 Apr 2023 15:14:32 +0900
Subject: [PATCH 13/41] Add test coverage of expected behaviour for playback of
loops with no explicit end time
---
.../Formats/LegacyStoryboardDecoderTest.cs | 19 +++++++++++++++++++
.../animation-loop-no-explicit-end-time.osb | 6 ++++++
2 files changed, 25 insertions(+)
create mode 100644 osu.Game.Tests/Resources/animation-loop-no-explicit-end-time.osb
diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs
index 3a776ac225..17e94a8b5f 100644
--- a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs
+++ b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs
@@ -95,6 +95,25 @@ namespace osu.Game.Tests.Beatmaps.Formats
}
}
+ [Test]
+ public void TestLoopWithoutExplicitFadeOut()
+ {
+ var decoder = new LegacyStoryboardDecoder();
+
+ using (var resStream = TestResources.OpenResource("animation-loop-no-explicit-end-time.osb"))
+ using (var stream = new LineBufferedReader(resStream))
+ {
+ var storyboard = decoder.Decode(stream);
+
+ StoryboardLayer background = storyboard.Layers.Single(l => l.Depth == 3);
+ Assert.AreEqual(1, background.Elements.Count);
+
+ Assert.AreEqual(2000, background.Elements[0].StartTime);
+ Assert.AreEqual(2000, (background.Elements[0] as StoryboardAnimation)?.EarliestTransformTime);
+ Assert.AreEqual(12000, (background.Elements[0] as StoryboardAnimation)?.GetEndTime());
+ }
+ }
+
[Test]
public void TestCorrectAnimationStartTime()
{
diff --git a/osu.Game.Tests/Resources/animation-loop-no-explicit-end-time.osb b/osu.Game.Tests/Resources/animation-loop-no-explicit-end-time.osb
new file mode 100644
index 0000000000..7afaa445df
--- /dev/null
+++ b/osu.Game.Tests/Resources/animation-loop-no-explicit-end-time.osb
@@ -0,0 +1,6 @@
+[Events]
+//Storyboard Layer 0 (Background)
+Animation,Background,Centre,"img.jpg",320,240,2,150,LoopForever
+ F,0,2000,,0,1
+ L,2000,10
+ F,18,0,1000,1,0
From e330052852a8692c769ed2152a5980a16679b576 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Tue, 25 Apr 2023 15:22:11 +0900
Subject: [PATCH 14/41] Add second definition of `EndTime` for storyboard
elements to account for loops in lifetime
---
.../Beatmaps/Formats/LegacyStoryboardDecoderTest.cs | 4 +++-
.../Background/TestSceneBackgroundScreenDefault.cs | 1 +
.../Storyboards/IStoryboardElementWithDuration.cs | 8 ++++++++
osu.Game/Storyboards/StoryboardSprite.cs | 13 +++++++++++++
4 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs
index 17e94a8b5f..f78825ffb1 100644
--- a/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs
+++ b/osu.Game.Tests/Beatmaps/Formats/LegacyStoryboardDecoderTest.cs
@@ -110,7 +110,9 @@ namespace osu.Game.Tests.Beatmaps.Formats
Assert.AreEqual(2000, background.Elements[0].StartTime);
Assert.AreEqual(2000, (background.Elements[0] as StoryboardAnimation)?.EarliestTransformTime);
- Assert.AreEqual(12000, (background.Elements[0] as StoryboardAnimation)?.GetEndTime());
+
+ Assert.AreEqual(3000, (background.Elements[0] as StoryboardAnimation)?.GetEndTime());
+ Assert.AreEqual(12000, (background.Elements[0] as StoryboardAnimation)?.EndTimeForDisplay);
}
}
diff --git a/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs b/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs
index fbdaad1cd8..8f4250799e 100644
--- a/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs
+++ b/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs
@@ -311,6 +311,7 @@ namespace osu.Game.Tests.Visual.Background
public bool IsDrawable => true;
public double StartTime => double.MinValue;
public double EndTime => double.MaxValue;
+ public double EndTimeForDisplay => double.MaxValue;
public Drawable CreateDrawable() => new DrawableTestStoryboardElement();
}
diff --git a/osu.Game/Storyboards/IStoryboardElementWithDuration.cs b/osu.Game/Storyboards/IStoryboardElementWithDuration.cs
index c8daeb3b3d..9eed139ad4 100644
--- a/osu.Game/Storyboards/IStoryboardElementWithDuration.cs
+++ b/osu.Game/Storyboards/IStoryboardElementWithDuration.cs
@@ -12,9 +12,17 @@ namespace osu.Game.Storyboards
{
///
/// The time at which the ends.
+ /// This is consumed to extend the length of a storyboard to ensure all visuals are played to completion.
///
double EndTime { get; }
+ ///
+ /// The time this element displays until.
+ /// This is used for lifetime purposes, and includes long playing animations which don't necessarily extend
+ /// a storyboard's play time.
+ ///
+ double EndTimeForDisplay { get; }
+
///
/// The duration of the StoryboardElement.
///
diff --git a/osu.Game/Storyboards/StoryboardSprite.cs b/osu.Game/Storyboards/StoryboardSprite.cs
index 0c28d7bce1..982185d51b 100644
--- a/osu.Game/Storyboards/StoryboardSprite.cs
+++ b/osu.Game/Storyboards/StoryboardSprite.cs
@@ -81,6 +81,19 @@ namespace osu.Game.Storyboards
}
}
+ public double EndTimeForDisplay
+ {
+ get
+ {
+ double latestEndTime = TimelineGroup.EndTime;
+
+ foreach (var l in loops)
+ latestEndTime = Math.Max(latestEndTime, l.StartTime + l.CommandsDuration * l.TotalIterations);
+
+ return latestEndTime;
+ }
+ }
+
public bool HasCommands => TimelineGroup.HasCommands || loops.Any(l => l.HasCommands);
private delegate void DrawablePropertyInitializer(Drawable drawable, T value);
From dd2c289ce96ed4c874f901476bef18e0c4657a6c Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Tue, 25 Apr 2023 20:22:12 +0900
Subject: [PATCH 15/41] Remove pointless default value
---
osu.Game/Screens/Play/ArgonKeyCounter.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/osu.Game/Screens/Play/ArgonKeyCounter.cs b/osu.Game/Screens/Play/ArgonKeyCounter.cs
index 70fe2e3a65..a978f001d5 100644
--- a/osu.Game/Screens/Play/ArgonKeyCounter.cs
+++ b/osu.Game/Screens/Play/ArgonKeyCounter.cs
@@ -56,7 +56,6 @@ namespace osu.Game.Screens.Play
Anchor = Anchor.BottomLeft,
Origin = Anchor.BottomLeft,
Font = OsuFont.Torus.With(size: count_font_size * scale_factor, weight: FontWeight.Bold),
- Text = "0"
},
};
From 76309586330690aee88bfc4b7f6ac6b70cdbf751 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Tue, 25 Apr 2023 20:24:36 +0900
Subject: [PATCH 16/41] Stop using `Drawable.Name` to convey actual UI
information
---
osu.Game/Screens/Play/ArgonKeyCounter.cs | 2 +-
osu.Game/Screens/Play/HUD/DefaultKeyCounter.cs | 2 +-
osu.Game/Screens/Play/HUD/KeyCounter.cs | 2 --
3 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/osu.Game/Screens/Play/ArgonKeyCounter.cs b/osu.Game/Screens/Play/ArgonKeyCounter.cs
index a978f001d5..6818b30823 100644
--- a/osu.Game/Screens/Play/ArgonKeyCounter.cs
+++ b/osu.Game/Screens/Play/ArgonKeyCounter.cs
@@ -49,7 +49,7 @@ namespace osu.Game.Screens.Play
Position = new Vector2(0, -13) * scale_factor,
Font = OsuFont.Torus.With(size: name_font_size * scale_factor, weight: FontWeight.Bold),
Colour = colours.Blue0,
- Text = Name
+ Text = Trigger.Name
},
countText = new OsuSpriteText
{
diff --git a/osu.Game/Screens/Play/HUD/DefaultKeyCounter.cs b/osu.Game/Screens/Play/HUD/DefaultKeyCounter.cs
index 69a3e53dfc..f7ac72035f 100644
--- a/osu.Game/Screens/Play/HUD/DefaultKeyCounter.cs
+++ b/osu.Game/Screens/Play/HUD/DefaultKeyCounter.cs
@@ -57,7 +57,7 @@ namespace osu.Game.Screens.Play.HUD
{
new OsuSpriteText
{
- Text = Name,
+ Text = Trigger.Name,
Font = OsuFont.Numeric.With(size: 12),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
diff --git a/osu.Game/Screens/Play/HUD/KeyCounter.cs b/osu.Game/Screens/Play/HUD/KeyCounter.cs
index 2a4ab1993a..7cdd6b025f 100644
--- a/osu.Game/Screens/Play/HUD/KeyCounter.cs
+++ b/osu.Game/Screens/Play/HUD/KeyCounter.cs
@@ -54,8 +54,6 @@ namespace osu.Game.Screens.Play.HUD
Trigger.OnActivate += Activate;
Trigger.OnDeactivate += Deactivate;
-
- Name = trigger.Name;
}
private void increment()
From 0c3a01595362d1e995dfe46d7fbd0d1c4bd8c814 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Tue, 25 Apr 2023 21:37:17 +0900
Subject: [PATCH 17/41] Fix key counter test not testing the full binding of
`IsCounting`
---
.../Visual/Gameplay/TestSceneKeyCounter.cs | 29 +++++++++----------
1 file changed, 13 insertions(+), 16 deletions(-)
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
index 1e35c24e97..aabc25d660 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
@@ -19,21 +19,21 @@ namespace osu.Game.Tests.Visual.Gameplay
{
public TestSceneKeyCounter()
{
- KeyCounterDisplay kc = new DefaultKeyCounterDisplay
+ KeyCounterDisplay defaultDisplay = new DefaultKeyCounterDisplay
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Position = new Vector2(0, 72.7f)
};
- KeyCounterDisplay argonKc = new ArgonKeyCounterDisplay
+ KeyCounterDisplay argonDisplay = new ArgonKeyCounterDisplay
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Position = new Vector2(0, -72.7f)
};
- kc.AddRange(new InputTrigger[]
+ defaultDisplay.AddRange(new InputTrigger[]
{
new KeyCounterKeyboardTrigger(Key.X),
new KeyCounterKeyboardTrigger(Key.X),
@@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual.Gameplay
new KeyCounterMouseTrigger(MouseButton.Right),
});
- argonKc.AddRange(new InputTrigger[]
+ argonDisplay.AddRange(new InputTrigger[]
{
new KeyCounterKeyboardTrigger(Key.X),
new KeyCounterKeyboardTrigger(Key.X),
@@ -49,32 +49,29 @@ namespace osu.Game.Tests.Visual.Gameplay
new KeyCounterMouseTrigger(MouseButton.Right),
});
- var testCounter = (DefaultKeyCounter)kc.Counters.First();
+ var testCounter = (DefaultKeyCounter)defaultDisplay.Counters.First();
AddStep("Add random", () =>
{
Key key = (Key)((int)Key.A + RNG.Next(26));
- kc.Add(new KeyCounterKeyboardTrigger(key));
- argonKc.Add(new KeyCounterKeyboardTrigger(key));
+ defaultDisplay.Add(new KeyCounterKeyboardTrigger(key));
+ argonDisplay.Add(new KeyCounterKeyboardTrigger(key));
});
- Key testKey = ((KeyCounterKeyboardTrigger)kc.Counters.First().Trigger).Key;
-
- void addPressKeyStep()
- {
- AddStep($"Press {testKey} key", () => InputManager.Key(testKey));
- }
+ Key testKey = ((KeyCounterKeyboardTrigger)defaultDisplay.Counters.First().Trigger).Key;
addPressKeyStep();
AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses.Value == 1);
addPressKeyStep();
AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses.Value == 2);
- AddStep("Disable counting", () => testCounter.IsCounting.Value = false);
+ AddStep("Disable counting", () => defaultDisplay.IsCounting.Value = false);
addPressKeyStep();
AddAssert($"Check {testKey} count has not changed", () => testCounter.CountPresses.Value == 2);
- Add(kc);
- Add(argonKc);
+ Add(defaultDisplay);
+ Add(argonDisplay);
+
+ void addPressKeyStep() => AddStep($"Press {testKey} key", () => InputManager.Key(testKey));
}
}
}
From 0a861ffcee21bae0b235b88b2455e1f2d3bfe2d6 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Tue, 25 Apr 2023 21:22:55 +0900
Subject: [PATCH 18/41] Restructure key counters to use a common flow
---
.../Screens/Play/ArgonKeyCounterDisplay.cs | 14 ++++-----
.../Play/HUD/DefaultKeyCounterDisplay.cs | 29 +++++++++----------
.../Screens/Play/HUD/KeyCounterDisplay.cs | 8 +++--
3 files changed, 24 insertions(+), 27 deletions(-)
diff --git a/osu.Game/Screens/Play/ArgonKeyCounterDisplay.cs b/osu.Game/Screens/Play/ArgonKeyCounterDisplay.cs
index a62ac3d39a..984c2a7287 100644
--- a/osu.Game/Screens/Play/ArgonKeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/ArgonKeyCounterDisplay.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.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Screens.Play.HUD;
@@ -13,13 +12,11 @@ namespace osu.Game.Screens.Play
{
private const int duration = 100;
- private readonly FillFlowContainer keyFlow;
-
- public override IEnumerable Counters => keyFlow;
+ protected override FillFlowContainer KeyFlow { get; }
public ArgonKeyCounterDisplay()
{
- InternalChild = keyFlow = new FillFlowContainer
+ InternalChild = KeyFlow = new FillFlowContainer
{
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
@@ -32,13 +29,12 @@ namespace osu.Game.Screens.Play
{
base.Update();
- Size = keyFlow.Size;
+ Size = KeyFlow.Size;
}
- public override void Add(InputTrigger trigger) =>
- keyFlow.Add(new ArgonKeyCounter(trigger));
+ protected override KeyCounter CreateCounter(InputTrigger trigger) => new ArgonKeyCounter(trigger);
protected override void UpdateVisibility()
- => keyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration);
+ => KeyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration);
}
}
diff --git a/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs
index 14d7f56093..e459574243 100644
--- a/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/HUD/DefaultKeyCounterDisplay.cs
@@ -1,7 +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.Collections.Generic;
+using System.Linq;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osuTK.Graphics;
@@ -13,13 +13,11 @@ namespace osu.Game.Screens.Play.HUD
private const int duration = 100;
private const double key_fade_time = 80;
- private readonly FillFlowContainer keyFlow;
-
- public override IEnumerable Counters => keyFlow;
+ protected override FillFlowContainer KeyFlow { get; }
public DefaultKeyCounterDisplay()
{
- InternalChild = keyFlow = new FillFlowContainer
+ InternalChild = KeyFlow = new FillFlowContainer
{
Direction = FillDirection.Horizontal,
AutoSizeAxes = Axes.Both,
@@ -33,20 +31,19 @@ namespace osu.Game.Screens.Play.HUD
// Don't use autosize as it will shrink to zero when KeyFlow is hidden.
// In turn this can cause the display to be masked off screen and never become visible again.
- Size = keyFlow.Size;
+ Size = KeyFlow.Size;
}
- public override void Add(InputTrigger trigger) =>
- keyFlow.Add(new DefaultKeyCounter(trigger)
- {
- FadeTime = key_fade_time,
- KeyDownTextColor = KeyDownTextColor,
- KeyUpTextColor = KeyUpTextColor,
- });
+ protected override KeyCounter CreateCounter(InputTrigger trigger) => new DefaultKeyCounter(trigger)
+ {
+ FadeTime = key_fade_time,
+ KeyDownTextColor = KeyDownTextColor,
+ KeyUpTextColor = KeyUpTextColor,
+ };
protected override void UpdateVisibility() =>
// Isolate changing visibility of the key counters from fading this component.
- keyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration);
+ KeyFlow.FadeTo(AlwaysVisible.Value || ConfigVisibility.Value ? 1 : 0, duration);
private Color4 keyDownTextColor = Color4.DarkGray;
@@ -58,7 +55,7 @@ namespace osu.Game.Screens.Play.HUD
if (value != keyDownTextColor)
{
keyDownTextColor = value;
- foreach (var child in keyFlow)
+ foreach (var child in KeyFlow.Cast())
child.KeyDownTextColor = value;
}
}
@@ -74,7 +71,7 @@ namespace osu.Game.Screens.Play.HUD
if (value != keyUpTextColor)
{
keyUpTextColor = value;
- foreach (var child in keyFlow)
+ foreach (var child in KeyFlow.Cast())
child.KeyUpTextColor = value;
}
}
diff --git a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs
index 49c0da6793..e218155af2 100644
--- a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs
@@ -29,7 +29,9 @@ namespace osu.Game.Screens.Play.HUD
///
/// The s contained in this .
///
- public abstract IEnumerable Counters { get; }
+ public IEnumerable Counters => KeyFlow;
+
+ protected abstract FillFlowContainer KeyFlow { get; }
///
/// Whether the actions reported by all s within this should be counted.
@@ -53,13 +55,15 @@ namespace osu.Game.Screens.Play.HUD
///
/// Add a to this display.
///
- public abstract void Add(InputTrigger trigger);
+ public void Add(InputTrigger trigger) => KeyFlow.Add(CreateCounter(trigger));
///
/// Add a range of to this display.
///
public void AddRange(IEnumerable triggers) => triggers.ForEach(Add);
+ protected abstract KeyCounter CreateCounter(InputTrigger trigger);
+
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
From 6b4032e34b57fba897a4f8906a9097c6543acb30 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Tue, 25 Apr 2023 21:31:39 +0900
Subject: [PATCH 19/41] Add missing binding of `IsCounting` with contained
counters
---
osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs
index e218155af2..05427d3a32 100644
--- a/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs
+++ b/osu.Game/Screens/Play/HUD/KeyCounterDisplay.cs
@@ -55,7 +55,14 @@ namespace osu.Game.Screens.Play.HUD
///
/// Add a to this display.
///
- public void Add(InputTrigger trigger) => KeyFlow.Add(CreateCounter(trigger));
+ public void Add(InputTrigger trigger)
+ {
+ var keyCounter = CreateCounter(trigger);
+
+ KeyFlow.Add(keyCounter);
+
+ IsCounting.BindTo(keyCounter.IsCounting);
+ }
///
/// Add a range of to this display.
From e08d7daffd7c5f582f98a43cad3f2fd2d64829bc Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Tue, 25 Apr 2023 21:43:14 +0900
Subject: [PATCH 20/41] Don't show decimal point in tooltip
---
osu.Game/Localisation/EditorStrings.cs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/osu.Game/Localisation/EditorStrings.cs b/osu.Game/Localisation/EditorStrings.cs
index 7c9b52275d..20258b9c35 100644
--- a/osu.Game/Localisation/EditorStrings.cs
+++ b/osu.Game/Localisation/EditorStrings.cs
@@ -100,14 +100,14 @@ namespace osu.Game.Localisation
public static LocalisableString TimelineTicks => new TranslatableString(getKey(@"timeline_ticks"), @"Ticks");
///
- /// "{0:0.0}°"
+ /// "{0:0}°"
///
- public static LocalisableString RotationUnsnapped(float newRotation) => new TranslatableString(getKey(@"rotation_unsnapped"), @"{0:0.0}°", newRotation);
+ public static LocalisableString RotationUnsnapped(float newRotation) => new TranslatableString(getKey(@"rotation_unsnapped"), @"{0:0}°", newRotation);
///
- /// "{0:0.0}° (snapped)"
+ /// "{0:0}° (snapped)"
///
- public static LocalisableString RotationSnapped(float newRotation) => new TranslatableString(getKey(@"rotation_snapped"), @"{0:0.0}° (snapped)", newRotation);
+ public static LocalisableString RotationSnapped(float newRotation) => new TranslatableString(getKey(@"rotation_snapped"), @"{0:0}° (snapped)", newRotation);
private static string getKey(string key) => $@"{prefix}:{key}";
}
From 753fa09356a2864060d0c8eb2dd95a29a7041785 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Tue, 25 Apr 2023 20:10:11 +0200
Subject: [PATCH 21/41] Fix test failures due to type mismatch
---
osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs | 2 +-
osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
index eecead5415..ae46dda750 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHUDOverlay.cs
@@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Gameplay
// best way to check without exposing.
private Drawable hideTarget => hudOverlay.KeyCounter;
- private Drawable keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().Single();
+ private Drawable keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().Single();
[BackgroundDependencyLoader]
private void load()
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs
index 7bbfc6a62b..0439656aae 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableHUDOverlay.cs
@@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual.Gameplay
// best way to check without exposing.
private Drawable hideTarget => hudOverlay.KeyCounter;
- private Drawable keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().Single();
+ private Drawable keyCounterFlow => hudOverlay.KeyCounter.ChildrenOfType>().Single();
[Test]
public void TestComboCounterIncrementing()
From 196b5b41eb07f7e0377c84b0d8ca381386dbc541 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bart=C5=82omiej=20Dach?=
Date: Tue, 25 Apr 2023 20:17:52 +0200
Subject: [PATCH 22/41] Also disable counting on argon display in test
Mostly for my own peace of mind.
---
osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
index aabc25d660..22f7111f68 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
@@ -64,7 +64,11 @@ namespace osu.Game.Tests.Visual.Gameplay
AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses.Value == 1);
addPressKeyStep();
AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses.Value == 2);
- AddStep("Disable counting", () => defaultDisplay.IsCounting.Value = false);
+ AddStep("Disable counting", () =>
+ {
+ argonDisplay.IsCounting.Value = false;
+ defaultDisplay.IsCounting.Value = false;
+ });
addPressKeyStep();
AddAssert($"Check {testKey} count has not changed", () => testCounter.CountPresses.Value == 2);
From 1efc78c0f8a7c3b17062c9a90318da3ef41a986c Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Wed, 26 Apr 2023 13:28:51 +0900
Subject: [PATCH 23/41] Actually use new end time property when setting
lifetimes
---
osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs | 2 +-
osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs
index e598c79b08..be77c9a98e 100644
--- a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs
+++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs
@@ -85,7 +85,7 @@ namespace osu.Game.Storyboards.Drawables
Loop = animation.LoopType == AnimationLoopType.LoopForever;
LifetimeStart = animation.StartTime;
- LifetimeEnd = animation.EndTime;
+ LifetimeEnd = animation.EndTimeForDisplay;
}
[Resolved]
diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs
index f9b09ed57c..400d33481c 100644
--- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs
+++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs
@@ -82,7 +82,7 @@ namespace osu.Game.Storyboards.Drawables
Position = sprite.InitialPosition;
LifetimeStart = sprite.StartTime;
- LifetimeEnd = sprite.EndTime;
+ LifetimeEnd = sprite.EndTimeForDisplay;
}
[Resolved]
From cb7b246e3352c08b73119b88fb0966e118720e2c Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Wed, 26 Apr 2023 15:27:58 +0900
Subject: [PATCH 24/41] Fix naming and update in line with nullability
---
osu.Game/Rulesets/Mods/ModFailCondition.cs | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/osu.Game/Rulesets/Mods/ModFailCondition.cs b/osu.Game/Rulesets/Mods/ModFailCondition.cs
index 63cebc9747..97789b7f5a 100644
--- a/osu.Game/Rulesets/Mods/ModFailCondition.cs
+++ b/osu.Game/Rulesets/Mods/ModFailCondition.cs
@@ -19,18 +19,19 @@ namespace osu.Game.Rulesets.Mods
public virtual bool PerformFail() => true;
public virtual bool RestartOnFail => Restart.Value;
- private event Action failureTriggered;
+
+ private Action? triggerFailureDelegate;
public void ApplyToHealthProcessor(HealthProcessor healthProcessor)
{
- failureTriggered = healthProcessor.TriggerFailure;
+ triggerFailureDelegate = healthProcessor.TriggerFailure;
healthProcessor.FailConditions += FailCondition;
}
///
/// Immediately triggers a failure on the loaded .
///
- protected void TriggerFailure() => failureTriggered?.Invoke();
+ protected void TriggerFailure() => triggerFailureDelegate?.Invoke();
///
/// Determines whether should trigger a failure. Called every time a
From 76df5fd3e27ddb2149182b5586ab1eff1634f7c4 Mon Sep 17 00:00:00 2001
From: sw1tchbl4d3
Date: Wed, 26 Apr 2023 18:05:47 +0200
Subject: [PATCH 25/41] Limit taiko playfield aspect ratio to 5:4 - 16:9
---
.../Mods/TaikoModClassic.cs | 2 +-
.../UI/DrawableTaikoRuleset.cs | 8 ++++---
.../UI/TaikoPlayfieldAdjustmentContainer.cs | 22 ++++++++++++++-----
3 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs
index d0361b1c8d..cdeaafde10 100644
--- a/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs
+++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModClassic.cs
@@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Taiko.Mods
public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset)
{
var drawableTaikoRuleset = (DrawableTaikoRuleset)drawableRuleset;
- drawableTaikoRuleset.LockPlayfieldMaxAspect.Value = false;
+ drawableTaikoRuleset.LockPlayfieldAspectRange.Value = false;
var playfield = (TaikoPlayfield)drawableRuleset.Playfield;
playfield.ClassicHitTargetPosition.Value = true;
diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs
index a08877e2dd..64d406a308 100644
--- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs
+++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs
@@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Taiko.UI
{
public new BindableDouble TimeRange => base.TimeRange;
- public readonly BindableBool LockPlayfieldMaxAspect = new BindableBool(true);
+ public readonly BindableBool LockPlayfieldAspectRange = new BindableBool(true);
public new TaikoInputManager KeyBindingInputManager => (TaikoInputManager)base.KeyBindingInputManager;
@@ -69,7 +69,9 @@ namespace osu.Game.Rulesets.Taiko.UI
const float scroll_rate = 10;
// Since the time range will depend on a positional value, it is referenced to the x480 pixel space.
- float ratio = DrawHeight / 480;
+ // Width is used because it defines how many notes fit on the playfield.
+ // We clamp the ratio to the maximum aspect ratio to keep scroll speed consistent on widths lower than the default.
+ float ratio = Math.Max(DrawSize.X / 768f, TaikoPlayfieldAdjustmentContainer.MAXIMUM_ASPECT);
TimeRange.Value = (Playfield.HitObjectContainer.DrawWidth / ratio) * scroll_rate;
}
@@ -92,7 +94,7 @@ namespace osu.Game.Rulesets.Taiko.UI
public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new TaikoPlayfieldAdjustmentContainer
{
- LockPlayfieldMaxAspect = { BindTarget = LockPlayfieldMaxAspect }
+ LockPlayfieldAspectRange = { BindTarget = LockPlayfieldAspectRange }
};
protected override PassThroughInputManager CreateInputManager() => new TaikoInputManager(Ruleset.RulesetInfo);
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs
index 42732d90e4..3587783104 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs
@@ -11,9 +11,11 @@ namespace osu.Game.Rulesets.Taiko.UI
public partial class TaikoPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer
{
private const float default_relative_height = TaikoPlayfield.DEFAULT_HEIGHT / 768;
- private const float default_aspect = 16f / 9f;
- public readonly IBindable LockPlayfieldMaxAspect = new BindableBool(true);
+ public const float MAXIMUM_ASPECT = 16f / 9f;
+ public const float MINIMUM_ASPECT = 5f / 4f;
+
+ public readonly IBindable LockPlayfieldAspectRange = new BindableBool(true);
protected override void Update()
{
@@ -26,12 +28,22 @@ namespace osu.Game.Rulesets.Taiko.UI
//
// As a middle-ground, the aspect ratio can still be adjusted in the downwards direction but has a maximum limit.
// This is still a bit weird, because readability changes with window size, but it is what it is.
- if (LockPlayfieldMaxAspect.Value && Parent.ChildSize.X / Parent.ChildSize.Y > default_aspect)
- height *= Math.Clamp(Parent.ChildSize.X / Parent.ChildSize.Y, 0.4f, 4) / default_aspect;
+ if (LockPlayfieldAspectRange.Value)
+ {
+ float currentAspect = Parent.ChildSize.X / Parent.ChildSize.Y;
+ if (currentAspect > MAXIMUM_ASPECT)
+ height *= currentAspect / MAXIMUM_ASPECT;
+ else if (currentAspect < MINIMUM_ASPECT)
+ height *= currentAspect / MINIMUM_ASPECT;
+ }
+
+ // Limit the maximum relative height of the playfield to one-third of available area to avoid it masking out on extreme resolutions.
+ height = Math.Min(height, 1f / 3f);
Height = height;
- // Position the taiko playfield exactly one playfield from the top of the screen.
+ // Position the taiko playfield exactly one playfield from the top of the screen, if there is enough space for it.
+ // Note that the relative height cannot exceed one-third - if that limit is hit, the playfield will be exactly centered.
RelativePositionAxes = Axes.Y;
Y = height;
}
From f5c652325a55402d71dfb3182dea9769906f5d1b Mon Sep 17 00:00:00 2001
From: _ltn <46729135+rltn@users.noreply.github.com>
Date: Thu, 27 Apr 2023 23:44:18 +0300
Subject: [PATCH 26/41] Create UpdateableCountryText.cs
---
.../Users/Drawables/UpdateableCountryText.cs | 67 +++++++++++++++++++
1 file changed, 67 insertions(+)
create mode 100644 osu.Game/Users/Drawables/UpdateableCountryText.cs
diff --git a/osu.Game/Users/Drawables/UpdateableCountryText.cs b/osu.Game/Users/Drawables/UpdateableCountryText.cs
new file mode 100644
index 0000000000..60174505a5
--- /dev/null
+++ b/osu.Game/Users/Drawables/UpdateableCountryText.cs
@@ -0,0 +1,67 @@
+// 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.Allocation;
+using osu.Framework.Input.Events;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
+using osu.Game.Graphics.UserInterface;
+using osu.Game.Overlays;
+using osu.Framework.Extensions;
+
+namespace osu.Game.Users.Drawables
+{
+ public partial class UpdateableCountryText : ModelBackedDrawable
+ {
+ public CountryCode CountryCode
+ {
+ get => Model;
+ set => Model = value;
+ }
+
+ public bool ShowPlaceholderOnUnknown = true;
+
+ public Action? Action;
+
+ protected override Drawable? CreateDrawable(CountryCode countryCode)
+ {
+ if (countryCode == CountryCode.Unknown && !ShowPlaceholderOnUnknown)
+ return null;
+
+ return new Container
+ {
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
+ {
+ new OsuSpriteText
+ {
+ Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular),
+ Margin = new MarginPadding { Left = 5 },
+ Origin = Anchor.CentreLeft,
+ Anchor = Anchor.CentreLeft,
+ Text = countryCode.GetDescription(),
+ },
+ new HoverClickSounds()
+ }
+ };
+ }
+
+ [Resolved]
+ private RankingsOverlay? rankingsOverlay { get; set; }
+
+ public UpdateableCountryText(CountryCode countryCode = CountryCode.Unknown)
+ {
+ CountryCode = countryCode;
+ }
+ protected override bool OnClick(ClickEvent e)
+ {
+ Action?.Invoke();
+ rankingsOverlay?.ShowCountry(CountryCode);
+ return true;
+ }
+ }
+
+}
\ No newline at end of file
From b13201fb792801e87b5a9148abd2a9ec6a011976 Mon Sep 17 00:00:00 2001
From: _ltn <46729135+rltn@users.noreply.github.com>
Date: Fri, 28 Apr 2023 01:14:42 +0300
Subject: [PATCH 27/41] UpdateableCountryText rewrite
---
.../Users/Drawables/UpdateableCountryText.cs | 55 ++++++-------------
1 file changed, 17 insertions(+), 38 deletions(-)
diff --git a/osu.Game/Users/Drawables/UpdateableCountryText.cs b/osu.Game/Users/Drawables/UpdateableCountryText.cs
index 60174505a5..fd749da707 100644
--- a/osu.Game/Users/Drawables/UpdateableCountryText.cs
+++ b/osu.Game/Users/Drawables/UpdateableCountryText.cs
@@ -7,6 +7,7 @@ using osu.Framework.Input.Events;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
+using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays;
@@ -14,53 +15,31 @@ using osu.Framework.Extensions;
namespace osu.Game.Users.Drawables
{
- public partial class UpdateableCountryText : ModelBackedDrawable
+ public partial class UpdateableCountryText : OsuHoverContainer
{
- public CountryCode CountryCode
- {
- get => Model;
- set => Model = value;
- }
public bool ShowPlaceholderOnUnknown = true;
- public Action? Action;
-
- protected override Drawable? CreateDrawable(CountryCode countryCode)
- {
- if (countryCode == CountryCode.Unknown && !ShowPlaceholderOnUnknown)
- return null;
-
- return new Container
- {
- RelativeSizeAxes = Axes.Both,
- Children = new Drawable[]
- {
- new OsuSpriteText
- {
- Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular),
- Margin = new MarginPadding { Left = 5 },
- Origin = Anchor.CentreLeft,
- Anchor = Anchor.CentreLeft,
- Text = countryCode.GetDescription(),
- },
- new HoverClickSounds()
- }
- };
- }
-
[Resolved]
private RankingsOverlay? rankingsOverlay { get; set; }
-
- public UpdateableCountryText(CountryCode countryCode = CountryCode.Unknown)
+ public UpdateableCountryText()
{
- CountryCode = countryCode;
+ AutoSizeAxes = Axes.Both;
}
- protected override bool OnClick(ClickEvent e)
+
+ // [BackgroundDependencyLoader]
+ public void load(CountryCode countryCode)
{
- Action?.Invoke();
- rankingsOverlay?.ShowCountry(CountryCode);
- return true;
+ Action = () =>
+ {
+ rankingsOverlay?.ShowCountry(countryCode);
+ };
+
+ Child = new OsuSpriteText
+ {
+ Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular),
+ Text = countryCode.GetDescription(),
+ };
}
}
From e9843f20665a00da524cc240a1ea307d00d548d2 Mon Sep 17 00:00:00 2001
From: _ltn <46729135+rltn@users.noreply.github.com>
Date: Fri, 28 Apr 2023 01:16:50 +0300
Subject: [PATCH 28/41] replace country text object
---
osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
index d04329430b..811628c3c1 100644
--- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
@@ -38,7 +38,7 @@ namespace osu.Game.Overlays.Profile.Header
private ExternalLinkButton openUserExternally = null!;
private OsuSpriteText titleText = null!;
private UpdateableFlag userFlag = null!;
- private OsuSpriteText userCountryText = null!;
+ private UpdateableCountryText userCountryText = null!;
private GroupBadgeFlow groupBadgeFlow = null!;
private ToggleCoverButton coverToggle = null!;
@@ -156,9 +156,8 @@ namespace osu.Game.Overlays.Profile.Header
Size = new Vector2(28, 20),
ShowPlaceholderOnUnknown = false,
},
- userCountryText = new OsuSpriteText
+ userCountryText = new UpdateableCountryText
{
- Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular),
Margin = new MarginPadding { Left = 5 },
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
@@ -201,7 +200,7 @@ namespace osu.Game.Overlays.Profile.Header
usernameText.Text = user?.Username ?? string.Empty;
openUserExternally.Link = $@"{api.WebsiteRootUrl}/users/{user?.Id ?? 0}";
userFlag.CountryCode = user?.CountryCode ?? default;
- userCountryText.Text = (user?.CountryCode ?? default).GetDescription();
+ userCountryText.load(user?.CountryCode ?? default);
supporterTag.SupportLevel = user?.SupportLevel ?? 0;
titleText.Text = user?.Title ?? string.Empty;
titleText.Colour = Color4Extensions.FromHex(user?.Colour ?? "fff");
From 092377fdaa234738a79eeb409cea0e5722c154a4 Mon Sep 17 00:00:00 2001
From: _ltn <46729135+rltn@users.noreply.github.com>
Date: Fri, 28 Apr 2023 01:47:14 +0300
Subject: [PATCH 29/41] moving UpdateableCountryText
---
.../Profile/Header/TopHeaderContainer.cs | 41 +++++++++++++++++
.../Users/Drawables/UpdateableCountryText.cs | 46 -------------------
2 files changed, 41 insertions(+), 46 deletions(-)
delete mode 100644 osu.Game/Users/Drawables/UpdateableCountryText.cs
diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
index 811628c3c1..54c84e08b8 100644
--- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
@@ -19,6 +19,20 @@ using osu.Game.Users;
using osu.Game.Users.Drawables;
using osuTK;
+
+using System;
+// using osu.Framework.Allocation;
+using osu.Framework.Input.Events;
+// using osu.Framework.Graphics;
+// using osu.Framework.Graphics.Containers;
+// using osu.Game.Graphics;
+using osu.Game.Graphics.Containers;
+// using osu.Game.Graphics.Sprites;
+// using osu.Game.Graphics.UserInterface;
+using osu.Game.Overlays;
+using osu.Framework.Graphics.Sprites;
+// using osu.Framework.Extensions;
+
namespace osu.Game.Overlays.Profile.Header
{
public partial class TopHeaderContainer : CompositeDrawable
@@ -158,6 +172,7 @@ namespace osu.Game.Overlays.Profile.Header
},
userCountryText = new UpdateableCountryText
{
+ Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular),
Margin = new MarginPadding { Left = 5 },
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
@@ -228,5 +243,31 @@ namespace osu.Game.Overlays.Profile.Header
Masking = true;
}
}
+
+ private partial class UpdateableCountryText : OsuHoverContainer
+ {
+ public bool ShowPlaceholderOnUnknown = true;
+ public FontUsage Font = default;
+ [Resolved]
+ private RankingsOverlay? rankingsOverlay { get; set; }
+ public UpdateableCountryText()
+ {
+ AutoSizeAxes = Axes.Both;
+ }
+
+ public void load(CountryCode countryCode)
+ {
+ Action = () =>
+ {
+ rankingsOverlay?.ShowCountry(countryCode);
+ };
+
+ Child = new OsuSpriteText
+ {
+ Font = Font,
+ Text = countryCode.GetDescription(),
+ };
+ }
+ }
}
}
diff --git a/osu.Game/Users/Drawables/UpdateableCountryText.cs b/osu.Game/Users/Drawables/UpdateableCountryText.cs
deleted file mode 100644
index fd749da707..0000000000
--- a/osu.Game/Users/Drawables/UpdateableCountryText.cs
+++ /dev/null
@@ -1,46 +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 System;
-using osu.Framework.Allocation;
-using osu.Framework.Input.Events;
-using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
-using osu.Game.Graphics;
-using osu.Game.Graphics.Containers;
-using osu.Game.Graphics.Sprites;
-using osu.Game.Graphics.UserInterface;
-using osu.Game.Overlays;
-using osu.Framework.Extensions;
-
-namespace osu.Game.Users.Drawables
-{
- public partial class UpdateableCountryText : OsuHoverContainer
- {
-
- public bool ShowPlaceholderOnUnknown = true;
-
- [Resolved]
- private RankingsOverlay? rankingsOverlay { get; set; }
- public UpdateableCountryText()
- {
- AutoSizeAxes = Axes.Both;
- }
-
- // [BackgroundDependencyLoader]
- public void load(CountryCode countryCode)
- {
- Action = () =>
- {
- rankingsOverlay?.ShowCountry(countryCode);
- };
-
- Child = new OsuSpriteText
- {
- Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular),
- Text = countryCode.GetDescription(),
- };
- }
- }
-
-}
\ No newline at end of file
From 4d144cd5b5fb3e787fd51b75cef459bfab56fbf4 Mon Sep 17 00:00:00 2001
From: _ltn <46729135+rltn@users.noreply.github.com>
Date: Fri, 28 Apr 2023 02:06:13 +0300
Subject: [PATCH 30/41] clearing the code
---
.../Profile/Header/TopHeaderContainer.cs | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)
diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
index 54c84e08b8..3485037925 100644
--- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
@@ -9,8 +9,10 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
+using osu.Framework.Graphics.Sprites;
using osu.Game.Configuration;
using osu.Game.Graphics;
+using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
@@ -20,19 +22,6 @@ using osu.Game.Users.Drawables;
using osuTK;
-using System;
-// using osu.Framework.Allocation;
-using osu.Framework.Input.Events;
-// using osu.Framework.Graphics;
-// using osu.Framework.Graphics.Containers;
-// using osu.Game.Graphics;
-using osu.Game.Graphics.Containers;
-// using osu.Game.Graphics.Sprites;
-// using osu.Game.Graphics.UserInterface;
-using osu.Game.Overlays;
-using osu.Framework.Graphics.Sprites;
-// using osu.Framework.Extensions;
-
namespace osu.Game.Overlays.Profile.Header
{
public partial class TopHeaderContainer : CompositeDrawable
@@ -246,10 +235,12 @@ namespace osu.Game.Overlays.Profile.Header
private partial class UpdateableCountryText : OsuHoverContainer
{
- public bool ShowPlaceholderOnUnknown = true;
+
public FontUsage Font = default;
+
[Resolved]
private RankingsOverlay? rankingsOverlay { get; set; }
+
public UpdateableCountryText()
{
AutoSizeAxes = Axes.Both;
From 17730f05bcf42c6af0c8876c46ae218adf71bb32 Mon Sep 17 00:00:00 2001
From: _ltn <46729135+rltn@users.noreply.github.com>
Date: Fri, 28 Apr 2023 05:47:05 +0300
Subject: [PATCH 31/41] remove UpdateableCountryText
---
.../Profile/Header/TopHeaderContainer.cs | 31 -------------------
1 file changed, 31 deletions(-)
diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
index 3485037925..01fbf137d8 100644
--- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
@@ -21,7 +21,6 @@ using osu.Game.Users;
using osu.Game.Users.Drawables;
using osuTK;
-
namespace osu.Game.Overlays.Profile.Header
{
public partial class TopHeaderContainer : CompositeDrawable
@@ -41,7 +40,6 @@ namespace osu.Game.Overlays.Profile.Header
private ExternalLinkButton openUserExternally = null!;
private OsuSpriteText titleText = null!;
private UpdateableFlag userFlag = null!;
- private UpdateableCountryText userCountryText = null!;
private GroupBadgeFlow groupBadgeFlow = null!;
private ToggleCoverButton coverToggle = null!;
@@ -204,7 +202,6 @@ namespace osu.Game.Overlays.Profile.Header
usernameText.Text = user?.Username ?? string.Empty;
openUserExternally.Link = $@"{api.WebsiteRootUrl}/users/{user?.Id ?? 0}";
userFlag.CountryCode = user?.CountryCode ?? default;
- userCountryText.load(user?.CountryCode ?? default);
supporterTag.SupportLevel = user?.SupportLevel ?? 0;
titleText.Text = user?.Title ?? string.Empty;
titleText.Colour = Color4Extensions.FromHex(user?.Colour ?? "fff");
@@ -232,33 +229,5 @@ namespace osu.Game.Overlays.Profile.Header
Masking = true;
}
}
-
- private partial class UpdateableCountryText : OsuHoverContainer
- {
-
- public FontUsage Font = default;
-
- [Resolved]
- private RankingsOverlay? rankingsOverlay { get; set; }
-
- public UpdateableCountryText()
- {
- AutoSizeAxes = Axes.Both;
- }
-
- public void load(CountryCode countryCode)
- {
- Action = () =>
- {
- rankingsOverlay?.ShowCountry(countryCode);
- };
-
- Child = new OsuSpriteText
- {
- Font = Font,
- Text = countryCode.GetDescription(),
- };
- }
- }
}
}
From 4b0ee392f6d5bb6ec29a0c014fdc199543475e40 Mon Sep 17 00:00:00 2001
From: _ltn <46729135+rltn@users.noreply.github.com>
Date: Fri, 28 Apr 2023 05:48:54 +0300
Subject: [PATCH 32/41] add OsuHoverContainer
---
.../Profile/Header/TopHeaderContainer.cs | 20 ++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
index 01fbf137d8..618e487dc3 100644
--- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
@@ -33,6 +33,9 @@ namespace osu.Game.Overlays.Profile.Header
[Resolved]
private IAPIProvider api { get; set; } = null!;
+ [Resolved]
+ private RankingsOverlay? rankingsOverlay { get; set; }
+
private UserCoverBackground cover = null!;
private SupporterIcon supporterTag = null!;
private UpdateableAvatar avatar = null!;
@@ -40,6 +43,8 @@ namespace osu.Game.Overlays.Profile.Header
private ExternalLinkButton openUserExternally = null!;
private OsuSpriteText titleText = null!;
private UpdateableFlag userFlag = null!;
+ private OsuHoverContainer userCountryContainer = null!;
+ private OsuSpriteText userCountryText = null!;
private GroupBadgeFlow groupBadgeFlow = null!;
private ToggleCoverButton coverToggle = null!;
@@ -157,13 +162,20 @@ namespace osu.Game.Overlays.Profile.Header
Size = new Vector2(28, 20),
ShowPlaceholderOnUnknown = false,
},
- userCountryText = new UpdateableCountryText
+ userCountryContainer = new OsuHoverContainer
{
- Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular),
Margin = new MarginPadding { Left = 5 },
Origin = Anchor.CentreLeft,
Anchor = Anchor.CentreLeft,
- }
+ AutoSizeAxes = Axes.Both,
+ Children = new Drawable[]
+ {
+ userCountryText = new OsuSpriteText
+ {
+ Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular),
+ },
+ },
+ },
}
},
}
@@ -202,6 +214,8 @@ namespace osu.Game.Overlays.Profile.Header
usernameText.Text = user?.Username ?? string.Empty;
openUserExternally.Link = $@"{api.WebsiteRootUrl}/users/{user?.Id ?? 0}";
userFlag.CountryCode = user?.CountryCode ?? default;
+ userCountryText.Text = (user?.CountryCode ?? default).GetDescription();
+ userCountryContainer.Action = () => rankingsOverlay?.ShowCountry(user?.CountryCode ?? default);
supporterTag.SupportLevel = user?.SupportLevel ?? 0;
titleText.Text = user?.Title ?? string.Empty;
titleText.Colour = Color4Extensions.FromHex(user?.Colour ?? "fff");
From 6929be49b707568074899d822c4df0d3e053cc2d Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Fri, 28 Apr 2023 22:35:55 +0900
Subject: [PATCH 33/41] Change condition for exclusive fullscreen notice to
only show when using the correct renderer
This avoids the notice showing when running on windows, but using the
newer renderers (where the underlying logic hasn't been tested properly
and can result in false-positives).
Supersedes https://github.com/ppy/osu-framework/pull/5759 as a more
correct implementation.
---
osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs
index 2765d2b437..a46205d40d 100644
--- a/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/Graphics/LayoutSettings.cs
@@ -256,7 +256,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
return;
}
- if (host.Window is WindowsWindow)
+ if (host.Renderer is IWindowsRenderer)
{
switch (fullscreenCapability.Value)
{
From 2d6c0d2900be5779bc1ceea643458372c403daeb Mon Sep 17 00:00:00 2001
From: _ltn <46729135+rltn@users.noreply.github.com>
Date: Fri, 28 Apr 2023 19:24:07 +0300
Subject: [PATCH 34/41] use of Child instead of Children
---
.../Overlays/Profile/Header/TopHeaderContainer.cs | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
index 618e487dc3..de678cb5d1 100644
--- a/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/TopHeaderContainer.cs
@@ -9,7 +9,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Graphics.Sprites;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
@@ -164,16 +163,13 @@ namespace osu.Game.Overlays.Profile.Header
},
userCountryContainer = new OsuHoverContainer
{
- Margin = new MarginPadding { Left = 5 },
- Origin = Anchor.CentreLeft,
- Anchor = Anchor.CentreLeft,
AutoSizeAxes = Axes.Both,
- Children = new Drawable[]
+ Anchor = Anchor.CentreLeft,
+ Origin = Anchor.CentreLeft,
+ Margin = new MarginPadding { Left = 5 },
+ Child = userCountryText = new OsuSpriteText
{
- userCountryText = new OsuSpriteText
- {
- Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular),
- },
+ Font = OsuFont.GetFont(size: 14f, weight: FontWeight.Regular),
},
},
}
From 607a04ae7319b823da095c948be9897767ff84bd Mon Sep 17 00:00:00 2001
From: Cootz
Date: Fri, 28 Apr 2023 17:45:00 +0300
Subject: [PATCH 35/41] Fix the issue
---
osu.Game/Screens/Edit/Editor.cs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs
index d89392f757..b5d304a031 100644
--- a/osu.Game/Screens/Edit/Editor.cs
+++ b/osu.Game/Screens/Edit/Editor.cs
@@ -210,7 +210,10 @@ namespace osu.Game.Screens.Edit
// this is a bit haphazard, but guards against setting the lease Beatmap bindable if
// the editor has already been exited.
if (!ValidForPush)
+ {
+ beatmapManager.Delete(loadableBeatmap.BeatmapSetInfo);
return;
+ }
}
try
From c5357d30ab0c545a7eb4dd652eeefcb828c1f433 Mon Sep 17 00:00:00 2001
From: Cootz
Date: Fri, 28 Apr 2023 20:36:31 +0300
Subject: [PATCH 36/41] Add test
---
.../Navigation/TestSceneBeatmapEditor.cs | 57 +++++++++++++++++++
1 file changed, 57 insertions(+)
create mode 100644 osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs
new file mode 100644
index 0000000000..67835ed0f5
--- /dev/null
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs
@@ -0,0 +1,57 @@
+// 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.Linq;
+using System.Threading.Tasks;
+using DeepEqual.Syntax;
+using NUnit.Framework;
+using osu.Framework.Screens;
+using osu.Game.Beatmaps;
+using osu.Game.Screens.Edit;
+using osu.Game.Screens.Menu;
+
+namespace osu.Game.Tests.Visual.Navigation
+{
+ public partial class TestSceneBeatmapEditor : OsuGameTestScene
+ {
+ [Test]
+ public void TestCancelNavigationToEditor()
+ {
+ BeatmapSetInfo[] beatmapSets = Array.Empty();
+
+ AddStep("Timestamp current beatmapsets", () =>
+ {
+ Game.Realm.Run(realm =>
+ {
+ beatmapSets = realm.All().Where(x => !x.DeletePending).ToArray();
+ });
+ });
+
+ AddStep("Open editor and close it while loading", () =>
+ {
+ var task = Task.Run(async () =>
+ {
+ await Task.Delay(100);
+ Game.ScreenStack.CurrentScreen.Exit();
+ });
+
+ Game.ScreenStack.Push(new EditorLoader());
+ });
+
+ AddUntilStep("wait for editor", () => Game.ScreenStack.CurrentScreen is MainMenu);
+
+ BeatmapSetInfo[] currentSetInfos = Array.Empty();
+
+ AddStep("Get current beatmaps", () =>
+ {
+ Game.Realm.Run(realm =>
+ {
+ currentSetInfos = realm.All().Where(x => !x.DeletePending).ToArray();
+ });
+ });
+
+ AddAssert("dummy beatmap didn't appear", () => currentSetInfos.IsDeepEqual(beatmapSets));
+ }
+ }
+}
From d9b3c97179d2f9fd5114909fcb323208ff630f22 Mon Sep 17 00:00:00 2001
From: Cootz
Date: Fri, 28 Apr 2023 21:23:00 +0300
Subject: [PATCH 37/41] Fix testing
---
.../Navigation/TestSceneBeatmapEditor.cs | 26 +++++++++++--------
1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs
index 67835ed0f5..9760fc2c97 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs
@@ -1,9 +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.Linq;
-using System.Threading.Tasks;
using DeepEqual.Syntax;
using NUnit.Framework;
using osu.Framework.Screens;
@@ -18,7 +16,7 @@ namespace osu.Game.Tests.Visual.Navigation
[Test]
public void TestCancelNavigationToEditor()
{
- BeatmapSetInfo[] beatmapSets = Array.Empty();
+ BeatmapSetInfo[]? beatmapSets = null;
AddStep("Timestamp current beatmapsets", () =>
{
@@ -28,20 +26,26 @@ namespace osu.Game.Tests.Visual.Navigation
});
});
- AddStep("Open editor and close it while loading", () =>
+ AddStep("Set current beatmap to default", () =>
{
- var task = Task.Run(async () =>
- {
- await Task.Delay(100);
- Game.ScreenStack.CurrentScreen.Exit();
- });
+ Game.Beatmap.SetDefault();
+ });
+ AddStep("Open editor loader", () =>
+ {
Game.ScreenStack.Push(new EditorLoader());
});
+ AddUntilStep("wait for editor", () => Game.ScreenStack.CurrentScreen is EditorLoader);
+
+ AddStep("close editor while loading", () =>
+ {
+ Game.ScreenStack.CurrentScreen.Exit();
+ });
+
AddUntilStep("wait for editor", () => Game.ScreenStack.CurrentScreen is MainMenu);
- BeatmapSetInfo[] currentSetInfos = Array.Empty();
+ BeatmapSetInfo[]? currentSetInfos = null;
AddStep("Get current beatmaps", () =>
{
@@ -51,7 +55,7 @@ namespace osu.Game.Tests.Visual.Navigation
});
});
- AddAssert("dummy beatmap didn't appear", () => currentSetInfos.IsDeepEqual(beatmapSets));
+ AddAssert("dummy beatmap didn't appear", () => currentSetInfos.IsDeepEqual(beatmapSets) && currentSetInfos is not null);
}
}
}
From 428b5fad3c45a545820d3fec8e06e9ce05803020 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Sat, 29 Apr 2023 10:34:50 +0900
Subject: [PATCH 38/41] Rename test scene to explicitly mention navigation
testing
---
...ceneBeatmapEditor.cs => TestSceneBeatmapEditorNavigation.cs} | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
rename osu.Game.Tests/Visual/Navigation/{TestSceneBeatmapEditor.cs => TestSceneBeatmapEditorNavigation.cs} (96%)
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs
similarity index 96%
rename from osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs
rename to osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs
index 9760fc2c97..e1fba1d630 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditor.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs
@@ -11,7 +11,7 @@ using osu.Game.Screens.Menu;
namespace osu.Game.Tests.Visual.Navigation
{
- public partial class TestSceneBeatmapEditor : OsuGameTestScene
+ public partial class TestSceneBeatmapEditorNavigation : OsuGameTestScene
{
[Test]
public void TestCancelNavigationToEditor()
From a6f01861124b3ba119c830c43178af95945864ad Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Sat, 29 Apr 2023 10:49:25 +0900
Subject: [PATCH 39/41] Improve legibility and code quality of new test
---
.../TestSceneBeatmapEditorNavigation.cs | 48 ++++++-------------
1 file changed, 14 insertions(+), 34 deletions(-)
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs
index e1fba1d630..c76758e6c6 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs
@@ -16,46 +16,26 @@ namespace osu.Game.Tests.Visual.Navigation
[Test]
public void TestCancelNavigationToEditor()
{
- BeatmapSetInfo[]? beatmapSets = null;
+ BeatmapSetInfo[] beatmapSets = null!;
- AddStep("Timestamp current beatmapsets", () =>
+ AddStep("Fetch initial beatmaps", () =>
{
- Game.Realm.Run(realm =>
- {
- beatmapSets = realm.All().Where(x => !x.DeletePending).ToArray();
- });
+ beatmapSets = Game.Realm.Run(realm => realm.All().Where(x => !x.DeletePending).ToArray());
});
- AddStep("Set current beatmap to default", () =>
+ AddStep("Set current beatmap to default", () => Game.Beatmap.SetDefault());
+
+ AddStep("Push editor loader", () => Game.ScreenStack.Push(new EditorLoader()));
+ AddUntilStep("Wait for loader current", () => Game.ScreenStack.CurrentScreen is EditorLoader);
+ AddStep("Close editor while loading", () => Game.ScreenStack.CurrentScreen.Exit());
+
+ AddUntilStep("Wait for menu", () => Game.ScreenStack.CurrentScreen is MainMenu);
+
+ AddAssert("Check no new beatmaps were made", () =>
{
- Game.Beatmap.SetDefault();
+ var beatmapSetsAfter = Game.Realm.Run(realm => realm.All().Where(x => !x.DeletePending).ToArray());
+ return beatmapSetsAfter.SequenceEqual(beatmapSets);
});
-
- AddStep("Open editor loader", () =>
- {
- Game.ScreenStack.Push(new EditorLoader());
- });
-
- AddUntilStep("wait for editor", () => Game.ScreenStack.CurrentScreen is EditorLoader);
-
- AddStep("close editor while loading", () =>
- {
- Game.ScreenStack.CurrentScreen.Exit();
- });
-
- AddUntilStep("wait for editor", () => Game.ScreenStack.CurrentScreen is MainMenu);
-
- BeatmapSetInfo[]? currentSetInfos = null;
-
- AddStep("Get current beatmaps", () =>
- {
- Game.Realm.Run(realm =>
- {
- currentSetInfos = realm.All().Where(x => !x.DeletePending).ToArray();
- });
- });
-
- AddAssert("dummy beatmap didn't appear", () => currentSetInfos.IsDeepEqual(beatmapSets) && currentSetInfos is not null);
}
}
}
From 32f8c674f4d751937db57082cc872bc38a1c7bed Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Sat, 29 Apr 2023 11:01:29 +0900
Subject: [PATCH 40/41] Extract beatmap retrieval method for more legibility
---
.../Navigation/TestSceneBeatmapEditorNavigation.cs | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs
index c76758e6c6..554da36cc4 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
-using DeepEqual.Syntax;
using NUnit.Framework;
using osu.Framework.Screens;
using osu.Game.Beatmaps;
@@ -18,10 +17,7 @@ namespace osu.Game.Tests.Visual.Navigation
{
BeatmapSetInfo[] beatmapSets = null!;
- AddStep("Fetch initial beatmaps", () =>
- {
- beatmapSets = Game.Realm.Run(realm => realm.All().Where(x => !x.DeletePending).ToArray());
- });
+ AddStep("Fetch initial beatmaps", () => beatmapSets = allBeatmapSets());
AddStep("Set current beatmap to default", () => Game.Beatmap.SetDefault());
@@ -30,12 +26,9 @@ namespace osu.Game.Tests.Visual.Navigation
AddStep("Close editor while loading", () => Game.ScreenStack.CurrentScreen.Exit());
AddUntilStep("Wait for menu", () => Game.ScreenStack.CurrentScreen is MainMenu);
+ AddAssert("Check no new beatmaps were made", () => allBeatmapSets().SequenceEqual(beatmapSets));
- AddAssert("Check no new beatmaps were made", () =>
- {
- var beatmapSetsAfter = Game.Realm.Run(realm => realm.All().Where(x => !x.DeletePending).ToArray());
- return beatmapSetsAfter.SequenceEqual(beatmapSets);
- });
+ BeatmapSetInfo[] allBeatmapSets() => Game.Realm.Run(realm => realm.All().Where(x => !x.DeletePending).ToArray());
}
}
}
From 26431006448c9d192ac5931fc1fc3cf10f76c2a9 Mon Sep 17 00:00:00 2001
From: Dean Herbert
Date: Sat, 29 Apr 2023 11:05:10 +0900
Subject: [PATCH 41/41] Add xmldoc to new test mentioning failure rate and
general purpose
---
.../Visual/Navigation/TestSceneBeatmapEditorNavigation.cs | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs
index 554da36cc4..603573058e 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneBeatmapEditorNavigation.cs
@@ -12,6 +12,14 @@ namespace osu.Game.Tests.Visual.Navigation
{
public partial class TestSceneBeatmapEditorNavigation : OsuGameTestScene
{
+ ///
+ /// When entering the editor, a new beatmap is created as part of the asynchronous load process.
+ /// This test ensures that in the case of an early exit from the editor (ie. while it's still loading)
+ /// doesn't leave a dangling beatmap behind.
+ ///
+ /// This may not fail 100% due to timing, but has a pretty high chance of hitting a failure so works well enough
+ /// as a test.
+ ///
[Test]
public void TestCancelNavigationToEditor()
{