From 4339e2dc4afb5035221398a88cc04f6718d8d523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 12 Jun 2024 12:41:07 +0200 Subject: [PATCH 01/54] Move `AudioLeadIn` out of `BeatmapInfo` --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 4 ++-- osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestSceneLeadIn.cs | 4 ++-- osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs | 2 +- .../Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs | 4 ++-- osu.Game/Beatmaps/Beatmap.cs | 2 ++ osu.Game/Beatmaps/BeatmapConverter.cs | 1 + osu.Game/Beatmaps/BeatmapImporter.cs | 1 - osu.Game/Beatmaps/BeatmapInfo.cs | 2 -- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 2 +- osu.Game/Beatmaps/IBeatmap.cs | 2 ++ osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs | 6 ++++++ osu.Game/Screens/Edit/EditorBeatmap.cs | 6 ++++++ osu.Game/Screens/Play/MasterGameplayClockContainer.cs | 4 ++-- 16 files changed, 30 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index a4cd888823..9ffb3327b9 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -80,7 +80,7 @@ namespace osu.Game.Tests.Beatmaps.Formats var metadata = beatmap.Metadata; Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", metadata.AudioFile); - Assert.AreEqual(0, beatmapInfo.AudioLeadIn); + Assert.AreEqual(0, beatmap.AudioLeadIn); Assert.AreEqual(164471, metadata.PreviewTime); Assert.AreEqual(0.7f, beatmapInfo.StackLeniency); Assert.IsTrue(beatmapInfo.Ruleset.OnlineID == 0); @@ -950,7 +950,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.Multiple(() => { - Assert.That(decoded.BeatmapInfo.AudioLeadIn, Is.EqualTo(0)); + Assert.That(decoded.AudioLeadIn, Is.EqualTo(0)); Assert.That(decoded.BeatmapInfo.StackLeniency, Is.EqualTo(0.7f)); Assert.That(decoded.BeatmapInfo.SpecialStyle, Is.False); Assert.That(decoded.BeatmapInfo.LetterboxInBreaks, Is.False); diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 3764467047..3fd05b692d 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -51,7 +51,7 @@ namespace osu.Game.Tests.Beatmaps.Formats { var beatmap = decodeAsJson(normal); var beatmapInfo = beatmap.BeatmapInfo; - Assert.AreEqual(0, beatmapInfo.AudioLeadIn); + Assert.AreEqual(0, beatmap.AudioLeadIn); Assert.AreEqual(0.7f, beatmapInfo.StackLeniency); Assert.AreEqual(false, beatmapInfo.SpecialStyle); Assert.IsTrue(beatmapInfo.Ruleset.OnlineID == 0); diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneLeadIn.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneLeadIn.cs index 5a71369976..a6b8e679b9 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneLeadIn.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneLeadIn.cs @@ -31,7 +31,7 @@ namespace osu.Game.Tests.Visual.Gameplay { loadPlayerWithBeatmap(new TestBeatmap(new OsuRuleset().RulesetInfo) { - BeatmapInfo = { AudioLeadIn = leadIn } + AudioLeadIn = leadIn }); checkFirstFrameTime(expectedStartTime); @@ -130,7 +130,7 @@ namespace osu.Game.Tests.Visual.Gameplay { Text = $"GameplayStartTime: {DrawableRuleset.GameplayStartTime} " + $"FirstHitObjectTime: {FirstHitObjectTime} " - + $"LeadInTime: {Beatmap.Value.BeatmapInfo.AudioLeadIn} " + + $"LeadInTime: {Beatmap.Value.Beatmap.AudioLeadIn} " + $"FirstFrameClockTime: {FirstFrameClockTime}" }); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index 1949808dfe..c17405c2ec 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -135,7 +135,7 @@ namespace osu.Game.Tests.Visual.Gameplay var workingBeatmap = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo); // Add intro time to test quick retry skipping (TestQuickRetry). - workingBeatmap.BeatmapInfo.AudioLeadIn = 60000; + workingBeatmap.Beatmap.AudioLeadIn = 60000; // Set up data for testing disclaimer display. workingBeatmap.BeatmapInfo.EpilepsyWarning = epilepsyWarning ?? false; diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs index ae10207de0..81dd23661c 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneReplayPlayer.cs @@ -63,7 +63,7 @@ namespace osu.Game.Tests.Visual.Gameplay { loadPlayerWithBeatmap(new TestBeatmap(new OsuRuleset().RulesetInfo) { - BeatmapInfo = { AudioLeadIn = 60000 } + AudioLeadIn = 60000 }); AddUntilStep("wait for skip overlay", () => Player.ChildrenOfType().First().IsButtonVisible); diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs index 2b17f91e68..6108260481 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiSpectatorScreen.cs @@ -406,13 +406,13 @@ namespace osu.Game.Tests.Visual.Multiplayer } /// - /// Tests spectating with a beatmap that has a high value. + /// Tests spectating with a beatmap that has a high value. /// /// This test is not intended not to check the correct initial time value, but only to guard against /// gameplay potentially getting stuck in a stopped state due to lead in time being present. /// [Test] - public void TestAudioLeadIn() => testLeadIn(b => b.BeatmapInfo.AudioLeadIn = 2000); + public void TestAudioLeadIn() => testLeadIn(b => b.Beatmap.AudioLeadIn = 2000); /// /// Tests spectating with a beatmap that has a storyboard element with a negative start time (i.e. intro storyboard element). diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index ae77e4adcf..f3ad02558a 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -114,6 +114,8 @@ namespace osu.Game.Beatmaps return mostCommon.beatLength; } + public double AudioLeadIn { get; set; } + IBeatmap IBeatmap.Clone() => Clone(); public Beatmap Clone() => (Beatmap)MemberwiseClone(); diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index b68c80d4b3..f33cdaf81f 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -67,6 +67,7 @@ namespace osu.Game.Beatmaps beatmap.HitObjects = convertHitObjects(original.HitObjects, original, cancellationToken).OrderBy(s => s.StartTime).ToList(); beatmap.Breaks = original.Breaks; beatmap.UnhandledEventLines = original.UnhandledEventLines; + beatmap.AudioLeadIn = original.AudioLeadIn; return beatmap; } diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index 2137f33e77..b8e253527b 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -414,7 +414,6 @@ namespace osu.Game.Beatmaps Hash = hash, DifficultyName = decodedInfo.DifficultyName, OnlineID = decodedInfo.OnlineID, - AudioLeadIn = decodedInfo.AudioLeadIn, StackLeniency = decodedInfo.StackLeniency, SpecialStyle = decodedInfo.SpecialStyle, LetterboxInBreaks = decodedInfo.LetterboxInBreaks, diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 425fd98d27..e1580dc74e 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -138,8 +138,6 @@ namespace osu.Game.Beatmaps #region Properties we may not want persisted (but also maybe no harm?) - public double AudioLeadIn { get; set; } - public float StackLeniency { get; set; } = 0.7f; public bool SpecialStyle { get; set; } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index c2f4097889..5966658c93 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -238,7 +238,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"AudioLeadIn": - beatmap.BeatmapInfo.AudioLeadIn = Parsing.ParseInt(pair.Value); + beatmap.AudioLeadIn = Parsing.ParseInt(pair.Value); break; case @"PreviewTime": diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 186b565c39..072223c8fb 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -79,7 +79,7 @@ namespace osu.Game.Beatmaps.Formats writer.WriteLine("[General]"); if (!string.IsNullOrEmpty(beatmap.Metadata.AudioFile)) writer.WriteLine(FormattableString.Invariant($"AudioFilename: {Path.GetFileName(beatmap.Metadata.AudioFile)}")); - writer.WriteLine(FormattableString.Invariant($"AudioLeadIn: {beatmap.BeatmapInfo.AudioLeadIn}")); + writer.WriteLine(FormattableString.Invariant($"AudioLeadIn: {beatmap.AudioLeadIn}")); writer.WriteLine(FormattableString.Invariant($"PreviewTime: {beatmap.Metadata.PreviewTime}")); writer.WriteLine(FormattableString.Invariant($"Countdown: {(int)beatmap.BeatmapInfo.Countdown}")); writer.WriteLine(FormattableString.Invariant( diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index 5cc38e5b84..993155a32e 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -68,6 +68,8 @@ namespace osu.Game.Beatmaps /// double GetMostCommonBeatLength(); + double AudioLeadIn { get; internal set; } + /// /// Creates a shallow-clone of this beatmap and returns it. /// diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index d37cfc28b9..5557051f05 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -337,6 +337,12 @@ namespace osu.Game.Rulesets.Difficulty public double GetMostCommonBeatLength() => baseBeatmap.GetMostCommonBeatLength(); public IBeatmap Clone() => new ProgressiveCalculationBeatmap(baseBeatmap.Clone()); + public double AudioLeadIn + { + get => baseBeatmap.AudioLeadIn; + set => baseBeatmap.AudioLeadIn = value; + } + #endregion } } diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 5be1d27805..7392c66a26 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -184,6 +184,12 @@ namespace osu.Game.Screens.Edit public double GetMostCommonBeatLength() => PlayableBeatmap.GetMostCommonBeatLength(); + public double AudioLeadIn + { + get => PlayableBeatmap.AudioLeadIn; + set => PlayableBeatmap.AudioLeadIn = value; + } + public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone(); private IList mutableHitObjects => (IList)PlayableBeatmap.HitObjects; diff --git a/osu.Game/Screens/Play/MasterGameplayClockContainer.cs b/osu.Game/Screens/Play/MasterGameplayClockContainer.cs index b2f0ae5561..3851806788 100644 --- a/osu.Game/Screens/Play/MasterGameplayClockContainer.cs +++ b/osu.Game/Screens/Play/MasterGameplayClockContainer.cs @@ -95,8 +95,8 @@ namespace osu.Game.Screens.Play // some beatmaps specify a current lead-in time which should be used instead of the ruleset-provided value when available. // this is not available as an option in the live editor but can still be applied via .osu editing. double firstHitObjectTime = beatmap.Beatmap.HitObjects.First().StartTime; - if (beatmap.BeatmapInfo.AudioLeadIn > 0) - time = Math.Min(time, firstHitObjectTime - beatmap.BeatmapInfo.AudioLeadIn); + if (beatmap.Beatmap.AudioLeadIn > 0) + time = Math.Min(time, firstHitObjectTime - beatmap.Beatmap.AudioLeadIn); return time; } From 0a4560a03e0c5dfccecc6be661586d378d3b88aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 12 Jun 2024 12:50:41 +0200 Subject: [PATCH 02/54] Move `StackLeniency` out of `BeatmapInfo` --- .../Mods/TestSceneOsuModFlashlight.cs | 5 +---- .../Mods/TestSceneOsuModRandom.cs | 2 +- .../TestSceneSliderLateHitJudgement.cs | 2 +- .../Beatmaps/OsuBeatmapProcessor.cs | 14 +++++++------- .../Edit/Setup/OsuSetupSection.cs | 4 ++-- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 4 ++-- .../Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- osu.Game/Beatmaps/Beatmap.cs | 2 ++ osu.Game/Beatmaps/BeatmapConverter.cs | 1 + osu.Game/Beatmaps/BeatmapImporter.cs | 1 - osu.Game/Beatmaps/BeatmapInfo.cs | 2 -- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 2 +- osu.Game/Beatmaps/IBeatmap.cs | 2 ++ .../Rulesets/Difficulty/DifficultyCalculator.cs | 6 ++++++ osu.Game/Screens/Edit/EditorBeatmap.cs | 6 ++++++ 16 files changed, 34 insertions(+), 23 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFlashlight.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFlashlight.cs index 075fdd88ca..1a3b0310f7 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFlashlight.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModFlashlight.cs @@ -83,10 +83,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods }) } }, - BeatmapInfo = - { - StackLeniency = 0, - } + StackLeniency = 0, }, ReplayFrames = new List { diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModRandom.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModRandom.cs index 060a845137..75a5d36f32 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModRandom.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModRandom.cs @@ -74,12 +74,12 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods { BeatmapInfo = new BeatmapInfo { - StackLeniency = 0, Difficulty = new BeatmapDifficulty { ApproachRate = 8.5f } }, + StackLeniency = 0, ControlPointInfo = controlPointInfo }; diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderLateHitJudgement.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderLateHitJudgement.cs index 1ba4a60b75..d089e924ca 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderLateHitJudgement.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderLateHitJudgement.cs @@ -465,7 +465,7 @@ namespace osu.Game.Rulesets.Osu.Tests private void performTest(List frames, Beatmap beatmap) { beatmap.BeatmapInfo.Ruleset = new OsuRuleset().RulesetInfo; - beatmap.BeatmapInfo.StackLeniency = 0; + beatmap.StackLeniency = 0; beatmap.BeatmapInfo.Difficulty = new BeatmapDifficulty { SliderMultiplier = 4, diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index d335913586..9cc22b764f 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -51,13 +51,13 @@ namespace osu.Game.Rulesets.Osu.Beatmaps h.StackHeight = 0; if (Beatmap.BeatmapInfo.BeatmapVersion >= 6) - applyStacking(Beatmap.BeatmapInfo, hitObjects, 0, hitObjects.Count - 1); + applyStacking(Beatmap, hitObjects, 0, hitObjects.Count - 1); else - applyStackingOld(Beatmap.BeatmapInfo, hitObjects); + applyStackingOld(Beatmap, hitObjects); } } - private void applyStacking(BeatmapInfo beatmapInfo, List hitObjects, int startIndex, int endIndex) + private void applyStacking(IBeatmap beatmap, List hitObjects, int startIndex, int endIndex) { ArgumentOutOfRangeException.ThrowIfGreaterThan(startIndex, endIndex); ArgumentOutOfRangeException.ThrowIfNegative(startIndex); @@ -82,7 +82,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps continue; double endTime = stackBaseObject.GetEndTime(); - double stackThreshold = objectN.TimePreempt * beatmapInfo.StackLeniency; + double stackThreshold = objectN.TimePreempt * beatmap.StackLeniency; if (objectN.StartTime - endTime > stackThreshold) // We are no longer within stacking range of the next object. @@ -127,7 +127,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps OsuHitObject objectI = hitObjects[i]; if (objectI.StackHeight != 0 || objectI is Spinner) continue; - double stackThreshold = objectI.TimePreempt * beatmapInfo.StackLeniency; + double stackThreshold = objectI.TimePreempt * beatmap.StackLeniency; /* If this object is a hitcircle, then we enter this "special" case. * It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider. @@ -209,7 +209,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps } } - private void applyStackingOld(BeatmapInfo beatmapInfo, List hitObjects) + private void applyStackingOld(IBeatmap beatmap, List hitObjects) { for (int i = 0; i < hitObjects.Count; i++) { @@ -223,7 +223,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps for (int j = i + 1; j < hitObjects.Count; j++) { - double stackThreshold = hitObjects[i].TimePreempt * beatmapInfo.StackLeniency; + double stackThreshold = hitObjects[i].TimePreempt * beatmap.StackLeniency; if (hitObjects[j].StartTime - stackThreshold > startTime) break; diff --git a/osu.Game.Rulesets.Osu/Edit/Setup/OsuSetupSection.cs b/osu.Game.Rulesets.Osu/Edit/Setup/OsuSetupSection.cs index 552b887081..e1a588a32a 100644 --- a/osu.Game.Rulesets.Osu/Edit/Setup/OsuSetupSection.cs +++ b/osu.Game.Rulesets.Osu/Edit/Setup/OsuSetupSection.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Setup { Label = "Stack Leniency", Description = "In play mode, osu! automatically stacks notes which occur at the same location. Increasing this value means it is more likely to snap notes of further time-distance.", - Current = new BindableFloat(Beatmap.BeatmapInfo.StackLeniency) + Current = new BindableFloat(Beatmap.StackLeniency) { Default = 0.7f, MinValue = 0, @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Setup private void updateBeatmap() { - Beatmap.BeatmapInfo.StackLeniency = stackLeniency.Current.Value; + Beatmap.StackLeniency = stackLeniency.Current.Value; Beatmap.UpdateAllHitObjects(); Beatmap.SaveState(); } diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 9ffb3327b9..565c481920 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -82,7 +82,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", metadata.AudioFile); Assert.AreEqual(0, beatmap.AudioLeadIn); Assert.AreEqual(164471, metadata.PreviewTime); - Assert.AreEqual(0.7f, beatmapInfo.StackLeniency); + Assert.AreEqual(0.7f, beatmap.StackLeniency); Assert.IsTrue(beatmapInfo.Ruleset.OnlineID == 0); Assert.IsFalse(beatmapInfo.LetterboxInBreaks); Assert.IsFalse(beatmapInfo.SpecialStyle); @@ -951,7 +951,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.Multiple(() => { Assert.That(decoded.AudioLeadIn, Is.EqualTo(0)); - Assert.That(decoded.BeatmapInfo.StackLeniency, Is.EqualTo(0.7f)); + Assert.That(decoded.StackLeniency, Is.EqualTo(0.7f)); Assert.That(decoded.BeatmapInfo.SpecialStyle, Is.False); Assert.That(decoded.BeatmapInfo.LetterboxInBreaks, Is.False); Assert.That(decoded.BeatmapInfo.WidescreenStoryboard, Is.False); diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 3fd05b692d..5d2d9e006e 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -52,7 +52,7 @@ namespace osu.Game.Tests.Beatmaps.Formats var beatmap = decodeAsJson(normal); var beatmapInfo = beatmap.BeatmapInfo; Assert.AreEqual(0, beatmap.AudioLeadIn); - Assert.AreEqual(0.7f, beatmapInfo.StackLeniency); + Assert.AreEqual(0.7f, beatmap.StackLeniency); Assert.AreEqual(false, beatmapInfo.SpecialStyle); Assert.IsTrue(beatmapInfo.Ruleset.OnlineID == 0); Assert.AreEqual(false, beatmapInfo.LetterboxInBreaks); diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index f3ad02558a..ecee6e3416 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -116,6 +116,8 @@ namespace osu.Game.Beatmaps public double AudioLeadIn { get; set; } + public float StackLeniency { get; set; } = 0.7f; + IBeatmap IBeatmap.Clone() => Clone(); public Beatmap Clone() => (Beatmap)MemberwiseClone(); diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index f33cdaf81f..a5e9025404 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -68,6 +68,7 @@ namespace osu.Game.Beatmaps beatmap.Breaks = original.Breaks; beatmap.UnhandledEventLines = original.UnhandledEventLines; beatmap.AudioLeadIn = original.AudioLeadIn; + beatmap.StackLeniency = original.StackLeniency; return beatmap; } diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index b8e253527b..e589b0a754 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -414,7 +414,6 @@ namespace osu.Game.Beatmaps Hash = hash, DifficultyName = decodedInfo.DifficultyName, OnlineID = decodedInfo.OnlineID, - StackLeniency = decodedInfo.StackLeniency, SpecialStyle = decodedInfo.SpecialStyle, LetterboxInBreaks = decodedInfo.LetterboxInBreaks, WidescreenStoryboard = decodedInfo.WidescreenStoryboard, diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index e1580dc74e..fa2911438b 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -138,8 +138,6 @@ namespace osu.Game.Beatmaps #region Properties we may not want persisted (but also maybe no harm?) - public float StackLeniency { get; set; } = 0.7f; - public bool SpecialStyle { get; set; } public bool LetterboxInBreaks { get; set; } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 5966658c93..86552b21dd 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -255,7 +255,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"StackLeniency": - beatmap.BeatmapInfo.StackLeniency = Parsing.ParseFloat(pair.Value); + beatmap.StackLeniency = Parsing.ParseFloat(pair.Value); break; case @"Mode": diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 072223c8fb..8c371026ff 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -84,7 +84,7 @@ namespace osu.Game.Beatmaps.Formats writer.WriteLine(FormattableString.Invariant($"Countdown: {(int)beatmap.BeatmapInfo.Countdown}")); writer.WriteLine(FormattableString.Invariant( $"SampleSet: {toLegacySampleBank(((beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePoints.FirstOrDefault() ?? SampleControlPoint.DEFAULT).SampleBank)}")); - writer.WriteLine(FormattableString.Invariant($"StackLeniency: {beatmap.BeatmapInfo.StackLeniency}")); + writer.WriteLine(FormattableString.Invariant($"StackLeniency: {beatmap.StackLeniency}")); writer.WriteLine(FormattableString.Invariant($"Mode: {onlineRulesetID}")); writer.WriteLine(FormattableString.Invariant($"LetterboxInBreaks: {(beatmap.BeatmapInfo.LetterboxInBreaks ? '1' : '0')}")); // if (beatmap.BeatmapInfo.UseSkinSprites) diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index 993155a32e..28d601620a 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -70,6 +70,8 @@ namespace osu.Game.Beatmaps double AudioLeadIn { get; internal set; } + float StackLeniency { get; internal set; } + /// /// Creates a shallow-clone of this beatmap and returns it. /// diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index 5557051f05..616d6d0848 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -343,6 +343,12 @@ namespace osu.Game.Rulesets.Difficulty set => baseBeatmap.AudioLeadIn = value; } + public float StackLeniency + { + get => baseBeatmap.StackLeniency; + set => baseBeatmap.StackLeniency = value; + } + #endregion } } diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 7392c66a26..c02a22ae03 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -190,6 +190,12 @@ namespace osu.Game.Screens.Edit set => PlayableBeatmap.AudioLeadIn = value; } + public float StackLeniency + { + get => PlayableBeatmap.StackLeniency; + set => PlayableBeatmap.StackLeniency = value; + } + public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone(); private IList mutableHitObjects => (IList)PlayableBeatmap.HitObjects; From 011c2e3651fe1485eca8663697630777a848a440 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 12 Jun 2024 13:12:30 +0200 Subject: [PATCH 03/54] Move `SpecialStyle` out of `BeatmapInfo` --- osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs | 4 ++-- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 4 ++-- osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- osu.Game/Beatmaps/Beatmap.cs | 2 ++ osu.Game/Beatmaps/BeatmapConverter.cs | 1 + osu.Game/Beatmaps/BeatmapImporter.cs | 1 - osu.Game/Beatmaps/BeatmapInfo.cs | 2 -- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 2 +- osu.Game/Beatmaps/IBeatmap.cs | 2 ++ osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs | 6 ++++++ osu.Game/Screens/Edit/EditorBeatmap.cs | 6 ++++++ 12 files changed, 24 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs b/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs index d5a9a311bc..8778c18c38 100644 --- a/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs +++ b/osu.Game.Rulesets.Mania/Edit/Setup/ManiaSetupSection.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Setup { Label = "Use special (N+1) style", Description = "Changes one column to act as a classic \"scratch\" or \"special\" column, which can be moved around by the user's skin (to the left/right/centre). Generally used in 6K (5+1) or 8K (7+1) configurations.", - Current = { Value = Beatmap.BeatmapInfo.SpecialStyle } + Current = { Value = Beatmap.SpecialStyle } } }; } @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Setup private void updateBeatmap() { - Beatmap.BeatmapInfo.SpecialStyle = specialStyle.Current.Value; + Beatmap.SpecialStyle = specialStyle.Current.Value; Beatmap.SaveState(); } } diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 565c481920..ad3721220a 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -85,7 +85,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(0.7f, beatmap.StackLeniency); Assert.IsTrue(beatmapInfo.Ruleset.OnlineID == 0); Assert.IsFalse(beatmapInfo.LetterboxInBreaks); - Assert.IsFalse(beatmapInfo.SpecialStyle); + Assert.IsFalse(beatmap.SpecialStyle); Assert.IsFalse(beatmapInfo.WidescreenStoryboard); Assert.IsFalse(beatmapInfo.SamplesMatchPlaybackRate); Assert.AreEqual(CountdownType.None, beatmapInfo.Countdown); @@ -952,7 +952,7 @@ namespace osu.Game.Tests.Beatmaps.Formats { Assert.That(decoded.AudioLeadIn, Is.EqualTo(0)); Assert.That(decoded.StackLeniency, Is.EqualTo(0.7f)); - Assert.That(decoded.BeatmapInfo.SpecialStyle, Is.False); + Assert.That(decoded.SpecialStyle, Is.False); Assert.That(decoded.BeatmapInfo.LetterboxInBreaks, Is.False); Assert.That(decoded.BeatmapInfo.WidescreenStoryboard, Is.False); Assert.That(decoded.BeatmapInfo.EpilepsyWarning, Is.False); diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 5d2d9e006e..18f4651e94 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Beatmaps.Formats var beatmapInfo = beatmap.BeatmapInfo; Assert.AreEqual(0, beatmap.AudioLeadIn); Assert.AreEqual(0.7f, beatmap.StackLeniency); - Assert.AreEqual(false, beatmapInfo.SpecialStyle); + Assert.AreEqual(false, beatmap.SpecialStyle); Assert.IsTrue(beatmapInfo.Ruleset.OnlineID == 0); Assert.AreEqual(false, beatmapInfo.LetterboxInBreaks); Assert.AreEqual(false, beatmapInfo.WidescreenStoryboard); diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index ecee6e3416..f06d884bd1 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -118,6 +118,8 @@ namespace osu.Game.Beatmaps public float StackLeniency { get; set; } = 0.7f; + public bool SpecialStyle { get; set; } + IBeatmap IBeatmap.Clone() => Clone(); public Beatmap Clone() => (Beatmap)MemberwiseClone(); diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index a5e9025404..3b3b68de0a 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -69,6 +69,7 @@ namespace osu.Game.Beatmaps beatmap.UnhandledEventLines = original.UnhandledEventLines; beatmap.AudioLeadIn = original.AudioLeadIn; beatmap.StackLeniency = original.StackLeniency; + beatmap.SpecialStyle = original.SpecialStyle; return beatmap; } diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index e589b0a754..435a282b52 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -414,7 +414,6 @@ namespace osu.Game.Beatmaps Hash = hash, DifficultyName = decodedInfo.DifficultyName, OnlineID = decodedInfo.OnlineID, - SpecialStyle = decodedInfo.SpecialStyle, LetterboxInBreaks = decodedInfo.LetterboxInBreaks, WidescreenStoryboard = decodedInfo.WidescreenStoryboard, EpilepsyWarning = decodedInfo.EpilepsyWarning, diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index fa2911438b..4a1fa9b0b4 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -138,8 +138,6 @@ namespace osu.Game.Beatmaps #region Properties we may not want persisted (but also maybe no harm?) - public bool SpecialStyle { get; set; } - public bool LetterboxInBreaks { get; set; } public bool WidescreenStoryboard { get; set; } = true; diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 86552b21dd..ea34c7d924 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -289,7 +289,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"SpecialStyle": - beatmap.BeatmapInfo.SpecialStyle = Parsing.ParseInt(pair.Value) == 1; + beatmap.SpecialStyle = Parsing.ParseInt(pair.Value) == 1; break; case @"WidescreenStoryboard": diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 8c371026ff..805ce49ca3 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -100,7 +100,7 @@ namespace osu.Game.Beatmaps.Formats if (beatmap.BeatmapInfo.CountdownOffset > 0) writer.WriteLine(FormattableString.Invariant($@"CountdownOffset: {beatmap.BeatmapInfo.CountdownOffset}")); if (onlineRulesetID == 3) - writer.WriteLine(FormattableString.Invariant($"SpecialStyle: {(beatmap.BeatmapInfo.SpecialStyle ? '1' : '0')}")); + writer.WriteLine(FormattableString.Invariant($"SpecialStyle: {(beatmap.SpecialStyle ? '1' : '0')}")); writer.WriteLine(FormattableString.Invariant($"WidescreenStoryboard: {(beatmap.BeatmapInfo.WidescreenStoryboard ? '1' : '0')}")); if (beatmap.BeatmapInfo.SamplesMatchPlaybackRate) writer.WriteLine(@"SamplesMatchPlaybackRate: 1"); diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index 28d601620a..3ac48c09b4 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -72,6 +72,8 @@ namespace osu.Game.Beatmaps float StackLeniency { get; internal set; } + bool SpecialStyle { get; internal set; } + /// /// Creates a shallow-clone of this beatmap and returns it. /// diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index 616d6d0848..87a20eec0b 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -349,6 +349,12 @@ namespace osu.Game.Rulesets.Difficulty set => baseBeatmap.StackLeniency = value; } + public bool SpecialStyle + { + get => baseBeatmap.SpecialStyle; + set => baseBeatmap.SpecialStyle = value; + } + #endregion } } diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index c02a22ae03..96216c6b1a 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -196,6 +196,12 @@ namespace osu.Game.Screens.Edit set => PlayableBeatmap.StackLeniency = value; } + public bool SpecialStyle + { + get => PlayableBeatmap.SpecialStyle; + set => PlayableBeatmap.SpecialStyle = value; + } + public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone(); private IList mutableHitObjects => (IList)PlayableBeatmap.HitObjects; From a6b7600bf2b85f154624d8893fd9e658b098ab3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 12 Jun 2024 13:15:41 +0200 Subject: [PATCH 04/54] Move `LetterboxInBreaks` out of `BeatmapInfo` --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 4 ++-- osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- osu.Game/Beatmaps/Beatmap.cs | 2 ++ osu.Game/Beatmaps/BeatmapConverter.cs | 1 + osu.Game/Beatmaps/BeatmapImporter.cs | 1 - osu.Game/Beatmaps/BeatmapInfo.cs | 2 -- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 2 +- osu.Game/Beatmaps/IBeatmap.cs | 2 ++ osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs | 6 ++++++ osu.Game/Screens/Edit/EditorBeatmap.cs | 6 ++++++ osu.Game/Screens/Edit/Setup/DesignSection.cs | 4 ++-- osu.Game/Screens/Play/Player.cs | 2 +- 13 files changed, 25 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index ad3721220a..103bafb2d8 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -84,7 +84,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(164471, metadata.PreviewTime); Assert.AreEqual(0.7f, beatmap.StackLeniency); Assert.IsTrue(beatmapInfo.Ruleset.OnlineID == 0); - Assert.IsFalse(beatmapInfo.LetterboxInBreaks); + Assert.IsFalse(beatmap.LetterboxInBreaks); Assert.IsFalse(beatmap.SpecialStyle); Assert.IsFalse(beatmapInfo.WidescreenStoryboard); Assert.IsFalse(beatmapInfo.SamplesMatchPlaybackRate); @@ -953,7 +953,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.That(decoded.AudioLeadIn, Is.EqualTo(0)); Assert.That(decoded.StackLeniency, Is.EqualTo(0.7f)); Assert.That(decoded.SpecialStyle, Is.False); - Assert.That(decoded.BeatmapInfo.LetterboxInBreaks, Is.False); + Assert.That(decoded.LetterboxInBreaks, Is.False); Assert.That(decoded.BeatmapInfo.WidescreenStoryboard, Is.False); Assert.That(decoded.BeatmapInfo.EpilepsyWarning, Is.False); Assert.That(decoded.BeatmapInfo.SamplesMatchPlaybackRate, Is.False); diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 18f4651e94..c1c996fd42 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(0.7f, beatmap.StackLeniency); Assert.AreEqual(false, beatmap.SpecialStyle); Assert.IsTrue(beatmapInfo.Ruleset.OnlineID == 0); - Assert.AreEqual(false, beatmapInfo.LetterboxInBreaks); + Assert.AreEqual(false, beatmap.LetterboxInBreaks); Assert.AreEqual(false, beatmapInfo.WidescreenStoryboard); Assert.AreEqual(CountdownType.None, beatmapInfo.Countdown); Assert.AreEqual(0, beatmapInfo.CountdownOffset); diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index f06d884bd1..614bb4f42a 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -120,6 +120,8 @@ namespace osu.Game.Beatmaps public bool SpecialStyle { get; set; } + public bool LetterboxInBreaks { get; set; } + IBeatmap IBeatmap.Clone() => Clone(); public Beatmap Clone() => (Beatmap)MemberwiseClone(); diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index 3b3b68de0a..a56ce58532 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -70,6 +70,7 @@ namespace osu.Game.Beatmaps beatmap.AudioLeadIn = original.AudioLeadIn; beatmap.StackLeniency = original.StackLeniency; beatmap.SpecialStyle = original.SpecialStyle; + beatmap.LetterboxInBreaks = original.LetterboxInBreaks; return beatmap; } diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index 435a282b52..c54eece9f8 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -414,7 +414,6 @@ namespace osu.Game.Beatmaps Hash = hash, DifficultyName = decodedInfo.DifficultyName, OnlineID = decodedInfo.OnlineID, - LetterboxInBreaks = decodedInfo.LetterboxInBreaks, WidescreenStoryboard = decodedInfo.WidescreenStoryboard, EpilepsyWarning = decodedInfo.EpilepsyWarning, SamplesMatchPlaybackRate = decodedInfo.SamplesMatchPlaybackRate, diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 4a1fa9b0b4..fafca5e014 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -138,8 +138,6 @@ namespace osu.Game.Beatmaps #region Properties we may not want persisted (but also maybe no harm?) - public bool LetterboxInBreaks { get; set; } - public bool WidescreenStoryboard { get; set; } = true; public bool EpilepsyWarning { get; set; } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index ea34c7d924..b8469f27dd 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -285,7 +285,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"LetterboxInBreaks": - beatmap.BeatmapInfo.LetterboxInBreaks = Parsing.ParseInt(pair.Value) == 1; + beatmap.LetterboxInBreaks = Parsing.ParseInt(pair.Value) == 1; break; case @"SpecialStyle": diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 805ce49ca3..5a3fd0a2f3 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -86,7 +86,7 @@ namespace osu.Game.Beatmaps.Formats $"SampleSet: {toLegacySampleBank(((beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePoints.FirstOrDefault() ?? SampleControlPoint.DEFAULT).SampleBank)}")); writer.WriteLine(FormattableString.Invariant($"StackLeniency: {beatmap.StackLeniency}")); writer.WriteLine(FormattableString.Invariant($"Mode: {onlineRulesetID}")); - writer.WriteLine(FormattableString.Invariant($"LetterboxInBreaks: {(beatmap.BeatmapInfo.LetterboxInBreaks ? '1' : '0')}")); + writer.WriteLine(FormattableString.Invariant($"LetterboxInBreaks: {(beatmap.LetterboxInBreaks ? '1' : '0')}")); // if (beatmap.BeatmapInfo.UseSkinSprites) // writer.WriteLine(@"UseSkinSprites: 1"); // if (b.AlwaysShowPlayfield) diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index 3ac48c09b4..e5562b608e 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -74,6 +74,8 @@ namespace osu.Game.Beatmaps bool SpecialStyle { get; internal set; } + bool LetterboxInBreaks { get; internal set; } + /// /// Creates a shallow-clone of this beatmap and returns it. /// diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index 87a20eec0b..04dcb2a552 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -355,6 +355,12 @@ namespace osu.Game.Rulesets.Difficulty set => baseBeatmap.SpecialStyle = value; } + public bool LetterboxInBreaks + { + get => baseBeatmap.LetterboxInBreaks; + set => baseBeatmap.LetterboxInBreaks = value; + } + #endregion } } diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 96216c6b1a..7470505712 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -202,6 +202,12 @@ namespace osu.Game.Screens.Edit set => PlayableBeatmap.SpecialStyle = value; } + public bool LetterboxInBreaks + { + get => PlayableBeatmap.LetterboxInBreaks; + set => PlayableBeatmap.LetterboxInBreaks = value; + } + public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone(); private IList mutableHitObjects => (IList)PlayableBeatmap.HitObjects; diff --git a/osu.Game/Screens/Edit/Setup/DesignSection.cs b/osu.Game/Screens/Edit/Setup/DesignSection.cs index b05a073146..c1fe7f405d 100644 --- a/osu.Game/Screens/Edit/Setup/DesignSection.cs +++ b/osu.Game/Screens/Edit/Setup/DesignSection.cs @@ -80,7 +80,7 @@ namespace osu.Game.Screens.Edit.Setup { Label = EditorSetupStrings.LetterboxDuringBreaks, Description = EditorSetupStrings.LetterboxDuringBreaksDescription, - Current = { Value = Beatmap.BeatmapInfo.LetterboxInBreaks } + Current = { Value = Beatmap.LetterboxInBreaks } }, samplesMatchPlaybackRate = new LabelledSwitchButton { @@ -123,7 +123,7 @@ namespace osu.Game.Screens.Edit.Setup Beatmap.BeatmapInfo.WidescreenStoryboard = widescreenSupport.Current.Value; Beatmap.BeatmapInfo.EpilepsyWarning = epilepsyWarning.Current.Value; - Beatmap.BeatmapInfo.LetterboxInBreaks = letterboxDuringBreaks.Current.Value; + Beatmap.LetterboxInBreaks = letterboxDuringBreaks.Current.Value; Beatmap.BeatmapInfo.SamplesMatchPlaybackRate = samplesMatchPlaybackRate.Current.Value; Beatmap.SaveState(); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 42ff1d74f3..eaadc236f7 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -430,7 +430,7 @@ namespace osu.Game.Screens.Play Children = new[] { DimmableStoryboard.OverlayLayerContainer.CreateProxy(), - BreakOverlay = new BreakOverlay(working.Beatmap.BeatmapInfo.LetterboxInBreaks, ScoreProcessor) + BreakOverlay = new BreakOverlay(working.Beatmap.LetterboxInBreaks, ScoreProcessor) { Clock = DrawableRuleset.FrameStableClock, ProcessCustomClock = false, From 1ab86ebd249e31812ee07af2191957d6115a02c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 12 Jun 2024 13:23:53 +0200 Subject: [PATCH 05/54] Move `WidescreenStoryboard` out of `BeatmapInfo` --- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 4 ++-- osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs | 2 +- osu.Game/Beatmaps/Beatmap.cs | 2 ++ osu.Game/Beatmaps/BeatmapConverter.cs | 1 + osu.Game/Beatmaps/BeatmapImporter.cs | 1 - osu.Game/Beatmaps/BeatmapInfo.cs | 2 -- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 10 +++++----- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 2 +- osu.Game/Beatmaps/IBeatmap.cs | 2 ++ osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs | 6 ++++++ osu.Game/Screens/Edit/EditorBeatmap.cs | 6 ++++++ osu.Game/Screens/Edit/Setup/DesignSection.cs | 4 ++-- osu.Game/Storyboards/Drawables/DrawableStoryboard.cs | 2 +- osu.Game/Storyboards/Storyboard.cs | 1 + 15 files changed, 31 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 103bafb2d8..cd36b6b986 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -86,7 +86,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsTrue(beatmapInfo.Ruleset.OnlineID == 0); Assert.IsFalse(beatmap.LetterboxInBreaks); Assert.IsFalse(beatmap.SpecialStyle); - Assert.IsFalse(beatmapInfo.WidescreenStoryboard); + Assert.IsFalse(beatmap.WidescreenStoryboard); Assert.IsFalse(beatmapInfo.SamplesMatchPlaybackRate); Assert.AreEqual(CountdownType.None, beatmapInfo.Countdown); Assert.AreEqual(0, beatmapInfo.CountdownOffset); @@ -954,7 +954,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.That(decoded.StackLeniency, Is.EqualTo(0.7f)); Assert.That(decoded.SpecialStyle, Is.False); Assert.That(decoded.LetterboxInBreaks, Is.False); - Assert.That(decoded.BeatmapInfo.WidescreenStoryboard, Is.False); + Assert.That(decoded.WidescreenStoryboard, Is.False); Assert.That(decoded.BeatmapInfo.EpilepsyWarning, Is.False); Assert.That(decoded.BeatmapInfo.SamplesMatchPlaybackRate, Is.False); Assert.That(decoded.BeatmapInfo.Countdown, Is.EqualTo(CountdownType.Normal)); diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index c1c996fd42..92715b6aa2 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -56,7 +56,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(false, beatmap.SpecialStyle); Assert.IsTrue(beatmapInfo.Ruleset.OnlineID == 0); Assert.AreEqual(false, beatmap.LetterboxInBreaks); - Assert.AreEqual(false, beatmapInfo.WidescreenStoryboard); + Assert.AreEqual(false, beatmap.WidescreenStoryboard); Assert.AreEqual(CountdownType.None, beatmapInfo.Countdown); Assert.AreEqual(0, beatmapInfo.CountdownOffset); } diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs index 893b9f11f4..95aee43456 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneStoryboard.cs @@ -50,7 +50,7 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("load storyboard with only video", () => { // LegacyStoryboardDecoder doesn't parse WidescreenStoryboard, so it is set manually - loadStoryboard("storyboard_only_video.osu", s => s.BeatmapInfo.WidescreenStoryboard = false); + loadStoryboard("storyboard_only_video.osu", s => s.Beatmap.WidescreenStoryboard = false); }); AddAssert("storyboard is correct width", () => Precision.AlmostEquals(storyboard?.Width ?? 0f, 480 * 16 / 9f)); diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 614bb4f42a..d909e87417 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -122,6 +122,8 @@ namespace osu.Game.Beatmaps public bool LetterboxInBreaks { get; set; } + public bool WidescreenStoryboard { get; set; } = true; + IBeatmap IBeatmap.Clone() => Clone(); public Beatmap Clone() => (Beatmap)MemberwiseClone(); diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index a56ce58532..c097389c56 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -71,6 +71,7 @@ namespace osu.Game.Beatmaps beatmap.StackLeniency = original.StackLeniency; beatmap.SpecialStyle = original.SpecialStyle; beatmap.LetterboxInBreaks = original.LetterboxInBreaks; + beatmap.WidescreenStoryboard = original.WidescreenStoryboard; return beatmap; } diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index c54eece9f8..0bb2ddda7d 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -414,7 +414,6 @@ namespace osu.Game.Beatmaps Hash = hash, DifficultyName = decodedInfo.DifficultyName, OnlineID = decodedInfo.OnlineID, - WidescreenStoryboard = decodedInfo.WidescreenStoryboard, EpilepsyWarning = decodedInfo.EpilepsyWarning, SamplesMatchPlaybackRate = decodedInfo.SamplesMatchPlaybackRate, DistanceSpacing = decodedInfo.DistanceSpacing, diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index fafca5e014..1bfa65a3fb 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -138,8 +138,6 @@ namespace osu.Game.Beatmaps #region Properties we may not want persisted (but also maybe no harm?) - public bool WidescreenStoryboard { get; set; } = true; - public bool EpilepsyWarning { get; set; } public bool SamplesMatchPlaybackRate { get; set; } = true; diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index b8469f27dd..355114fd0b 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -81,7 +81,7 @@ namespace osu.Game.Beatmaps.Formats this.beatmap = beatmap; this.beatmap.BeatmapInfo.BeatmapVersion = FormatVersion; - applyLegacyDefaults(this.beatmap.BeatmapInfo); + applyLegacyDefaults(this.beatmap); base.ParseStreamInto(stream, beatmap); @@ -183,10 +183,10 @@ namespace osu.Game.Beatmaps.Formats /// This method's intention is to restore those legacy defaults. /// See also: https://osu.ppy.sh/wiki/en/Client/File_formats/Osu_%28file_format%29 /// - private static void applyLegacyDefaults(BeatmapInfo beatmapInfo) + private static void applyLegacyDefaults(Beatmap beatmap) { - beatmapInfo.WidescreenStoryboard = false; - beatmapInfo.SamplesMatchPlaybackRate = false; + beatmap.WidescreenStoryboard = false; + beatmap.BeatmapInfo.SamplesMatchPlaybackRate = false; } protected override void ParseLine(Beatmap beatmap, Section section, string line) @@ -293,7 +293,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"WidescreenStoryboard": - beatmap.BeatmapInfo.WidescreenStoryboard = Parsing.ParseInt(pair.Value) == 1; + beatmap.WidescreenStoryboard = Parsing.ParseInt(pair.Value) == 1; break; case @"EpilepsyWarning": diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 5a3fd0a2f3..478b78fa29 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -101,7 +101,7 @@ namespace osu.Game.Beatmaps.Formats writer.WriteLine(FormattableString.Invariant($@"CountdownOffset: {beatmap.BeatmapInfo.CountdownOffset}")); if (onlineRulesetID == 3) writer.WriteLine(FormattableString.Invariant($"SpecialStyle: {(beatmap.SpecialStyle ? '1' : '0')}")); - writer.WriteLine(FormattableString.Invariant($"WidescreenStoryboard: {(beatmap.BeatmapInfo.WidescreenStoryboard ? '1' : '0')}")); + writer.WriteLine(FormattableString.Invariant($"WidescreenStoryboard: {(beatmap.WidescreenStoryboard ? '1' : '0')}")); if (beatmap.BeatmapInfo.SamplesMatchPlaybackRate) writer.WriteLine(@"SamplesMatchPlaybackRate: 1"); } diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index e5562b608e..3091e02054 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -76,6 +76,8 @@ namespace osu.Game.Beatmaps bool LetterboxInBreaks { get; internal set; } + bool WidescreenStoryboard { get; internal set; } + /// /// Creates a shallow-clone of this beatmap and returns it. /// diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index 04dcb2a552..bd051383de 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -361,6 +361,12 @@ namespace osu.Game.Rulesets.Difficulty set => baseBeatmap.LetterboxInBreaks = value; } + public bool WidescreenStoryboard + { + get => baseBeatmap.WidescreenStoryboard; + set => baseBeatmap.WidescreenStoryboard = value; + } + #endregion } } diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 7470505712..a217e132d0 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -208,6 +208,12 @@ namespace osu.Game.Screens.Edit set => PlayableBeatmap.LetterboxInBreaks = value; } + public bool WidescreenStoryboard + { + get => PlayableBeatmap.WidescreenStoryboard; + set => PlayableBeatmap.WidescreenStoryboard = value; + } + public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone(); private IList mutableHitObjects => (IList)PlayableBeatmap.HitObjects; diff --git a/osu.Game/Screens/Edit/Setup/DesignSection.cs b/osu.Game/Screens/Edit/Setup/DesignSection.cs index c1fe7f405d..8c420b979f 100644 --- a/osu.Game/Screens/Edit/Setup/DesignSection.cs +++ b/osu.Game/Screens/Edit/Setup/DesignSection.cs @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Edit.Setup { Label = EditorSetupStrings.WidescreenSupport, Description = EditorSetupStrings.WidescreenSupportDescription, - Current = { Value = Beatmap.BeatmapInfo.WidescreenStoryboard } + Current = { Value = Beatmap.WidescreenStoryboard } }, epilepsyWarning = new LabelledSwitchButton { @@ -121,7 +121,7 @@ namespace osu.Game.Screens.Edit.Setup Beatmap.BeatmapInfo.Countdown = EnableCountdown.Current.Value ? CountdownSpeed.Current.Value : CountdownType.None; Beatmap.BeatmapInfo.CountdownOffset = int.TryParse(CountdownOffset.Current.Value, NumberStyles.None, CultureInfo.InvariantCulture, out int offset) ? offset : 0; - Beatmap.BeatmapInfo.WidescreenStoryboard = widescreenSupport.Current.Value; + Beatmap.WidescreenStoryboard = widescreenSupport.Current.Value; Beatmap.BeatmapInfo.EpilepsyWarning = epilepsyWarning.Current.Value; Beatmap.LetterboxInBreaks = letterboxDuringBreaks.Current.Value; Beatmap.BeatmapInfo.SamplesMatchPlaybackRate = samplesMatchPlaybackRate.Current.Value; diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index fc5ef12fb8..858c257e85 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs @@ -78,7 +78,7 @@ namespace osu.Game.Storyboards.Drawables bool onlyHasVideoElements = Storyboard.Layers.SelectMany(l => l.Elements).All(e => e is StoryboardVideo); - Width = Height * (storyboard.BeatmapInfo.WidescreenStoryboard || onlyHasVideoElements ? 16 / 9f : 4 / 3f); + Width = Height * (storyboard.Beatmap.WidescreenStoryboard || onlyHasVideoElements ? 16 / 9f : 4 / 3f); Anchor = Anchor.Centre; Origin = Anchor.Centre; diff --git a/osu.Game/Storyboards/Storyboard.cs b/osu.Game/Storyboards/Storyboard.cs index 8c43b99702..aca5fc34f4 100644 --- a/osu.Game/Storyboards/Storyboard.cs +++ b/osu.Game/Storyboards/Storyboard.cs @@ -16,6 +16,7 @@ namespace osu.Game.Storyboards public IEnumerable Layers => layers.Values; public BeatmapInfo BeatmapInfo = new BeatmapInfo(); + public IBeatmap Beatmap { get; set; } = new Beatmap(); /// /// Whether the storyboard should prefer textures from the current skin before using local storyboard textures. From f64a0624a5b1808a7c0ca91db99ecc7d679c4ddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 12 Jun 2024 13:28:41 +0200 Subject: [PATCH 06/54] Move `EpilepsyWarning` out of `BeatmapInfo` --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 2 +- osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs | 2 +- osu.Game/Beatmaps/Beatmap.cs | 2 ++ osu.Game/Beatmaps/BeatmapConverter.cs | 1 + osu.Game/Beatmaps/BeatmapImporter.cs | 1 - osu.Game/Beatmaps/BeatmapInfo.cs | 2 -- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 2 +- osu.Game/Beatmaps/IBeatmap.cs | 2 ++ osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs | 6 ++++++ osu.Game/Screens/Edit/EditorBeatmap.cs | 6 ++++++ osu.Game/Screens/Edit/Setup/DesignSection.cs | 4 ++-- osu.Game/Screens/Play/PlayerLoader.cs | 2 +- 13 files changed, 24 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index cd36b6b986..d3b027d253 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -955,7 +955,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.That(decoded.SpecialStyle, Is.False); Assert.That(decoded.LetterboxInBreaks, Is.False); Assert.That(decoded.WidescreenStoryboard, Is.False); - Assert.That(decoded.BeatmapInfo.EpilepsyWarning, Is.False); + Assert.That(decoded.EpilepsyWarning, Is.False); Assert.That(decoded.BeatmapInfo.SamplesMatchPlaybackRate, Is.False); Assert.That(decoded.BeatmapInfo.Countdown, Is.EqualTo(CountdownType.Normal)); Assert.That(decoded.BeatmapInfo.CountdownOffset, Is.EqualTo(0)); diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs index c17405c2ec..64211cddf3 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs @@ -138,7 +138,7 @@ namespace osu.Game.Tests.Visual.Gameplay workingBeatmap.Beatmap.AudioLeadIn = 60000; // Set up data for testing disclaimer display. - workingBeatmap.BeatmapInfo.EpilepsyWarning = epilepsyWarning ?? false; + workingBeatmap.Beatmap.EpilepsyWarning = epilepsyWarning ?? false; workingBeatmap.BeatmapInfo.Status = onlineStatus ?? BeatmapOnlineStatus.Ranked; Beatmap.Value = workingBeatmap; diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index d909e87417..7516c8958c 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -124,6 +124,8 @@ namespace osu.Game.Beatmaps public bool WidescreenStoryboard { get; set; } = true; + public bool EpilepsyWarning { get; set; } + IBeatmap IBeatmap.Clone() => Clone(); public Beatmap Clone() => (Beatmap)MemberwiseClone(); diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index c097389c56..f9be44599f 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -72,6 +72,7 @@ namespace osu.Game.Beatmaps beatmap.SpecialStyle = original.SpecialStyle; beatmap.LetterboxInBreaks = original.LetterboxInBreaks; beatmap.WidescreenStoryboard = original.WidescreenStoryboard; + beatmap.EpilepsyWarning = original.EpilepsyWarning; return beatmap; } diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index 0bb2ddda7d..232c8b7e24 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -414,7 +414,6 @@ namespace osu.Game.Beatmaps Hash = hash, DifficultyName = decodedInfo.DifficultyName, OnlineID = decodedInfo.OnlineID, - EpilepsyWarning = decodedInfo.EpilepsyWarning, SamplesMatchPlaybackRate = decodedInfo.SamplesMatchPlaybackRate, DistanceSpacing = decodedInfo.DistanceSpacing, BeatDivisor = decodedInfo.BeatDivisor, diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 1bfa65a3fb..41a0260250 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -138,8 +138,6 @@ namespace osu.Game.Beatmaps #region Properties we may not want persisted (but also maybe no harm?) - public bool EpilepsyWarning { get; set; } - public bool SamplesMatchPlaybackRate { get; set; } = true; /// diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 355114fd0b..1152e5f30d 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -297,7 +297,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"EpilepsyWarning": - beatmap.BeatmapInfo.EpilepsyWarning = Parsing.ParseInt(pair.Value) == 1; + beatmap.EpilepsyWarning = Parsing.ParseInt(pair.Value) == 1; break; case @"SamplesMatchPlaybackRate": diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 478b78fa29..d7078a71d9 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -95,7 +95,7 @@ namespace osu.Game.Beatmaps.Formats // writer.WriteLine(@"OverlayPosition: " + b.OverlayPosition); // if (!string.IsNullOrEmpty(b.SkinPreference)) // writer.WriteLine(@"SkinPreference:" + b.SkinPreference); - if (beatmap.BeatmapInfo.EpilepsyWarning) + if (beatmap.EpilepsyWarning) writer.WriteLine(@"EpilepsyWarning: 1"); if (beatmap.BeatmapInfo.CountdownOffset > 0) writer.WriteLine(FormattableString.Invariant($@"CountdownOffset: {beatmap.BeatmapInfo.CountdownOffset}")); diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index 3091e02054..3d563004d1 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -78,6 +78,8 @@ namespace osu.Game.Beatmaps bool WidescreenStoryboard { get; internal set; } + bool EpilepsyWarning { get; internal set; } + /// /// Creates a shallow-clone of this beatmap and returns it. /// diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index bd051383de..7f9d2ae6ab 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -367,6 +367,12 @@ namespace osu.Game.Rulesets.Difficulty set => baseBeatmap.WidescreenStoryboard = value; } + public bool EpilepsyWarning + { + get => baseBeatmap.EpilepsyWarning; + set => baseBeatmap.EpilepsyWarning = value; + } + #endregion } } diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index a217e132d0..063803ab42 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -214,6 +214,12 @@ namespace osu.Game.Screens.Edit set => PlayableBeatmap.WidescreenStoryboard = value; } + public bool EpilepsyWarning + { + get => PlayableBeatmap.EpilepsyWarning; + set => PlayableBeatmap.EpilepsyWarning = value; + } + public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone(); private IList mutableHitObjects => (IList)PlayableBeatmap.HitObjects; diff --git a/osu.Game/Screens/Edit/Setup/DesignSection.cs b/osu.Game/Screens/Edit/Setup/DesignSection.cs index 8c420b979f..5d729cf4f8 100644 --- a/osu.Game/Screens/Edit/Setup/DesignSection.cs +++ b/osu.Game/Screens/Edit/Setup/DesignSection.cs @@ -74,7 +74,7 @@ namespace osu.Game.Screens.Edit.Setup { Label = EditorSetupStrings.EpilepsyWarning, Description = EditorSetupStrings.EpilepsyWarningDescription, - Current = { Value = Beatmap.BeatmapInfo.EpilepsyWarning } + Current = { Value = Beatmap.EpilepsyWarning } }, letterboxDuringBreaks = new LabelledSwitchButton { @@ -122,7 +122,7 @@ namespace osu.Game.Screens.Edit.Setup Beatmap.BeatmapInfo.CountdownOffset = int.TryParse(CountdownOffset.Current.Value, NumberStyles.None, CultureInfo.InvariantCulture, out int offset) ? offset : 0; Beatmap.WidescreenStoryboard = widescreenSupport.Current.Value; - Beatmap.BeatmapInfo.EpilepsyWarning = epilepsyWarning.Current.Value; + Beatmap.EpilepsyWarning = epilepsyWarning.Current.Value; Beatmap.LetterboxInBreaks = letterboxDuringBreaks.Current.Value; Beatmap.BeatmapInfo.SamplesMatchPlaybackRate = samplesMatchPlaybackRate.Current.Value; diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 51a0c94ff0..fc7e7fb58f 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -228,7 +228,7 @@ namespace osu.Game.Screens.Play sampleRestart = new SkinnableSound(new SampleInfo(@"Gameplay/restart", @"pause-retry-click")) }; - if (Beatmap.Value.BeatmapInfo.EpilepsyWarning) + if (Beatmap.Value.Beatmap.EpilepsyWarning) { disclaimers.Add(epilepsyWarning = new PlayerLoaderDisclaimer(PlayerLoaderStrings.EpilepsyWarningTitle, PlayerLoaderStrings.EpilepsyWarningContent)); } From c216283bf4ee5964e793869f2a63d941e58e6d74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 12 Jun 2024 13:32:23 +0200 Subject: [PATCH 07/54] Move `SamplesMatchPlaybackRate` out of `BeatmapInfo` --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 4 ++-- osu.Game/Beatmaps/Beatmap.cs | 2 ++ osu.Game/Beatmaps/BeatmapConverter.cs | 1 + osu.Game/Beatmaps/BeatmapImporter.cs | 1 - osu.Game/Beatmaps/BeatmapInfo.cs | 2 -- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 4 ++-- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 2 +- osu.Game/Beatmaps/IBeatmap.cs | 2 ++ osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs | 6 ++++++ osu.Game/Screens/Edit/EditorBeatmap.cs | 6 ++++++ osu.Game/Screens/Edit/Setup/DesignSection.cs | 4 ++-- 11 files changed, 24 insertions(+), 10 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index d3b027d253..51c1e51d3b 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -87,7 +87,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsFalse(beatmap.LetterboxInBreaks); Assert.IsFalse(beatmap.SpecialStyle); Assert.IsFalse(beatmap.WidescreenStoryboard); - Assert.IsFalse(beatmapInfo.SamplesMatchPlaybackRate); + Assert.IsFalse(beatmap.SamplesMatchPlaybackRate); Assert.AreEqual(CountdownType.None, beatmapInfo.Countdown); Assert.AreEqual(0, beatmapInfo.CountdownOffset); } @@ -956,7 +956,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.That(decoded.LetterboxInBreaks, Is.False); Assert.That(decoded.WidescreenStoryboard, Is.False); Assert.That(decoded.EpilepsyWarning, Is.False); - Assert.That(decoded.BeatmapInfo.SamplesMatchPlaybackRate, Is.False); + Assert.That(decoded.SamplesMatchPlaybackRate, Is.False); Assert.That(decoded.BeatmapInfo.Countdown, Is.EqualTo(CountdownType.Normal)); Assert.That(decoded.BeatmapInfo.CountdownOffset, Is.EqualTo(0)); Assert.That(decoded.BeatmapInfo.Metadata.PreviewTime, Is.EqualTo(-1)); diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 7516c8958c..76864a1d70 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -126,6 +126,8 @@ namespace osu.Game.Beatmaps public bool EpilepsyWarning { get; set; } + public bool SamplesMatchPlaybackRate { get; set; } = true; + IBeatmap IBeatmap.Clone() => Clone(); public Beatmap Clone() => (Beatmap)MemberwiseClone(); diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index f9be44599f..b86a445aa8 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -73,6 +73,7 @@ namespace osu.Game.Beatmaps beatmap.LetterboxInBreaks = original.LetterboxInBreaks; beatmap.WidescreenStoryboard = original.WidescreenStoryboard; beatmap.EpilepsyWarning = original.EpilepsyWarning; + beatmap.SamplesMatchPlaybackRate = original.SamplesMatchPlaybackRate; return beatmap; } diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index 232c8b7e24..650b0bf510 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -414,7 +414,6 @@ namespace osu.Game.Beatmaps Hash = hash, DifficultyName = decodedInfo.DifficultyName, OnlineID = decodedInfo.OnlineID, - SamplesMatchPlaybackRate = decodedInfo.SamplesMatchPlaybackRate, DistanceSpacing = decodedInfo.DistanceSpacing, BeatDivisor = decodedInfo.BeatDivisor, GridSize = decodedInfo.GridSize, diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 41a0260250..93abfa8d9b 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -138,8 +138,6 @@ namespace osu.Game.Beatmaps #region Properties we may not want persisted (but also maybe no harm?) - public bool SamplesMatchPlaybackRate { get; set; } = true; - /// /// The time at which this beatmap was last played by the local user. /// diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 1152e5f30d..0c8770782d 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -186,7 +186,7 @@ namespace osu.Game.Beatmaps.Formats private static void applyLegacyDefaults(Beatmap beatmap) { beatmap.WidescreenStoryboard = false; - beatmap.BeatmapInfo.SamplesMatchPlaybackRate = false; + beatmap.SamplesMatchPlaybackRate = false; } protected override void ParseLine(Beatmap beatmap, Section section, string line) @@ -301,7 +301,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"SamplesMatchPlaybackRate": - beatmap.BeatmapInfo.SamplesMatchPlaybackRate = Parsing.ParseInt(pair.Value) == 1; + beatmap.SamplesMatchPlaybackRate = Parsing.ParseInt(pair.Value) == 1; break; case @"Countdown": diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index d7078a71d9..860ca68f6b 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -102,7 +102,7 @@ namespace osu.Game.Beatmaps.Formats if (onlineRulesetID == 3) writer.WriteLine(FormattableString.Invariant($"SpecialStyle: {(beatmap.SpecialStyle ? '1' : '0')}")); writer.WriteLine(FormattableString.Invariant($"WidescreenStoryboard: {(beatmap.WidescreenStoryboard ? '1' : '0')}")); - if (beatmap.BeatmapInfo.SamplesMatchPlaybackRate) + if (beatmap.SamplesMatchPlaybackRate) writer.WriteLine(@"SamplesMatchPlaybackRate: 1"); } diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index 3d563004d1..9900609f18 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -80,6 +80,8 @@ namespace osu.Game.Beatmaps bool EpilepsyWarning { get; internal set; } + bool SamplesMatchPlaybackRate { get; internal set; } + /// /// Creates a shallow-clone of this beatmap and returns it. /// diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index 7f9d2ae6ab..960eab6f2c 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -373,6 +373,12 @@ namespace osu.Game.Rulesets.Difficulty set => baseBeatmap.EpilepsyWarning = value; } + public bool SamplesMatchPlaybackRate + { + get => baseBeatmap.SamplesMatchPlaybackRate; + set => baseBeatmap.SamplesMatchPlaybackRate = value; + } + #endregion } } diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 063803ab42..4303764fa7 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -220,6 +220,12 @@ namespace osu.Game.Screens.Edit set => PlayableBeatmap.EpilepsyWarning = value; } + public bool SamplesMatchPlaybackRate + { + get => PlayableBeatmap.SamplesMatchPlaybackRate; + set => PlayableBeatmap.SamplesMatchPlaybackRate = value; + } + public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone(); private IList mutableHitObjects => (IList)PlayableBeatmap.HitObjects; diff --git a/osu.Game/Screens/Edit/Setup/DesignSection.cs b/osu.Game/Screens/Edit/Setup/DesignSection.cs index 5d729cf4f8..4c4755064f 100644 --- a/osu.Game/Screens/Edit/Setup/DesignSection.cs +++ b/osu.Game/Screens/Edit/Setup/DesignSection.cs @@ -86,7 +86,7 @@ namespace osu.Game.Screens.Edit.Setup { Label = EditorSetupStrings.SamplesMatchPlaybackRate, Description = EditorSetupStrings.SamplesMatchPlaybackRateDescription, - Current = { Value = Beatmap.BeatmapInfo.SamplesMatchPlaybackRate } + Current = { Value = Beatmap.SamplesMatchPlaybackRate } } }; } @@ -124,7 +124,7 @@ namespace osu.Game.Screens.Edit.Setup Beatmap.WidescreenStoryboard = widescreenSupport.Current.Value; Beatmap.EpilepsyWarning = epilepsyWarning.Current.Value; Beatmap.LetterboxInBreaks = letterboxDuringBreaks.Current.Value; - Beatmap.BeatmapInfo.SamplesMatchPlaybackRate = samplesMatchPlaybackRate.Current.Value; + Beatmap.SamplesMatchPlaybackRate = samplesMatchPlaybackRate.Current.Value; Beatmap.SaveState(); } From 3634307d7ceadc23604014fba8aaa077682f2988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 12 Jun 2024 13:36:27 +0200 Subject: [PATCH 08/54] Move `DistanceSpacing` out of `BeatmapInfo` --- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 14 +++++++------- .../Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- .../Visual/Editing/TestSceneHitObjectComposer.cs | 4 ++-- osu.Game/Beatmaps/Beatmap.cs | 2 ++ osu.Game/Beatmaps/BeatmapConverter.cs | 1 + osu.Game/Beatmaps/BeatmapImporter.cs | 1 - osu.Game/Beatmaps/BeatmapInfo.cs | 14 -------------- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 2 +- osu.Game/Beatmaps/IBeatmap.cs | 13 +++++++++++++ .../Rulesets/Difficulty/DifficultyCalculator.cs | 6 ++++++ .../Rulesets/Edit/ComposerDistanceSnapProvider.cs | 4 ++-- osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs | 2 +- osu.Game/Screens/Edit/EditorBeatmap.cs | 6 ++++++ 14 files changed, 43 insertions(+), 30 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 51c1e51d3b..71dcd38bcd 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -101,7 +101,7 @@ namespace osu.Game.Tests.Beatmaps.Formats using (var resStream = TestResources.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) using (var stream = new LineBufferedReader(resStream)) { - var beatmapInfo = decoder.Decode(stream).BeatmapInfo; + var beatmap = decoder.Decode(stream); int[] expectedBookmarks = { @@ -109,13 +109,13 @@ namespace osu.Game.Tests.Beatmaps.Formats 95901, 106450, 116999, 119637, 130186, 140735, 151285, 161834, 164471, 175020, 185570, 196119, 206669, 209306 }; - Assert.AreEqual(expectedBookmarks.Length, beatmapInfo.Bookmarks.Length); + Assert.AreEqual(expectedBookmarks.Length, beatmap.BeatmapInfo.Bookmarks.Length); for (int i = 0; i < expectedBookmarks.Length; i++) - Assert.AreEqual(expectedBookmarks[i], beatmapInfo.Bookmarks[i]); - Assert.AreEqual(1.8, beatmapInfo.DistanceSpacing); - Assert.AreEqual(4, beatmapInfo.BeatDivisor); - Assert.AreEqual(4, beatmapInfo.GridSize); - Assert.AreEqual(2, beatmapInfo.TimelineZoom); + Assert.AreEqual(expectedBookmarks[i], beatmap.BeatmapInfo.Bookmarks[i]); + Assert.AreEqual(1.8, beatmap.DistanceSpacing); + Assert.AreEqual(4, beatmap.BeatmapInfo.BeatDivisor); + Assert.AreEqual(4, beatmap.BeatmapInfo.GridSize); + Assert.AreEqual(2, beatmap.BeatmapInfo.TimelineZoom); } } diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 92715b6aa2..4832ee26b7 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -76,7 +76,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(expectedBookmarks.Length, beatmapInfo.Bookmarks.Length); for (int i = 0; i < expectedBookmarks.Length; i++) Assert.AreEqual(expectedBookmarks[i], beatmapInfo.Bookmarks[i]); - Assert.AreEqual(1.8, beatmapInfo.DistanceSpacing); + Assert.AreEqual(1.8, beatmap.DistanceSpacing); Assert.AreEqual(4, beatmapInfo.BeatDivisor); Assert.AreEqual(4, beatmapInfo.GridSize); Assert.AreEqual(2, beatmapInfo.TimelineZoom); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs index f392841ac7..d77c86729a 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneHitObjectComposer.cs @@ -165,7 +165,7 @@ namespace osu.Game.Tests.Visual.Editing { double originalSpacing = 0; - AddStep("retrieve original spacing", () => originalSpacing = editorBeatmap.BeatmapInfo.DistanceSpacing); + AddStep("retrieve original spacing", () => originalSpacing = editorBeatmap.DistanceSpacing); AddStep("hold ctrl", () => InputManager.PressKey(Key.LControl)); AddStep("hold alt", () => InputManager.PressKey(Key.LAlt)); @@ -175,7 +175,7 @@ namespace osu.Game.Tests.Visual.Editing AddStep("release alt", () => InputManager.ReleaseKey(Key.LAlt)); AddStep("release ctrl", () => InputManager.ReleaseKey(Key.LControl)); - AddAssert("distance spacing increased by 0.5", () => editorBeatmap.BeatmapInfo.DistanceSpacing == originalSpacing + 0.5); + AddAssert("distance spacing increased by 0.5", () => editorBeatmap.DistanceSpacing == originalSpacing + 0.5); } public partial class EditorBeatmapContainer : PopoverContainer diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 76864a1d70..2f7c00af4a 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -128,6 +128,8 @@ namespace osu.Game.Beatmaps public bool SamplesMatchPlaybackRate { get; set; } = true; + public double DistanceSpacing { get; set; } = 1.0; + IBeatmap IBeatmap.Clone() => Clone(); public Beatmap Clone() => (Beatmap)MemberwiseClone(); diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index b86a445aa8..eda7f8025f 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -74,6 +74,7 @@ namespace osu.Game.Beatmaps beatmap.WidescreenStoryboard = original.WidescreenStoryboard; beatmap.EpilepsyWarning = original.EpilepsyWarning; beatmap.SamplesMatchPlaybackRate = original.SamplesMatchPlaybackRate; + beatmap.DistanceSpacing = original.DistanceSpacing; return beatmap; } diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index 650b0bf510..a8964a365a 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -414,7 +414,6 @@ namespace osu.Game.Beatmaps Hash = hash, DifficultyName = decodedInfo.DifficultyName, OnlineID = decodedInfo.OnlineID, - DistanceSpacing = decodedInfo.DistanceSpacing, BeatDivisor = decodedInfo.BeatDivisor, GridSize = decodedInfo.GridSize, TimelineZoom = decodedInfo.TimelineZoom, diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 93abfa8d9b..8328e3df95 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -6,14 +6,12 @@ using System.Diagnostics; using System.Linq; using JetBrains.Annotations; using Newtonsoft.Json; -using osu.Game.Beatmaps.ControlPoints; using osu.Game.Collections; using osu.Game.Database; using osu.Game.Models; using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.BeatmapSet.Scores; using osu.Game.Rulesets; -using osu.Game.Rulesets.Edit; using osu.Game.Scoring; using Realms; @@ -143,18 +141,6 @@ namespace osu.Game.Beatmaps /// public DateTimeOffset? LastPlayed { get; set; } - /// - /// The ratio of distance travelled per time unit. - /// Generally used to decouple the spacing between hit objects from the enforced "velocity" of the beatmap (see ). - /// - /// - /// The most common method of understanding is that at a default value of 1.0, the time-to-distance ratio will match the slider velocity of the beatmap - /// at the current point in time. Increasing this value will make hit objects more spaced apart when compared to the cursor movement required to track a slider. - /// - /// This is only a hint property, used by the editor in implementations. It does not directly affect the beatmap or gameplay. - /// - public double DistanceSpacing { get; set; } = 1.0; - public int BeatDivisor { get; set; } = 4; public int GridSize { get; set; } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 0c8770782d..92a26464ee 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -329,7 +329,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"DistanceSpacing": - beatmap.BeatmapInfo.DistanceSpacing = Math.Max(0, Parsing.ParseDouble(pair.Value)); + beatmap.DistanceSpacing = Math.Max(0, Parsing.ParseDouble(pair.Value)); break; case @"BeatDivisor": diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 860ca68f6b..a07e8d2226 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -112,7 +112,7 @@ namespace osu.Game.Beatmaps.Formats if (beatmap.BeatmapInfo.Bookmarks.Length > 0) writer.WriteLine(FormattableString.Invariant($"Bookmarks: {string.Join(',', beatmap.BeatmapInfo.Bookmarks)}")); - writer.WriteLine(FormattableString.Invariant($"DistanceSpacing: {beatmap.BeatmapInfo.DistanceSpacing}")); + writer.WriteLine(FormattableString.Invariant($"DistanceSpacing: {beatmap.DistanceSpacing}")); writer.WriteLine(FormattableString.Invariant($"BeatDivisor: {beatmap.BeatmapInfo.BeatDivisor}")); writer.WriteLine(FormattableString.Invariant($"GridSize: {beatmap.BeatmapInfo.GridSize}")); writer.WriteLine(FormattableString.Invariant($"TimelineZoom: {beatmap.BeatmapInfo.TimelineZoom}")); diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index 9900609f18..b2c8b7604a 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Beatmaps.Timing; +using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Scoring; @@ -82,6 +83,18 @@ namespace osu.Game.Beatmaps bool SamplesMatchPlaybackRate { get; internal set; } + /// + /// The ratio of distance travelled per time unit. + /// Generally used to decouple the spacing between hit objects from the enforced "velocity" of the beatmap (see ). + /// + /// + /// The most common method of understanding is that at a default value of 1.0, the time-to-distance ratio will match the slider velocity of the beatmap + /// at the current point in time. Increasing this value will make hit objects more spaced apart when compared to the cursor movement required to track a slider. + /// + /// This is only a hint property, used by the editor in implementations. It does not directly affect the beatmap or gameplay. + /// + double DistanceSpacing { get; internal set; } + /// /// Creates a shallow-clone of this beatmap and returns it. /// diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index 960eab6f2c..7473882c15 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -379,6 +379,12 @@ namespace osu.Game.Rulesets.Difficulty set => baseBeatmap.SamplesMatchPlaybackRate = value; } + public double DistanceSpacing + { + get => baseBeatmap.DistanceSpacing; + set => baseBeatmap.DistanceSpacing = value; + } + #endregion } } diff --git a/osu.Game/Rulesets/Edit/ComposerDistanceSnapProvider.cs b/osu.Game/Rulesets/Edit/ComposerDistanceSnapProvider.cs index b9850a94a3..665e6ba074 100644 --- a/osu.Game/Rulesets/Edit/ComposerDistanceSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/ComposerDistanceSnapProvider.cs @@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Edit } }); - DistanceSpacingMultiplier.Value = editorBeatmap.BeatmapInfo.DistanceSpacing; + DistanceSpacingMultiplier.Value = editorBeatmap.DistanceSpacing; DistanceSpacingMultiplier.BindValueChanged(multiplier => { distanceSpacingSlider.ContractedLabelText = $"D. S. ({multiplier.NewValue:0.##x})"; @@ -108,7 +108,7 @@ namespace osu.Game.Rulesets.Edit if (multiplier.NewValue != multiplier.OldValue) onScreenDisplay?.Display(new DistanceSpacingToast(multiplier.NewValue.ToLocalisableString(@"0.##x"), multiplier)); - editorBeatmap.BeatmapInfo.DistanceSpacing = multiplier.NewValue; + editorBeatmap.DistanceSpacing = multiplier.NewValue; }, true); DistanceSpacingMultiplier.BindDisabledChanged(disabled => distanceSpacingSlider.Alpha = disabled ? 0 : 1, true); diff --git a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs index 380038eadf..c312642fbd 100644 --- a/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs +++ b/osu.Game/Rulesets/Edit/IDistanceSnapProvider.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Edit /// A multiplier which changes the ratio of distance travelled per time unit. /// Importantly, this is provided for manual usage, and not multiplied into any of the methods exposed by this interface. /// - /// + /// Bindable DistanceSpacingMultiplier { get; } /// diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 4303764fa7..aa63dfab8d 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -226,6 +226,12 @@ namespace osu.Game.Screens.Edit set => PlayableBeatmap.SamplesMatchPlaybackRate = value; } + public double DistanceSpacing + { + get => PlayableBeatmap.DistanceSpacing; + set => PlayableBeatmap.DistanceSpacing = value; + } + public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone(); private IList mutableHitObjects => (IList)PlayableBeatmap.HitObjects; From 6685c5ab741441140e7e9ba4d1e67b29f3ce828a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 12 Jun 2024 13:44:36 +0200 Subject: [PATCH 09/54] Move `GridSize` out of `BeatmapInfo` --- .../Editor/TestSceneOsuEditorGrids.cs | 2 +- osu.Game.Rulesets.Osu/Edit/OsuGridToolboxGroup.cs | 4 ++-- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 2 +- osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- osu.Game/Beatmaps/Beatmap.cs | 2 ++ osu.Game/Beatmaps/BeatmapConverter.cs | 1 + osu.Game/Beatmaps/BeatmapImporter.cs | 1 - osu.Game/Beatmaps/BeatmapInfo.cs | 2 -- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 2 +- osu.Game/Beatmaps/IBeatmap.cs | 2 ++ osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs | 6 ++++++ osu.Game/Screens/Edit/EditorBeatmap.cs | 6 ++++++ 13 files changed, 24 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs index 48aa74c5bf..cb9347b177 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuEditorGrids.cs @@ -185,6 +185,6 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor private void gridSizeIs(int size) => AddAssert($"grid size is {size}", () => this.ChildrenOfType().Single().Spacing.Value == new Vector2(size) - && EditorBeatmap.BeatmapInfo.GridSize == size); + && EditorBeatmap.GridSize == size); } } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuGridToolboxGroup.cs b/osu.Game.Rulesets.Osu/Edit/OsuGridToolboxGroup.cs index 21cce553b1..3740c54752 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuGridToolboxGroup.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuGridToolboxGroup.cs @@ -111,7 +111,7 @@ namespace osu.Game.Rulesets.Osu.Edit }, }; - Spacing.Value = editorBeatmap.BeatmapInfo.GridSize; + Spacing.Value = editorBeatmap.GridSize; } protected override void LoadComplete() @@ -137,7 +137,7 @@ namespace osu.Game.Rulesets.Osu.Edit spacingSlider.ContractedLabelText = $"S: {spacing.NewValue:N0}"; spacingSlider.ExpandedLabelText = $"Spacing: {spacing.NewValue:N0}"; SpacingVector.Value = new Vector2(spacing.NewValue); - editorBeatmap.BeatmapInfo.GridSize = (int)spacing.NewValue; + editorBeatmap.GridSize = (int)spacing.NewValue; }, true); GridLinesRotation.BindValueChanged(rotation => diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 71dcd38bcd..a15485cdf1 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -114,7 +114,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(expectedBookmarks[i], beatmap.BeatmapInfo.Bookmarks[i]); Assert.AreEqual(1.8, beatmap.DistanceSpacing); Assert.AreEqual(4, beatmap.BeatmapInfo.BeatDivisor); - Assert.AreEqual(4, beatmap.BeatmapInfo.GridSize); + Assert.AreEqual(4, beatmap.GridSize); Assert.AreEqual(2, beatmap.BeatmapInfo.TimelineZoom); } } diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 4832ee26b7..95cba082a7 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -78,7 +78,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(expectedBookmarks[i], beatmapInfo.Bookmarks[i]); Assert.AreEqual(1.8, beatmap.DistanceSpacing); Assert.AreEqual(4, beatmapInfo.BeatDivisor); - Assert.AreEqual(4, beatmapInfo.GridSize); + Assert.AreEqual(4, beatmap.GridSize); Assert.AreEqual(2, beatmapInfo.TimelineZoom); } diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 2f7c00af4a..aacbe359b1 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -130,6 +130,8 @@ namespace osu.Game.Beatmaps public double DistanceSpacing { get; set; } = 1.0; + public int GridSize { get; set; } + IBeatmap IBeatmap.Clone() => Clone(); public Beatmap Clone() => (Beatmap)MemberwiseClone(); diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index eda7f8025f..a70d449fc5 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -75,6 +75,7 @@ namespace osu.Game.Beatmaps beatmap.EpilepsyWarning = original.EpilepsyWarning; beatmap.SamplesMatchPlaybackRate = original.SamplesMatchPlaybackRate; beatmap.DistanceSpacing = original.DistanceSpacing; + beatmap.GridSize = original.GridSize; return beatmap; } diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index a8964a365a..ff9bf4b477 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -415,7 +415,6 @@ namespace osu.Game.Beatmaps DifficultyName = decodedInfo.DifficultyName, OnlineID = decodedInfo.OnlineID, BeatDivisor = decodedInfo.BeatDivisor, - GridSize = decodedInfo.GridSize, TimelineZoom = decodedInfo.TimelineZoom, MD5Hash = memoryStream.ComputeMD5Hash(), EndTimeObjectCount = decoded.HitObjects.Count(h => h is IHasDuration), diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 8328e3df95..6b192063e8 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -143,8 +143,6 @@ namespace osu.Game.Beatmaps public int BeatDivisor { get; set; } = 4; - public int GridSize { get; set; } - public double TimelineZoom { get; set; } = 1.0; /// diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 92a26464ee..80bfae3036 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -337,7 +337,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"GridSize": - beatmap.BeatmapInfo.GridSize = Parsing.ParseInt(pair.Value); + beatmap.GridSize = Parsing.ParseInt(pair.Value); break; case @"TimelineZoom": diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index a07e8d2226..1bfba0962c 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -114,7 +114,7 @@ namespace osu.Game.Beatmaps.Formats writer.WriteLine(FormattableString.Invariant($"Bookmarks: {string.Join(',', beatmap.BeatmapInfo.Bookmarks)}")); writer.WriteLine(FormattableString.Invariant($"DistanceSpacing: {beatmap.DistanceSpacing}")); writer.WriteLine(FormattableString.Invariant($"BeatDivisor: {beatmap.BeatmapInfo.BeatDivisor}")); - writer.WriteLine(FormattableString.Invariant($"GridSize: {beatmap.BeatmapInfo.GridSize}")); + writer.WriteLine(FormattableString.Invariant($"GridSize: {beatmap.GridSize}")); writer.WriteLine(FormattableString.Invariant($"TimelineZoom: {beatmap.BeatmapInfo.TimelineZoom}")); } diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index b2c8b7604a..ecfc8ea398 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -95,6 +95,8 @@ namespace osu.Game.Beatmaps /// double DistanceSpacing { get; internal set; } + int GridSize { get; internal set; } + /// /// Creates a shallow-clone of this beatmap and returns it. /// diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index 7473882c15..d4a95558cc 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -385,6 +385,12 @@ namespace osu.Game.Rulesets.Difficulty set => baseBeatmap.DistanceSpacing = value; } + public int GridSize + { + get => baseBeatmap.GridSize; + set => baseBeatmap.GridSize = value; + } + #endregion } } diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index aa63dfab8d..b1df60126d 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -232,6 +232,12 @@ namespace osu.Game.Screens.Edit set => PlayableBeatmap.DistanceSpacing = value; } + public int GridSize + { + get => PlayableBeatmap.GridSize; + set => PlayableBeatmap.GridSize = value; + } + public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone(); private IList mutableHitObjects => (IList)PlayableBeatmap.HitObjects; From 7f2a6f6f5a143e44ca427060eee77c5acad84d5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 12 Jun 2024 13:54:31 +0200 Subject: [PATCH 10/54] Move `TimelineZoom` out of `BeatmapInfo` --- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 2 +- osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs | 8 ++++---- osu.Game/Beatmaps/Beatmap.cs | 2 ++ osu.Game/Beatmaps/BeatmapConverter.cs | 1 + osu.Game/Beatmaps/BeatmapImporter.cs | 1 - osu.Game/Beatmaps/BeatmapInfo.cs | 2 -- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 2 +- osu.Game/Beatmaps/IBeatmap.cs | 2 ++ osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs | 6 ++++++ .../Screens/Edit/Compose/Components/Timeline/Timeline.cs | 6 +++--- osu.Game/Screens/Edit/EditorBeatmap.cs | 6 ++++++ 13 files changed, 28 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index a15485cdf1..af0e4a8b3c 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -115,7 +115,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(1.8, beatmap.DistanceSpacing); Assert.AreEqual(4, beatmap.BeatmapInfo.BeatDivisor); Assert.AreEqual(4, beatmap.GridSize); - Assert.AreEqual(2, beatmap.BeatmapInfo.TimelineZoom); + Assert.AreEqual(2, beatmap.TimelineZoom); } } diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 95cba082a7..1fed9633f7 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -79,7 +79,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(1.8, beatmap.DistanceSpacing); Assert.AreEqual(4, beatmapInfo.BeatDivisor); Assert.AreEqual(4, beatmap.GridSize); - Assert.AreEqual(2, beatmapInfo.TimelineZoom); + Assert.AreEqual(2, beatmap.TimelineZoom); } [Test] diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs index 64c48e74cf..429b458b9f 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorSaving.cs @@ -70,7 +70,7 @@ namespace osu.Game.Tests.Visual.Editing AddStep("Set beat divisor", () => Editor.Dependencies.Get().Value = 16); AddStep("Set timeline zoom", () => { - originalTimelineZoom = EditorBeatmap.BeatmapInfo.TimelineZoom; + originalTimelineZoom = EditorBeatmap.TimelineZoom; var timeline = Editor.ChildrenOfType().Single(); InputManager.MoveMouseTo(timeline); @@ -81,19 +81,19 @@ namespace osu.Game.Tests.Visual.Editing AddAssert("Ensure timeline zoom changed", () => { - changedTimelineZoom = EditorBeatmap.BeatmapInfo.TimelineZoom; + changedTimelineZoom = EditorBeatmap.TimelineZoom; return !Precision.AlmostEquals(changedTimelineZoom, originalTimelineZoom); }); SaveEditor(); AddAssert("Beatmap has correct beat divisor", () => EditorBeatmap.BeatmapInfo.BeatDivisor == 16); - AddAssert("Beatmap has correct timeline zoom", () => EditorBeatmap.BeatmapInfo.TimelineZoom == changedTimelineZoom); + AddAssert("Beatmap has correct timeline zoom", () => EditorBeatmap.TimelineZoom == changedTimelineZoom); ReloadEditorToSameBeatmap(); AddAssert("Beatmap still has correct beat divisor", () => EditorBeatmap.BeatmapInfo.BeatDivisor == 16); - AddAssert("Beatmap still has correct timeline zoom", () => EditorBeatmap.BeatmapInfo.TimelineZoom == changedTimelineZoom); + AddAssert("Beatmap still has correct timeline zoom", () => EditorBeatmap.TimelineZoom == changedTimelineZoom); } [Test] diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index aacbe359b1..35bd935d66 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -132,6 +132,8 @@ namespace osu.Game.Beatmaps public int GridSize { get; set; } + public double TimelineZoom { get; set; } = 1.0; + IBeatmap IBeatmap.Clone() => Clone(); public Beatmap Clone() => (Beatmap)MemberwiseClone(); diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index a70d449fc5..140771a5d5 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -76,6 +76,7 @@ namespace osu.Game.Beatmaps beatmap.SamplesMatchPlaybackRate = original.SamplesMatchPlaybackRate; beatmap.DistanceSpacing = original.DistanceSpacing; beatmap.GridSize = original.GridSize; + beatmap.TimelineZoom = original.TimelineZoom; return beatmap; } diff --git a/osu.Game/Beatmaps/BeatmapImporter.cs b/osu.Game/Beatmaps/BeatmapImporter.cs index ff9bf4b477..e230f912ab 100644 --- a/osu.Game/Beatmaps/BeatmapImporter.cs +++ b/osu.Game/Beatmaps/BeatmapImporter.cs @@ -415,7 +415,6 @@ namespace osu.Game.Beatmaps DifficultyName = decodedInfo.DifficultyName, OnlineID = decodedInfo.OnlineID, BeatDivisor = decodedInfo.BeatDivisor, - TimelineZoom = decodedInfo.TimelineZoom, MD5Hash = memoryStream.ComputeMD5Hash(), EndTimeObjectCount = decoded.HitObjects.Count(h => h is IHasDuration), TotalObjectCount = decoded.HitObjects.Count diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 6b192063e8..39cd320ad7 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -143,8 +143,6 @@ namespace osu.Game.Beatmaps public int BeatDivisor { get; set; } = 4; - public double TimelineZoom { get; set; } = 1.0; - /// /// The time in milliseconds when last exiting the editor with this beatmap loaded. /// diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 80bfae3036..cb2b1820d7 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -341,7 +341,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"TimelineZoom": - beatmap.BeatmapInfo.TimelineZoom = Math.Max(0, Parsing.ParseDouble(pair.Value)); + beatmap.TimelineZoom = Math.Max(0, Parsing.ParseDouble(pair.Value)); break; } } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 1bfba0962c..d705deb5df 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -115,7 +115,7 @@ namespace osu.Game.Beatmaps.Formats writer.WriteLine(FormattableString.Invariant($"DistanceSpacing: {beatmap.DistanceSpacing}")); writer.WriteLine(FormattableString.Invariant($"BeatDivisor: {beatmap.BeatmapInfo.BeatDivisor}")); writer.WriteLine(FormattableString.Invariant($"GridSize: {beatmap.GridSize}")); - writer.WriteLine(FormattableString.Invariant($"TimelineZoom: {beatmap.BeatmapInfo.TimelineZoom}")); + writer.WriteLine(FormattableString.Invariant($"TimelineZoom: {beatmap.TimelineZoom}")); } private void handleMetadata(TextWriter writer) diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index ecfc8ea398..99a9d31807 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -97,6 +97,8 @@ namespace osu.Game.Beatmaps int GridSize { get; internal set; } + double TimelineZoom { get; internal set; } + /// /// Creates a shallow-clone of this beatmap and returns it. /// diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index d4a95558cc..ebdde0fca6 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -391,6 +391,12 @@ namespace osu.Game.Rulesets.Difficulty set => baseBeatmap.GridSize = value; } + public double TimelineZoom + { + get => baseBeatmap.TimelineZoom; + set => baseBeatmap.TimelineZoom = value; + } + #endregion } } diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index a2704e550c..7c1f2e3730 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -147,7 +147,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline Scheduler.AddOnce(applyVisualOffset, beatmap); }, true); - Zoom = (float)(defaultTimelineZoom * editorBeatmap.BeatmapInfo.TimelineZoom); + Zoom = (float)(defaultTimelineZoom * editorBeatmap.TimelineZoom); } private void applyVisualOffset(IBindable beatmap) @@ -215,7 +215,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline float minimumZoom = getZoomLevelForVisibleMilliseconds(10000); float maximumZoom = getZoomLevelForVisibleMilliseconds(500); - float initialZoom = (float)Math.Clamp(defaultTimelineZoom * (editorBeatmap.BeatmapInfo.TimelineZoom == 0 ? 1 : editorBeatmap.BeatmapInfo.TimelineZoom), minimumZoom, maximumZoom); + float initialZoom = (float)Math.Clamp(defaultTimelineZoom * (editorBeatmap.TimelineZoom == 0 ? 1 : editorBeatmap.TimelineZoom), minimumZoom, maximumZoom); SetupZoom(initialZoom, minimumZoom, maximumZoom); @@ -237,7 +237,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline protected override void OnZoomChanged() { base.OnZoomChanged(); - editorBeatmap.BeatmapInfo.TimelineZoom = Zoom / defaultTimelineZoom; + editorBeatmap.TimelineZoom = Zoom / defaultTimelineZoom; } protected override void UpdateAfterChildren() diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index b1df60126d..0d07e16828 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -238,6 +238,12 @@ namespace osu.Game.Screens.Edit set => PlayableBeatmap.GridSize = value; } + public double TimelineZoom + { + get => PlayableBeatmap.TimelineZoom; + set => PlayableBeatmap.TimelineZoom = value; + } + public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone(); private IList mutableHitObjects => (IList)PlayableBeatmap.HitObjects; From d373f752d667c35ae68ef47eced2dcb3c94920ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 12 Jun 2024 13:58:00 +0200 Subject: [PATCH 11/54] Move `Countdown` out of `BeatmapInfo` --- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 4 ++-- osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- osu.Game.Tests/Visual/Editing/TestSceneDesignSection.cs | 8 ++++---- osu.Game/Beatmaps/Beatmap.cs | 2 ++ osu.Game/Beatmaps/BeatmapInfo.cs | 3 --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 2 +- osu.Game/Beatmaps/IBeatmap.cs | 2 ++ osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs | 6 ++++++ osu.Game/Screens/Edit/EditorBeatmap.cs | 6 ++++++ osu.Game/Screens/Edit/Setup/DesignSection.cs | 6 +++--- 11 files changed, 28 insertions(+), 15 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index af0e4a8b3c..9cea6ef507 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -88,7 +88,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsFalse(beatmap.SpecialStyle); Assert.IsFalse(beatmap.WidescreenStoryboard); Assert.IsFalse(beatmap.SamplesMatchPlaybackRate); - Assert.AreEqual(CountdownType.None, beatmapInfo.Countdown); + Assert.AreEqual(CountdownType.None, beatmap.Countdown); Assert.AreEqual(0, beatmapInfo.CountdownOffset); } } @@ -957,7 +957,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.That(decoded.WidescreenStoryboard, Is.False); Assert.That(decoded.EpilepsyWarning, Is.False); Assert.That(decoded.SamplesMatchPlaybackRate, Is.False); - Assert.That(decoded.BeatmapInfo.Countdown, Is.EqualTo(CountdownType.Normal)); + Assert.That(decoded.Countdown, Is.EqualTo(CountdownType.Normal)); Assert.That(decoded.BeatmapInfo.CountdownOffset, Is.EqualTo(0)); Assert.That(decoded.BeatmapInfo.Metadata.PreviewTime, Is.EqualTo(-1)); Assert.That(decoded.BeatmapInfo.Ruleset.OnlineID, Is.EqualTo(0)); diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 1fed9633f7..bc6628cea0 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsTrue(beatmapInfo.Ruleset.OnlineID == 0); Assert.AreEqual(false, beatmap.LetterboxInBreaks); Assert.AreEqual(false, beatmap.WidescreenStoryboard); - Assert.AreEqual(CountdownType.None, beatmapInfo.Countdown); + Assert.AreEqual(CountdownType.None, beatmap.Countdown); Assert.AreEqual(0, beatmapInfo.CountdownOffset); } diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDesignSection.cs b/osu.Game.Tests/Visual/Editing/TestSceneDesignSection.cs index 9a66e1676d..c91c22a145 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDesignSection.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDesignSection.cs @@ -51,7 +51,7 @@ namespace osu.Game.Tests.Visual.Editing { AddStep("turn countdown off", () => designSection.EnableCountdown.Current.Value = false); - AddAssert("beatmap has correct type", () => editorBeatmap.BeatmapInfo.Countdown == CountdownType.None); + AddAssert("beatmap has correct type", () => editorBeatmap.Countdown == CountdownType.None); AddUntilStep("other controls hidden", () => !designSection.CountdownSettings.IsPresent); } @@ -60,12 +60,12 @@ namespace osu.Game.Tests.Visual.Editing { AddStep("turn countdown on", () => designSection.EnableCountdown.Current.Value = true); - AddAssert("beatmap has correct type", () => editorBeatmap.BeatmapInfo.Countdown == CountdownType.Normal); + AddAssert("beatmap has correct type", () => editorBeatmap.Countdown == CountdownType.Normal); AddUntilStep("other controls shown", () => designSection.CountdownSettings.IsPresent); AddStep("change countdown speed", () => designSection.CountdownSpeed.Current.Value = CountdownType.DoubleSpeed); - AddAssert("beatmap has correct type", () => editorBeatmap.BeatmapInfo.Countdown == CountdownType.DoubleSpeed); + AddAssert("beatmap has correct type", () => editorBeatmap.Countdown == CountdownType.DoubleSpeed); AddUntilStep("other controls still shown", () => designSection.CountdownSettings.IsPresent); } @@ -74,7 +74,7 @@ namespace osu.Game.Tests.Visual.Editing { AddStep("turn countdown on", () => designSection.EnableCountdown.Current.Value = true); - AddAssert("beatmap has correct type", () => editorBeatmap.BeatmapInfo.Countdown == CountdownType.Normal); + AddAssert("beatmap has correct type", () => editorBeatmap.Countdown == CountdownType.Normal); checkOffsetAfter("1", 1); checkOffsetAfter(string.Empty, 0); diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 35bd935d66..54fb1fd3b1 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -134,6 +134,8 @@ namespace osu.Game.Beatmaps public double TimelineZoom { get; set; } = 1.0; + public CountdownType Countdown { get; set; } = CountdownType.Normal; + IBeatmap IBeatmap.Clone() => Clone(); public Beatmap Clone() => (Beatmap)MemberwiseClone(); diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 39cd320ad7..0214ae4c3a 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -148,9 +148,6 @@ namespace osu.Game.Beatmaps /// public double? EditorTimestamp { get; set; } - [Ignored] - public CountdownType Countdown { get; set; } = CountdownType.Normal; - /// /// The number of beats to move the countdown backwards (compared to its default location). /// diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index cb2b1820d7..48959025c9 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -305,7 +305,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"Countdown": - beatmap.BeatmapInfo.Countdown = Enum.Parse(pair.Value); + beatmap.Countdown = Enum.Parse(pair.Value); break; case @"CountdownOffset": diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index d705deb5df..73399e93d0 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -81,7 +81,7 @@ namespace osu.Game.Beatmaps.Formats if (!string.IsNullOrEmpty(beatmap.Metadata.AudioFile)) writer.WriteLine(FormattableString.Invariant($"AudioFilename: {Path.GetFileName(beatmap.Metadata.AudioFile)}")); writer.WriteLine(FormattableString.Invariant($"AudioLeadIn: {beatmap.AudioLeadIn}")); writer.WriteLine(FormattableString.Invariant($"PreviewTime: {beatmap.Metadata.PreviewTime}")); - writer.WriteLine(FormattableString.Invariant($"Countdown: {(int)beatmap.BeatmapInfo.Countdown}")); + writer.WriteLine(FormattableString.Invariant($"Countdown: {(int)beatmap.Countdown}")); writer.WriteLine(FormattableString.Invariant( $"SampleSet: {toLegacySampleBank(((beatmap.ControlPointInfo as LegacyControlPointInfo)?.SamplePoints.FirstOrDefault() ?? SampleControlPoint.DEFAULT).SampleBank)}")); writer.WriteLine(FormattableString.Invariant($"StackLeniency: {beatmap.StackLeniency}")); diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index 99a9d31807..cf7bd29088 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -99,6 +99,8 @@ namespace osu.Game.Beatmaps double TimelineZoom { get; internal set; } + CountdownType Countdown { get; internal set; } + /// /// Creates a shallow-clone of this beatmap and returns it. /// diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index ebdde0fca6..a444cc135b 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -397,6 +397,12 @@ namespace osu.Game.Rulesets.Difficulty set => baseBeatmap.TimelineZoom = value; } + public CountdownType Countdown + { + get => baseBeatmap.Countdown; + set => baseBeatmap.Countdown = value; + } + #endregion } } diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 0d07e16828..a86d1fbaef 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -244,6 +244,12 @@ namespace osu.Game.Screens.Edit set => PlayableBeatmap.TimelineZoom = value; } + public CountdownType Countdown + { + get => PlayableBeatmap.Countdown; + set => PlayableBeatmap.Countdown = value; + } + public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone(); private IList mutableHitObjects => (IList)PlayableBeatmap.HitObjects; diff --git a/osu.Game/Screens/Edit/Setup/DesignSection.cs b/osu.Game/Screens/Edit/Setup/DesignSection.cs index 4c4755064f..b40f1bea72 100644 --- a/osu.Game/Screens/Edit/Setup/DesignSection.cs +++ b/osu.Game/Screens/Edit/Setup/DesignSection.cs @@ -38,7 +38,7 @@ namespace osu.Game.Screens.Edit.Setup EnableCountdown = new LabelledSwitchButton { Label = EditorSetupStrings.EnableCountdown, - Current = { Value = Beatmap.BeatmapInfo.Countdown != CountdownType.None }, + Current = { Value = Beatmap.Countdown != CountdownType.None }, Description = EditorSetupStrings.CountdownDescription }, CountdownSettings = new FillFlowContainer @@ -52,7 +52,7 @@ namespace osu.Game.Screens.Edit.Setup CountdownSpeed = new LabelledEnumDropdown { Label = EditorSetupStrings.CountdownSpeed, - Current = { Value = Beatmap.BeatmapInfo.Countdown != CountdownType.None ? Beatmap.BeatmapInfo.Countdown : CountdownType.Normal }, + Current = { Value = Beatmap.Countdown != CountdownType.None ? Beatmap.Countdown : CountdownType.Normal }, Items = Enum.GetValues().Where(type => type != CountdownType.None) }, CountdownOffset = new LabelledNumberBox @@ -118,7 +118,7 @@ namespace osu.Game.Screens.Edit.Setup private void updateBeatmap() { - Beatmap.BeatmapInfo.Countdown = EnableCountdown.Current.Value ? CountdownSpeed.Current.Value : CountdownType.None; + Beatmap.Countdown = EnableCountdown.Current.Value ? CountdownSpeed.Current.Value : CountdownType.None; Beatmap.BeatmapInfo.CountdownOffset = int.TryParse(CountdownOffset.Current.Value, NumberStyles.None, CultureInfo.InvariantCulture, out int offset) ? offset : 0; Beatmap.WidescreenStoryboard = widescreenSupport.Current.Value; From dd50d6fa6e61d02e7e0a995a8e47569a5d7564e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 12 Jun 2024 14:03:02 +0200 Subject: [PATCH 12/54] Move `CountdownOffset` out of `BeatmapInfo` --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 4 ++-- osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- .../Database/RealmSubscriptionRegistrationTests.cs | 2 +- osu.Game.Tests/Visual/Editing/TestSceneDesignSection.cs | 2 +- osu.Game/Beatmaps/Beatmap.cs | 2 ++ osu.Game/Beatmaps/BeatmapConverter.cs | 1 + osu.Game/Beatmaps/BeatmapInfo.cs | 5 ----- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 2 +- osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs | 4 ++-- osu.Game/Beatmaps/IBeatmap.cs | 5 +++++ osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs | 6 ++++++ osu.Game/Screens/Edit/EditorBeatmap.cs | 6 ++++++ osu.Game/Screens/Edit/Setup/DesignSection.cs | 6 +++--- 13 files changed, 31 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 9cea6ef507..ab0ec7ee39 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -89,7 +89,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.IsFalse(beatmap.WidescreenStoryboard); Assert.IsFalse(beatmap.SamplesMatchPlaybackRate); Assert.AreEqual(CountdownType.None, beatmap.Countdown); - Assert.AreEqual(0, beatmapInfo.CountdownOffset); + Assert.AreEqual(0, beatmap.CountdownOffset); } } @@ -958,7 +958,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.That(decoded.EpilepsyWarning, Is.False); Assert.That(decoded.SamplesMatchPlaybackRate, Is.False); Assert.That(decoded.Countdown, Is.EqualTo(CountdownType.Normal)); - Assert.That(decoded.BeatmapInfo.CountdownOffset, Is.EqualTo(0)); + Assert.That(decoded.CountdownOffset, Is.EqualTo(0)); Assert.That(decoded.BeatmapInfo.Metadata.PreviewTime, Is.EqualTo(-1)); Assert.That(decoded.BeatmapInfo.Ruleset.OnlineID, Is.EqualTo(0)); }); diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index bc6628cea0..e57a4fff62 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -58,7 +58,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(false, beatmap.LetterboxInBreaks); Assert.AreEqual(false, beatmap.WidescreenStoryboard); Assert.AreEqual(CountdownType.None, beatmap.Countdown); - Assert.AreEqual(0, beatmapInfo.CountdownOffset); + Assert.AreEqual(0, beatmap.CountdownOffset); } [Test] diff --git a/osu.Game.Tests/Database/RealmSubscriptionRegistrationTests.cs b/osu.Game.Tests/Database/RealmSubscriptionRegistrationTests.cs index 45842a952a..541f3b0417 100644 --- a/osu.Game.Tests/Database/RealmSubscriptionRegistrationTests.cs +++ b/osu.Game.Tests/Database/RealmSubscriptionRegistrationTests.cs @@ -41,7 +41,7 @@ namespace osu.Game.Tests.Database Assert.That(lastChanges?.ModifiedIndices, Is.Empty); Assert.That(lastChanges?.NewModifiedIndices, Is.Empty); - realm.Write(r => r.All().First().Beatmaps.First().CountdownOffset = 5); + realm.Write(r => r.All().First().Beatmaps.First().EditorTimestamp = 5); realm.Run(r => r.Refresh()); Assert.That(collectionChanges, Is.EqualTo(1)); diff --git a/osu.Game.Tests/Visual/Editing/TestSceneDesignSection.cs b/osu.Game.Tests/Visual/Editing/TestSceneDesignSection.cs index c91c22a145..0011a4ceb4 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneDesignSection.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneDesignSection.cs @@ -94,7 +94,7 @@ namespace osu.Game.Tests.Visual.Editing AddStep("commit text", () => InputManager.Key(Key.Enter)); AddAssert($"displayed value is {expectedFinalValue}", () => designSection.CountdownOffset.Current.Value == expectedFinalValue.ToString(CultureInfo.InvariantCulture)); - AddAssert($"beatmap value is {expectedFinalValue}", () => editorBeatmap.BeatmapInfo.CountdownOffset == expectedFinalValue); + AddAssert($"beatmap value is {expectedFinalValue}", () => editorBeatmap.CountdownOffset == expectedFinalValue); } private partial class TestDesignSection : DesignSection diff --git a/osu.Game/Beatmaps/Beatmap.cs b/osu.Game/Beatmaps/Beatmap.cs index 54fb1fd3b1..19a7ee3303 100644 --- a/osu.Game/Beatmaps/Beatmap.cs +++ b/osu.Game/Beatmaps/Beatmap.cs @@ -136,6 +136,8 @@ namespace osu.Game.Beatmaps public CountdownType Countdown { get; set; } = CountdownType.Normal; + public int CountdownOffset { get; set; } + IBeatmap IBeatmap.Clone() => Clone(); public Beatmap Clone() => (Beatmap)MemberwiseClone(); diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index 140771a5d5..8e917a179e 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -77,6 +77,7 @@ namespace osu.Game.Beatmaps beatmap.DistanceSpacing = original.DistanceSpacing; beatmap.GridSize = original.GridSize; beatmap.TimelineZoom = original.TimelineZoom; + beatmap.CountdownOffset = original.CountdownOffset; return beatmap; } diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 0214ae4c3a..3ed15f52fb 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -148,11 +148,6 @@ namespace osu.Game.Beatmaps /// public double? EditorTimestamp { get; set; } - /// - /// The number of beats to move the countdown backwards (compared to its default location). - /// - public int CountdownOffset { get; set; } - #endregion public bool Equals(BeatmapInfo? other) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 48959025c9..14de31a2a3 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -309,7 +309,7 @@ namespace osu.Game.Beatmaps.Formats break; case @"CountdownOffset": - beatmap.BeatmapInfo.CountdownOffset = Parsing.ParseInt(pair.Value); + beatmap.CountdownOffset = Parsing.ParseInt(pair.Value); break; } } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs index 73399e93d0..b924b7aea5 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapEncoder.cs @@ -97,8 +97,8 @@ namespace osu.Game.Beatmaps.Formats // writer.WriteLine(@"SkinPreference:" + b.SkinPreference); if (beatmap.EpilepsyWarning) writer.WriteLine(@"EpilepsyWarning: 1"); - if (beatmap.BeatmapInfo.CountdownOffset > 0) - writer.WriteLine(FormattableString.Invariant($@"CountdownOffset: {beatmap.BeatmapInfo.CountdownOffset}")); + if (beatmap.CountdownOffset > 0) + writer.WriteLine(FormattableString.Invariant($@"CountdownOffset: {beatmap.CountdownOffset}")); if (onlineRulesetID == 3) writer.WriteLine(FormattableString.Invariant($"SpecialStyle: {(beatmap.SpecialStyle ? '1' : '0')}")); writer.WriteLine(FormattableString.Invariant($"WidescreenStoryboard: {(beatmap.WidescreenStoryboard ? '1' : '0')}")); diff --git a/osu.Game/Beatmaps/IBeatmap.cs b/osu.Game/Beatmaps/IBeatmap.cs index cf7bd29088..f08fdfaf6a 100644 --- a/osu.Game/Beatmaps/IBeatmap.cs +++ b/osu.Game/Beatmaps/IBeatmap.cs @@ -101,6 +101,11 @@ namespace osu.Game.Beatmaps CountdownType Countdown { get; internal set; } + /// + /// The number of beats to move the countdown backwards (compared to its default location). + /// + int CountdownOffset { get; internal set; } + /// /// Creates a shallow-clone of this beatmap and returns it. /// diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index a444cc135b..6dd85cefe4 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -403,6 +403,12 @@ namespace osu.Game.Rulesets.Difficulty set => baseBeatmap.Countdown = value; } + public int CountdownOffset + { + get => baseBeatmap.CountdownOffset; + set => baseBeatmap.CountdownOffset = value; + } + #endregion } } diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index a86d1fbaef..deb46c3d2e 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -250,6 +250,12 @@ namespace osu.Game.Screens.Edit set => PlayableBeatmap.Countdown = value; } + public int CountdownOffset + { + get => PlayableBeatmap.CountdownOffset; + set => PlayableBeatmap.CountdownOffset = value; + } + public IBeatmap Clone() => (EditorBeatmap)MemberwiseClone(); private IList mutableHitObjects => (IList)PlayableBeatmap.HitObjects; diff --git a/osu.Game/Screens/Edit/Setup/DesignSection.cs b/osu.Game/Screens/Edit/Setup/DesignSection.cs index b40f1bea72..3ed0a78175 100644 --- a/osu.Game/Screens/Edit/Setup/DesignSection.cs +++ b/osu.Game/Screens/Edit/Setup/DesignSection.cs @@ -58,7 +58,7 @@ namespace osu.Game.Screens.Edit.Setup CountdownOffset = new LabelledNumberBox { Label = EditorSetupStrings.CountdownOffset, - Current = { Value = Beatmap.BeatmapInfo.CountdownOffset.ToString() }, + Current = { Value = Beatmap.CountdownOffset.ToString() }, Description = EditorSetupStrings.CountdownOffsetDescription, } } @@ -113,13 +113,13 @@ namespace osu.Game.Screens.Edit.Setup { updateBeatmap(); // update displayed text to ensure parsed value matches display (i.e. if empty string was provided). - CountdownOffset.Current.Value = Beatmap.BeatmapInfo.CountdownOffset.ToString(CultureInfo.InvariantCulture); + CountdownOffset.Current.Value = Beatmap.CountdownOffset.ToString(CultureInfo.InvariantCulture); } private void updateBeatmap() { Beatmap.Countdown = EnableCountdown.Current.Value ? CountdownSpeed.Current.Value : CountdownType.None; - Beatmap.BeatmapInfo.CountdownOffset = int.TryParse(CountdownOffset.Current.Value, NumberStyles.None, CultureInfo.InvariantCulture, out int offset) ? offset : 0; + Beatmap.CountdownOffset = int.TryParse(CountdownOffset.Current.Value, NumberStyles.None, CultureInfo.InvariantCulture, out int offset) ? offset : 0; Beatmap.WidescreenStoryboard = widescreenSupport.Current.Value; Beatmap.EpilepsyWarning = epilepsyWarning.Current.Value; From 9fbf2872e1a63547f44adafc790f8bc57a1c18a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 12 Jun 2024 14:27:35 +0200 Subject: [PATCH 13/54] Remove no longer applicable region marking --- osu.Game/Beatmaps/BeatmapInfo.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 3ed15f52fb..0a6719a96a 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -134,8 +134,6 @@ namespace osu.Game.Beatmaps Status = BeatmapOnlineStatus.None; } - #region Properties we may not want persisted (but also maybe no harm?) - /// /// The time at which this beatmap was last played by the local user. /// @@ -148,8 +146,6 @@ namespace osu.Game.Beatmaps /// public double? EditorTimestamp { get; set; } - #endregion - public bool Equals(BeatmapInfo? other) { if (ReferenceEquals(this, other)) return true; From c67e2dc301696654132b2d31f9f07abc4ede47c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 12 Jun 2024 14:51:20 +0200 Subject: [PATCH 14/54] Bump schema version --- osu.Game/Database/RealmAccess.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs index 1ece81be50..33b06f32b1 100644 --- a/osu.Game/Database/RealmAccess.cs +++ b/osu.Game/Database/RealmAccess.cs @@ -93,8 +93,9 @@ namespace osu.Game.Database /// 39 2023-12-19 Migrate any EndTimeObjectCount and TotalObjectCount values of 0 to -1 to better identify non-calculated values. /// 40 2023-12-21 Add ScoreInfo.Version to keep track of which build scores were set on. /// 41 2024-04-17 Add ScoreInfo.TotalScoreWithoutMods for future mod multiplier rebalances. + /// 42 2024-06-12 Removed several properties from ScoreInfo which did not need to be persisted to realm. /// - private const int schema_version = 41; + private const int schema_version = 42; /// /// Lock object which is held during sections, blocking realm retrieval during blocking periods. From 04527f3c9da63b5fc54d9afd3c7304b0634a8434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 13 Jun 2024 09:30:00 +0200 Subject: [PATCH 15/54] Fix `TestBeatmap` not transferring newly migrated properties --- osu.Game/Tests/Beatmaps/TestBeatmap.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game/Tests/Beatmaps/TestBeatmap.cs b/osu.Game/Tests/Beatmaps/TestBeatmap.cs index de7bcfcfaa..863badbd4a 100644 --- a/osu.Game/Tests/Beatmaps/TestBeatmap.cs +++ b/osu.Game/Tests/Beatmaps/TestBeatmap.cs @@ -28,6 +28,17 @@ namespace osu.Game.Tests.Beatmaps ControlPointInfo = baseBeatmap.ControlPointInfo; Breaks = baseBeatmap.Breaks; UnhandledEventLines = baseBeatmap.UnhandledEventLines; + AudioLeadIn = baseBeatmap.AudioLeadIn; + StackLeniency = baseBeatmap.StackLeniency; + SpecialStyle = baseBeatmap.SpecialStyle; + LetterboxInBreaks = baseBeatmap.LetterboxInBreaks; + WidescreenStoryboard = baseBeatmap.WidescreenStoryboard; + EpilepsyWarning = baseBeatmap.EpilepsyWarning; + SamplesMatchPlaybackRate = baseBeatmap.SamplesMatchPlaybackRate; + DistanceSpacing = baseBeatmap.DistanceSpacing; + GridSize = baseBeatmap.GridSize; + TimelineZoom = baseBeatmap.TimelineZoom; + CountdownOffset = baseBeatmap.CountdownOffset; if (withHitObjects) HitObjects = baseBeatmap.HitObjects; From 1d4d8063622dbc552fd695bfb6561fbe14b63e57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 23 Jul 2024 12:19:45 +0200 Subject: [PATCH 16/54] Fix `WidescreenStoryboard` breakage after moving out of `BeatmapInfo` --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 4 ++-- .../Beatmaps/Formats/LegacyStoryboardDecoder.cs | 15 +++++++++++++++ osu.Game/Beatmaps/WorkingBeatmap.cs | 7 ++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index f873eaf535..bd81892d95 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -80,7 +80,7 @@ namespace osu.Game.Beatmaps.Formats this.beatmap = beatmap; this.beatmap.BeatmapInfo.BeatmapVersion = FormatVersion; - applyLegacyDefaults(this.beatmap); + ApplyLegacyDefaults(this.beatmap); base.ParseStreamInto(stream, beatmap); @@ -186,7 +186,7 @@ namespace osu.Game.Beatmaps.Formats /// This method's intention is to restore those legacy defaults. /// See also: https://osu.ppy.sh/wiki/en/Client/File_formats/Osu_%28file_format%29 /// - private static void applyLegacyDefaults(Beatmap beatmap) + internal static void ApplyLegacyDefaults(Beatmap beatmap) { beatmap.WidescreenStoryboard = false; beatmap.SamplesMatchPlaybackRate = false; diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 2f9a256d31..dc96c2ff82 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -37,6 +37,17 @@ namespace osu.Game.Beatmaps.Formats SetFallbackDecoder(() => new LegacyStoryboardDecoder()); } + protected override Storyboard CreateTemplateObject() + { + var sb = base.CreateTemplateObject(); + + var beatmap = new Beatmap(); + LegacyBeatmapDecoder.ApplyLegacyDefaults(beatmap); + sb.Beatmap = beatmap; + + return sb; + } + protected override void ParseStreamInto(LineBufferedReader stream, Storyboard storyboard) { this.storyboard = storyboard; @@ -72,6 +83,10 @@ namespace osu.Game.Beatmaps.Formats case "UseSkinSprites": storyboard.UseSkinSprites = pair.Value == "1"; break; + + case @"WidescreenStoryboard": + storyboard.Beatmap.WidescreenStoryboard = Parsing.ParseInt(pair.Value) == 1; + break; } } diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 25159996f3..8b0d3dda6a 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -62,7 +62,12 @@ namespace osu.Game.Beatmaps #region Resource getters protected virtual Waveform GetWaveform() => new Waveform(null); - protected virtual Storyboard GetStoryboard() => new Storyboard { BeatmapInfo = BeatmapInfo }; + + protected virtual Storyboard GetStoryboard() => new Storyboard + { + BeatmapInfo = BeatmapInfo, + Beatmap = Beatmap, + }; protected abstract IBeatmap GetBeatmap(); public abstract Texture GetBackground(); From 29e7adcd3b195bc466cb7c434ce493c32e3e94c5 Mon Sep 17 00:00:00 2001 From: Sheppsu <49356627+Sheppsu@users.noreply.github.com> Date: Mon, 18 Nov 2024 03:57:50 -0500 Subject: [PATCH 17/54] add player settings to multi spectator screen --- .../Spectate/MultiSpectatorScreen.cs | 3 +- .../Spectate/MultiSpectatorSettings.cs | 81 +++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs index cb00763e6b..841aaf7a45 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs @@ -126,7 +126,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate syncManager = new SpectatorSyncManager(masterClockContainer) { ReadyToStart = performInitialSeek, - } + }, + new MultiSpectatorSettings() }; for (int i = 0; i < Users.Count; i++) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs new file mode 100644 index 0000000000..7ed6b95110 --- /dev/null +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs @@ -0,0 +1,81 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using osu.Game.Screens.Play.HUD; +using osuTK; + +namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate +{ + public partial class MultiSpectatorSettings : CompositeDrawable + { + private const double slide_duration = 200; + + private readonly PlayerSettingsOverlay playerSettingsOverlay; + private readonly Container slidingContainer; + + private readonly BindableBool opened = new BindableBool(); + + public MultiSpectatorSettings() + { + Origin = Anchor.TopLeft; + Anchor = Anchor.TopRight; + AutoSizeAxes = Axes.Both; + + InternalChildren = new Drawable[] + { + slidingContainer = new Container + { + Origin = Anchor.TopLeft, + Anchor = Anchor.TopLeft, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new IconButton + { + Icon = FontAwesome.Solid.Cog, + Origin = Anchor.TopLeft, + Anchor = Anchor.TopLeft, + Scale = new Vector2(1f), + Position = new Vector2(-30, 0), + Action = () => opened.Toggle() + }, + playerSettingsOverlay = new PlayerSettingsOverlay() + } + } + }; + + playerSettingsOverlay.Show(); + + opened.BindValueChanged(value => + { + if (value.NewValue) + open(); + else + close(); + }); + } + + private void open() + { + slidingContainer.MoveToOffset(new Vector2(-playerSettingsOverlay.Width, 0), slide_duration, Easing.Out).Then().OnComplete(c => + { + c.Origin = Anchor.TopRight; + c.Position = Vector2.Zero; + }); + } + + private void close() + { + slidingContainer.MoveToOffset(new Vector2(playerSettingsOverlay.Width, 0), slide_duration, Easing.Out).Then().OnComplete(c => + { + c.Origin = Anchor.TopLeft; + c.Position = Vector2.Zero; + }); + } + } +} From 7d4062d2adba94f38805f9b59ad047ce3822f260 Mon Sep 17 00:00:00 2001 From: Sheppsu <49356627+Sheppsu@users.noreply.github.com> Date: Mon, 18 Nov 2024 04:04:28 -0500 Subject: [PATCH 18/54] remove redundant Scale attribute --- .../OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs index 7ed6b95110..64c798b092 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs @@ -40,7 +40,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate Icon = FontAwesome.Solid.Cog, Origin = Anchor.TopLeft, Anchor = Anchor.TopLeft, - Scale = new Vector2(1f), Position = new Vector2(-30, 0), Action = () => opened.Toggle() }, From ead7e99c591aa037110635a304d9368a8ea2435a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 22 Nov 2024 11:06:36 +0100 Subject: [PATCH 19/54] Fix incorrect comment --- osu.Game/Database/RealmAccess.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Database/RealmAccess.cs b/osu.Game/Database/RealmAccess.cs index 698acc9822..a520040ad1 100644 --- a/osu.Game/Database/RealmAccess.cs +++ b/osu.Game/Database/RealmAccess.cs @@ -94,7 +94,7 @@ namespace osu.Game.Database /// 41 2024-04-17 Add ScoreInfo.TotalScoreWithoutMods for future mod multiplier rebalances. /// 42 2024-08-07 Update mania key bindings to reflect changes to ManiaAction /// 43 2024-10-14 Reset keybind for toggling FPS display to avoid conflict with "convert to stream" in the editor, if not already changed by user. - /// 44 2024-11-22 Removed several properties from ScoreInfo which did not need to be persisted to realm. + /// 44 2024-11-22 Removed several properties from BeatmapInfo which did not need to be persisted to realm. /// private const int schema_version = 44; From 3713bb48b775c00da2fbbb6d86b98fc7b8ddafa5 Mon Sep 17 00:00:00 2001 From: Sheppsu <49356627+Sheppsu@users.noreply.github.com> Date: Sat, 23 Nov 2024 01:09:58 -0500 Subject: [PATCH 20/54] expand and contract settings from hover --- .../Spectate/MultiSpectatorSettings.cs | 78 +++++++------------ 1 file changed, 29 insertions(+), 49 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs index 64c798b092..dfb26d104a 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs @@ -1,80 +1,60 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; +using osu.Framework.Input.Events; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Play.HUD; -using osuTK; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate { - public partial class MultiSpectatorSettings : CompositeDrawable + public partial class MultiSpectatorSettings : ExpandingContainer { - private const double slide_duration = 200; - - private readonly PlayerSettingsOverlay playerSettingsOverlay; - private readonly Container slidingContainer; - - private readonly BindableBool opened = new BindableBool(); + public const float CONTRACTED_WIDTH = 30; + public const int EXPANDED_WIDTH = 300; public MultiSpectatorSettings() + : base(CONTRACTED_WIDTH, EXPANDED_WIDTH) { - Origin = Anchor.TopLeft; + Origin = Anchor.TopRight; Anchor = Anchor.TopRight; - AutoSizeAxes = Axes.Both; - InternalChildren = new Drawable[] + PlayerSettingsOverlay playerSettingsOverlay; + + InternalChild = new FillFlowContainer { - slidingContainer = new Container + Origin = Anchor.TopLeft, + Anchor = Anchor.TopLeft, + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] { - Origin = Anchor.TopLeft, - Anchor = Anchor.TopLeft, - AutoSizeAxes = Axes.Both, - Children = new Drawable[] + new IconButton { - new IconButton - { - Icon = FontAwesome.Solid.Cog, - Origin = Anchor.TopLeft, - Anchor = Anchor.TopLeft, - Position = new Vector2(-30, 0), - Action = () => opened.Toggle() - }, - playerSettingsOverlay = new PlayerSettingsOverlay() + Icon = FontAwesome.Solid.Cog, + Origin = Anchor.TopLeft, + Anchor = Anchor.TopLeft, + Action = () => Expanded.Toggle() + }, + playerSettingsOverlay = new PlayerSettingsOverlay + { + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft } } }; playerSettingsOverlay.Show(); - - opened.BindValueChanged(value => - { - if (value.NewValue) - open(); - else - close(); - }); } - private void open() + protected override void OnHoverLost(HoverLostEvent e) { - slidingContainer.MoveToOffset(new Vector2(-playerSettingsOverlay.Width, 0), slide_duration, Easing.Out).Then().OnComplete(c => - { - c.Origin = Anchor.TopRight; - c.Position = Vector2.Zero; - }); - } - - private void close() - { - slidingContainer.MoveToOffset(new Vector2(playerSettingsOverlay.Width, 0), slide_duration, Easing.Out).Then().OnComplete(c => - { - c.Origin = Anchor.TopLeft; - c.Position = Vector2.Zero; - }); + // Prevent unexpanding when hovering player settings + if (!Contains(e.ScreenSpaceMousePosition)) + base.OnHoverLost(e); } } } From 242079346661b3bb5734ef6db066627addea2681 Mon Sep 17 00:00:00 2001 From: Salman Alshamrani Date: Sun, 24 Nov 2024 05:39:42 -0500 Subject: [PATCH 21/54] Allow controlling back button visibility state from screens --- osu.Game/OsuGame.cs | 13 ++++++++----- osu.Game/Screens/IOsuScreen.cs | 12 ++++++++++++ osu.Game/Screens/OsuScreen.cs | 5 +++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index dce24c6ee7..4d6bc4fd14 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1581,12 +1581,20 @@ namespace osu.Game if (current is IOsuScreen currentOsuScreen) { + if (currentOsuScreen.AllowBackButton) + BackButton.State.UnbindFrom(currentOsuScreen.BackButtonState); + OverlayActivationMode.UnbindFrom(currentOsuScreen.OverlayActivationMode); API.Activity.UnbindFrom(currentOsuScreen.Activity); } if (newScreen is IOsuScreen newOsuScreen) { + if (newOsuScreen.AllowBackButton) + ((IBindable)BackButton.State).BindTo(newOsuScreen.BackButtonState); + else + BackButton.Hide(); + OverlayActivationMode.BindTo(newOsuScreen.OverlayActivationMode); API.Activity.BindTo(newOsuScreen.Activity); @@ -1597,11 +1605,6 @@ namespace osu.Game else Toolbar.Show(); - if (newOsuScreen.AllowBackButton) - BackButton.Show(); - else - BackButton.Hide(); - if (newOsuScreen.ShowFooter) { BackButton.Hide(); diff --git a/osu.Game/Screens/IOsuScreen.cs b/osu.Game/Screens/IOsuScreen.cs index b80c1f87a4..7025460daa 100644 --- a/osu.Game/Screens/IOsuScreen.cs +++ b/osu.Game/Screens/IOsuScreen.cs @@ -3,8 +3,11 @@ using System.Collections.Generic; using osu.Framework.Bindables; +using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; +using osu.Game.Graphics.UserInterface; +using osu.Game.Input.Bindings; using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Screens.Footer; @@ -59,6 +62,15 @@ namespace osu.Game.Screens /// IBindable OverlayActivationMode { get; } + /// + /// Controls the visibility state of to better work with screen-specific transitions (i.e. quick restart in player). + /// The back button can still be triggered by the action even while hidden. + /// + /// + /// This is ignored when is set to false. + /// + IBindable BackButtonState { get; } + /// /// The current for this screen. /// diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 695a074907..2c5c889154 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -11,6 +11,7 @@ using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Overlays; @@ -56,6 +57,10 @@ namespace osu.Game.Screens IBindable IOsuScreen.OverlayActivationMode => OverlayActivationMode; + public readonly Bindable BackButtonState = new Bindable(Visibility.Visible); + + IBindable IOsuScreen.BackButtonState => BackButtonState; + public virtual bool CursorVisible => true; protected new OsuGameBase Game => base.Game as OsuGameBase; From ae9119eef044c348805e4b2488fb768fc342e621 Mon Sep 17 00:00:00 2001 From: Salman Alshamrani Date: Sun, 24 Nov 2024 05:40:06 -0500 Subject: [PATCH 22/54] Hide back button when quick-restarting unless load time takes long --- osu.Game/Screens/Play/PlayerLoader.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 3e36c630db..a6e171ba02 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -478,6 +478,8 @@ namespace osu.Game.Screens.Play if (quickRestart) { + BackButtonState.Value = Visibility.Hidden; + // A quick restart starts by triggering a fade to black AddInternal(quickRestartBlackLayer = new Box { @@ -496,6 +498,8 @@ namespace osu.Game.Screens.Play .Delay(quick_restart_initial_delay) .ScaleTo(1) .FadeInFromZero(500, Easing.OutQuint); + + this.Delay(quick_restart_initial_delay).Schedule(() => BackButtonState.Value = Visibility.Visible); } else { From 46d1f005907f83c769840974eda24630136e9701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Tue, 26 Nov 2024 11:39:03 +0100 Subject: [PATCH 23/54] Fix `Beatmap.Countdown` not being copied on conversion --- osu.Game/Beatmaps/BeatmapConverter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Beatmaps/BeatmapConverter.cs b/osu.Game/Beatmaps/BeatmapConverter.cs index c0066cc637..82b40c0318 100644 --- a/osu.Game/Beatmaps/BeatmapConverter.cs +++ b/osu.Game/Beatmaps/BeatmapConverter.cs @@ -83,6 +83,7 @@ namespace osu.Game.Beatmaps beatmap.DistanceSpacing = original.DistanceSpacing; beatmap.GridSize = original.GridSize; beatmap.TimelineZoom = original.TimelineZoom; + beatmap.Countdown = original.Countdown; beatmap.CountdownOffset = original.CountdownOffset; return beatmap; From 3e1b4f4ac564a1b69b2d8111b19d3908f99980e4 Mon Sep 17 00:00:00 2001 From: Salman Alshamrani Date: Tue, 26 Nov 2024 16:50:23 -0500 Subject: [PATCH 24/54] Rename `AllowBackButton` to `AllowUserExit` and rewrite visibility flow structure Co-authored-by: Dean Herbert --- osu.Game/OsuGame.cs | 25 ++++++++++++------- .../Maintenance/MigrationRunScreen.cs | 2 +- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/Edit/EditorLoader.cs | 2 +- osu.Game/Screens/IOsuScreen.cs | 21 ++++++++-------- osu.Game/Screens/Menu/MainMenu.cs | 2 +- .../Screens/OnlinePlay/OnlinePlayScreen.cs | 2 +- osu.Game/Screens/OsuScreen.cs | 13 +++++++--- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/Play/PlayerLoader.cs | 4 +-- osu.Game/Screens/StartupScreen.cs | 2 +- 11 files changed, 44 insertions(+), 33 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 4d6bc4fd14..514209524e 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -175,6 +175,11 @@ namespace osu.Game /// public readonly IBindable OverlayActivationMode = new Bindable(); + /// + /// Whether the back button is currently displayed. + /// + public readonly IBindable BackButtonVisibility = new Bindable(); + IBindable ILocalUserPlayInfo.PlayingState => playingState; private readonly Bindable playingState = new Bindable(); @@ -1019,7 +1024,7 @@ namespace osu.Game if (!(ScreenStack.CurrentScreen is IOsuScreen currentScreen)) return; - if (!((Drawable)currentScreen).IsLoaded || (currentScreen.AllowBackButton && !currentScreen.OnBackButton())) + if (!((Drawable)currentScreen).IsLoaded || (currentScreen.AllowUserExit && !currentScreen.OnBackButton())) ScreenStack.Exit(); } }, @@ -1189,6 +1194,14 @@ namespace osu.Game if (mode.NewValue != OverlayActivation.All) CloseAllOverlays(); }; + BackButtonVisibility.ValueChanged += visible => + { + if (visible.NewValue) + BackButton.Show(); + else + BackButton.Hide(); + }; + // Importantly, this should be run after binding PostNotification to the import handlers so they can present the import after game startup. handleStartupImport(); } @@ -1581,20 +1594,14 @@ namespace osu.Game if (current is IOsuScreen currentOsuScreen) { - if (currentOsuScreen.AllowBackButton) - BackButton.State.UnbindFrom(currentOsuScreen.BackButtonState); - + BackButtonVisibility.UnbindFrom(currentOsuScreen.BackButtonVisibility); OverlayActivationMode.UnbindFrom(currentOsuScreen.OverlayActivationMode); API.Activity.UnbindFrom(currentOsuScreen.Activity); } if (newScreen is IOsuScreen newOsuScreen) { - if (newOsuScreen.AllowBackButton) - ((IBindable)BackButton.State).BindTo(newOsuScreen.BackButtonState); - else - BackButton.Hide(); - + BackButtonVisibility.BindTo(newOsuScreen.BackButtonVisibility); OverlayActivationMode.BindTo(newOsuScreen.OverlayActivationMode); API.Activity.BindTo(newOsuScreen.Activity); diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs index 3bba480aaa..c0363851ef 100644 --- a/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/MigrationRunScreen.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance [Resolved(canBeNull: true)] private OsuGame game { get; set; } - public override bool AllowBackButton => false; + public override bool AllowUserExit => false; public override bool AllowExternalScreenChange => false; diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 644e1afb3b..13e5791605 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -80,7 +80,7 @@ namespace osu.Game.Screens.Edit public override float BackgroundParallaxAmount => 0.1f; - public override bool AllowBackButton => false; + public override bool AllowUserExit => false; public override bool HideOverlaysOnEnter => true; diff --git a/osu.Game/Screens/Edit/EditorLoader.cs b/osu.Game/Screens/Edit/EditorLoader.cs index 0e0fb9f795..7c6ee10840 100644 --- a/osu.Game/Screens/Edit/EditorLoader.cs +++ b/osu.Game/Screens/Edit/EditorLoader.cs @@ -36,7 +36,7 @@ namespace osu.Game.Screens.Edit public override float BackgroundParallaxAmount => 0.1f; - public override bool AllowBackButton => false; + public override bool AllowUserExit => false; public override bool HideOverlaysOnEnter => true; diff --git a/osu.Game/Screens/IOsuScreen.cs b/osu.Game/Screens/IOsuScreen.cs index 7025460daa..46dfbfb1ac 100644 --- a/osu.Game/Screens/IOsuScreen.cs +++ b/osu.Game/Screens/IOsuScreen.cs @@ -3,10 +3,8 @@ using System.Collections.Generic; using osu.Framework.Bindables; -using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; -using osu.Game.Graphics.UserInterface; using osu.Game.Input.Bindings; using osu.Game.Overlays; using osu.Game.Rulesets; @@ -24,15 +22,20 @@ namespace osu.Game.Screens bool DisallowExternalBeatmapRulesetChanges { get; } /// - /// Whether the user can exit this by pressing the back button. + /// Whether the user can exit this . /// - bool AllowBackButton { get; } + /// + /// When overriden to false, + /// the user is blocked from exiting the screen via the action, + /// and the back button is hidden from this screen by the initial state of being set to hidden. + /// + bool AllowUserExit { get; } /// /// Whether a footer (and a back button) should be displayed underneath the screen. /// /// - /// Temporarily, the back button is shown regardless of whether is true. + /// Temporarily, the back button is shown regardless of whether is true. /// bool ShowFooter { get; } @@ -63,13 +66,9 @@ namespace osu.Game.Screens IBindable OverlayActivationMode { get; } /// - /// Controls the visibility state of to better work with screen-specific transitions (i.e. quick restart in player). - /// The back button can still be triggered by the action even while hidden. + /// Whether the back button should be displayed in this screen. /// - /// - /// This is ignored when is set to false. - /// - IBindable BackButtonState { get; } + IBindable BackButtonVisibility { get; } /// /// The current for this screen. diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 35c6bab81b..6b94d4bdfb 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -48,7 +48,7 @@ namespace osu.Game.Screens.Menu public override bool HideOverlaysOnEnter => Buttons == null || Buttons.State == ButtonSystemState.Initial; - public override bool AllowBackButton => false; + public override bool AllowUserExit => false; public override bool AllowExternalScreenChange => true; diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index cc6a4e09e1..17fb667e14 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -180,7 +180,7 @@ namespace osu.Game.Screens.OnlinePlay if (!(screenStack.CurrentScreen is IOnlinePlaySubScreen onlineSubScreen)) return false; - if (((Drawable)onlineSubScreen).IsLoaded && onlineSubScreen.AllowBackButton && onlineSubScreen.OnBackButton()) + if (((Drawable)onlineSubScreen).IsLoaded && onlineSubScreen.AllowUserExit && onlineSubScreen.OnBackButton()) return true; if (screenStack.CurrentScreen != null && !(screenStack.CurrentScreen is LoungeSubScreen)) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 2c5c889154..ab66241a77 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -11,7 +11,6 @@ using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Overlays; @@ -38,7 +37,7 @@ namespace osu.Game.Screens public string Description => Title; - public virtual bool AllowBackButton => true; + public virtual bool AllowUserExit => true; public virtual bool ShowFooter => false; @@ -57,9 +56,14 @@ namespace osu.Game.Screens IBindable IOsuScreen.OverlayActivationMode => OverlayActivationMode; - public readonly Bindable BackButtonState = new Bindable(Visibility.Visible); + /// + /// The initial visibility state of the back button when this screen is entered for the first time. + /// + protected virtual bool InitialBackButtonVisibility => AllowUserExit; - IBindable IOsuScreen.BackButtonState => BackButtonState; + public readonly Bindable BackButtonVisibility; + + IBindable IOsuScreen.BackButtonVisibility => BackButtonVisibility; public virtual bool CursorVisible => true; @@ -159,6 +163,7 @@ namespace osu.Game.Screens Origin = Anchor.Centre; OverlayActivationMode = new Bindable(InitialOverlayActivationMode); + BackButtonVisibility = new Bindable(InitialBackButtonVisibility); } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index e9722350bd..f4e3e6f434 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -57,7 +57,7 @@ namespace osu.Game.Screens.Play /// public event Action OnGameplayStarted; - public override bool AllowBackButton => false; // handled by HoldForMenuButton + public override bool AllowUserExit => false; // handled by HoldForMenuButton protected override bool PlayExitSound => !isRestarting; diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index a6e171ba02..49db0f05bd 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -478,7 +478,7 @@ namespace osu.Game.Screens.Play if (quickRestart) { - BackButtonState.Value = Visibility.Hidden; + BackButtonVisibility.Value = false; // A quick restart starts by triggering a fade to black AddInternal(quickRestartBlackLayer = new Box @@ -499,7 +499,7 @@ namespace osu.Game.Screens.Play .ScaleTo(1) .FadeInFromZero(500, Easing.OutQuint); - this.Delay(quick_restart_initial_delay).Schedule(() => BackButtonState.Value = Visibility.Visible); + this.Delay(quick_restart_initial_delay).Schedule(() => BackButtonVisibility.Value = true); } else { diff --git a/osu.Game/Screens/StartupScreen.cs b/osu.Game/Screens/StartupScreen.cs index 9e04a238eb..0724327a9f 100644 --- a/osu.Game/Screens/StartupScreen.cs +++ b/osu.Game/Screens/StartupScreen.cs @@ -10,7 +10,7 @@ namespace osu.Game.Screens /// public abstract partial class StartupScreen : OsuScreen { - public override bool AllowBackButton => false; + public override bool AllowUserExit => false; public override bool HideOverlaysOnEnter => true; From 9c707ed3418b5bde88dd76d5d5f790fb69decb1b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Nov 2024 16:47:54 +0900 Subject: [PATCH 25/54] Rename class and fix padding considerations --- ...ings.cs => ExpandingPlayerSettingsOverlay.cs} | 16 ++++++++++++---- .../Multiplayer/Spectate/MultiSpectatorScreen.cs | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) rename osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/{MultiSpectatorSettings.cs => ExpandingPlayerSettingsOverlay.cs} (75%) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/ExpandingPlayerSettingsOverlay.cs similarity index 75% rename from osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs rename to osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/ExpandingPlayerSettingsOverlay.cs index dfb26d104a..6ad53d4aeb 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorSettings.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/ExpandingPlayerSettingsOverlay.cs @@ -8,15 +8,21 @@ using osu.Framework.Input.Events; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Play.HUD; +using osuTK; namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate { - public partial class MultiSpectatorSettings : ExpandingContainer + public partial class ExpandingPlayerSettingsOverlay : ExpandingContainer { - public const float CONTRACTED_WIDTH = 30; - public const int EXPANDED_WIDTH = 300; + private const float padding = 10; - public MultiSpectatorSettings() + public const float CONTRACTED_WIDTH = button_size + padding * 2; + public const float EXPANDED_WIDTH = player_settings_width + button_size + padding * 3; + + private const float player_settings_width = 270; + private const float button_size = IconButton.DEFAULT_BUTTON_SIZE; + + public ExpandingPlayerSettingsOverlay() : base(CONTRACTED_WIDTH, EXPANDED_WIDTH) { Origin = Anchor.TopRight; @@ -30,6 +36,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate Anchor = Anchor.TopLeft, Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, + Margin = new MarginPadding(padding), + Spacing = new Vector2(padding), Children = new Drawable[] { new IconButton diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs index 841aaf7a45..44d26a6dd0 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs @@ -127,7 +127,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate { ReadyToStart = performInitialSeek, }, - new MultiSpectatorSettings() + new ExpandingPlayerSettingsOverlay() }; for (int i = 0; i < Users.Count; i++) From 782ce24ca67c08525ff8c4f3d4382c5627b6af8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Nov 2024 17:09:13 +0900 Subject: [PATCH 26/54] Move player settings out of right flow --- osu.Game/Screens/Play/HUDOverlay.cs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index a6c2405eb6..62d9686aad 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -146,7 +146,6 @@ namespace osu.Game.Screens.Play Children = new Drawable[] { ModDisplay = CreateModsContainer(), - PlayerSettingsOverlay = CreatePlayerSettingsOverlay(), } }, bottomRightElements = new FillFlowContainer @@ -164,6 +163,7 @@ namespace osu.Game.Screens.Play HoldToQuit = CreateHoldForMenuButton(), } }, + PlayerSettingsOverlay = new PlayerSettingsOverlay(), LeaderboardFlow = new FillFlowContainer { AutoSizeAxes = Axes.Both, @@ -173,7 +173,7 @@ namespace osu.Game.Screens.Play }, }; - hideTargets = new List { mainComponents, topRightElements }; + hideTargets = new List { mainComponents, topRightElements, PlayerSettingsOverlay }; if (rulesetComponents != null) hideTargets.Add(rulesetComponents); @@ -389,8 +389,6 @@ namespace osu.Game.Screens.Play Origin = Anchor.TopRight, }; - protected PlayerSettingsOverlay CreatePlayerSettingsOverlay() => new PlayerSettingsOverlay(); - public bool OnPressed(KeyBindingPressEvent e) { if (e.Repeat) From 7fdf13911b7500a4cc9b08259655aabc49142142 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Nov 2024 17:47:27 +0900 Subject: [PATCH 27/54] Adjust the colour of non-pinned settings groups' headers to be more legible --- osu.Game/Overlays/SettingsToolboxGroup.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SettingsToolboxGroup.cs b/osu.Game/Overlays/SettingsToolboxGroup.cs index 53849fa53c..f8cf218564 100644 --- a/osu.Game/Overlays/SettingsToolboxGroup.cs +++ b/osu.Game/Overlays/SettingsToolboxGroup.cs @@ -184,7 +184,7 @@ namespace osu.Game.Overlays content.ResizeHeightTo(0, animate ? transition_duration : 0, Easing.OutQuint); } - headerContent.FadeColour(Expanded.Value ? Color4.White : OsuColour.Gray(0.5f), 200, Easing.OutQuint); + headerContent.FadeColour(Expanded.Value ? Color4.White : OsuColour.Gray(0.7f), 200, Easing.OutQuint); } private void updateFadeState() From 0f739418084d99925a0e91691ed459122aec23d1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 27 Nov 2024 17:47:42 +0900 Subject: [PATCH 28/54] Combine new implementation back into the old one and use everywhere --- .../ExpandingPlayerSettingsOverlay.cs | 68 -------------- .../Spectate/MultiSpectatorScreen.cs | 2 +- .../Screens/Play/HUD/PlayerSettingsOverlay.cs | 88 +++++++++++++++---- 3 files changed, 74 insertions(+), 84 deletions(-) delete mode 100644 osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/ExpandingPlayerSettingsOverlay.cs diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/ExpandingPlayerSettingsOverlay.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/ExpandingPlayerSettingsOverlay.cs deleted file mode 100644 index 6ad53d4aeb..0000000000 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/ExpandingPlayerSettingsOverlay.cs +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Framework.Input.Events; -using osu.Game.Graphics.Containers; -using osu.Game.Graphics.UserInterface; -using osu.Game.Screens.Play.HUD; -using osuTK; - -namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate -{ - public partial class ExpandingPlayerSettingsOverlay : ExpandingContainer - { - private const float padding = 10; - - public const float CONTRACTED_WIDTH = button_size + padding * 2; - public const float EXPANDED_WIDTH = player_settings_width + button_size + padding * 3; - - private const float player_settings_width = 270; - private const float button_size = IconButton.DEFAULT_BUTTON_SIZE; - - public ExpandingPlayerSettingsOverlay() - : base(CONTRACTED_WIDTH, EXPANDED_WIDTH) - { - Origin = Anchor.TopRight; - Anchor = Anchor.TopRight; - - PlayerSettingsOverlay playerSettingsOverlay; - - InternalChild = new FillFlowContainer - { - Origin = Anchor.TopLeft, - Anchor = Anchor.TopLeft, - Direction = FillDirection.Horizontal, - AutoSizeAxes = Axes.Both, - Margin = new MarginPadding(padding), - Spacing = new Vector2(padding), - Children = new Drawable[] - { - new IconButton - { - Icon = FontAwesome.Solid.Cog, - Origin = Anchor.TopLeft, - Anchor = Anchor.TopLeft, - Action = () => Expanded.Toggle() - }, - playerSettingsOverlay = new PlayerSettingsOverlay - { - Anchor = Anchor.TopLeft, - Origin = Anchor.TopLeft - } - } - }; - - playerSettingsOverlay.Show(); - } - - protected override void OnHoverLost(HoverLostEvent e) - { - // Prevent unexpanding when hovering player settings - if (!Contains(e.ScreenSpaceMousePosition)) - base.OnHoverLost(e); - } - } -} diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs index 44d26a6dd0..33c3c60ed3 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Spectate/MultiSpectatorScreen.cs @@ -127,7 +127,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Spectate { ReadyToStart = performInitialSeek, }, - new ExpandingPlayerSettingsOverlay() + new PlayerSettingsOverlay() }; for (int i = 0; i < Users.Count; i++) diff --git a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs index a2b49f6302..e68ca4da7a 100644 --- a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs +++ b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs @@ -1,46 +1,104 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// 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.Extensions.Color4Extensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.Containers; -using osuTK; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Input; +using osu.Framework.Input.Events; +using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; using osu.Game.Screens.Play.PlayerSettings; +using osuTK; +using osuTK.Graphics; namespace osu.Game.Screens.Play.HUD { - public partial class PlayerSettingsOverlay : VisibilityContainer + public partial class PlayerSettingsOverlay : ExpandingContainer { + public VisualSettings VisualSettings { get; private set; } + + private const float padding = 10; + + public const float CONTRACTED_WIDTH = button_size + padding * 2; + public const float EXPANDED_WIDTH = player_settings_width + padding * 2; + + private const float player_settings_width = 270; + private const float button_size = IconButton.DEFAULT_BUTTON_SIZE; + + public override void Show() => this.FadeIn(fade_duration); + public override void Hide() => this.FadeOut(fade_duration); + private const int fade_duration = 200; - public readonly VisualSettings VisualSettings; + // we'll handle this ourselves because we have slightly custom logic. + protected override bool ExpandOnHover => false; protected override Container Content => content; private readonly FillFlowContainer content; - public PlayerSettingsOverlay() - { - Anchor = Anchor.TopRight; - Origin = Anchor.TopRight; - AutoSizeAxes = Axes.Both; + private readonly IconButton button; - InternalChild = content = new FillFlowContainer + private InputManager inputManager = null!; + + public PlayerSettingsOverlay() + : base(0, EXPANDED_WIDTH) + { + Origin = Anchor.TopRight; + Anchor = Anchor.TopRight; + + base.Content.Add(content = new FillFlowContainer { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, AutoSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 20), + Margin = new MarginPadding(padding), Children = new PlayerSettingsGroup[] { VisualSettings = new VisualSettings { Expanded = { Value = false } }, new AudioSettings { Expanded = { Value = false } } } - }; + }); + + AddInternal(button = new IconButton + { + Icon = FontAwesome.Solid.Cog, + Origin = Anchor.TopRight, + Anchor = Anchor.TopLeft, + Margin = new MarginPadding(5), + Action = () => Expanded.Toggle() + }); + + AddInternal(new Box + { + Colour = ColourInfo.GradientHorizontal(Color4.Black.Opacity(0), Color4.Black.Opacity(0.8f)), + Depth = float.MaxValue, + RelativeSizeAxes = Axes.Both, + }); } - protected override void PopIn() => this.FadeIn(fade_duration); - protected override void PopOut() => this.FadeOut(fade_duration); + protected override void LoadComplete() + { + base.LoadComplete(); + + inputManager = GetContainingInputManager()!; + } + + protected override void Update() + { + base.Update(); + + Expanded.Value = inputManager.CurrentState.Mouse.Position.X >= button.ScreenSpaceDrawQuad.TopLeft.X; + } + + protected override void OnHoverLost(HoverLostEvent e) + { + // handle un-expanding manually because our children do weird hover blocking stuff. + } public void AddAtStart(PlayerSettingsGroup drawable) => content.Insert(-1, drawable); } From 4ae3ccfe480bb40ffa3b44bb1fc0879bfb129f98 Mon Sep 17 00:00:00 2001 From: Salman Alshamrani Date: Wed, 27 Nov 2024 06:05:02 -0500 Subject: [PATCH 29/54] Make `BackButtonVisibility` in game class private --- osu.Game/OsuGame.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 514209524e..c52755197b 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -178,7 +178,7 @@ namespace osu.Game /// /// Whether the back button is currently displayed. /// - public readonly IBindable BackButtonVisibility = new Bindable(); + private readonly IBindable backButtonVisibility = new Bindable(); IBindable ILocalUserPlayInfo.PlayingState => playingState; @@ -1194,7 +1194,7 @@ namespace osu.Game if (mode.NewValue != OverlayActivation.All) CloseAllOverlays(); }; - BackButtonVisibility.ValueChanged += visible => + backButtonVisibility.ValueChanged += visible => { if (visible.NewValue) BackButton.Show(); @@ -1594,14 +1594,14 @@ namespace osu.Game if (current is IOsuScreen currentOsuScreen) { - BackButtonVisibility.UnbindFrom(currentOsuScreen.BackButtonVisibility); + backButtonVisibility.UnbindFrom(currentOsuScreen.BackButtonVisibility); OverlayActivationMode.UnbindFrom(currentOsuScreen.OverlayActivationMode); API.Activity.UnbindFrom(currentOsuScreen.Activity); } if (newScreen is IOsuScreen newOsuScreen) { - BackButtonVisibility.BindTo(newOsuScreen.BackButtonVisibility); + backButtonVisibility.BindTo(newOsuScreen.BackButtonVisibility); OverlayActivationMode.BindTo(newOsuScreen.OverlayActivationMode); API.Activity.BindTo(newOsuScreen.Activity); From f792b6de002f1e82e004ba2c4c7b3d8de5360a27 Mon Sep 17 00:00:00 2001 From: Salman Alshamrani Date: Wed, 27 Nov 2024 06:07:10 -0500 Subject: [PATCH 30/54] Fix comment --- osu.Game/Screens/IOsuScreen.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/IOsuScreen.cs b/osu.Game/Screens/IOsuScreen.cs index 46dfbfb1ac..9e474ed0c6 100644 --- a/osu.Game/Screens/IOsuScreen.cs +++ b/osu.Game/Screens/IOsuScreen.cs @@ -35,7 +35,8 @@ namespace osu.Game.Screens /// Whether a footer (and a back button) should be displayed underneath the screen. /// /// - /// Temporarily, the back button is shown regardless of whether is true. + /// Temporarily, the footer's own back button is shown regardless of whether is set to hidden. + /// This will be corrected as the footer becomes used more commonly. /// bool ShowFooter { get; } From 932afcde01469543084467b4699d9774123b8363 Mon Sep 17 00:00:00 2001 From: Salman Alshamrani Date: Thu, 28 Nov 2024 17:43:32 -0500 Subject: [PATCH 31/54] Make editor make sense --- osu.Game/Screens/Edit/Editor.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index 13e5791605..0e4807dc78 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -80,8 +80,6 @@ namespace osu.Game.Screens.Edit public override float BackgroundParallaxAmount => 0.1f; - public override bool AllowUserExit => false; - public override bool HideOverlaysOnEnter => true; public override bool DisallowExternalBeatmapRulesetChanges => true; @@ -194,6 +192,8 @@ namespace osu.Game.Screens.Edit } } + protected override bool InitialBackButtonVisibility => false; + protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(base.CreateChildDependencies(parent)); @@ -760,11 +760,6 @@ namespace osu.Game.Screens.Edit switch (e.Action) { - case GlobalAction.Back: - // as we don't want to display the back button, manual handling of exit action is required. - this.Exit(); - return true; - case GlobalAction.EditorCloneSelection: Clone(); return true; From 3cfa455369c432b69f11a8a7f121abb0d8fac476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 29 Nov 2024 10:54:32 +0100 Subject: [PATCH 32/54] Fix strong drum rolls being counted for double the combo in legacy scoring attributes --- .../Difficulty/TaikoLegacyScoreSimulator.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoLegacyScoreSimulator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoLegacyScoreSimulator.cs index 9839d94277..416a11c2a8 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoLegacyScoreSimulator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoLegacyScoreSimulator.cs @@ -144,6 +144,13 @@ namespace osu.Game.Rulesets.Taiko.Difficulty foreach (var nested in hitObject.NestedHitObjects) simulateHit(nested, ref attributes); return; + + case StrongNestedHitObject: + // we never need to deal with these directly. + // the only thing strong hits do in terms of scoring is double their object's score increase, + // which is already handled at the parent object level via the `strongable.IsStrong` check lower down in this method. + // not handling these here can lead to them falsely being counted as combo-increasing when handling strong drum rolls! + return; } if (hitObject is DrumRollTick tick) From 1e2e364cd3d74281ffb921c7d9542ba82f02d6b4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 30 Nov 2024 21:01:22 +0900 Subject: [PATCH 33/54] Stop loudly logging backwards seek bug to sentry Several users have reported stutters when this happens. It's potentially from the error report overhead. We now know that this is a BASS level issue anyway, so having this logging is not helpful. --- osu.Game/Rulesets/UI/FrameStabilityContainer.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs index c4feb249f4..92258f3fc9 100644 --- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs +++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs @@ -3,19 +3,15 @@ using System; using System.Diagnostics; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Logging; -using osu.Framework.Testing; using osu.Framework.Timing; -using osu.Game.Beatmaps; using osu.Game.Input.Handlers; using osu.Game.Screens.Play; -using osu.Game.Utils; namespace osu.Game.Rulesets.UI { @@ -168,13 +164,7 @@ namespace osu.Game.Rulesets.UI if (lastBackwardsSeekLogTime == null || Math.Abs(Clock.CurrentTime - lastBackwardsSeekLogTime.Value) > 1000) { lastBackwardsSeekLogTime = Clock.CurrentTime; - - string loggableContent = $"Denying backwards seek during gameplay (reference: {referenceClock.CurrentTime:N2} stable: {proposedTime:N2})"; - - if (parentGameplayClock is GameplayClockContainer gcc) - loggableContent += $"\n{gcc.ChildrenOfType().Single().GetSnapshot()}"; - - Logger.Error(new SentryOnlyDiagnosticsException("backwards seek"), loggableContent); + Logger.Log($"Denying backwards seek during gameplay (reference: {referenceClock.CurrentTime:N2} stable: {proposedTime:N2})"); } state = PlaybackState.NotValid; From f4e155bfa6a6f8158a578540e9e01621e5b46553 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 30 Nov 2024 15:19:35 +0100 Subject: [PATCH 34/54] Account for rate changing mods when disabling the "Ready" button --- .../Playlists/PlaylistsReadyButton.cs | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs index a460779ea6..3c7808356c 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.ComponentModel; using System.Linq; using osu.Framework.Allocation; @@ -10,7 +11,9 @@ using osu.Framework.Localisation; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Online.Rooms; +using osu.Game.Rulesets.Mods; using osu.Game.Screens.OnlinePlay.Components; +using osu.Game.Utils; namespace osu.Game.Screens.OnlinePlay.Playlists { @@ -19,6 +22,9 @@ namespace osu.Game.Screens.OnlinePlay.Playlists [Resolved] private IBindable gameBeatmap { get; set; } = null!; + [Resolved] + private IBindable> mods { get; set; } = null!; + private readonly Room room; public PlaylistsReadyButton(Room room) @@ -63,14 +69,14 @@ namespace osu.Game.Screens.OnlinePlay.Playlists { base.Update(); - Enabled.Value = hasRemainingAttempts && enoughTimeLeft; + Enabled.Value = hasRemainingAttempts && enoughTimeLeft(); } public override LocalisableString TooltipText { get { - if (!enoughTimeLeft) + if (!enoughTimeLeft()) return "No time left!"; if (!hasRemainingAttempts) @@ -80,9 +86,16 @@ namespace osu.Game.Screens.OnlinePlay.Playlists } } - private bool enoughTimeLeft => + private bool enoughTimeLeft() + { + // this doesn't consider mods which apply variable rates, yet. + double rate = ModUtils.CalculateRateWithMods(mods.Value); + + double hitLength = Math.Round(gameBeatmap.Value.Track.Length / rate); + // This should probably consider the length of the currently selected item, rather than a constant 30 seconds. - room.EndDate != null && DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(gameBeatmap.Value.Track.Length) < room.EndDate; + return room.EndDate != null && DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(hitLength) < room.EndDate; + } protected override void Dispose(bool isDisposing) { From 164b809c8911262c5f8f775b5c8c4c3ce843afc7 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Sat, 30 Nov 2024 23:02:22 +0100 Subject: [PATCH 35/54] Document ready button enable state with some comments --- .../OnlinePlay/Playlists/PlaylistsReadyButton.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs index 3c7808356c..0a4b504749 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs @@ -88,13 +88,15 @@ namespace osu.Game.Screens.OnlinePlay.Playlists private bool enoughTimeLeft() { - // this doesn't consider mods which apply variable rates, yet. + // TODO: This doesn't consider mods which apply variable rates, yet. double rate = ModUtils.CalculateRateWithMods(mods.Value); - double hitLength = Math.Round(gameBeatmap.Value.Track.Length / rate); + // We want to avoid users not being able to submit scores if they chose to not skip, + // so track length is chosen over playable length. + double trackLength = Math.Round(gameBeatmap.Value.Track.Length / rate); - // This should probably consider the length of the currently selected item, rather than a constant 30 seconds. - return room.EndDate != null && DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(hitLength) < room.EndDate; + // Additional 30 second delay added to account for load and/or submit time. + return room.EndDate != null && DateTimeOffset.UtcNow.AddSeconds(30).AddMilliseconds(trackLength) < room.EndDate; } protected override void Dispose(bool isDisposing) From 9140893249037130c9a2bae7bd67be20f8be098a Mon Sep 17 00:00:00 2001 From: Salman Alshamrani Date: Sat, 30 Nov 2024 23:36:02 -0500 Subject: [PATCH 36/54] Fix score no longer being saved when quick-restarting after pass --- .../Visual/Mods/TestSceneModFailCondition.cs | 2 +- osu.Game/Screens/Play/Player.cs | 10 +++------- osu.Game/Screens/Play/PlayerLoader.cs | 6 ++---- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/osu.Game.Tests/Visual/Mods/TestSceneModFailCondition.cs b/osu.Game.Tests/Visual/Mods/TestSceneModFailCondition.cs index f4732234a7..a7447a92cd 100644 --- a/osu.Game.Tests/Visual/Mods/TestSceneModFailCondition.cs +++ b/osu.Game.Tests/Visual/Mods/TestSceneModFailCondition.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual.Mods protected override TestPlayer CreateModPlayer(Ruleset ruleset) { var player = base.CreateModPlayer(ruleset); - player.RestartRequested = _ => restartRequested = true; + player.PrepareLoaderForRestart = _ => restartRequested = true; return player; } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 2d1f602832..cb24b99ce2 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -83,7 +83,7 @@ namespace osu.Game.Screens.Play /// protected virtual bool PauseOnFocusLost => true; - public Action RestartRequested; + public Action PrepareLoaderForRestart; private bool isRestarting; private bool skipExitTransition; @@ -719,12 +719,8 @@ namespace osu.Game.Screens.Play // stopping here is to ensure music doesn't become audible after exiting back to PlayerLoader. musicController.Stop(); - if (RestartRequested != null) - { - skipExitTransition = quickRestart; - RestartRequested?.Invoke(quickRestart); - return true; - } + skipExitTransition = quickRestart; + PrepareLoaderForRestart?.Invoke(quickRestart); return PerformExit(quickRestart); } diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 0db96b71ad..d2ba5398e4 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -457,7 +457,7 @@ namespace osu.Game.Screens.Play CurrentPlayer = createPlayer(); CurrentPlayer.Configuration.AutomaticallySkipIntro |= quickRestart; CurrentPlayer.RestartCount = restartCount++; - CurrentPlayer.RestartRequested = restartRequested; + CurrentPlayer.PrepareLoaderForRestart = prepareForRestart; LoadTask = LoadComponentAsync(CurrentPlayer, _ => { @@ -470,13 +470,11 @@ namespace osu.Game.Screens.Play { } - private void restartRequested(bool quickRestartRequested) + private void prepareForRestart(bool quickRestartRequested) { quickRestart = quickRestartRequested; hideOverlays = true; ValidForResume = true; - - this.MakeCurrent(); } private void contentIn(double delayBeforeSideDisplays = 0) From 53dce83b56b9c67657c5a8033016150e20c8e939 Mon Sep 17 00:00:00 2001 From: Salman Alshamrani Date: Sun, 1 Dec 2024 02:11:53 -0500 Subject: [PATCH 37/54] Fix restarting no longer working from results screen Thanks to tests for pointing that out :blobsweat: --- osu.Game/Screens/Play/Player.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index cb24b99ce2..3a0a0613f3 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -722,6 +722,16 @@ namespace osu.Game.Screens.Play skipExitTransition = quickRestart; PrepareLoaderForRestart?.Invoke(quickRestart); + if (!this.IsCurrentScreen()) + { + // if we're called externally (i.e. from results screen), + // use MakeCurrent to exit results screen as well as this player screen + // since ValidForResume = false in here + Debug.Assert(!ValidForResume); + this.MakeCurrent(); + return true; + } + return PerformExit(quickRestart); } From 6afe083ec96f218fbad7638630a6069a761404c9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Dec 2024 18:44:26 +0900 Subject: [PATCH 38/54] Fix settings showing up during gameplay --- osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs | 6 ++---- osu.Game/Screens/Play/HUDOverlay.cs | 12 ++++++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs index e68ca4da7a..18d7f6a503 100644 --- a/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs +++ b/osu.Game/Screens/Play/HUD/PlayerSettingsOverlay.cs @@ -23,17 +23,15 @@ namespace osu.Game.Screens.Play.HUD private const float padding = 10; - public const float CONTRACTED_WIDTH = button_size + padding * 2; public const float EXPANDED_WIDTH = player_settings_width + padding * 2; private const float player_settings_width = 270; - private const float button_size = IconButton.DEFAULT_BUTTON_SIZE; + + private const int fade_duration = 200; public override void Show() => this.FadeIn(fade_duration); public override void Hide() => this.FadeOut(fade_duration); - private const int fade_duration = 200; - // we'll handle this ourselves because we have slightly custom logic. protected override bool ExpandOnHover => false; diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 62d9686aad..1c5277a8d9 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -88,6 +88,7 @@ namespace osu.Game.Screens.Play private readonly FillFlowContainer bottomRightElements; private readonly FillFlowContainer topRightElements; + private readonly Container rightSettings; internal readonly IBindable IsPlaying = new Bindable(); @@ -163,7 +164,14 @@ namespace osu.Game.Screens.Play HoldToQuit = CreateHoldForMenuButton(), } }, - PlayerSettingsOverlay = new PlayerSettingsOverlay(), + rightSettings = new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Drawable[] + { + PlayerSettingsOverlay = new PlayerSettingsOverlay(), + } + }, LeaderboardFlow = new FillFlowContainer { AutoSizeAxes = Axes.Both, @@ -173,7 +181,7 @@ namespace osu.Game.Screens.Play }, }; - hideTargets = new List { mainComponents, topRightElements, PlayerSettingsOverlay }; + hideTargets = new List { mainComponents, topRightElements, rightSettings }; if (rulesetComponents != null) hideTargets.Add(rulesetComponents); From 23522b02d899a1a73b2ad56452dd932d7ff6ee3e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 1 Dec 2024 19:53:57 +0900 Subject: [PATCH 39/54] Use local instead of field for local only usage --- osu.Game/Screens/Play/HUDOverlay.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/HUDOverlay.cs b/osu.Game/Screens/Play/HUDOverlay.cs index 1c5277a8d9..fca871e42f 100644 --- a/osu.Game/Screens/Play/HUDOverlay.cs +++ b/osu.Game/Screens/Play/HUDOverlay.cs @@ -88,7 +88,6 @@ namespace osu.Game.Screens.Play private readonly FillFlowContainer bottomRightElements; private readonly FillFlowContainer topRightElements; - private readonly Container rightSettings; internal readonly IBindable IsPlaying = new Bindable(); @@ -116,6 +115,8 @@ namespace osu.Game.Screens.Play public HUDOverlay([CanBeNull] DrawableRuleset drawableRuleset, IReadOnlyList mods, bool alwaysShowLeaderboard = true) { + Container rightSettings; + this.drawableRuleset = drawableRuleset; this.mods = mods; From b14dde937ddc8132cb47cdfca6c3c2ce8426c002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 2 Dec 2024 13:51:41 +0100 Subject: [PATCH 40/54] Add failing test case --- .../Editor/TestSceneOsuComposerSelection.cs | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs index b97fe5c5a8..345965b912 100644 --- a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs +++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs @@ -231,6 +231,36 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor AddAssert("slider still has 2 anchors", () => secondSlider.Path.ControlPoints.Count, () => Is.EqualTo(2)); } + [Test] + public void TestControlClickDoesNotDiscardExistingSelectionEvenIfNothingHit() + { + var firstSlider = new Slider + { + StartTime = 0, + Position = new Vector2(0, 0), + Path = new SliderPath + { + ControlPoints = + { + new PathControlPoint(), + new PathControlPoint(new Vector2(100)) + } + } + }; + + AddStep("add object", () => EditorBeatmap.AddRange([firstSlider])); + AddStep("select first slider", () => EditorBeatmap.SelectedHitObjects.AddRange([firstSlider])); + + AddStep("move mouse to middle of playfield", () => InputManager.MoveMouseTo(blueprintContainer.ScreenSpaceDrawQuad.Centre)); + AddStep("control-click left mouse", () => + { + InputManager.PressKey(Key.ControlLeft); + InputManager.Click(MouseButton.Left); + InputManager.ReleaseKey(Key.ControlLeft); + }); + AddAssert("selection preserved", () => EditorBeatmap.SelectedHitObjects.Count, () => Is.EqualTo(1)); + } + private ComposeBlueprintContainer blueprintContainer => Editor.ChildrenOfType().First(); From b505ecc7ba8e44afd38e0ba3cb77edf277d3593c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 2 Dec 2024 13:51:43 +0100 Subject: [PATCH 41/54] Do not deselect objects when control-clicking without hitting anything As per feedback in https://discord.com/channels/90072389919997952/1259818301517725707/1310270647187935284. --- .../Edit/Compose/Components/BlueprintContainer.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs index e12574f7ee..4a321f4a81 100644 --- a/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/BlueprintContainer.cs @@ -433,7 +433,10 @@ namespace osu.Game.Screens.Edit.Compose.Components /// Finishes the current blueprint selection. /// /// The mouse event which triggered end of selection. - /// Whether a click selection was active. + /// + /// Whether the mouse event is considered to be fully handled. + /// If the return value is , the standard click / mouse up action will follow. + /// private bool endClickSelection(MouseButtonEvent e) { // If already handled a selection, double-click, or drag, we don't want to perform a mouse up / click action. @@ -443,14 +446,16 @@ namespace osu.Game.Screens.Edit.Compose.Components if (e.ControlPressed) { - // if a selection didn't occur, we may want to trigger a deselection. - // Iterate from the top of the input stack (blueprints closest to the front of the screen first). // Priority is given to already-selected blueprints. foreach (SelectionBlueprint blueprint in SelectionBlueprints.AliveChildren.Where(b => b.IsHovered).OrderByDescending(b => b.IsSelected)) return clickSelectionHandled = SelectionHandler.MouseUpSelectionRequested(blueprint, e); - return false; + // can only be reached if there are no hovered blueprints. + // in that case, we still want to suppress mouse up / click handling, because when control is pressed, + // it is presumed we want to add to existing selection, not remove from it + // (unless explicitly control-clicking a selected object, which is handled above). + return true; } if (selectedBlueprintAlreadySelectedOnMouseDown && SelectedItems.Count == 1) From e920cfa1872d233f90df27f4db76ffd0e75da6a8 Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Mon, 2 Dec 2024 23:49:26 +0100 Subject: [PATCH 42/54] Move rate-changing TODO to a common place in CalculateRateWithMods --- osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs | 1 - osu.Game/Screens/Select/BeatmapInfoWedge.cs | 1 - osu.Game/Utils/ModUtils.cs | 1 + 3 files changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs index 0a4b504749..e72f8be50a 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsReadyButton.cs @@ -88,7 +88,6 @@ namespace osu.Game.Screens.OnlinePlay.Playlists private bool enoughTimeLeft() { - // TODO: This doesn't consider mods which apply variable rates, yet. double rate = ModUtils.CalculateRateWithMods(mods.Value); // We want to avoid users not being able to submit scores if they chose to not skip, diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 3b0fdc3e47..fd1c944689 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -401,7 +401,6 @@ namespace osu.Game.Screens.Select if (beatmap == null || bpmLabelContainer == null) return; - // this doesn't consider mods which apply variable rates, yet. double rate = ModUtils.CalculateRateWithMods(mods.Value); int bpmMax = FormatUtils.RoundBPM(beatmap.ControlPointInfo.BPMMaximum, rate); diff --git a/osu.Game/Utils/ModUtils.cs b/osu.Game/Utils/ModUtils.cs index f901f15388..15fc34b468 100644 --- a/osu.Game/Utils/ModUtils.cs +++ b/osu.Game/Utils/ModUtils.cs @@ -286,6 +286,7 @@ namespace osu.Game.Utils { double rate = 1; + // TODO: This doesn't consider mods which apply variable rates, yet. foreach (var mod in mods.OfType()) rate = mod.ApplyToRate(0, rate); From 2ceb3f6f85e2d592e7b10794b7949de61ff84d6c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Dec 2024 13:43:20 +0900 Subject: [PATCH 43/54] Show an ongoing operation when checking for updates Addresses https://github.com/ppy/osu/discussions/30950. --- osu.Game/Localisation/GeneralSettingsStrings.cs | 5 +++++ .../Overlays/Settings/Sections/General/UpdateSettings.cs | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/osu.Game/Localisation/GeneralSettingsStrings.cs b/osu.Game/Localisation/GeneralSettingsStrings.cs index 42623f4632..83a3af574c 100644 --- a/osu.Game/Localisation/GeneralSettingsStrings.cs +++ b/osu.Game/Localisation/GeneralSettingsStrings.cs @@ -44,6 +44,11 @@ namespace osu.Game.Localisation /// public static LocalisableString CheckUpdate => new TranslatableString(getKey(@"check_update"), @"Check for updates"); + /// + /// "Checking for updates" + /// + public static LocalisableString CheckingForUpdates => new TranslatableString(getKey(@"checking_for_updates"), @"Checking for updates"); + /// /// "Open osu! folder" /// diff --git a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs index 82cc952e53..53567109e3 100644 --- a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs @@ -53,8 +53,16 @@ namespace osu.Game.Overlays.Settings.Sections.General Action = () => { checkForUpdatesButton.Enabled.Value = false; + + var checkingNotification = new ProgressNotification { Text = GeneralSettingsStrings.CheckingForUpdates, }; + notifications?.Post(checkingNotification); + Task.Run(updateManager.CheckForUpdateAsync).ContinueWith(task => Schedule(() => { + // This sequence allows the notification to be immediately dismissed. + checkingNotification.State = ProgressNotificationState.Cancelled; + checkingNotification.Close(false); + if (!task.GetResultSafely()) { notifications?.Post(new SimpleNotification From 457957d3b8d9a68b359e15953d4f151a3cc5b44b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 3 Dec 2024 14:20:39 +0900 Subject: [PATCH 44/54] Refactor check-update flow to better handle unobserved exceptions --- .../Sections/General/UpdateSettings.cs | 71 ++++++++++++------- 1 file changed, 44 insertions(+), 27 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs index 53567109e3..261103173e 100644 --- a/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/General/UpdateSettings.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using osu.Framework; using osu.Framework.Allocation; -using osu.Framework.Extensions; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Framework.Logging; @@ -13,6 +12,7 @@ using osu.Framework.Screens; using osu.Framework.Statistics; using osu.Game.Configuration; using osu.Game.Localisation; +using osu.Game.Online.Multiplayer; using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Settings.Sections.Maintenance; using osu.Game.Updater; @@ -36,8 +36,11 @@ namespace osu.Game.Overlays.Settings.Sections.General [Resolved] private Storage storage { get; set; } = null!; + [Resolved] + private OsuGame? game { get; set; } + [BackgroundDependencyLoader] - private void load(OsuConfigManager config, OsuGame? game) + private void load(OsuConfigManager config) { Add(new SettingsEnumDropdown { @@ -50,31 +53,7 @@ namespace osu.Game.Overlays.Settings.Sections.General Add(checkForUpdatesButton = new SettingsButton { Text = GeneralSettingsStrings.CheckUpdate, - Action = () => - { - checkForUpdatesButton.Enabled.Value = false; - - var checkingNotification = new ProgressNotification { Text = GeneralSettingsStrings.CheckingForUpdates, }; - notifications?.Post(checkingNotification); - - Task.Run(updateManager.CheckForUpdateAsync).ContinueWith(task => Schedule(() => - { - // This sequence allows the notification to be immediately dismissed. - checkingNotification.State = ProgressNotificationState.Cancelled; - checkingNotification.Close(false); - - if (!task.GetResultSafely()) - { - notifications?.Post(new SimpleNotification - { - Text = GeneralSettingsStrings.RunningLatestRelease(game!.Version), - Icon = FontAwesome.Solid.CheckCircle, - }); - } - - checkForUpdatesButton.Enabled.Value = true; - })); - } + Action = () => checkForUpdates().FireAndForget() }); } @@ -102,6 +81,44 @@ namespace osu.Game.Overlays.Settings.Sections.General } } + private async Task checkForUpdates() + { + if (updateManager == null || game == null) + return; + + checkForUpdatesButton.Enabled.Value = false; + + var checkingNotification = new ProgressNotification + { + Text = GeneralSettingsStrings.CheckingForUpdates, + }; + notifications?.Post(checkingNotification); + + try + { + bool foundUpdate = await updateManager.CheckForUpdateAsync().ConfigureAwait(true); + + if (!foundUpdate) + { + notifications?.Post(new SimpleNotification + { + Text = GeneralSettingsStrings.RunningLatestRelease(game.Version), + Icon = FontAwesome.Solid.CheckCircle, + }); + } + } + catch + { + } + finally + { + // This sequence allows the notification to be immediately dismissed. + checkingNotification.State = ProgressNotificationState.Cancelled; + checkingNotification.Close(false); + checkForUpdatesButton.Enabled.Value = true; + } + } + private void exportLogs() { ProgressNotification notification = new ProgressNotification From 6ff1dec7b2b9fa2eebcd96620c316ddfc7a67c6e Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Tue, 3 Dec 2024 15:45:58 +0900 Subject: [PATCH 45/54] Add tests --- .../TestScenePlaylistsRoomSubScreen.cs | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs index 5f9e06fda5..de84ca680d 100644 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs +++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomSubScreen.cs @@ -5,25 +5,64 @@ using System; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Extensions; +using osu.Framework.Platform; using osu.Framework.Screens; using osu.Framework.Testing; +using osu.Game.Beatmaps; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Rooms; using osu.Game.Online.Rooms.RoomStatuses; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Scoring; using osu.Game.Screens.OnlinePlay.Playlists; +using osu.Game.Tests.Resources; using osu.Game.Tests.Visual.OnlinePlay; namespace osu.Game.Tests.Visual.Playlists { public partial class TestScenePlaylistsRoomSubScreen : OnlinePlayTestScene { + private const double track_length = 10000; + [Resolved] private IAPIProvider api { get; set; } = null!; protected new TestRoomManager RoomManager => (TestRoomManager)base.RoomManager; + private BeatmapManager beatmaps = null!; + private RulesetStore rulesets = null!; + private BeatmapSetInfo? importedSet; + + [BackgroundDependencyLoader] + private void load(GameHost host, AudioManager audio) + { + Dependencies.Cache(rulesets = new RealmRulesetStore(Realm)); + Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, Realm, null, audio, Resources, host, Beatmap.Default)); + Dependencies.Cache(new ScoreManager(rulesets, () => beatmaps, LocalStorage, Realm, API)); + Dependencies.Cache(Realm); + + beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).WaitSafely(); + + Realm.Write(r => + { + foreach (var set in r.All()) + { + foreach (var b in set.Beatmaps) + { + // These will all have a virtual track length of 1000, see WorkingBeatmap.GetVirtualTrack(). + b.Length = track_length - 1000; + } + } + }); + + importedSet = beatmaps.GetAllUsableBeatmapSets().First(); + } + [Test] public void TestStatusUpdateOnEnter() { @@ -69,5 +108,42 @@ namespace osu.Game.Tests.Visual.Playlists AddAssert("close button present", () => roomScreen.ChildrenOfType().Any()); AddUntilStep("wait for close button to disappear", () => !roomScreen.ChildrenOfType().Any()); } + + [TestCase(120_000, true)] // Definitely enough time. + [TestCase(45_000, true)] // Enough time. + [TestCase(35_000, false)] // Not enough time to complete beatmap after lenience. + [TestCase(20_000, false)] // Not enough time. + [TestCase(5_000, false)] // Not enough time to complete beatmap before lenience. + [TestCase(37_500, true, 2)] // Enough time to complete beatmap after mods are applied. + public void TestReadyButtonEnablementPeriod(int offsetMs, bool enabled, double rate = 1) + { + Room room = null!; + PlaylistsRoomSubScreen roomScreen = null!; + + AddStep("create room", () => + { + RoomManager.AddRoom(room = new Room + { + Name = @"Test Room", + Host = api.LocalUser.Value, + Category = RoomCategory.Normal, + StartDate = DateTimeOffset.Now, + EndDate = DateTimeOffset.Now.AddMilliseconds(offsetMs), + Playlist = + [ + new PlaylistItem(importedSet!.Beatmaps[0]) + { + RequiredMods = rate == 1 + ? [] + : [new APIMod(new OsuModDoubleTime { SpeedChange = { Value = rate } })] + } + ] + }); + }); + + AddStep("push screen", () => LoadScreen(roomScreen = new PlaylistsRoomSubScreen(room))); + AddUntilStep("wait for screen load", () => roomScreen.IsCurrentScreen()); + AddUntilStep("ready button enabled", () => roomScreen.ChildrenOfType().SingleOrDefault()?.Enabled.Value, () => Is.EqualTo(enabled)); + } } } From 837744b0aa9ffbd2587f332721eef868ff80878d Mon Sep 17 00:00:00 2001 From: Susko3 Date: Tue, 3 Dec 2024 23:26:33 +0000 Subject: [PATCH 46/54] Use LocalisationManager.GetLocalisedString() instead of bindable hack Made possible by https://github.com/ppy/osu-framework/pull/6377. --- osu.Desktop/Windows/WindowsAssociationManager.cs | 10 +--------- .../Overlays/Settings/Sections/Input/TabletSettings.cs | 4 ++-- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/osu.Desktop/Windows/WindowsAssociationManager.cs b/osu.Desktop/Windows/WindowsAssociationManager.cs index c8066cabda..6f53c65ca9 100644 --- a/osu.Desktop/Windows/WindowsAssociationManager.cs +++ b/osu.Desktop/Windows/WindowsAssociationManager.cs @@ -148,15 +148,7 @@ namespace osu.Desktop.Windows foreach (var association in uri_associations) association.UpdateDescription(getLocalisedString(association.Description)); - string getLocalisedString(LocalisableString s) - { - if (localisation == null) - return s.ToString(); - - var b = localisation.GetLocalisedBindableString(s); - b.UnbindAll(); - return b.Value; - } + string getLocalisedString(LocalisableString s) => localisation?.GetLocalisedString(s) ?? s.ToString(); } #region Native interop diff --git a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs index 4c9320c2a6..00ffbc1120 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/TabletSettings.cs @@ -114,10 +114,10 @@ namespace osu.Game.Overlays.Settings.Sections.Input if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows || RuntimeInfo.OS == RuntimeInfo.Platform.Linux) { t.NewLine(); - var formattedSource = MessageFormatter.FormatText(localisation.GetLocalisedBindableString(TabletSettingsStrings.NoTabletDetectedDescription( + var formattedSource = MessageFormatter.FormatText(localisation.GetLocalisedString(TabletSettingsStrings.NoTabletDetectedDescription( RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? @"https://opentabletdriver.net/Wiki/FAQ/Windows" - : @"https://opentabletdriver.net/Wiki/FAQ/Linux")).Value); + : @"https://opentabletdriver.net/Wiki/FAQ/Linux"))); t.AddLinks(formattedSource.Text, formattedSource.Links); } }), From 296fa69edd24c658d7525e8fe903923abb874bfc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Dec 2024 14:30:59 +0900 Subject: [PATCH 47/54] Add "buttons" as a search term for key bindings --- osu.Game/Overlays/Settings/Sections/Input/BindingSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Input/BindingSettings.cs b/osu.Game/Overlays/Settings/Sections/Input/BindingSettings.cs index a93e6c37af..704fa6e907 100644 --- a/osu.Game/Overlays/Settings/Sections/Input/BindingSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Input/BindingSettings.cs @@ -13,7 +13,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input { protected override LocalisableString Header => BindingSettingsStrings.ShortcutAndGameplayBindings; - public override IEnumerable FilterTerms => base.FilterTerms.Concat(new LocalisableString[] { @"keybindings", @"controls", @"keyboard", @"keys" }); + public override IEnumerable FilterTerms => base.FilterTerms.Concat(new LocalisableString[] { @"keybindings", @"controls", @"keyboard", @"keys", @"buttons" }); public BindingSettings(KeyBindingPanel keyConfig) { From a4d58648e23e19ef9cda687dbb5127ba17becc14 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 4 Dec 2024 14:31:39 +0900 Subject: [PATCH 48/54] Fix quick retry transition from results screen --- osu.Game/Screens/Ranking/ResultsScreen.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Ranking/ResultsScreen.cs b/osu.Game/Screens/Ranking/ResultsScreen.cs index 0209fbd39c..507d138d90 100644 --- a/osu.Game/Screens/Ranking/ResultsScreen.cs +++ b/osu.Game/Screens/Ranking/ResultsScreen.cs @@ -55,6 +55,8 @@ namespace osu.Game.Screens.Ranking [Resolved] private Player? player { get; set; } + private bool skipExitTransition; + [Resolved] private IAPIProvider api { get; set; } = null!; @@ -203,6 +205,7 @@ namespace osu.Game.Screens.Ranking { if (!this.IsCurrentScreen()) return; + skipExitTransition = true; player?.Restart(true); }, }); @@ -313,7 +316,8 @@ namespace osu.Game.Screens.Ranking // HitObject references from HitEvent. Score?.HitEvents.Clear(); - this.FadeOut(100); + if (!skipExitTransition) + this.FadeOut(100); return false; } From ad4df82593e334b9b9c0522326655479077717f8 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Wed, 4 Dec 2024 16:26:36 +0900 Subject: [PATCH 49/54] Improve multiplayer listing search by making it fuzzy --- .../Lounge/Components/RoomsContainer.cs | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs index 17aed021b2..6eda993f94 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; +using System.Globalization; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -80,19 +81,34 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components bool matchingFilter = true; matchingFilter &= criteria.Ruleset == null || r.Room.PlaylistItemStats?.RulesetIDs.Any(id => id == criteria.Ruleset.OnlineID) != false; - - if (!string.IsNullOrEmpty(criteria.SearchString)) - { - // Room name isn't translatable, so ToString() is used here for simplicity. - matchingFilter &= r.FilterTerms.Any(term => term.ToString().Contains(criteria.SearchString, StringComparison.InvariantCultureIgnoreCase)); - } - matchingFilter &= matchPermissions(r, criteria.Permissions); + // Room name isn't translatable, so ToString() is used here for simplicity. + string[] filterTerms = r.FilterTerms.Select(t => t.ToString()).ToArray(); + string[] searchTerms = criteria.SearchString.Split(' ', StringSplitOptions.RemoveEmptyEntries); + matchingFilter &= searchTerms.All(searchTerm => filterTerms.Any(filterTerm => checkTerm(filterTerm, searchTerm))); + r.MatchingFilter = matchingFilter; } }); + // Lifted from SearchContainer. + static bool checkTerm(string haystack, string needle) + { + int index = 0; + + for (int i = 0; i < needle.Length; i++) + { + int found = CultureInfo.InvariantCulture.CompareInfo.IndexOf(haystack, needle[i], index, CompareOptions.OrdinalIgnoreCase); + if (found < 0) + return false; + + index = found + 1; + } + + return true; + } + static bool matchPermissions(DrawableLoungeRoom room, RoomPermissionsFilter accessType) { switch (accessType) From fa87df6c6af7879f1bc2e60b276724dddd3c2136 Mon Sep 17 00:00:00 2001 From: Salman Alshamrani Date: Wed, 4 Dec 2024 04:55:40 -0500 Subject: [PATCH 50/54] Move non-current handling to `PerformExit` Co-authored-by: Dean Herbert --- osu.Game/Screens/Play/Player.cs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 3a0a0613f3..1866ed26ce 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -646,7 +646,6 @@ namespace osu.Game.Screens.Play // import current score if possible. prepareAndImportScoreAsync(); - // Screen may not be current if a restart has been performed. if (this.IsCurrentScreen()) { skipExitTransition = skipTransition; @@ -657,6 +656,12 @@ namespace osu.Game.Screens.Play // - the pause / fail dialog was requested but couldn't be displayed due to the type or state of this Player instance. this.Exit(); } + else + { + // May be restarting from results screen. + if (this.GetChildScreen() != null) + this.MakeCurrent(); + } return true; } @@ -722,16 +727,6 @@ namespace osu.Game.Screens.Play skipExitTransition = quickRestart; PrepareLoaderForRestart?.Invoke(quickRestart); - if (!this.IsCurrentScreen()) - { - // if we're called externally (i.e. from results screen), - // use MakeCurrent to exit results screen as well as this player screen - // since ValidForResume = false in here - Debug.Assert(!ValidForResume); - this.MakeCurrent(); - return true; - } - return PerformExit(quickRestart); } From f83ec721fb31f9f3ac9840c246d6bf3f176fdd96 Mon Sep 17 00:00:00 2001 From: Salman Alshamrani Date: Thu, 5 Dec 2024 02:41:00 -0500 Subject: [PATCH 51/54] Move latency certifier and import files button outside debug section --- .../Sections/DebugSettings/GeneralSettings.cs | 16 +-------- .../Sections/Maintenance/GeneralSettings.cs | 36 +++++++++++++++++++ .../Settings/Sections/MaintenanceSection.cs | 1 + 3 files changed, 38 insertions(+), 15 deletions(-) create mode 100644 osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs diff --git a/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs index df46e38491..57f36e2875 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs @@ -5,11 +5,7 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Localisation; -using osu.Framework.Screens; using osu.Game.Localisation; -using osu.Game.Screens; -using osu.Game.Screens.Import; -using osu.Game.Screens.Utility; namespace osu.Game.Overlays.Settings.Sections.DebugSettings { @@ -18,7 +14,7 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings protected override LocalisableString Header => CommonStrings.General; [BackgroundDependencyLoader] - private void load(FrameworkDebugConfigManager config, FrameworkConfigManager frameworkConfig, IPerformFromScreenRunner? performer) + private void load(FrameworkDebugConfigManager config, FrameworkConfigManager frameworkConfig) { Children = new Drawable[] { @@ -32,16 +28,6 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings LabelText = DebugSettingsStrings.BypassFrontToBackPass, Current = config.GetBindable(DebugSetting.BypassFrontToBackPass) }, - new SettingsButton - { - Text = DebugSettingsStrings.ImportFiles, - Action = () => performer?.PerformFromScreen(menu => menu.Push(new FileImportScreen())) - }, - new SettingsButton - { - Text = DebugSettingsStrings.RunLatencyCertifier, - Action = () => performer?.PerformFromScreen(menu => menu.Push(new LatencyCertifierScreen())) - } }; } } diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs new file mode 100644 index 0000000000..f75fc2c8bc --- /dev/null +++ b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs @@ -0,0 +1,36 @@ +// 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.Localisation; +using osu.Framework.Screens; +using osu.Game.Localisation; +using osu.Game.Screens; +using osu.Game.Screens.Import; +using osu.Game.Screens.Utility; + +namespace osu.Game.Overlays.Settings.Sections.Maintenance +{ + public partial class GeneralSettings : SettingsSubsection + { + protected override LocalisableString Header => CommonStrings.General; + + [BackgroundDependencyLoader] + private void load(IPerformFromScreenRunner? performer) + { + Children = new[] + { + new SettingsButton + { + Text = DebugSettingsStrings.ImportFiles, + Action = () => performer?.PerformFromScreen(menu => menu.Push(new FileImportScreen())) + }, + new SettingsButton + { + Text = DebugSettingsStrings.RunLatencyCertifier, + Action = () => performer?.PerformFromScreen(menu => menu.Push(new LatencyCertifierScreen())) + } + }; + } + } +} diff --git a/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs b/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs index bd90e4c35d..f1b1511df8 100644 --- a/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs +++ b/osu.Game/Overlays/Settings/Sections/MaintenanceSection.cs @@ -23,6 +23,7 @@ namespace osu.Game.Overlays.Settings.Sections { Children = new Drawable[] { + new GeneralSettings(), new BeatmapSettings(), new SkinSettings(), new CollectionsSettings(), From 7ab16a55e561f37a4ffe07b2076f6917a46ea414 Mon Sep 17 00:00:00 2001 From: Salman Alshamrani Date: Thu, 5 Dec 2024 02:41:17 -0500 Subject: [PATCH 52/54] Make debug section only visible on debug builds --- .../Overlays/FirstRunSetup/ScreenBehaviour.cs | 5 ++- osu.Game/Overlays/SettingsOverlay.cs | 36 +++++++++++-------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/osu.Game/Overlays/FirstRunSetup/ScreenBehaviour.cs b/osu.Game/Overlays/FirstRunSetup/ScreenBehaviour.cs index 31a56c9748..d31ce7ea18 100644 --- a/osu.Game/Overlays/FirstRunSetup/ScreenBehaviour.cs +++ b/osu.Game/Overlays/FirstRunSetup/ScreenBehaviour.cs @@ -5,6 +5,7 @@ using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Development; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Localisation; @@ -90,11 +91,13 @@ namespace osu.Game.Overlays.FirstRunSetup new GraphicsSection(), new OnlineSection(), new MaintenanceSection(), - new DebugSection(), }, SearchTerm = SettingsItem.CLASSIC_DEFAULT_SEARCH_TERM, } }; + + if (DebugUtils.IsDebugBuild) + searchContainer.Add(new DebugSection()); } private void applyClassic() diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 9076dadf93..1157860e03 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -7,6 +7,7 @@ using System.Collections.Generic; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; +using osu.Framework.Development; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -27,21 +28,28 @@ namespace osu.Game.Overlays public LocalisableString Title => SettingsStrings.HeaderTitle; public LocalisableString Description => SettingsStrings.HeaderDescription; - protected override IEnumerable CreateSections() => new SettingsSection[] + protected override IEnumerable CreateSections() { - // This list should be kept in sync with ScreenBehaviour. - new GeneralSection(), - new SkinSection(), - new InputSection(createSubPanel(new KeyBindingPanel())), - new UserInterfaceSection(), - new GameplaySection(), - new RulesetSection(), - new AudioSection(), - new GraphicsSection(), - new OnlineSection(), - new MaintenanceSection(), - new DebugSection(), - }; + var sections = new List + { + // This list should be kept in sync with ScreenBehaviour. + new GeneralSection(), + new SkinSection(), + new InputSection(createSubPanel(new KeyBindingPanel())), + new UserInterfaceSection(), + new GameplaySection(), + new RulesetSection(), + new AudioSection(), + new GraphicsSection(), + new OnlineSection(), + new MaintenanceSection(), + }; + + if (DebugUtils.IsDebugBuild) + sections.Add(new DebugSection()); + + return sections; + } private readonly List subPanels = new List(); From 7c1be5eca25cdf1749329b8a9c0972711673dbe5 Mon Sep 17 00:00:00 2001 From: Salman Alshamrani Date: Thu, 5 Dec 2024 02:45:43 -0500 Subject: [PATCH 53/54] Remove unnecessary localisations --- osu.Game/Localisation/DebugSettingsStrings.cs | 25 ------------------- .../Settings/Sections/DebugSection.cs | 3 +-- .../Sections/DebugSettings/GeneralSettings.cs | 7 +++--- .../Sections/DebugSettings/MemorySettings.cs | 5 ++-- 4 files changed, 6 insertions(+), 34 deletions(-) diff --git a/osu.Game/Localisation/DebugSettingsStrings.cs b/osu.Game/Localisation/DebugSettingsStrings.cs index 066c07858c..bdb0348981 100644 --- a/osu.Game/Localisation/DebugSettingsStrings.cs +++ b/osu.Game/Localisation/DebugSettingsStrings.cs @@ -9,21 +9,6 @@ namespace osu.Game.Localisation { private const string prefix = @"osu.Game.Resources.Localisation.DebugSettings"; - /// - /// "Debug" - /// - public static LocalisableString DebugSectionHeader => new TranslatableString(getKey(@"debug_section_header"), @"Debug"); - - /// - /// "Show log overlay" - /// - public static LocalisableString ShowLogOverlay => new TranslatableString(getKey(@"show_log_overlay"), @"Show log overlay"); - - /// - /// "Bypass front-to-back render pass" - /// - public static LocalisableString BypassFrontToBackPass => new TranslatableString(getKey(@"bypass_front_to_back_pass"), @"Bypass front-to-back render pass"); - /// /// "Import files" /// @@ -34,16 +19,6 @@ namespace osu.Game.Localisation /// public static LocalisableString RunLatencyCertifier => new TranslatableString(getKey(@"run_latency_certifier"), @"Run latency certifier"); - /// - /// "Memory" - /// - public static LocalisableString MemoryHeader => new TranslatableString(getKey(@"memory_header"), @"Memory"); - - /// - /// "Clear all caches" - /// - public static LocalisableString ClearAllCaches => new TranslatableString(getKey(@"clear_all_caches"), @"Clear all caches"); - private static string getKey(string key) => $"{prefix}:{key}"; } } diff --git a/osu.Game/Overlays/Settings/Sections/DebugSection.cs b/osu.Game/Overlays/Settings/Sections/DebugSection.cs index b84c441057..15951d462b 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSection.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSection.cs @@ -6,14 +6,13 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Graphics; -using osu.Game.Localisation; using osu.Game.Overlays.Settings.Sections.DebugSettings; namespace osu.Game.Overlays.Settings.Sections { public partial class DebugSection : SettingsSection { - public override LocalisableString Header => DebugSettingsStrings.DebugSectionHeader; + public override LocalisableString Header => "Debug"; public override Drawable CreateIcon() => new SpriteIcon { diff --git a/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs index 57f36e2875..280aa685a9 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs @@ -5,13 +5,12 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Localisation; -using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.DebugSettings { public partial class GeneralSettings : SettingsSubsection { - protected override LocalisableString Header => CommonStrings.General; + protected override LocalisableString Header => "General"; [BackgroundDependencyLoader] private void load(FrameworkDebugConfigManager config, FrameworkConfigManager frameworkConfig) @@ -20,12 +19,12 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings { new SettingsCheckbox { - LabelText = DebugSettingsStrings.ShowLogOverlay, + LabelText = "Show log overlay", Current = frameworkConfig.GetBindable(FrameworkSetting.ShowLogOverlay) }, new SettingsCheckbox { - LabelText = DebugSettingsStrings.BypassFrontToBackPass, + LabelText = @"Bypass front-to-back render pass", Current = config.GetBindable(DebugSetting.BypassFrontToBackPass) }, }; diff --git a/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs b/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs index d5de7ae2db..d43abd58a8 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs @@ -11,13 +11,12 @@ using osu.Framework.Localisation; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.Database; -using osu.Game.Localisation; namespace osu.Game.Overlays.Settings.Sections.DebugSettings { public partial class MemorySettings : SettingsSubsection { - protected override LocalisableString Header => DebugSettingsStrings.MemoryHeader; + protected override LocalisableString Header => "Memory"; [BackgroundDependencyLoader] private void load(GameHost host, RealmAccess realm) @@ -29,7 +28,7 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings { new SettingsButton { - Text = DebugSettingsStrings.ClearAllCaches, + Text = "Clear all caches", Action = host.Collect }, new SettingsButton From 1b1e7b63e96717903f71e73ec775ae77bbee407f Mon Sep 17 00:00:00 2001 From: Salman Alshamrani Date: Thu, 5 Dec 2024 02:48:46 -0500 Subject: [PATCH 54/54] Clean up code slightly --- .../Overlays/Settings/Sections/DebugSection.cs | 15 +++++++-------- .../Sections/DebugSettings/GeneralSettings.cs | 4 ++-- .../Sections/DebugSettings/MemorySettings.cs | 16 ++++++++-------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/DebugSection.cs b/osu.Game/Overlays/Settings/Sections/DebugSection.cs index 15951d462b..1d2129413c 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSection.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSection.cs @@ -1,7 +1,6 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Development; using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; @@ -12,7 +11,7 @@ namespace osu.Game.Overlays.Settings.Sections { public partial class DebugSection : SettingsSection { - public override LocalisableString Header => "Debug"; + public override LocalisableString Header => @"Debug"; public override Drawable CreateIcon() => new SpriteIcon { @@ -21,12 +20,12 @@ namespace osu.Game.Overlays.Settings.Sections public DebugSection() { - Add(new GeneralSettings()); - - if (DebugUtils.IsDebugBuild) - Add(new BatchImportSettings()); - - Add(new MemorySettings()); + Children = new Drawable[] + { + new GeneralSettings(), + new BatchImportSettings(), + new MemorySettings(), + }; } } } diff --git a/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs index 280aa685a9..bd6ada4ca7 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSettings/GeneralSettings.cs @@ -10,7 +10,7 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings { public partial class GeneralSettings : SettingsSubsection { - protected override LocalisableString Header => "General"; + protected override LocalisableString Header => @"General"; [BackgroundDependencyLoader] private void load(FrameworkDebugConfigManager config, FrameworkConfigManager frameworkConfig) @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings { new SettingsCheckbox { - LabelText = "Show log overlay", + LabelText = @"Show log overlay", Current = frameworkConfig.GetBindable(FrameworkSetting.ShowLogOverlay) }, new SettingsCheckbox diff --git a/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs b/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs index d43abd58a8..b693822838 100644 --- a/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs +++ b/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings { public partial class MemorySettings : SettingsSubsection { - protected override LocalisableString Header => "Memory"; + protected override LocalisableString Header => @"Memory"; [BackgroundDependencyLoader] private void load(GameHost host, RealmAccess realm) @@ -28,27 +28,27 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings { new SettingsButton { - Text = "Clear all caches", + Text = @"Clear all caches", Action = host.Collect }, new SettingsButton { - Text = "Compact realm", + Text = @"Compact realm", Action = () => { // Blocking operations implicitly causes a Compact(). - using (realm.BlockAllOperations("compact")) + using (realm.BlockAllOperations(@"compact")) { } } }, blockAction = new SettingsButton { - Text = "Block realm", + Text = @"Block realm", }, unblockAction = new SettingsButton { - Text = "Unblock realm", + Text = @"Unblock realm", }, }; @@ -56,7 +56,7 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings { try { - IDisposable? token = realm.BlockAllOperations("maintenance"); + IDisposable? token = realm.BlockAllOperations(@"maintenance"); blockAction.Enabled.Value = false; @@ -88,7 +88,7 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings } catch (Exception e) { - Logger.Error(e, "Blocking realm failed"); + Logger.Error(e, @"Blocking realm failed"); } }; }